diff --git a/src/App.tsx b/src/App.tsx index 58a48ae..3488bf9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import { bitable, FieldType } from '@lark-base-open/js-sdk'; import { Button, Typography, List, Card, Space, Divider, Spin, Table, Select, Modal, DatePicker } from '@douyinfe/semi-ui'; import { useState, useEffect } from 'react'; -import { addDays, format, isWeekend } from 'date-fns'; +import { addDays, format } from 'date-fns'; import { zhCN } from 'date-fns/locale'; import { executePricingQuery, executeSecondaryProcessQuery, executePricingDetailsQuery } from './services/apiService'; @@ -37,14 +37,23 @@ export default function App() { // 客户期望日期状态 const [expectedDate, setExpectedDate] = useState(null); - // 预览相关状态 - const [previewLoading, setPreviewLoading] = useState(false); + // 预览相关状态(已移除未使用的 previewLoading 状态) // 时效计算相关状态 const [timelineVisible, setTimelineVisible] = useState(false); const [timelineLoading, setTimelineLoading] = useState(false); const [timelineResults, setTimelineResults] = useState([]); const [timelineAdjustments, setTimelineAdjustments] = useState<{[key: number]: number}>({}); + // 快照回填来源(foreign_id、款式、颜色) + const [currentForeignId, setCurrentForeignId] = useState(null); + const [currentStyleText, setCurrentStyleText] = useState(''); + const [currentColorText, setCurrentColorText] = useState(''); + // 功能入口模式与调整相关状态 + const [mode, setMode] = useState<'generate' | 'adjust' | null>(null); + const [modeSelectionVisible, setModeSelectionVisible] = useState(true); + const [adjustLoading, setAdjustLoading] = useState(false); + // 删除未使用的 deliveryRecords 状态 + const [selectedDeliveryRecordId, setSelectedDeliveryRecordId] = useState(''); // 指定的数据表ID和视图ID const TABLE_ID = 'tblPIJ7unndydSMu'; @@ -68,6 +77,148 @@ export default function App() { const TIMELINE_NODE_FIELD_ID = 'fldeIZzokl'; // 时效表中的节点名称字段ID const CALCULATION_METHOD_FIELD_ID = 'fldxfLZNUu'; // 时效计算方式字段ID + // 已移除:调整模式不再加载货期记录列表 + + // 入口选择处理 + const chooseMode = (m: 'generate' | 'adjust') => { + setMode(m); + setModeSelectionVisible(false); + }; + + // 根据货期记录ID读取节点详情并还原流程数据 + const loadProcessDataFromDeliveryRecord = async (deliveryRecordId: string) => { + if (!deliveryRecordId) { + if (bitable.ui.showToast) { + await bitable.ui.showToast({ toastType: 'warning', message: '请先选择一条货期记录' }); + } + return; + } + setTimelineLoading(true); + try { + const deliveryTable = await bitable.base.getTable(DELIVERY_RECORD_TABLE_ID); + const deliveryRecord = await deliveryTable.getRecordById(deliveryRecordId); + const nodeDetailsVal = deliveryRecord?.fields?.[DELIVERY_NODE_DETAILS_FIELD_ID]; + + let recordIds: string[] = []; + if (nodeDetailsVal && typeof nodeDetailsVal === 'object' && (nodeDetailsVal as any).recordIds) { + recordIds = (nodeDetailsVal as any).recordIds as string[]; + } else if (Array.isArray(nodeDetailsVal)) { + recordIds = nodeDetailsVal.map((item: any) => item?.recordId || item?.id || item).filter(Boolean); + } + + if (!recordIds || recordIds.length === 0) { + if (bitable.ui.showToast) { + await bitable.ui.showToast({ toastType: 'warning', message: '该货期记录未包含节点详情或为空' }); + } + setTimelineLoading(false); + return; + } + + const processTable = await bitable.base.getTable(PROCESS_DATA_TABLE_ID); + const records = await Promise.all(recordIds.map(id => processTable.getRecordById(id))); + + // 优先使用文本2快照一模一样还原 + try { + // 在所有记录中查找非空快照 + let snapStr: string | null = null; + for (const rec of records) { + const snapVal = rec?.fields?.[PROCESS_SNAPSHOT_JSON_FIELD_ID]; + let candidate: string | null = null; + if (typeof snapVal === 'string') { + candidate = snapVal; + } else if (Array.isArray(snapVal)) { + // 文本结构:拼接所有text片段 + const texts = snapVal + .filter((el: any) => el && el.type === 'text' && typeof el.text === 'string') + .map((el: any) => el.text); + candidate = texts.length > 0 ? texts.join('') : null; + } else if (snapVal && typeof snapVal === 'object') { + // 兼容 {text: '...'} 或 {type:'text', text:'...'} + if ((snapVal as any).text && typeof (snapVal as any).text === 'string') { + candidate = (snapVal as any).text; + } else if ((snapVal as any).type === 'text' && typeof (snapVal as any).text === 'string') { + candidate = (snapVal as any).text; + } + } + if (candidate && candidate.trim() !== '') { + snapStr = candidate; + break; + } + } + if (snapStr && snapStr.trim() !== '') { + const snapshot = JSON.parse(snapStr); + // 恢复页面状态 + if (snapshot.selectedLabels) setSelectedLabels(snapshot.selectedLabels); + if (snapshot.mode) setMode(snapshot.mode); + // 快照回填的foreign_id/款式/颜色 + if (snapshot.foreignId) setCurrentForeignId(snapshot.foreignId); + if (snapshot.styleText) setCurrentStyleText(snapshot.styleText); + if (snapshot.colorText) setCurrentColorText(snapshot.colorText); + if (snapshot.timelineAdjustments) setTimelineAdjustments(snapshot.timelineAdjustments); + if (snapshot.expectedDateTimestamp) { + setExpectedDate(new Date(snapshot.expectedDateTimestamp)); + } else if (snapshot.expectedDateString) { + setExpectedDate(new Date(snapshot.expectedDateString)); + } + if (Array.isArray(snapshot.timelineResults)) { + setTimelineResults(snapshot.timelineResults); + setTimelineVisible(true); + if (bitable.ui.showToast) { + await bitable.ui.showToast({ toastType: 'success', message: '已按快照一模一样还原流程数据' }); + } + setTimelineLoading(false); + return; // 快照还原完成,退出函数 + } + } + } catch (snapError) { + console.warn('解析快照失败,降级为基于字段的还原:', snapError); + } + + const results = records.map((rec: any) => { + const fields = rec?.fields || {}; + const processOrder = fields[PROCESS_ORDER_FIELD_ID_DATA]; + const nodeName = fields[PROCESS_NAME_FIELD_ID]; + const startTs = fields[ESTIMATED_START_DATE_FIELD_ID]; + const endTs = fields[ESTIMATED_END_DATE_FIELD_ID]; + const startDate = typeof startTs === 'number' ? new Date(startTs) : (startTs ? new Date(startTs) : null); + const endDate = typeof endTs === 'number' ? new Date(endTs) : (endTs ? new Date(endTs) : null); + return { + processOrder: typeof processOrder === 'number' ? processOrder : parseInt(processOrder) || undefined, + nodeName: typeof nodeName === 'string' ? nodeName : (nodeName?.text || ''), + estimatedStart: startDate ? format(startDate, DATE_FORMATS.STORAGE_FORMAT) : '未找到时效数据', + estimatedEnd: endDate ? format(endDate, DATE_FORMATS.STORAGE_FORMAT) : '未找到时效数据', + timelineRecordId: rec?.id || rec?.recordId || null, + timelineValue: undefined, + calculationMethod: undefined, + weekendDaysConfig: [], + matchedLabels: [], + skippedWeekends: 0, + skippedHolidays: 0, + actualDays: undefined, + startDateRule: undefined, + dateAdjustmentRule: undefined, + ruleDescription: undefined, + adjustmentDescription: undefined + }; + }); + + const sorted = results.sort((a, b) => (a.processOrder || 0) - (b.processOrder || 0)); + setTimelineResults(sorted); + setTimelineVisible(true); + + if (bitable.ui.showToast) { + await bitable.ui.showToast({ toastType: 'success', message: '已从货期记录还原流程数据' }); + } + } catch (error) { + console.error('从货期记录还原流程数据失败:', error); + if (bitable.ui.showToast) { + await bitable.ui.showToast({ toastType: 'error', message: `还原失败: ${(error as Error).message}` }); + } + } finally { + setTimelineLoading(false); + } + }; + // 流程数据表相关常量 const PROCESS_DATA_TABLE_ID = 'tblsJzCxXClj5oK5'; // 流程数据表ID const FOREIGN_ID_FIELD_ID = 'fld3oxJmpr'; // foreign_id字段 @@ -75,6 +226,9 @@ export default function App() { const PROCESS_ORDER_FIELD_ID_DATA = 'fldmND6vjT'; // 流程顺序字段 const ESTIMATED_START_DATE_FIELD_ID = 'fldlzvHjYP'; // 预计开始日期字段 const ESTIMATED_END_DATE_FIELD_ID = 'fldaPtY7Jk'; // 预计完成日期字段 + const PROCESS_SNAPSHOT_JSON_FIELD_ID = 'fldSHTxfnC'; // 文本2:用于保存计算页面快照(JSON) + const PROCESS_VERSION_FIELD_ID = 'fldwk5X7Yw'; // 版本字段 + const PROCESS_TIMELINESS_FIELD_ID = 'fldEYCXnWt'; // 时效字段(天) // 货期记录表相关常量 const DELIVERY_RECORD_TABLE_ID = 'tblwiA49gksQrnfg'; // 货期记录表ID @@ -87,6 +241,7 @@ export default function App() { const DELIVERY_NODE_DETAILS_FIELD_ID = 'fldu1KL9yC'; // 节点详情字段(需要替换为实际字段ID) const DELIVERY_CUSTOMER_EXPECTED_DATE_FIELD_ID = 'fldYNluU8D'; // 客户期望日期字段 const DELIVERY_ADJUSTMENT_INFO_FIELD_ID = 'fldNc6nNsz'; // 货期调整信息字段(需要替换为实际字段ID) + const DELIVERY_VERSION_FIELD_ID = 'fld5OmvZrn'; // 版本字段(新增) // 中国法定节假日配置(需要手动维护或使用API) const CHINESE_HOLIDAYS = [ @@ -100,19 +255,7 @@ export default function App() { // ... 其他节假日 ]; - // 获取节假日数据的函数 - const fetchHolidays = async (year: number): Promise => { - try { - // 使用免费的节假日API - const response = await fetch(`https://timor.tech/api/holiday/year/${year}`); - const data = await response.json(); - - return Object.keys(data.holiday || {}); - } catch (error) { - console.error('获取节假日数据失败:', error); - return CHINESE_HOLIDAYS; // fallback到本地配置 - } - }; + // 已移除未使用的 fetchHolidays 函数 // 这个变量声明也不需要了 // const nodeNameToOptionId = new Map(); @@ -674,8 +817,7 @@ export default function App() { } } - console.log('客户期望日期:', expectedDate ? format(expectedDate, 'yyyy-MM-dd') : '未选择'); - + // 移除冗余日志:客户期望日期输出 setTimelineLoading(true); try { // 构建业务选择的所有标签值集合(用于快速查找) @@ -691,9 +833,7 @@ export default function App() { } } - console.log('业务选择的所有标签值:', Array.from(businessLabelValues)); - - // 优化1:预先获取时效数据表的字段映射,避免重复获取 + // 已移除冗余日志:业务选择标签值 const timelineTable = await bitable.base.getTable(TIMELINE_TABLE_ID); const timelineFieldMetaList = await timelineTable.getFieldMetaList(); const timelineLabelFields: {[key: string]: string} = {}; @@ -1446,36 +1586,12 @@ export default function App() { recalculateTimeline({}); }; - // 获取时效表中标签字段ID的辅助函数 - const getTimelineLabelFieldId = async (timelineTable: any, labelKey: string) => { - try { - const fieldMetaList = await timelineTable.getFieldMetaList(); - for (const fieldMeta of fieldMetaList) { - if (fieldMeta.name === labelKey) { - return fieldMeta.id; - } - } - } catch (error) { - console.warn(`获取时效表${labelKey}字段ID失败:`, error); - } - return null; - }; + // 已移除未使用的 getTimelineLabelFieldId 辅助函数 // 写入货期记录表的函数 const writeToDeliveryRecordTable = async (timelineResults: any[], processRecordIds: string[], timelineAdjustments: {[key: number]: number} = {}) => { try { - console.log('开始写入货期记录表'); - console.log('货期记录表ID:', DELIVERY_RECORD_TABLE_ID); - console.log('各字段ID:', { - DELIVERY_FOREIGN_ID_FIELD_ID, - DELIVERY_LABELS_FIELD_ID, - DELIVERY_STYLE_FIELD_ID, - DELIVERY_COLOR_FIELD_ID, - DELIVERY_CREATE_TIME_FIELD_ID, - DELIVERY_EXPECTED_DATE_FIELD_ID, - DELIVERY_NODE_DETAILS_FIELD_ID, - DELIVERY_CUSTOMER_EXPECTED_DATE_FIELD_ID - }); + // 写入货期记录表 // 获取货期记录表 const deliveryRecordTable = await bitable.base.getTable(DELIVERY_RECORD_TABLE_ID); @@ -1503,8 +1619,9 @@ export default function App() { const nodeDetailsField = await deliveryRecordTable.getField(DELIVERY_NODE_DETAILS_FIELD_ID); const customerExpectedDateField = await deliveryRecordTable.getField(DELIVERY_CUSTOMER_EXPECTED_DATE_FIELD_ID); const adjustmentInfoField = await deliveryRecordTable.getField(DELIVERY_ADJUSTMENT_INFO_FIELD_ID); + const versionField = await deliveryRecordTable.getField(DELIVERY_VERSION_FIELD_ID); - // 获取foreign_id(从选择的记录中获取fldpvBfeC0字段) + // 获取foreign_id:优先使用选择记录,其次记录详情,最后快照回填 let foreignId = ''; if (selectedRecords.length > 0) { const table = await bitable.base.getTable(TABLE_ID); @@ -1524,36 +1641,52 @@ export default function App() { foreignId = fieldValue.text; } } - - // 获取款式(从选择记录中获取fld6Uw95kt) - let style = ''; - if (selectedRecords.length > 0) { - const table = await bitable.base.getTable(TABLE_ID); - const firstRecord = await table.getRecordById(selectedRecords[0]); - const styleValue = firstRecord.fields['fld6Uw95kt']; - - if (Array.isArray(styleValue) && styleValue.length > 0) { - style = styleValue[0]?.text || styleValue[0] || ''; - } else if (typeof styleValue === 'string') { - style = styleValue; - } else if (styleValue && styleValue.text) { - style = styleValue.text; + // 回退:记录详情 + if (!foreignId && recordDetails.length > 0) { + const first = recordDetails[0]; + const val = first.fields['fldpvBfeC0']; + if (Array.isArray(val) && val.length > 0) { + const item = val[0]; + foreignId = typeof item === 'string' ? item : (item?.text || item?.name || ''); + } else if (typeof val === 'string') { + foreignId = val; + } else if (val && typeof val === 'object') { + foreignId = val.text || val.name || ''; } } + // 回退:快照状态 + if (!foreignId && currentForeignId) { + foreignId = currentForeignId; + } - // 获取颜色(从选择记录中获取flde85ni4O) + // 获取款式与颜色:优先使用记录详情或快照回填,避免重复请求 + let style = ''; let color = ''; - if (selectedRecords.length > 0) { - const table = await bitable.base.getTable(TABLE_ID); - const firstRecord = await table.getRecordById(selectedRecords[0]); - const colorValue = firstRecord.fields['flde85ni4O']; - - if (Array.isArray(colorValue) && colorValue.length > 0) { - color = colorValue[0]?.text || colorValue[0] || ''; - } else if (typeof colorValue === 'string') { - color = colorValue; - } else if (colorValue && colorValue.text) { - color = colorValue.text; + const extractText = (val: any) => { + if (Array.isArray(val) && val.length > 0) { + const item = val[0]; + return typeof item === 'string' ? item : (item?.text || item?.name || ''); + } else if (typeof val === 'string') { + return val; + } else if (val && typeof val === 'object') { + return val.text || val.name || ''; + } + return ''; + }; + if (recordDetails.length > 0) { + const first = recordDetails[0]; + style = extractText(first.fields['fld6Uw95kt']) || currentStyleText || ''; + color = extractText(first.fields['flde85ni4O']) || currentColorText || ''; + } else { + // 回退:使用快照回填的状态 + style = currentStyleText || ''; + color = currentColorText || ''; + // 若仍为空且有选择记录,仅做一次读取 + if ((!style || !color) && selectedRecords.length > 0) { + const table = await bitable.base.getTable(TABLE_ID); + const firstRecord = await table.getRecordById(selectedRecords[0]); + style = style || extractText(firstRecord.fields['fld6Uw95kt']); + color = color || extractText(firstRecord.fields['flde85ni4O']); } } @@ -1582,28 +1715,38 @@ export default function App() { // 创建当前时间戳 const currentTime = new Date().getTime(); - // 格式化货期调整信息 - let adjustmentInfo = ''; + // 计算版本号(数字)并格式化货期调整信息 + let versionNumber = 1; + try { + if (foreignId) { + const existing = await deliveryRecordTable.getRecords({ + pageSize: 5000, + filter: { + conjunction: 'and', + conditions: [{ + fieldId: DELIVERY_FOREIGN_ID_FIELD_ID, + operator: 'is', + value: [foreignId] + }] + } + }); + const count = existing.records?.length || 0; + versionNumber = count + 1; + } + } catch (e) { + console.warn('计算版本号失败:', e); + } + + let adjustmentInfo = `版本:V${versionNumber}`; if (Object.keys(timelineAdjustments).length > 0) { const adjustmentTexts = Object.entries(timelineAdjustments).map(([nodeIndex, adjustment]) => { const nodeName = timelineResults[parseInt(nodeIndex)]?.nodeName || `节点${parseInt(nodeIndex) + 1}`; return `${nodeName}: ${adjustment > 0 ? '+' : ''}${adjustment.toFixed(1)} 天`; }); - adjustmentInfo = `当前调整:\n${adjustmentTexts.join('\n')}`; + adjustmentInfo += `\n当前调整:\n${adjustmentTexts.join('\n')}`; } - // 在创建Cell之前添加数据验证 - console.log('准备写入的数据:', { - foreignId, - selectedLabelValues, - style, - color, - currentTime, - expectedDeliveryDate, - customerExpectedDate, - processRecordIds, - adjustmentInfo - }); + // 在创建Cell之前进行数据校验(移除冗余日志) // 使用createCell方法创建各个字段的Cell const foreignIdCell = await foreignIdField.createCell(foreignId); @@ -1618,9 +1761,11 @@ export default function App() { await nodeDetailsField.createCell({ recordIds: processRecordIds }) : null; // 创建货期调整信息Cell const adjustmentInfoCell = adjustmentInfo ? await adjustmentInfoField.createCell(adjustmentInfo) : null; + // 创建版本号Cell(数字) + const versionCell = await versionField.createCell(versionNumber); // 组合所有Cell到一个记录中 - const recordCells = [foreignIdCell, styleCell, colorCell, createTimeCell]; + const recordCells = [foreignIdCell, styleCell, colorCell, createTimeCell, versionCell]; // 只有当数据存在时才添加对应的Cell if (labelsCell) recordCells.push(labelsCell); @@ -1630,14 +1775,7 @@ export default function App() { if (adjustmentInfoCell) recordCells.push(adjustmentInfoCell); // 添加记录到货期记录表 - console.log('准备添加记录,Cell数量:', recordCells.length); - console.log('recordCells详情:', recordCells.map(cell => ({ - fieldId: cell.fieldId, - value: cell.value - }))); - const addedRecord = await deliveryRecordTable.addRecord(recordCells); - console.log('成功写入货期记录表,记录ID:', addedRecord); return addedRecord; } catch (error) { @@ -1673,6 +1811,9 @@ export default function App() { const processOrderField = await processDataTable.getField(PROCESS_ORDER_FIELD_ID_DATA); const startDateField = await processDataTable.getField(ESTIMATED_START_DATE_FIELD_ID); const endDateField = await processDataTable.getField(ESTIMATED_END_DATE_FIELD_ID); + const snapshotField = await processDataTable.getField(PROCESS_SNAPSHOT_JSON_FIELD_ID); + const versionField = await processDataTable.getField(PROCESS_VERSION_FIELD_ID); + const timelinessField = await processDataTable.getField(PROCESS_TIMELINESS_FIELD_ID); // 获取foreign_id - 修改这部分逻辑 let foreignId = null; @@ -1706,6 +1847,12 @@ export default function App() { } } + // 快照回填:在调整模式通过快照还原时使用当前foreign_id状态 + if (!foreignId && currentForeignId) { + foreignId = currentForeignId; + console.log('使用快照恢复的foreign_id:', foreignId); + } + if (!foreignId) { console.warn('未找到foreign_id,跳过写入流程数据表'); if (bitable.ui.showToast) { @@ -1748,6 +1895,85 @@ export default function App() { // 继续执行,不中断流程 } + // 构建页面快照JSON(确保可一模一样还原) + // 计算版本号:数字。默认按 foreign_id 在货期记录表的记录数量 + 1 + let versionNumber = 1; + try { + const deliveryRecordTable = await bitable.base.getTable(DELIVERY_RECORD_TABLE_ID); + if (mode === 'adjust' && selectedDeliveryRecordId) { + // 调整模式:基于选中货期记录版本 +1 + const srcRecord = await deliveryRecordTable.getRecordById(selectedDeliveryRecordId); + const vVal = srcRecord?.fields?.[DELIVERY_VERSION_FIELD_ID]; + let baseVersion = 0; + if (typeof vVal === 'number') baseVersion = vVal; + else if (typeof vVal === 'string') baseVersion = parseInt(vVal) || 0; + else if (vVal && typeof vVal === 'object' && vVal.value !== undefined) baseVersion = vVal.value || 0; + versionNumber = baseVersion + 1; + } else if (foreignId) { + const existing = await deliveryRecordTable.getRecords({ + pageSize: 5000, + filter: { + conjunction: 'and', + conditions: [{ + fieldId: DELIVERY_FOREIGN_ID_FIELD_ID, + operator: 'is', + value: [foreignId] + }] + } + }); + const count = existing.records?.length || 0; + versionNumber = count + 1; + } + } catch (e) { + console.warn('计算版本号失败:', e); + } + + const expectedDateTimestamp = expectedDate ? expectedDate.getTime() : null; + const expectedDateString = expectedDate ? format(expectedDate, DATE_FORMATS.STORAGE_FORMAT) : null; + + // 从记录详情提取款式和颜色,用于快照存档(回填写入来源) + let styleText = ''; + let colorText = ''; + if (recordDetails.length > 0) { + const firstRecord = recordDetails[0]; + const styleFieldValue = firstRecord.fields['fld6Uw95kt']; + if (Array.isArray(styleFieldValue) && styleFieldValue.length > 0) { + const firstItem = styleFieldValue[0]; + styleText = typeof firstItem === 'string' ? firstItem : (firstItem?.text || firstItem?.name || ''); + } else if (typeof styleFieldValue === 'string') { + styleText = styleFieldValue; + } else if (styleFieldValue && typeof styleFieldValue === 'object') { + styleText = (styleFieldValue.text || styleFieldValue.name || ''); + } + + const colorFieldValue = firstRecord.fields['flde85ni4O']; + if (Array.isArray(colorFieldValue) && colorFieldValue.length > 0) { + const firstItemC = colorFieldValue[0]; + colorText = typeof firstItemC === 'string' ? firstItemC : (firstItemC?.text || firstItemC?.name || ''); + } else if (typeof colorFieldValue === 'string') { + colorText = colorFieldValue; + } else if (colorFieldValue && typeof colorFieldValue === 'object') { + colorText = (colorFieldValue.text || colorFieldValue.name || ''); + } + } + // 快照回填的备用值 + if (!styleText && currentStyleText) styleText = currentStyleText; + if (!colorText && currentColorText) colorText = currentColorText; + + const pageSnapshot = { + version: versionNumber, + foreignId, + styleText, + colorText, + mode, + selectedLabels, + expectedDateTimestamp, + expectedDateString, + timelineAdjustments, + timelineResults + }; + const snapshotJson = JSON.stringify(pageSnapshot); + // 使用createCell方法准备要写入的记录数据 const recordCellsToAdd = []; @@ -1796,15 +2022,23 @@ export default function App() { const endDateCell = endTimestamp ? await endDateField.createCell(endTimestamp) : null; // 组合所有Cell到一个记录中 + const snapshotCell = await snapshotField.createCell(snapshotJson); + const versionCell = await versionField.createCell(versionNumber); + const timelinessCell = (typeof result.timelineValue === 'number') + ? await timelinessField.createCell(result.timelineValue) + : null; const recordCells = [ foreignIdCell, processNameCell, - processOrderCell + processOrderCell, + snapshotCell, + versionCell ]; // 只有当时间戳存在时才添加日期Cell if (startDateCell) recordCells.push(startDateCell); if (endDateCell) recordCells.push(endDateCell); + if (timelinessCell) recordCells.push(timelinessCell); console.log(`准备写入的Cell记录 - ${result.nodeName}:`, recordCells); recordCellsToAdd.push(recordCells); @@ -2064,6 +2298,7 @@ export default function App() { // 获取记录详情的函数 const fetchRecordDetails = async (recordIdList: string[]) => { + try { const table = await bitable.base.getTable(TABLE_ID); @@ -2091,6 +2326,7 @@ export default function App() { // 选择记录 const handleSelectRecords = async () => { + setLoading(true); // 清空标签选择 setSelectedLabels({}); @@ -2374,7 +2610,92 @@ export default function App() { return (
- 数据查询工具 + {/* 入口选择弹窗 */} + setModeSelectionVisible(false)} + maskClosable={false} + > +
+ chooseMode('generate')} + > + 生成流程日期 + 基于业务数据计算并生成节点时间线 +
+ +
+
+ chooseMode('adjust')} + > + 调整流程日期 + 读取货期记录,精确还原时间线 +
+ +
+
+
+
+ + {mode === 'generate' && 数据查询工具} + {/* 功能入口切换与调整入口 */} + {mode !== null && ( +
+ +