|
|
@@ -133,8 +133,27 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ✅ 问题1:添加详细的调试打印 |
|
|
|
|
|
console.log("🔍 Time Remaining Debug:", { |
|
|
|
|
|
lineId: lineDetail?.id, |
|
|
|
|
|
equipmentId: lineDetail?.equipmentId, |
|
|
|
|
|
equipmentType: lineDetail?.equipmentType, |
|
|
|
|
|
durationInMinutes: lineDetail?.durationInMinutes, |
|
|
|
|
|
startTime: lineDetail?.startTime, |
|
|
|
|
|
startTimeType: typeof lineDetail?.startTime, |
|
|
|
|
|
isStartTimeArray: Array.isArray(lineDetail?.startTime), |
|
|
|
|
|
status: lineDetail?.status, |
|
|
|
|
|
hasDuration: !!lineDetail?.durationInMinutes, |
|
|
|
|
|
hasStartTime: !!lineDetail?.startTime, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
if (!lineDetail?.durationInMinutes || !lineDetail?.startTime) { |
|
|
if (!lineDetail?.durationInMinutes || !lineDetail?.startTime) { |
|
|
console.log("Line duration or start time is not valid"); |
|
|
|
|
|
|
|
|
console.log("❌ Line duration or start time is not valid", { |
|
|
|
|
|
durationInMinutes: lineDetail?.durationInMinutes, |
|
|
|
|
|
startTime: lineDetail?.startTime, |
|
|
|
|
|
equipmentId: lineDetail?.equipmentId, |
|
|
|
|
|
equipmentType: lineDetail?.equipmentType, |
|
|
|
|
|
}); |
|
|
setRemainingTime(null); |
|
|
setRemainingTime(null); |
|
|
setIsOverTime(false); |
|
|
setIsOverTime(false); |
|
|
return; |
|
|
return; |
|
|
@@ -143,13 +162,13 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro |
|
|
// Handle startTime format - it can be string or number array |
|
|
// Handle startTime format - it can be string or number array |
|
|
let start: Date; |
|
|
let start: Date; |
|
|
if (Array.isArray(lineDetail.startTime)) { |
|
|
if (Array.isArray(lineDetail.startTime)) { |
|
|
console.log("Line start time is an array"); |
|
|
|
|
|
|
|
|
console.log("Line start time is an array:", lineDetail.startTime); |
|
|
// If it's an array like [2025, 12, 15, 10, 30, 0], convert to Date |
|
|
// If it's an array like [2025, 12, 15, 10, 30, 0], convert to Date |
|
|
const [year, month, day, hour = 0, minute = 0, second = 0] = lineDetail.startTime; |
|
|
const [year, month, day, hour = 0, minute = 0, second = 0] = lineDetail.startTime; |
|
|
start = new Date(year, month - 1, day, hour, minute, second); |
|
|
start = new Date(year, month - 1, day, hour, minute, second); |
|
|
} else { |
|
|
} else { |
|
|
start = new Date(lineDetail.startTime); |
|
|
start = new Date(lineDetail.startTime); |
|
|
console.log("Line start time is a string"); |
|
|
|
|
|
|
|
|
console.log("Line start time is a string:", lineDetail.startTime); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Check if date is valid |
|
|
// Check if date is valid |
|
|
@@ -165,13 +184,45 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro |
|
|
// Check if line is paused |
|
|
// Check if line is paused |
|
|
const isPaused = lineDetail.status === "Paused" || lineDetail.productProcessIssueStatus === "Paused"; |
|
|
const isPaused = lineDetail.status === "Paused" || lineDetail.productProcessIssueStatus === "Paused"; |
|
|
|
|
|
|
|
|
|
|
|
// ✅ 问题2:修复 stopTime 类型处理,像 startTime 一样处理 |
|
|
|
|
|
const parseStopTime = (stopTime: string | number[] | undefined): Date | null => { |
|
|
|
|
|
if (!stopTime) return null; |
|
|
|
|
|
|
|
|
|
|
|
if (Array.isArray(stopTime)) { |
|
|
|
|
|
const [year, month, day, hour = 0, minute = 0, second = 0] = stopTime; |
|
|
|
|
|
return new Date(year, month - 1, day, hour, minute, second); |
|
|
|
|
|
} else { |
|
|
|
|
|
return new Date(stopTime); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
const update = () => { |
|
|
const update = () => { |
|
|
if (isPaused) { |
|
|
if (isPaused) { |
|
|
// If paused, freeze the time at the last calculated value |
|
|
// If paused, freeze the time at the last calculated value |
|
|
// If we don't have a frozen value yet, calculate it based on current time |
|
|
|
|
|
|
|
|
// If we don't have a frozen value yet, calculate it based on stopTime |
|
|
if (!frozenRemainingTime) { |
|
|
if (!frozenRemainingTime) { |
|
|
const now = new Date(); |
|
|
|
|
|
const elapsed = now.getTime() - start.getTime(); |
|
|
|
|
|
|
|
|
// ✅ 修复问题2:正确处理 stopTime 的类型(string | number[]) |
|
|
|
|
|
const pauseTime = lineDetail.stopTime |
|
|
|
|
|
? parseStopTime(lineDetail.stopTime) |
|
|
|
|
|
: null; |
|
|
|
|
|
|
|
|
|
|
|
// 如果没有 stopTime,使用当前时间(首次暂停时) |
|
|
|
|
|
const pauseTimeToUse = pauseTime && !isNaN(pauseTime.getTime()) |
|
|
|
|
|
? pauseTime |
|
|
|
|
|
: new Date(); |
|
|
|
|
|
|
|
|
|
|
|
// ✅ 计算总暂停时间(所有已恢复的暂停记录) |
|
|
|
|
|
const totalPausedTimeMs = (lineDetail as any).totalPausedTimeMs || 0; |
|
|
|
|
|
|
|
|
|
|
|
console.log("⏸️ Paused - calculating frozen time:", { |
|
|
|
|
|
stopTime: lineDetail.stopTime, |
|
|
|
|
|
pauseTime: pauseTimeToUse, |
|
|
|
|
|
startTime: start, |
|
|
|
|
|
totalPausedTimeMs: totalPausedTimeMs, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// ✅ 实际工作时间 = 暂停时间 - 开始时间 - 已恢复的暂停时间 |
|
|
|
|
|
const elapsed = pauseTimeToUse.getTime() - start.getTime() - totalPausedTimeMs; |
|
|
const remaining = durationMs - elapsed; |
|
|
const remaining = durationMs - elapsed; |
|
|
|
|
|
|
|
|
if (remaining <= 0) { |
|
|
if (remaining <= 0) { |
|
|
@@ -182,6 +233,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro |
|
|
setFrozenRemainingTime(frozenValue); |
|
|
setFrozenRemainingTime(frozenValue); |
|
|
setRemainingTime(frozenValue); |
|
|
setRemainingTime(frozenValue); |
|
|
setIsOverTime(true); |
|
|
setIsOverTime(true); |
|
|
|
|
|
console.log("⏸️ Frozen time (overtime):", frozenValue); |
|
|
} else { |
|
|
} else { |
|
|
const minutes = Math.floor(remaining / 60000).toString().padStart(2, "0"); |
|
|
const minutes = Math.floor(remaining / 60000).toString().padStart(2, "0"); |
|
|
const seconds = Math.floor((remaining % 60000) / 1000).toString().padStart(2, "0"); |
|
|
const seconds = Math.floor((remaining % 60000) / 1000).toString().padStart(2, "0"); |
|
|
@@ -189,24 +241,40 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro |
|
|
setFrozenRemainingTime(frozenValue); |
|
|
setFrozenRemainingTime(frozenValue); |
|
|
setRemainingTime(frozenValue); |
|
|
setRemainingTime(frozenValue); |
|
|
setIsOverTime(false); |
|
|
setIsOverTime(false); |
|
|
|
|
|
console.log("⏸️ Frozen time:", frozenValue); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
// Keep using frozen value while paused |
|
|
|
|
|
|
|
|
// ✅ 关键修复:暂停时始终使用冻结的值,不重新计算 |
|
|
setRemainingTime(frozenRemainingTime); |
|
|
setRemainingTime(frozenRemainingTime); |
|
|
|
|
|
console.log("⏸️ Using frozen time:", frozenRemainingTime); |
|
|
} |
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// If resumed or in progress, clear frozen time and continue counting |
|
|
// If resumed or in progress, clear frozen time and continue counting |
|
|
if (frozenRemainingTime && !isPaused) { |
|
|
if (frozenRemainingTime && !isPaused) { |
|
|
|
|
|
console.log("▶️ Resumed - clearing frozen time"); |
|
|
setFrozenRemainingTime(null); |
|
|
setFrozenRemainingTime(null); |
|
|
setLastPauseTime(null); |
|
|
setLastPauseTime(null); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ✅ 关键修复:计算剩余时间时,需要减去所有已恢复的暂停时间 |
|
|
|
|
|
const totalPausedTimeMs = (lineDetail as any).totalPausedTimeMs || 0; |
|
|
const now = new Date(); |
|
|
const now = new Date(); |
|
|
const elapsed = now.getTime() - start.getTime(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ✅ 实际工作时间 = 当前时间 - 开始时间 - 所有已恢复的暂停时间 |
|
|
|
|
|
const elapsed = now.getTime() - start.getTime() - totalPausedTimeMs; |
|
|
const remaining = durationMs - elapsed; |
|
|
const remaining = durationMs - elapsed; |
|
|
|
|
|
|
|
|
|
|
|
console.log("⏱️ Time calculation:", { |
|
|
|
|
|
now: now, |
|
|
|
|
|
start: start, |
|
|
|
|
|
totalPausedTimeMs: totalPausedTimeMs, |
|
|
|
|
|
elapsed: elapsed, |
|
|
|
|
|
remaining: remaining, |
|
|
|
|
|
durationMs: durationMs, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
if (remaining <= 0) { |
|
|
if (remaining <= 0) { |
|
|
// Over time - show negative time in red |
|
|
// Over time - show negative time in red |
|
|
const overTime = Math.abs(remaining); |
|
|
const overTime = Math.abs(remaining); |
|
|
@@ -229,7 +297,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro |
|
|
const timer = setInterval(update, 1000); |
|
|
const timer = setInterval(update, 1000); |
|
|
return () => clearInterval(timer); |
|
|
return () => clearInterval(timer); |
|
|
} |
|
|
} |
|
|
}, [lineDetail?.durationInMinutes, lineDetail?.startTime, lineDetail?.status, lineDetail?.productProcessIssueStatus]); |
|
|
|
|
|
|
|
|
}, [lineDetail?.durationInMinutes, lineDetail?.startTime, lineDetail?.status, lineDetail?.productProcessIssueStatus, lineDetail?.stopTime, frozenRemainingTime]); |
|
|
|
|
|
|
|
|
// Reset frozen time when status changes from paused to in progress |
|
|
// Reset frozen time when status changes from paused to in progress |
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
|
|