11
This commit is contained in:
2025-12-29 18:29:14 +08:00
parent 7d52c3955b
commit 2fdae6b04d

View File

@ -2903,7 +2903,10 @@ export default function App() {
}; };
// 获取重新计算后的时间线结果(不更新状态,逻辑对齐页面的重算口径) // 获取重新计算后的时间线结果(不更新状态,逻辑对齐页面的重算口径)
const getRecalculatedTimeline = (adjustments: { [key: number]: number }) => { const getRecalculatedTimeline = (
adjustments: { [key: number]: number },
opts?: { ignoreActualCompletionDates?: boolean; actualCompletionDatesOverride?: { [key: number]: Date | null } }
) => {
const updatedResults = [...timelineResults]; const updatedResults = [...timelineResults];
let cumulativeStartTime = startTime ? new Date(startTime) : new Date(); // 从起始时间开始 let cumulativeStartTime = startTime ? new Date(startTime) : new Date(); // 从起始时间开始
@ -2974,11 +2977,18 @@ export default function App() {
nodeEndTime = new Date(nodeStartTime); nodeEndTime = new Date(nodeStartTime);
} }
const actualEnd = opts?.ignoreActualCompletionDates
? null
: (opts?.actualCompletionDatesOverride ?? actualCompletionDates)?.[i] ?? null;
// 计算跳过的天数及日期范围内的自定义跳过日期 // 计算跳过的天数及日期范围内的自定义跳过日期
const adjustedStartTime = adjustToNextWorkingHour(nodeStartTime, nodeCalculationMethod, nodeWeekendDays, nodeExcludedDates); const adjustedStartTime = adjustToNextWorkingHour(nodeStartTime, nodeCalculationMethod, nodeWeekendDays, nodeExcludedDates);
const skippedWeekends = calculateSkippedWeekends(adjustedStartTime, nodeEndTime, nodeWeekendDays); const skippedWeekends = calculateSkippedWeekends(adjustedStartTime, nodeEndTime, nodeWeekendDays);
const estimatedStartStr = formatDate(adjustedStartTime); const estimatedStartStr = formatDate(adjustedStartTime);
const estimatedEndStr = adjustedTimelineValue !== 0 ? formatDate(nodeEndTime) : '时效值为0'; let estimatedEndStr = adjustedTimelineValue !== 0 ? formatDate(nodeEndTime) : '时效值为0';
if (actualEnd && actualEnd instanceof Date && !isNaN(actualEnd.getTime())) {
estimatedEndStr = formatDate(actualEnd);
}
const actualDays = calculateActualDays(estimatedStartStr, estimatedEndStr); const actualDays = calculateActualDays(estimatedStartStr, estimatedEndStr);
const excludedDatesInRange = calculateExcludedDatesInRange(adjustedStartTime, nodeEndTime, nodeExcludedDates); const excludedDatesInRange = calculateExcludedDatesInRange(adjustedStartTime, nodeEndTime, nodeExcludedDates);
@ -3000,7 +3010,11 @@ export default function App() {
// 更新累积开始时间:使用当前节点的预计完成时间 // 更新累积开始时间:使用当前节点的预计完成时间
if (adjustedTimelineValue !== 0) { if (adjustedTimelineValue !== 0) {
cumulativeStartTime = new Date(nodeEndTime); if (actualEnd && actualEnd instanceof Date && !isNaN(actualEnd.getTime())) {
cumulativeStartTime = new Date(actualEnd);
} else {
cumulativeStartTime = new Date(nodeEndTime);
}
} }
} }
@ -3168,7 +3182,7 @@ export default function App() {
const computeLastNodeEndDeltaDays = (adjustments: { [key: number]: number }): number => { const computeLastNodeEndDeltaDays = (adjustments: { [key: number]: number }): number => {
try { try {
if (timelineDirection === 'backward') return 0; if (timelineDirection === 'backward') return 0;
const baseline = getRecalculatedTimeline({}); const baseline = getRecalculatedTimeline({}, { ignoreActualCompletionDates: true });
const current = getRecalculatedTimeline(adjustments); const current = getRecalculatedTimeline(adjustments);
const pickLastNodeEnd = (results: any[]): Date | null => { const pickLastNodeEnd = (results: any[]): Date | null => {
@ -3216,10 +3230,19 @@ export default function App() {
const handleExpectedDeliveryDateLockChange = (checked: boolean) => { const handleExpectedDeliveryDateLockChange = (checked: boolean) => {
const nextLocked = !!checked; const nextLocked = !!checked;
setIsExpectedDeliveryDateLocked(nextLocked); setIsExpectedDeliveryDateLocked(nextLocked);
if (!nextLocked) return; if (!nextLocked) {
if (lockedExpectedDeliveryDateTs !== null && lockedExpectedDeliveryDateTs !== undefined) return; setLockedExpectedDeliveryDateTs(null);
const computed = computeExpectedDeliveryDateTsFromResults(timelineResults, timelineAdjustments); return;
if (computed !== null) setLockedExpectedDeliveryDateTs(computed); }
if (!expectedDate || isNaN(expectedDate.getTime())) {
setIsExpectedDeliveryDateLocked(false);
setLockedExpectedDeliveryDateTs(null);
if (bitable.ui.showToast) {
bitable.ui.showToast({ toastType: ToastType.warning, message: '请先选择客户期望日期,再开启锁交付' });
}
return;
}
setLockedExpectedDeliveryDateTs(expectedDate.getTime());
}; };
const computeDynamicBufferDaysUsingEndDelta = (adjustments: { [key: number]: number }, baseBufferDaysOverride?: number): number => { const computeDynamicBufferDaysUsingEndDelta = (adjustments: { [key: number]: number }, baseBufferDaysOverride?: number): number => {
@ -5675,11 +5698,9 @@ export default function App() {
} }
}} }}
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> <Text>{mode === 'adjust' && isExpectedDeliveryDateLocked ? '基础缓冲期(天)(不影响已锁交付)' : '基础缓冲期(天)'}</Text>
{mode === 'adjust' && isExpectedDeliveryDateLocked ? '缓冲期(天)(不影响已锁交付)' : '缓冲期(天)'}
</Text>
<InputNumber <InputNumber
min={0} min={0}
step={1} step={1}
@ -5690,6 +5711,12 @@ export default function App() {
}} }}
style={{ width: 90 }} style={{ width: 90 }}
/> />
<Text>()</Text>
<InputNumber
value={computeDynamicBufferDaysUsingEndDelta(timelineAdjustments)}
disabled
style={{ width: 90 }}
/>
<Button onClick={resetToInitialState}> <Button onClick={resetToInitialState}>
</Button> </Button>
@ -6249,6 +6276,7 @@ export default function App() {
style={{ width: '200px' }} style={{ width: '200px' }}
placeholder="请选择客户期望日期" placeholder="请选择客户期望日期"
value={expectedDate ?? undefined} value={expectedDate ?? undefined}
disabled={mode === 'adjust' && isExpectedDeliveryDateLocked}
onChange={(date) => { onChange={(date) => {
if (date instanceof Date) { if (date instanceof Date) {
setExpectedDate(date); setExpectedDate(date);