1
This commit is contained in:
2025-07-31 14:01:14 +08:00
parent 33b800869d
commit 0ca23f97db

View File

@ -23,6 +23,8 @@ interface ProcessRecord {
recordId: string;
fields: Record<string, any>;
displayData: Record<string, string>;
// 新增:记录是否可插入
canInsert: boolean;
}
interface AppState {
@ -34,13 +36,16 @@ interface AppState {
currentProgress: string | null;
nextProgress: string | null;
parallelProgress: string[];
// 新增:当前进度的流程顺序值
currentProgressOrder: number | null;
}
// 修改接口定义
interface InsertState {
modalVisible: boolean;
currentRecord: ProcessRecord | null;
direction: 'up' | 'down' | null;
selectedTemplate: string[];
selectedTemplate: string; // 改为单选
templateOptions: { label: string; value: string }[];
}
@ -50,6 +55,8 @@ interface TableState {
posRecordIdFieldId: string | null;
tableColumns: any[];
allTableColumns: any[];
// 新增流程顺序字段ID
processOrderFieldId: string | null;
}
export default function App() {
@ -61,14 +68,15 @@ export default function App() {
showAllColumns: false,
currentProgress: null,
nextProgress: null,
parallelProgress: []
parallelProgress: [],
currentProgressOrder: null
});
const [insertState, setInsertState] = useState<InsertState>({
modalVisible: false,
currentRecord: null,
direction: null,
selectedTemplate: [],
selectedTemplate: '', // 改为空字符串
templateOptions: []
});
@ -77,7 +85,8 @@ export default function App() {
processTable: null,
posRecordIdFieldId: null,
tableColumns: [],
allTableColumns: []
allTableColumns: [],
processOrderFieldId: null
});
// 工具函数
@ -135,11 +144,16 @@ export default function App() {
const processFields = await processTable.getFieldMetaList();
const posRecordIdField = processFields.find(field => field.name === CONSTANTS.POS_RECORD_ID_FIELD_NAME);
const processOrderField = processFields.find(field => field.name === CONSTANTS.PROCESS_ORDER_FIELD);
if (!posRecordIdField) {
throw new Error(`在表格 ${CONSTANTS.PROCESS_TABLE_NAME} 中未找到字段: ${CONSTANTS.POS_RECORD_ID_FIELD_NAME}`);
}
if (!processOrderField) {
throw new Error(`在表格 ${CONSTANTS.PROCESS_TABLE_NAME} 中未找到字段: ${CONSTANTS.PROCESS_ORDER_FIELD}`);
}
// 设置表格列
const actionColumn = {
title: '操作',
@ -170,6 +184,7 @@ export default function App() {
posTable,
processTable,
posRecordIdFieldId: posRecordIdField.id,
processOrderFieldId: processOrderField.id,
allTableColumns: allColumns,
tableColumns: visibleColumns
});
@ -247,7 +262,7 @@ export default function App() {
}
});
return { recordId: record.recordId, fields, displayData };
return { recordId: record.recordId, fields, displayData, canInsert: false };
})
);
@ -282,7 +297,8 @@ export default function App() {
let progressInfo = {
currentProgress: null as string | null,
nextProgress: null as string | null,
parallelProgress: [] as string[]
parallelProgress: [] as string[],
currentProgressOrder: null as number | null
};
// 计算进度信息
@ -294,7 +310,17 @@ export default function App() {
if (currentProgressRecord) {
progressInfo.currentProgress = currentProgressRecord.displayData[processNameField.id];
const currentOrder = Number(currentProgressRecord.fields[orderField.id]);
progressInfo.currentProgressOrder = Number(currentProgressRecord.fields[orderField.id]);
// 计算哪些记录可以显示插入按钮(当前进度及之后的记录)
records.forEach(record => {
const recordOrder = Number(record.fields[orderField.id]);
record.canInsert = !isNaN(recordOrder) &&
progressInfo.currentProgressOrder !== null &&
recordOrder >= progressInfo.currentProgressOrder;
});
const currentOrder = progressInfo.currentProgressOrder;
const nextRecords = records
.filter(record => {
@ -336,80 +362,24 @@ export default function App() {
// 加载模板选项
const loadTemplateOptions = async () => {
let { posTable } = tableState;
// 暂时关闭从pos_订单基础明细表读取流程模板的功能
// 改为使用固定的选项列表
const fixedOptions = [
{ label: '复版2', value: '复版2' },
{ label: '复版3', value: '复版3' },
{ label: '拍照版2', value: '拍照版2' },
{ label: '拍照版3', value: '拍照版3' }
];
if (!posTable) {
try {
const tableList = await bitable.base.getTableList();
const tables = await Promise.all(
tableList.map(async table => ({ table, name: await table.getName() }))
);
posTable = tables.find(t => t.name === CONSTANTS.POS_TABLE_NAME)?.table || null;
if (!posTable) throw new Error('POS表未找到');
updateTableState({ posTable });
} catch (error) {
Toast.error('POS表初始化失败');
return;
}
}
try {
const posFields = await posTable.getFieldMetaList();
const templateField = posFields.find(field => field.name === CONSTANTS.TEMPLATE_FIELD_NAME);
if (!templateField) {
Toast.error('未找到[流程模板]字段');
return;
}
let options: { label: string; value: string }[] = [];
if (templateField.type === FieldType.MultiSelect) {
const field = await posTable.getField<IMultiSelectField>(templateField.id);
const fieldOptions = await field.getOptions();
options = fieldOptions.map(option => ({ label: option.name, value: option.id }));
} else if (templateField.type === FieldType.SingleSelect) {
const field = await posTable.getField<ISingleSelectField>(templateField.id);
const fieldOptions = await field.getOptions();
options = fieldOptions.map(option => ({ label: option.name, value: option.id }));
} else {
const records = await posTable.getRecords({ pageSize: 1000 });
const uniqueTemplates = new Set<string>();
for (const record of records.records) {
const fields = await record.fields;
const templateValue = fields[templateField.id];
if (typeof templateValue === 'string') {
uniqueTemplates.add(templateValue);
} else if (Array.isArray(templateValue)) {
templateValue.forEach(value => {
const text = typeof value === 'object' && value.text ? value.text : String(value);
if (text) uniqueTemplates.add(text);
});
} else if (templateValue?.text) {
uniqueTemplates.add(templateValue.text);
}
}
options = Array.from(uniqueTemplates).map(template => ({
label: template,
value: template
}));
}
updateInsertState({ templateOptions: options });
} catch (error) {
Toast.error(`获取流程模板选项失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
updateInsertState({ templateOptions: fixedOptions });
};
// 处理插入确认
const handleInsertConfirm = async () => {
const { selectedTemplate, currentRecord, direction } = insertState;
if (!selectedTemplate.length) {
Toast.warning('请选择一个或多个流程模板');
if (!selectedTemplate) {
Toast.warning('请选择一个流程模板');
return;
}
@ -431,12 +401,59 @@ export default function App() {
const newOrder = Number(currentOrder) + (direction === 'up' ? -0.1 : 0.1);
// 获取pos表当前选择记录中的流程模板数据
let posTemplateData = null;
let posAdditionalData = {}; // 新增存储额外的pos表数据
if (tableState.posTable && appState.selectedRecordId) {
try {
const posFields = await tableState.posTable.getFieldMetaList();
const templateField = posFields.find(field => field.name === CONSTANTS.TEMPLATE_FIELD_NAME);
// 获取pos记录
const posRecord = await tableState.posTable.getRecordById(appState.selectedRecordId);
// 获取流程模板数据
if (templateField) {
const templateValue = posRecord.fields[templateField.id];
// 根据字段类型处理数据
if (templateField.type === FieldType.MultiSelect || templateField.type === FieldType.SingleSelect) {
posTemplateData = templateValue;
} else {
posTemplateData = templateValue;
}
}
// 获取新增的三个字段数据
const salesOrderTimeField = posFields.find(field => field.name === '下销售单时间');
const styleSKCField = posFields.find(field => field.name === '款式SKC');
const poField = posFields.find(field => field.name === 'PO1');
if (salesOrderTimeField) {
posAdditionalData['下销售单时间'] = posRecord.fields[salesOrderTimeField.id];
}
if (styleSKCField) {
posAdditionalData['款式SKC'] = posRecord.fields[styleSKCField.id];
}
if (poField) {
posAdditionalData['PO1'] = posRecord.fields[poField.id];
}
} catch (error) {
console.warn('获取pos表数据失败:', error);
}
}
const callbackData = {
selectedTemplates: selectedTemplate,
selectedTemplates: [selectedTemplate], // 包装为数组发送
processOrder: currentOrder,
insertDirection: direction,
newProcessOrder: newOrder,
recordId: appState.selectedRecordId,
posTemplateData: posTemplateData,
"下销售单时间": posAdditionalData['下销售单时间'],
"款式SKC": posAdditionalData['款式SKC'],
"PO": posAdditionalData['PO'],
timestamp: new Date().toISOString()
};
@ -463,13 +480,18 @@ export default function App() {
modalVisible: false,
currentRecord: null,
direction: null,
selectedTemplate: [],
selectedTemplate: '', // 改为空字符串
templateOptions: []
});
};
// 渲染插入按钮
// 渲染插入按钮 - 添加了权限判断
const renderInsertButton = (record: ProcessRecord) => {
// 如果当前记录不可插入,则不显示按钮
if (!record.canInsert) {
return null;
}
const handleDirectionSelect = (direction: 'up' | 'down') => {
updateInsertState({
direction,
@ -546,7 +568,7 @@ export default function App() {
// 渲染组件
const renderProgressInfo = () => {
const { currentProgress, nextProgress, parallelProgress } = appState;
const { currentProgress, nextProgress, parallelProgress, currentProgressOrder } = appState;
if (!currentProgress && !nextProgress) return null;
return (
@ -561,7 +583,7 @@ export default function App() {
</Typography.Text>
<Typography.Text strong style={{ fontSize: 16, color: '#165DFF' }}>
{currentProgress}
{currentProgress} {currentProgressOrder ? `(顺序: ${currentProgressOrder})` : ''}
</Typography.Text>
</div>
)}
@ -603,7 +625,8 @@ export default function App() {
2. ID<br/>
3. <Typography.Text code>{CONSTANTS.PROCESS_TABLE_NAME}</Typography.Text> <Typography.Text code>{CONSTANTS.POS_RECORD_ID_FIELD_NAME}</Typography.Text> <br/>
4. <br/>
5. "展开所有字段"
5. "展开所有字段"<br/>
6.
</Typography.Paragraph>
</Card>
);
@ -692,17 +715,17 @@ export default function App() {
onCancel={resetInsertState}
>
<div style={{ marginBottom: '16px' }}>
<Typography.Text></Typography.Text>
<Typography.Text></Typography.Text>
</div>
<Select
value={insertState.selectedTemplate}
onChange={(value) => updateInsertState({ selectedTemplate: value })}
placeholder="请选择流程模板"
placeholder="单选"
style={{ width: '100%' }}
showClear
multiple
maxTagCount={3}
// 移除 multiple 属性
// 移除 maxTagCount 属性
filter
emptyContent={insertState.templateOptions.length === 0 ? '暂无选项' : '未找到匹配项'}
>
@ -713,12 +736,10 @@ export default function App() {
))}
</Select>
{insertState.selectedTemplate.length > 0 && (
{insertState.selectedTemplate && ( // 改为检查字符串
<div style={{ marginTop: '12px', color: '#666' }}>
<Typography.Text type="secondary">
: {insertState.selectedTemplate.map(id =>
insertState.templateOptions.find(opt => opt.value === id)?.label
).filter(Boolean).join(', ')}
: {insertState.templateOptions.find(opt => opt.value === insertState.selectedTemplate)?.label}
</Typography.Text>
</div>
)}