mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
@@ -1208,7 +1208,17 @@ Long processStartTime = getProcessStartTime(context); if (processStartTime == null) { // 第一次检测到玻璃,记录开始处理时间 setProcessStartTime(context, System.currentTimeMillis()); long now = System.currentTimeMillis(); setProcessStartTime(context, now); // 补齐步骤的开始时间与状态,确保前端耗时正常显示 if (!TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) { step.setStatus(TaskStepDetail.Status.RUNNING.name()); } if (step.getStartTime() == null) { step.setStartTime(new Date(now)); } taskStepDetailMapper.updateById(step); notificationService.notifyStepUpdate(task.getTaskId(), step); log.debug("大理片笼设备开始处理: taskId={}, deviceId={}, glassCount={}, processTime={}s", task.getTaskId(), device.getId(), loadedGlassIds.size(), processTimeSeconds); return; @@ -1234,6 +1244,17 @@ // 更新步骤状态 step.setStatus(TaskStepDetail.Status.COMPLETED.name()); step.setErrorMessage(null); // 记录结束时间与耗时 if (step.getEndTime() == null) { step.setEndTime(new Date()); } if (step.getStartTime() == null) { // 如果开始时间缺失,用处理开始时间或结束时间兜底 step.setStartTime(new Date(processStartTime)); } if (step.getStartTime() != null && step.getEndTime() != null) { step.setDurationMs(step.getEndTime().getTime() - step.getStartTime().getTime()); } step.setOutputData(toJson(Collections.singletonMap("glassIds", loadedGlassIds))); taskStepDetailMapper.updateById(step); // 大理片笼完成后尝试自动收尾整个任务 mes-web/src/views/plcTest/components/MultiDeviceTest/ExecutionMonitor.vue
@@ -179,6 +179,12 @@ let eventSource = null const baseURL = import.meta.env.VITE_API_BASE_URL || '' // 统一的ID比较,避免数字/字符串不一致导致SSE更新被忽略 const isSameId = (a, b) => { if (a == null || b == null) return false return String(a) === String(b) } const fetchTasks = async () => { try { loading.value = true @@ -262,9 +268,11 @@ // 监听步骤更新 eventSource.addEventListener('stepUpdate', (event) => { try { const data = JSON.parse(event.data) const raw = JSON.parse(event.data) // 后端全量监听时的数据结构为 { taskId, step: { ... } },需要展开 step const data = raw?.step ? { ...raw.step, taskId: raw.taskId || raw.step.taskId } : raw // 如果数据中包含 taskId,检查是否匹配当前查看的任务 if (data.taskId && data.taskId === currentTaskId.value) { if (data.taskId && isSameId(data.taskId, currentTaskId.value)) { updateStepFromSSE(data) } else if (!data.taskId) { // 如果没有 taskId,可能是步骤数据直接传递 @@ -311,7 +319,7 @@ return } const taskIndex = tasks.value.findIndex(t => t.taskId === data.taskId) const taskIndex = tasks.value.findIndex(t => isSameId(t.taskId, data.taskId)) if (taskIndex >= 0) { // 更新任务 - 保留原有字段,只更新SSE传来的字段 const existingTask = tasks.value[taskIndex] @@ -344,7 +352,7 @@ if (!data) return // 如果数据中包含 taskId,检查是否匹配当前查看的任务 if (data.taskId && data.taskId !== currentTaskId.value) { if (data.taskId && !isSameId(data.taskId, currentTaskId.value)) { return }