5
This commit is contained in:
2026-03-13 14:18:19 +08:00
parent b8b65e684a
commit 24fa103a01

View File

@ -172,6 +172,7 @@ export default function App() {
}, },
showUI: boolean showUI: boolean
} | null>(null); } | null>(null);
const skipNextGroupConfigPopupRef = useRef(false);
// 客户期望日期状态 // 客户期望日期状态
const [expectedDate, setExpectedDate] = useState<Date | null>(null); const [expectedDate, setExpectedDate] = useState<Date | null>(null);
@ -203,8 +204,8 @@ export default function App() {
const [completionDateAdjustment, setCompletionDateAdjustment] = useState<number>(0); const [completionDateAdjustment, setCompletionDateAdjustment] = useState<number>(0);
// 实际完成日期状态:记录每个节点的实际完成日期 // 实际完成日期状态:记录每个节点的实际完成日期
const [actualCompletionDates, setActualCompletionDates] = useState<{[key: number]: Date | null}>({}); const [actualCompletionDates, setActualCompletionDates] = useState<{[key: number]: Date | null}>({});
// 基础缓冲期天数(可配置),用于计算动态缓冲期,默认14 // 基础缓冲期天数(可配置),用于计算动态缓冲期,默认0
const [baseBufferDays, setBaseBufferDays] = useState<number>(14); const [baseBufferDays, setBaseBufferDays] = useState<number>(0);
const [lockedExpectedDeliveryDateTs, setLockedExpectedDeliveryDateTs] = useState<number | null>(null); const [lockedExpectedDeliveryDateTs, setLockedExpectedDeliveryDateTs] = useState<number | null>(null);
const [isExpectedDeliveryDateLocked, setIsExpectedDeliveryDateLocked] = useState<boolean>(false); const [isExpectedDeliveryDateLocked, setIsExpectedDeliveryDateLocked] = useState<boolean>(false);
// 快照回填来源foreign_id、款式、颜色、文本2 // 快照回填来源foreign_id、款式、颜色、文本2
@ -276,7 +277,7 @@ export default function App() {
setTimelineResults([]); setTimelineResults([]);
setTimelineAdjustments({}); setTimelineAdjustments({});
// 新增:重置固定缓冲期、实际完成日期以及一次性建议缓冲期应用标志 // 新增:重置固定缓冲期、实际完成日期以及一次性建议缓冲期应用标志
setBaseBufferDays(14); setBaseBufferDays(0);
setActualCompletionDates({}); setActualCompletionDates({});
setHasAppliedSuggestedBuffer(false); setHasAppliedSuggestedBuffer(false);
setIsRestoringSnapshot(false); setIsRestoringSnapshot(false);
@ -3115,8 +3116,15 @@ export default function App() {
) )
); );
if (allGroups.length > 1 && groupOrderConfig.length === 0 && showUI) { if (showUI && allGroups.length > 0) {
const initial = deriveGroupOrderDraftByProcessOrder(matchedProcessNodes); if (skipNextGroupConfigPopupRef.current) {
skipNextGroupConfigPopupRef.current = false;
} else {
const groupSet = new Set(allGroups);
const existing = Array.isArray(groupOrderConfig)
? groupOrderConfig.filter(inst => groupSet.has((inst?.groupName || '').trim()))
: [];
const initial = existing.length > 0 ? existing : deriveGroupOrderDraftByProcessOrder(matchedProcessNodes);
setGroupOrderDraft(initial); setGroupOrderDraft(initial);
setGroupConfigVisible(true); setGroupConfigVisible(true);
setTimelineLoading(false); setTimelineLoading(false);
@ -3133,6 +3141,7 @@ export default function App() {
}; };
return []; return [];
} }
}
let orderedProcessNodes: any[] = matchedProcessNodes; let orderedProcessNodes: any[] = matchedProcessNodes;
@ -3681,43 +3690,6 @@ export default function App() {
pendingRecalculateAfterCalculateAdjustmentsRef.current = nextAdjustments; pendingRecalculateAfterCalculateAdjustmentsRef.current = nextAdjustments;
pendingRecalculateAfterCalculateRef.current = true; pendingRecalculateAfterCalculateRef.current = true;
setTimelineResults(results); setTimelineResults(results);
if (!isBackward && mode === 'generate' && showUI && currentExpectedDate && results.length > 0) {
let lastCompletionDate: Date | null = null;
for (let i = results.length - 1; i >= 0; i--) {
const end = results[i]?.estimatedEnd;
if (!end || end === '时效值为0') continue;
const parsed = typeof end === 'string' ? parseDate(end) : (end as any as Date);
if (parsed && !isNaN(parsed.getTime())) {
lastCompletionDate = parsed;
break;
}
}
if (lastCompletionDate) {
const bufferDays = Math.max(0, Math.ceil(baseBufferDays));
const computedDeliveryDate = new Date(lastCompletionDate);
computedDeliveryDate.setDate(computedDeliveryDate.getDate() + bufferDays);
const slackDays = differenceInCalendarDays(currentExpectedDate, computedDeliveryDate);
if (slackDays > 0) {
const suggested = bufferDays + slackDays;
await new Promise<void>((resolve) => {
Modal.confirm({
title: '建议增加缓冲期',
content: `客户交期 ${formatDate(currentExpectedDate)}${getDayOfWeek(currentExpectedDate)})晚于当前预计交付日期 ${formatDate(computedDeliveryDate)}${getDayOfWeek(computedDeliveryDate)}),建议将缓冲期从 ${bufferDays} 天调整为 ${suggested} 天以对齐。`,
okText: '增加缓冲期',
cancelText: '不调整',
onOk: () => {
setBaseBufferDays(suggested);
setHasAppliedSuggestedBuffer(true);
setLastSuggestedApplied(suggested);
resolve();
},
onCancel: () => resolve()
});
});
}
}
}
if (showUI && !delayShowTimelineModal) { if (showUI && !delayShowTimelineModal) {
setTimelineVisible(true); setTimelineVisible(true);
} else if (showUI && delayShowTimelineModal) { } else if (showUI && delayShowTimelineModal) {
@ -4105,24 +4077,57 @@ export default function App() {
} }
}; };
const getAdjustedLastCompletionDate = (results: any[], completionAdjustmentOverride?: number): Date | null => {
const lastCompletionDate = getLastValidCompletionDateFromResults(results);
if (!lastCompletionDate) return null;
const adjusted = new Date(lastCompletionDate);
const adj = Number.isFinite(completionAdjustmentOverride as number)
? (completionAdjustmentOverride as number)
: completionDateAdjustment;
if (Number.isFinite(adj) && adj !== 0) {
adjusted.setDate(adjusted.getDate() + adj);
}
return adjusted;
};
const computeAutoBufferDaysUsingExpectedDate = (
results: any[],
expectedDateOverride?: Date | null,
completionAdjustmentOverride?: number
): number => {
try {
if (timelineDirection === 'backward') return 0;
const expected = expectedDateOverride ?? expectedDate;
if (!expected || isNaN(expected.getTime())) return 0;
const adjustedCompletionDate = getAdjustedLastCompletionDate(results, completionAdjustmentOverride);
if (!adjustedCompletionDate) return 0;
return differenceInCalendarDays(expected, adjustedCompletionDate);
} catch {
return 0;
}
};
const computeBufferDeficitDaysUsingEndDelta = (adjustments: Record<string, number>): number => { const computeBufferDeficitDaysUsingEndDelta = (adjustments: Record<string, number>): number => {
const deltaDays = computeLastNodeEndDeltaDays(adjustments); const deltaDays = computeLastNodeEndDeltaDays(adjustments);
const base = Math.max(0, Math.ceil(baseBufferDays)); const autoBufferDays = computeAutoBufferDaysUsingExpectedDate(timelineResults, expectedDate, completionDateAdjustment);
return Math.max(0, deltaDays - base); return Math.max(0, deltaDays - autoBufferDays);
}; };
const computeExpectedDeliveryDateTsFromResults = ( const computeExpectedDeliveryDateTsFromResults = (
results: any[], results: any[],
adjustments: Record<string, number>, adjustments: Record<string, number>,
baseBufferDaysOverride?: number expectedDateOverride?: Date | null,
completionAdjustmentOverride?: number
): number | null => { ): number | null => {
if (timelineDirection === 'backward') return null; if (timelineDirection === 'backward') return null;
const lastCompletionDate = getLastValidCompletionDateFromResults(results); const adjustedCompletionDate = getAdjustedLastCompletionDate(results, completionAdjustmentOverride);
if (!lastCompletionDate) return null; if (!adjustedCompletionDate) return null;
const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(adjustments, baseBufferDaysOverride); const expected = expectedDateOverride ?? expectedDate;
const deliveryDate = new Date(lastCompletionDate); if (expected && !isNaN(expected.getTime())) {
deliveryDate.setDate(deliveryDate.getDate() + dynamicBufferDays); const ts = expected.getTime();
const ts = deliveryDate.getTime(); return Number.isFinite(ts) ? ts : null;
}
const ts = adjustedCompletionDate.getTime();
return Number.isFinite(ts) ? ts : null; return Number.isFinite(ts) ? ts : null;
}; };
@ -4144,17 +4149,18 @@ export default function App() {
setLockedExpectedDeliveryDateTs(expectedDate.getTime()); setLockedExpectedDeliveryDateTs(expectedDate.getTime());
}; };
const computeDynamicBufferDaysUsingEndDelta = (adjustments: Record<string, number>, baseBufferDaysOverride?: number): number => { const computeDynamicBufferDaysUsingEndDelta = (
try { adjustments: Record<string, number>,
if (timelineDirection === 'backward') return 0; expectedDateOverride?: Date | null,
const deltaDays = computeLastNodeEndDeltaDays(adjustments); resultsOverride?: any[],
const base = Math.max(0, Math.ceil(baseBufferDaysOverride ?? baseBufferDays)); completionAdjustmentOverride?: number
const remaining = base - deltaDays; ): number => {
return Math.max(0, Math.min(base, remaining)); const results = resultsOverride ?? timelineResults;
} catch { const expected = expectedDateOverride ?? expectedDate;
const base = Math.max(0, Math.ceil(baseBufferDaysOverride ?? baseBufferDays)); const completionAdj = Number.isFinite(completionAdjustmentOverride as number)
return base; ? (completionAdjustmentOverride as number)
} : completionDateAdjustment;
return computeAutoBufferDaysUsingExpectedDate(results, expected, completionAdj);
}; };
// 重新计算时间线的函数 // 重新计算时间线的函数
@ -4441,7 +4447,7 @@ export default function App() {
setDeliveryMarginDeductions(0); // 同时重置交期余量扣减 setDeliveryMarginDeductions(0); // 同时重置交期余量扣减
setCompletionDateAdjustment(0); // 重置最后流程完成日期调整 setCompletionDateAdjustment(0); // 重置最后流程完成日期调整
setActualCompletionDates({}); // 重置实际完成日期 setActualCompletionDates({}); // 重置实际完成日期
setBaseBufferDays(14); // 重置固定缓冲期为默认值 setBaseBufferDays(0); // 重置固定缓冲期为默认值
setIsExpectedDeliveryDateLocked(false); setIsExpectedDeliveryDateLocked(false);
try { lastBufferDeficitRef.current = 0; } catch {} try { lastBufferDeficitRef.current = 0; } catch {}
setHasAppliedSuggestedBuffer(false); // 重置建议缓冲期应用标志 setHasAppliedSuggestedBuffer(false); // 重置建议缓冲期应用标志
@ -4470,7 +4476,7 @@ export default function App() {
setSelectedLabels(s.selectedLabels || {}); setSelectedLabels(s.selectedLabels || {});
const normalizedAdjustments = normalizeTimelineAdjustmentsFromSnapshot(s.timelineAdjustments || {}, s.timelineResults || []); const normalizedAdjustments = normalizeTimelineAdjustmentsFromSnapshot(s.timelineAdjustments || {}, s.timelineResults || []);
setTimelineAdjustments(normalizedAdjustments); setTimelineAdjustments(normalizedAdjustments);
setBaseBufferDays(s.baseBufferDays ?? 14); setBaseBufferDays(s.baseBufferDays ?? 0);
const shouldLock = s.isExpectedDeliveryDateLocked === true || (s.isExpectedDeliveryDateLocked === undefined && s.lockedExpectedDeliveryDateTs !== null && s.lockedExpectedDeliveryDateTs !== undefined); const shouldLock = s.isExpectedDeliveryDateLocked === true || (s.isExpectedDeliveryDateLocked === undefined && s.lockedExpectedDeliveryDateTs !== null && s.lockedExpectedDeliveryDateTs !== undefined);
if (shouldLock && typeof s.lockedExpectedDeliveryDateTs === 'number' && Number.isFinite(s.lockedExpectedDeliveryDateTs)) { if (shouldLock && typeof s.lockedExpectedDeliveryDateTs === 'number' && Number.isFinite(s.lockedExpectedDeliveryDateTs)) {
setLockedExpectedDeliveryDateTs(s.lockedExpectedDeliveryDateTs); setLockedExpectedDeliveryDateTs(s.lockedExpectedDeliveryDateTs);
@ -4669,11 +4675,9 @@ export default function App() {
// 获取标签汇总批量模式优先使用传入的labels // 获取标签汇总批量模式优先使用传入的labels
const selectedLabelValues = Object.values(overrides?.selectedLabels ?? selectedLabels).flat().filter(Boolean); const selectedLabelValues = Object.values(overrides?.selectedLabels ?? selectedLabels).flat().filter(Boolean);
const baseBufferDaysToUse = Math.max(0, Math.ceil(overrides?.baseBufferDays ?? baseBufferDays)); // 获取预计交付日期(交期余量的日期版本:根据客户期望日期自动计算缓冲期)
let expectedDeliveryDate = computeExpectedDeliveryDateTsFromResults(timelineResults, timelineAdjustments, overrides?.expectedDate ?? expectedDate, completionDateAdjustment);
// 获取预计交付日期(交期余量的日期版本:最后流程完成日期 + 基础缓冲期) if (isExpectedDeliveryDateLocked && lockedExpectedDeliveryDateTs !== null) {
let expectedDeliveryDate = computeExpectedDeliveryDateTsFromResults(timelineResults, timelineAdjustments, baseBufferDaysToUse);
if (mode === 'adjust' && isExpectedDeliveryDateLocked && lockedExpectedDeliveryDateTs !== null) {
expectedDeliveryDate = lockedExpectedDeliveryDateTs; expectedDeliveryDate = lockedExpectedDeliveryDateTs;
} }
@ -4734,26 +4738,21 @@ export default function App() {
const styleText = style || ''; const styleText = style || '';
const colorText = color || ''; const colorText = color || '';
const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments, baseBufferDaysToUse); const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments, expectedDateToUse, timelineResults, completionDateAdjustment);
// 检查是否达到最终限制 // 检查是否达到最终限制
let hasReachedFinalLimit = false; let hasReachedFinalLimit = false;
const currentExpectedDate = expectedDate; const currentExpectedDate = expectedDateToUse;
if (dynamicBufferDays === 0 && currentExpectedDate && timelineResults.length > 0) { if (currentExpectedDate) {
const lastNode = timelineResults[timelineResults.length - 1]; const adjustedLastCompletion = getAdjustedLastCompletionDate(timelineResults, completionDateAdjustment);
if (lastNode && lastNode.estimatedEnd && !lastNode.estimatedEnd.includes('未找到')) { if (adjustedLastCompletion) {
try { const daysToExpected = differenceInCalendarDays(currentExpectedDate, adjustedLastCompletion);
const lastCompletionDate = new Date(lastNode.estimatedEnd);
const daysToExpected = Math.ceil((currentExpectedDate.getTime() - lastCompletionDate.getTime()) / (1000 * 60 * 60 * 24));
hasReachedFinalLimit = daysToExpected <= 0; hasReachedFinalLimit = daysToExpected <= 0;
} catch (error) {
console.warn('计算最终限制状态失败:', error);
}
} }
} }
// 为快照提供基础缓冲与节点调整总量(用于兼容历史字段),尽管动态缓冲期已改为“自然日差”口径 // 为快照提供基础缓冲与节点调整总量(用于兼容历史字段),尽管动态缓冲期已改为“自然日差”口径
const baseBuferDays = baseBufferDaysToUse; const baseBuferDays = dynamicBufferDays;
const totalAdjustments = Object.values(timelineAdjustments).reduce((sum, adj) => sum + adj, 0); const totalAdjustments = Object.values(timelineAdjustments).reduce((sum, adj) => sum + adj, 0);
const globalSnapshot = { const globalSnapshot = {
@ -5566,16 +5565,6 @@ export default function App() {
try { try {
const results = await handleCalculateTimeline(true, { selectedLabels: labels, expectedDate: expectedDateObj || null, startTime: startDate || null, excludedDates: batchExcludedDates }, false); const results = await handleCalculateTimeline(true, { selectedLabels: labels, expectedDate: expectedDateObj || null, startTime: startDate || null, excludedDates: batchExcludedDates }, false);
if (results && results.length > 0) { if (results && results.length > 0) {
const baseForSuggestion = 14;
const suggestedBaseBufferDays = (() => {
if (!expectedDateObj || isNaN(expectedDateObj.getTime())) return baseForSuggestion;
const lastCompletionDate = getLastValidCompletionDateFromResults(results);
if (!lastCompletionDate) return baseForSuggestion;
const computedDeliveryDate = new Date(lastCompletionDate);
computedDeliveryDate.setDate(computedDeliveryDate.getDate() + baseForSuggestion);
const slackDays = differenceInCalendarDays(expectedDateObj, computedDeliveryDate);
return slackDays > 0 ? (baseForSuggestion + slackDays) : baseForSuggestion;
})();
const processRecordIds = await writeToProcessDataTable(results, { foreignId, style: styleText, color: colorText }); const processRecordIds = await writeToProcessDataTable(results, { foreignId, style: styleText, color: colorText });
const deliveryRecordId = await writeToDeliveryRecordTable( const deliveryRecordId = await writeToDeliveryRecordTable(
results, results,
@ -5587,8 +5576,7 @@ export default function App() {
color: colorText, color: colorText,
expectedDate: expectedDateObj || null, expectedDate: expectedDateObj || null,
startTime: startDate || null, startTime: startDate || null,
selectedLabels: labels, selectedLabels: labels
baseBufferDays: suggestedBaseBufferDays
} }
); );
try { try {
@ -6718,6 +6706,7 @@ export default function App() {
onClick={() => { onClick={() => {
const nextConfig = Array.isArray(groupOrderDraft) ? groupOrderDraft : []; const nextConfig = Array.isArray(groupOrderDraft) ? groupOrderDraft : [];
setGroupOrderConfig(nextConfig); setGroupOrderConfig(nextConfig);
skipNextGroupConfigPopupRef.current = true;
setGroupConfigVisible(false); setGroupConfigVisible(false);
if (!pendingGroupConfigCalcRef.current && mode === 'adjust') { if (!pendingGroupConfigCalcRef.current && mode === 'adjust') {
const next = applyGroupOrderConfigToTimelineResults(timelineResults, nextConfig); const next = applyGroupOrderConfigToTimelineResults(timelineResults, nextConfig);
@ -6958,7 +6947,6 @@ export default function App() {
> >
<span style={{ fontSize: 14, lineHeight: 1 }}></span> <span style={{ fontSize: 14, lineHeight: 1 }}></span>
</Button> </Button>
{mode === 'adjust' && (
<> <>
<Text type="tertiary" style={{ marginLeft: 8 }}></Text> <Text type="tertiary" style={{ marginLeft: 8 }}></Text>
<Switch <Switch
@ -6967,7 +6955,6 @@ export default function App() {
style={{ marginLeft: 4 }} style={{ marginLeft: 4 }}
/> />
</> </>
)}
</div> </div>
</div> </div>
} }
@ -6978,31 +6965,38 @@ export default function App() {
setDeliveryMarginDeductions(0); // 关闭时重置交期余量扣减 setDeliveryMarginDeductions(0); // 关闭时重置交期余量扣减
setCompletionDateAdjustment(0); // 关闭时重置最后流程完成日期调整 setCompletionDateAdjustment(0); // 关闭时重置最后流程完成日期调整
setStyleColorEditable(false); // 关闭弹窗后恢复为锁定状态 setStyleColorEditable(false); // 关闭弹窗后恢复为锁定状态
if (mode !== 'adjust') {
setLockedExpectedDeliveryDateTs(null);
setIsExpectedDeliveryDateLocked(false);
}
}} }}
footer={ footer={
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Space align="center"> <Space align="center">
<Text>{mode === 'adjust' && isExpectedDeliveryDateLocked ? '基础缓冲期(天)(不影响已锁交付)' : '基础缓冲期(天)'}</Text> <Text>{isExpectedDeliveryDateLocked ? '缓冲期(天)(不影响已锁交付)' : '缓冲期(天)'}</Text>
{(() => {
const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments, expectedDate, timelineResults, completionDateAdjustment);
const canEdit = !isExpectedDeliveryDateLocked && !!getAdjustedLastCompletionDate(timelineResults, completionDateAdjustment);
return (
<InputNumber <InputNumber
min={0} value={dynamicBufferDays}
disabled={!canEdit}
step={1} step={1}
value={baseBufferDays}
onChange={(val) => { onChange={(val) => {
if (!canEdit) return;
const n = Number(val); const n = Number(val);
setBaseBufferDays(Number.isFinite(n) && n >= 0 ? Math.ceil(n) : 0); if (!Number.isFinite(n)) return;
const adjustedCompletion = getAdjustedLastCompletionDate(timelineResults, completionDateAdjustment);
if (!adjustedCompletion) return;
const nextExpected = new Date(adjustedCompletion);
nextExpected.setDate(nextExpected.getDate() + n);
setExpectedDate(nextExpected);
}}
style={{
width: 90,
backgroundColor: dynamicBufferDays < 0 ? '#fff1f0' : undefined,
borderColor: dynamicBufferDays < 0 ? '#ff4d4f' : undefined,
color: dynamicBufferDays < 0 ? '#cf1322' : undefined
}} }}
style={{ width: 90 }}
/>
<Text>()</Text>
<InputNumber
value={computeDynamicBufferDaysUsingEndDelta(timelineAdjustments)}
disabled
style={{ width: 90 }}
/> />
);
})()}
<Button onClick={resetToInitialState}> <Button onClick={resetToInitialState}>
</Button> </Button>
@ -7082,8 +7076,8 @@ export default function App() {
// 当前节点是否为零值的周转周期节点 // 当前节点是否为零值的周转周期节点
const isCurrentTurnoverZero = isTurnoverNode && adjustedValue === 0; const isCurrentTurnoverZero = isTurnoverNode && adjustedValue === 0;
// 计算动态缓冲期(按“最后完成时间变动天数”扣减缓冲期) // 计算动态缓冲期
const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments); const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments, expectedDate, timelineResults, completionDateAdjustment);
return ( return (
<Card key={index} style={{ marginBottom: '8px', padding: '12px', position: 'relative' }}> <Card key={index} style={{ marginBottom: '8px', padding: '12px', position: 'relative' }}>
@ -7522,12 +7516,12 @@ export default function App() {
} }
// 缓冲期(动态)与调整后的最后完成日期 // 缓冲期(动态)与调整后的最后完成日期
const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments); const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments, expectedDate, timelineResults, completionDateAdjustment);
const adjustedCompletionDate = new Date(lastCompletionDate!); const adjustedCompletionDate = new Date(lastCompletionDate!);
adjustedCompletionDate.setDate(adjustedCompletionDate.getDate() + completionDateAdjustment); adjustedCompletionDate.setDate(adjustedCompletionDate.getDate() + completionDateAdjustment);
const deliveryDate = new Date(adjustedCompletionDate); const deliveryDate = new Date(adjustedCompletionDate);
deliveryDate.setDate(deliveryDate.getDate() + dynamicBufferDays); deliveryDate.setDate(deliveryDate.getDate() + dynamicBufferDays);
const lockedDeliveryDate = (mode === 'adjust' && isExpectedDeliveryDateLocked && lockedExpectedDeliveryDateTs !== null) const lockedDeliveryDate = (isExpectedDeliveryDateLocked && lockedExpectedDeliveryDateTs !== null)
? new Date(lockedExpectedDeliveryDateTs) ? new Date(lockedExpectedDeliveryDateTs)
: null; : null;
@ -7558,9 +7552,9 @@ export default function App() {
<span style={{ fontSize: 13, color: '#666', fontWeight: 600 }}></span> <span style={{ fontSize: 13, color: '#666', fontWeight: 600 }}></span>
<span style={{ <span style={{
fontSize: 13, fontSize: 13,
color: '#1890ff', color: dynamicBufferDays < 0 ? '#cf1322' : '#1890ff',
backgroundColor: 'rgba(24, 144, 255, 0.08)', backgroundColor: dynamicBufferDays < 0 ? '#fff1f0' : 'rgba(24, 144, 255, 0.08)',
border: '1px solid rgba(24, 144, 255, 0.2)', border: dynamicBufferDays < 0 ? '1px solid #ff4d4f' : '1px solid rgba(24, 144, 255, 0.2)',
borderRadius: 16, borderRadius: 16,
padding: '3px 8px', padding: '3px 8px',
fontWeight: 700, fontWeight: 700,
@ -7610,7 +7604,7 @@ export default function App() {
style={{ width: '200px' }} style={{ width: '200px' }}
placeholder="请选择客户期望日期" placeholder="请选择客户期望日期"
value={expectedDate ?? undefined} value={expectedDate ?? undefined}
disabled={mode === 'adjust' && isExpectedDeliveryDateLocked} disabled={isExpectedDeliveryDateLocked}
onChange={(date) => { onChange={(date) => {
if (date instanceof Date) { if (date instanceof Date) {
setExpectedDate(date); setExpectedDate(date);