diff --git a/src/App.tsx b/src/App.tsx index 3488bf9..81a9d97 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -36,6 +36,8 @@ export default function App() { // 客户期望日期状态 const [expectedDate, setExpectedDate] = useState(null); + // 起始时间状态(默认当前时间,用于驱动所有节点时间) + const [startTime, setStartTime] = useState(new Date()); // 预览相关状态(已移除未使用的 previewLoading 状态) @@ -48,12 +50,14 @@ export default function App() { const [currentForeignId, setCurrentForeignId] = useState(null); const [currentStyleText, setCurrentStyleText] = useState(''); const [currentColorText, setCurrentColorText] = useState(''); + const [currentVersionNumber, setCurrentVersionNumber] = useState(null); // 功能入口模式与调整相关状态 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'; @@ -149,17 +153,37 @@ export default function App() { const snapshot = JSON.parse(snapStr); // 恢复页面状态 if (snapshot.selectedLabels) setSelectedLabels(snapshot.selectedLabels); - if (snapshot.mode) setMode(snapshot.mode); - // 快照回填的foreign_id/款式/颜色 + // 保留当前模式,不覆写为快照的模式(避免调整模式被还原为生成模式) + if (!mode && 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.version !== undefined) { + let vNum: number | null = null; + if (typeof snapshot.version === 'number') { + vNum = snapshot.version; + } else if (typeof snapshot.version === 'string') { + const match = snapshot.version.match(/\d+/); + if (match) { + vNum = parseInt(match[0], 10); + } + } + if (vNum !== null && !isNaN(vNum)) setCurrentVersionNumber(vNum); + } if (snapshot.timelineAdjustments) setTimelineAdjustments(snapshot.timelineAdjustments); if (snapshot.expectedDateTimestamp) { setExpectedDate(new Date(snapshot.expectedDateTimestamp)); } else if (snapshot.expectedDateString) { setExpectedDate(new Date(snapshot.expectedDateString)); } + // 回填起始时间(优先时间戳,其次字符串) + if (snapshot.startTimestamp) { + setStartTime(new Date(snapshot.startTimestamp)); + } else if (snapshot.startString) { + const parsed = new Date(snapshot.startString); + if (!isNaN(parsed.getTime())) setStartTime(parsed); + } if (Array.isArray(snapshot.timelineResults)) { setTimelineResults(snapshot.timelineResults); setTimelineVisible(true); @@ -242,6 +266,8 @@ export default function App() { const DELIVERY_CUSTOMER_EXPECTED_DATE_FIELD_ID = 'fldYNluU8D'; // 客户期望日期字段 const DELIVERY_ADJUSTMENT_INFO_FIELD_ID = 'fldNc6nNsz'; // 货期调整信息字段(需要替换为实际字段ID) const DELIVERY_VERSION_FIELD_ID = 'fld5OmvZrn'; // 版本字段(新增) + // 起始时间字段(货期记录表新增) + const DELIVERY_START_TIME_FIELD_ID = 'fld727qCAv'; // 中国法定节假日配置(需要手动维护或使用API) const CHINESE_HOLIDAYS = [ @@ -1076,7 +1102,7 @@ export default function App() { const results: any[] = []; // 3. 按顺序为每个匹配的流程节点查找时效数据并计算累积时间 - let cumulativeStartTime = new Date(); // 累积开始时间 + let cumulativeStartTime = startTime ? new Date(startTime) : new Date(); // 累积开始时间 for (let i = 0; i < matchedProcessNodes.length; i++) { const processNode = matchedProcessNodes[i]; @@ -1467,9 +1493,13 @@ export default function App() { const currentAdjustment = newAdjustments[nodeIndex] || 0; const newAdjustment = currentAdjustment + adjustment; - // 防止调整后的时效值小于0 - const originalValue = timelineResults[nodeIndex]?.timelineValue || 0; - if (originalValue + newAdjustment < 0) { + // 防止调整后的时效值小于0(优先使用原始时效值,其次使用上次重算后的值) + const baseValue = (typeof timelineResults[nodeIndex]?.timelineValue === 'number') + ? timelineResults[nodeIndex]!.timelineValue + : (typeof timelineResults[nodeIndex]?.adjustedTimelineValue === 'number') + ? timelineResults[nodeIndex]!.adjustedTimelineValue + : 0; + if (baseValue + newAdjustment < 0) { return; } @@ -1483,13 +1513,17 @@ export default function App() { // 重新计算时间线的函数 const recalculateTimeline = (adjustments: {[key: number]: number}) => { const updatedResults = [...timelineResults]; - let cumulativeStartTime = new Date(); // 从当前时间开始 + let cumulativeStartTime = startTime ? new Date(startTime) : new Date(); // 从起始时间开始 for (let i = 0; i < updatedResults.length; i++) { const result = updatedResults[i]; - const originalTimelineValue = result.timelineValue || 0; + const baseTimelineValue = (typeof result.timelineValue === 'number') + ? result.timelineValue + : (typeof result.adjustedTimelineValue === 'number') + ? result.adjustedTimelineValue + : 0; const adjustment = adjustments[i] || 0; - const adjustedTimelineValue = originalTimelineValue + adjustment; + const adjustedTimelineValue = baseTimelineValue + adjustment; // 计算当前节点的开始时间 let nodeStartTime = new Date(cumulativeStartTime); @@ -1580,6 +1614,13 @@ export default function App() { setTimelineResults(updatedResults); }; + // 当起始时间变更时,重新以最新起始时间为基准重算全流程 + useEffect(() => { + if (timelineResults.length > 0) { + recalculateTimeline(timelineAdjustments); + } + }, [startTime]); + // 重置调整的函数 const resetTimelineAdjustments = () => { setTimelineAdjustments({}); @@ -1606,7 +1647,8 @@ export default function App() { DELIVERY_EXPECTED_DATE_FIELD_ID, DELIVERY_CUSTOMER_EXPECTED_DATE_FIELD_ID, DELIVERY_NODE_DETAILS_FIELD_ID, - DELIVERY_ADJUSTMENT_INFO_FIELD_ID // 添加货期调整信息字段 + DELIVERY_ADJUSTMENT_INFO_FIELD_ID, // 添加货期调整信息字段 + DELIVERY_START_TIME_FIELD_ID // 新增:起始时间字段 ]; // 获取各个字段 @@ -1620,6 +1662,7 @@ export default function App() { 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); + const startTimeField = await deliveryRecordTable.getField(DELIVERY_START_TIME_FIELD_ID); // 获取foreign_id:优先使用选择记录,其次记录详情,最后快照回填 let foreignId = ''; @@ -1718,7 +1761,10 @@ export default function App() { // 计算版本号(数字)并格式化货期调整信息 let versionNumber = 1; try { - if (foreignId) { + if (mode === 'adjust' && currentVersionNumber !== null) { + // 调整模式:优先使用快照version +1 + versionNumber = currentVersionNumber + 1; + } else if (foreignId) { const existing = await deliveryRecordTable.getRecords({ pageSize: 5000, filter: { @@ -1754,6 +1800,8 @@ export default function App() { const styleCell = await styleField.createCell(style); const colorCell = await colorField.createCell(color); const createTimeCell = await createTimeField.createCell(currentTime); + const startTimestamp = startTime ? startTime.getTime() : currentTime; + const startTimeCell = await startTimeField.createCell(startTimestamp); const expectedDateCell = expectedDeliveryDate ? await expectedDateField.createCell(expectedDeliveryDate) : null; const customerExpectedDateCell = customerExpectedDate ? await customerExpectedDateField.createCell(customerExpectedDate) : null; // 对于关联记录字段,确保传入的是记录ID数组 @@ -1765,7 +1813,7 @@ export default function App() { const versionCell = await versionField.createCell(versionNumber); // 组合所有Cell到一个记录中 - const recordCells = [foreignIdCell, styleCell, colorCell, createTimeCell, versionCell]; + const recordCells = [foreignIdCell, styleCell, colorCell, createTimeCell, startTimeCell, versionCell]; // 只有当数据存在时才添加对应的Cell if (labelsCell) recordCells.push(labelsCell); @@ -1900,15 +1948,9 @@ export default function App() { 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; + if (mode === 'adjust' && currentVersionNumber !== null) { + // 调整模式:优先使用快照version +1,避免公式字段读取错误 + versionNumber = currentVersionNumber + 1; } else if (foreignId) { const existing = await deliveryRecordTable.getRecords({ pageSize: 5000, @@ -1969,6 +2011,8 @@ export default function App() { selectedLabels, expectedDateTimestamp, expectedDateString, + startTimestamp: startTime ? startTime.getTime() : undefined, + startString: startTime ? formatDate(startTime, 'STORAGE_FORMAT') : undefined, timelineAdjustments, timelineResults }; @@ -2755,10 +2799,27 @@ export default function App() { ) : (
+
+ 起始时间 + { + setStartTime(date); + }} + type="dateTime" + format="yyyy-MM-dd HH:mm" + /> +
{timelineResults.map((result, index) => { const adjustment = timelineAdjustments[index] || 0; - const originalValue = result.timelineValue || 0; - const adjustedValue = originalValue + adjustment; + const baseValue = (typeof result.timelineValue === 'number') + ? result.timelineValue + : (typeof result.adjustedTimelineValue === 'number') + ? result.adjustedTimelineValue + : 0; + const adjustedValue = baseValue + adjustment; return (