18
18
This commit is contained in:
116
src/App.tsx
116
src/App.tsx
@ -206,8 +206,6 @@ export default function App() {
|
||||
const [actualCompletionDates, setActualCompletionDates] = useState<{[key: number]: Date | null}>({});
|
||||
// 基础缓冲期天数(可配置),用于计算动态缓冲期,默认0天
|
||||
const [baseBufferDays, setBaseBufferDays] = useState<number>(0);
|
||||
const [lockedExpectedDeliveryDateTs, setLockedExpectedDeliveryDateTs] = useState<number | null>(null);
|
||||
const [isExpectedDeliveryDateLocked, setIsExpectedDeliveryDateLocked] = useState<boolean>(false);
|
||||
// 快照回填来源(foreign_id、款式、颜色、文本2)
|
||||
const [currentForeignId, setCurrentForeignId] = useState<string | null>(null);
|
||||
const [currentStyleText, setCurrentStyleText] = useState<string>('');
|
||||
@ -283,8 +281,6 @@ export default function App() {
|
||||
setIsRestoringSnapshot(false);
|
||||
setRestoredRecordIds([]);
|
||||
setRestoredRecordIdsText('');
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
|
||||
// 重置初始快照捕获状态
|
||||
try {
|
||||
@ -475,8 +471,6 @@ export default function App() {
|
||||
// 切换功能时重置全局变量,但保留新的mode
|
||||
resetGlobalState({ resetMode: false });
|
||||
setMode(m);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setModeSelectionVisible(false);
|
||||
};
|
||||
|
||||
@ -1068,26 +1062,6 @@ export default function App() {
|
||||
: deriveTimelineAdjustmentsFromResults(snapshot?.timelineResults);
|
||||
setTimelineAdjustments(normalized);
|
||||
}
|
||||
{
|
||||
const snapLockedFlag = snapshot?.isExpectedDeliveryDateLocked;
|
||||
const snapLockedTs = snapshot?.lockedExpectedDeliveryDateTs;
|
||||
const shouldLock = snapLockedFlag === true || (snapLockedFlag === undefined && snapLockedTs !== undefined && snapLockedTs !== null);
|
||||
if (shouldLock) {
|
||||
const ts = (typeof snapLockedTs === 'number' && Number.isFinite(snapLockedTs))
|
||||
? snapLockedTs
|
||||
: expectedDeliveryTsFromField;
|
||||
if (ts !== null && ts !== undefined) {
|
||||
setLockedExpectedDeliveryDateTs(ts);
|
||||
setIsExpectedDeliveryDateLocked(true);
|
||||
} else {
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
}
|
||||
} else {
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
}
|
||||
}
|
||||
restoreExcludedDatesOverrideFromSnapshot(snapshot, snapshot.timelineResults);
|
||||
restoreExcludedDatesByNodeOverrideFromSnapshot(snapshot, snapshot.timelineResults);
|
||||
if (snapshot.expectedDateTimestamp) {
|
||||
@ -1238,18 +1212,6 @@ export default function App() {
|
||||
: deriveTimelineAdjustmentsFromResults(snapshot?.timelineResults);
|
||||
setTimelineAdjustments(normalized);
|
||||
}
|
||||
{
|
||||
const snapLockedFlag = snapshot?.isExpectedDeliveryDateLocked;
|
||||
const snapLockedTs = snapshot?.lockedExpectedDeliveryDateTs;
|
||||
const shouldLock = snapLockedFlag === true || (snapLockedFlag === undefined && snapLockedTs !== undefined && snapLockedTs !== null);
|
||||
if (shouldLock && typeof snapLockedTs === 'number' && Number.isFinite(snapLockedTs)) {
|
||||
setLockedExpectedDeliveryDateTs(snapLockedTs);
|
||||
setIsExpectedDeliveryDateLocked(true);
|
||||
} else {
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
}
|
||||
}
|
||||
if (snapshot.expectedDateTimestamp) {
|
||||
setExpectedDate(new Date(snapshot.expectedDateTimestamp));
|
||||
} else if (snapshot.expectedDateString) {
|
||||
@ -1591,8 +1553,6 @@ export default function App() {
|
||||
text2: nodeSnapshot.text2,
|
||||
mode: nodeSnapshot.mode,
|
||||
timelineDirection: nodeSnapshot.timelineDirection,
|
||||
lockedExpectedDeliveryDateTs: nodeSnapshot.lockedExpectedDeliveryDateTs,
|
||||
isExpectedDeliveryDateLocked: nodeSnapshot.isExpectedDeliveryDateLocked,
|
||||
selectedLabels: nodeSnapshot.selectedLabels,
|
||||
expectedDateTimestamp: nodeSnapshot.expectedDateTimestamp,
|
||||
expectedDateString: nodeSnapshot.expectedDateString,
|
||||
@ -1707,18 +1667,6 @@ export default function App() {
|
||||
setTimelineResults(nodeSnapshots);
|
||||
setTimelineVisible(true);
|
||||
|
||||
{
|
||||
const snapLockedFlag = (globalSnapshotData as any)?.isExpectedDeliveryDateLocked;
|
||||
const snapLockedTs = (globalSnapshotData as any)?.lockedExpectedDeliveryDateTs;
|
||||
const shouldLock = snapLockedFlag === true || (snapLockedFlag === undefined && snapLockedTs !== undefined && snapLockedTs !== null);
|
||||
if (shouldLock && typeof snapLockedTs === 'number' && Number.isFinite(snapLockedTs)) {
|
||||
setLockedExpectedDeliveryDateTs(snapLockedTs);
|
||||
setIsExpectedDeliveryDateLocked(true);
|
||||
} else {
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复智能缓冲期状态(如果存在)
|
||||
if (globalSnapshotData.bufferManagement) {
|
||||
@ -4153,24 +4101,6 @@ export default function App() {
|
||||
return Number.isFinite(ts) ? ts : null;
|
||||
};
|
||||
|
||||
const handleExpectedDeliveryDateLockChange = (checked: boolean) => {
|
||||
const nextLocked = !!checked;
|
||||
setIsExpectedDeliveryDateLocked(nextLocked);
|
||||
if (!nextLocked) {
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
return;
|
||||
}
|
||||
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: Record<string, number>,
|
||||
expectedDateOverride?: Date | null,
|
||||
@ -4450,8 +4380,6 @@ export default function App() {
|
||||
timelineResults,
|
||||
timelineAdjustments,
|
||||
baseBufferDays,
|
||||
lockedExpectedDeliveryDateTs,
|
||||
isExpectedDeliveryDateLocked,
|
||||
actualCompletionDates,
|
||||
completionDateAdjustment,
|
||||
hasAppliedSuggestedBuffer,
|
||||
@ -4470,7 +4398,6 @@ export default function App() {
|
||||
setCompletionDateAdjustment(0); // 重置最后流程完成日期调整
|
||||
setActualCompletionDates({}); // 重置实际完成日期
|
||||
setBaseBufferDays(0); // 重置固定缓冲期为默认值
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
try { lastBufferDeficitRef.current = 0; } catch {}
|
||||
setHasAppliedSuggestedBuffer(false); // 重置建议缓冲期应用标志
|
||||
setLastSuggestedApplied(null); // 清空上次建议值
|
||||
@ -4499,14 +4426,6 @@ export default function App() {
|
||||
const normalizedAdjustments = normalizeTimelineAdjustmentsFromSnapshot(s.timelineAdjustments || {}, s.timelineResults || []);
|
||||
setTimelineAdjustments(normalizedAdjustments);
|
||||
setBaseBufferDays(s.baseBufferDays ?? 0);
|
||||
const shouldLock = s.isExpectedDeliveryDateLocked === true || (s.isExpectedDeliveryDateLocked === undefined && s.lockedExpectedDeliveryDateTs !== null && s.lockedExpectedDeliveryDateTs !== undefined);
|
||||
if (shouldLock && typeof s.lockedExpectedDeliveryDateTs === 'number' && Number.isFinite(s.lockedExpectedDeliveryDateTs)) {
|
||||
setLockedExpectedDeliveryDateTs(s.lockedExpectedDeliveryDateTs);
|
||||
setIsExpectedDeliveryDateLocked(true);
|
||||
} else {
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
}
|
||||
setActualCompletionDates(s.actualCompletionDates || {});
|
||||
setCompletionDateAdjustment(s.completionDateAdjustment || 0);
|
||||
setHasAppliedSuggestedBuffer(!!s.hasAppliedSuggestedBuffer && s.hasAppliedSuggestedBuffer);
|
||||
@ -4699,9 +4618,6 @@ export default function App() {
|
||||
|
||||
// 获取预计交付日期(交期余量的日期版本:根据客户期望日期自动计算缓冲期)
|
||||
let expectedDeliveryDate = computeExpectedDeliveryDateTsFromResults(timelineResults, timelineAdjustments, overrides?.expectedDate ?? expectedDate, completionDateAdjustment);
|
||||
if (isExpectedDeliveryDateLocked && lockedExpectedDeliveryDateTs !== null) {
|
||||
expectedDeliveryDate = lockedExpectedDeliveryDateTs;
|
||||
}
|
||||
|
||||
// 获取客户期望日期:批量模式优先使用传入的expectedDate
|
||||
let customerExpectedDate = null;
|
||||
@ -4787,8 +4703,6 @@ export default function App() {
|
||||
timelineDirection,
|
||||
excludedDatesOverride,
|
||||
excludedDatesByNodeOverride: excludedDatesByNodeOverrideRef.current || excludedDatesByNodeOverride,
|
||||
lockedExpectedDeliveryDateTs,
|
||||
isExpectedDeliveryDateLocked,
|
||||
selectedLabels: currentSelectedLabels,
|
||||
expectedDateTimestamp,
|
||||
expectedDateString,
|
||||
@ -6396,8 +6310,6 @@ export default function App() {
|
||||
<Select value={mode} onChange={(v) => {
|
||||
const next = v as any;
|
||||
setMode(next);
|
||||
setIsExpectedDeliveryDateLocked(false);
|
||||
setLockedExpectedDeliveryDateTs(null);
|
||||
setExcludedDatesOverride([]);
|
||||
setExcludedDatesOverrideText('');
|
||||
}}
|
||||
@ -7016,10 +6928,10 @@ export default function App() {
|
||||
footer={
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Space align="center">
|
||||
<Text>{isExpectedDeliveryDateLocked ? '缓冲期(天)(不影响已锁交付):' : '缓冲期(天):'}</Text>
|
||||
<Text>缓冲期(天):</Text>
|
||||
{(() => {
|
||||
const dynamicBufferDays = computeDynamicBufferDaysUsingEndDelta(timelineAdjustments, expectedDate, timelineResults, completionDateAdjustment);
|
||||
const canEdit = !isExpectedDeliveryDateLocked && !!getAdjustedLastCompletionDate(timelineResults, completionDateAdjustment);
|
||||
const canEdit = !!getAdjustedLastCompletionDate(timelineResults, completionDateAdjustment);
|
||||
return (
|
||||
<InputNumber
|
||||
value={dynamicBufferDays}
|
||||
@ -7568,9 +7480,6 @@ export default function App() {
|
||||
adjustedCompletionDate.setDate(adjustedCompletionDate.getDate() + completionDateAdjustment);
|
||||
const deliveryDate = new Date(adjustedCompletionDate);
|
||||
deliveryDate.setDate(deliveryDate.getDate() + dynamicBufferDays);
|
||||
const lockedDeliveryDate = (isExpectedDeliveryDateLocked && lockedExpectedDeliveryDateTs !== null)
|
||||
? new Date(lockedExpectedDeliveryDateTs)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -7611,7 +7520,7 @@ export default function App() {
|
||||
</span>
|
||||
<span style={{ fontSize: 16, color: '#1890ff', fontWeight: 700 }}>=</span>
|
||||
<span style={{ fontSize: 13, color: '#666', fontWeight: 600 }}>
|
||||
{lockedDeliveryDate ? '结束日期(未锁)' : '结束日期'}
|
||||
结束日期
|
||||
</span>
|
||||
<span style={{
|
||||
fontSize: 13,
|
||||
@ -7626,24 +7535,6 @@ export default function App() {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{lockedDeliveryDate && (
|
||||
<div style={{ marginTop: 8, display: 'flex', alignItems: 'center', justifyContent: 'flex-start', gap: 8, flexWrap: 'nowrap', whiteSpace: 'nowrap', overflowX: 'auto' }}>
|
||||
<Text style={{ fontSize: 13, color: '#333', fontWeight: 600, whiteSpace: 'nowrap' }}>结束日期(已锁定)</Text>
|
||||
<span style={{
|
||||
fontSize: 13,
|
||||
color: '#722ed1',
|
||||
backgroundColor: 'rgba(114, 46, 209, 0.08)',
|
||||
border: '1px solid rgba(114, 46, 209, 0.24)',
|
||||
borderRadius: 6,
|
||||
padding: '3px 8px',
|
||||
fontWeight: 700,
|
||||
whiteSpace: 'nowrap'
|
||||
}}>
|
||||
{formatDate(lockedDeliveryDate)}({getDayOfWeek(lockedDeliveryDate)})
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 第二行:客户期望日期(可更改,优化展示为标签样式) */}
|
||||
<div style={{ marginTop: 8, display: 'flex', alignItems: 'center', justifyContent: 'flex-start', gap: 8, flexWrap: 'nowrap', whiteSpace: 'nowrap', overflowX: 'auto' }}>
|
||||
<Text style={{ fontSize: 13, color: '#333', fontWeight: 600, whiteSpace: 'nowrap' }}>客户期望日期(可更改)</Text>
|
||||
@ -7651,7 +7542,6 @@ export default function App() {
|
||||
style={{ width: '200px' }}
|
||||
placeholder="请选择客户期望日期"
|
||||
value={expectedDate ?? undefined}
|
||||
disabled={isExpectedDeliveryDateLocked}
|
||||
onChange={(date) => {
|
||||
if (date instanceof Date) {
|
||||
setExpectedDate(date);
|
||||
|
||||
Reference in New Issue
Block a user