1
1
This commit is contained in:
199
src/App.tsx
199
src/App.tsx
@ -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,10 +144,15 @@ 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 = {
|
||||
@ -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,16 +736,14 @@ 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>
|
||||
)}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user