From 04914a9997afbbead6f8adbb9d9c40e05b2edbd1 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期三, 17 十二月 2025 17:04:34 +0800
Subject: [PATCH] 修复调用导入工程失败 重复保存;修复分批出片逻辑
---
mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java | 552 +++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 375 insertions(+), 177 deletions(-)
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
index 4c5f2d3..196e3d7 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
@@ -247,17 +247,11 @@
// 4. 澶х悊鐗囩璁惧锛氬惎鍔ㄥ畾鏃跺櫒閫昏緫澶勭悊锛堜笉娑夊強PLC浜や簰锛屽彧璐熻矗閫昏緫澶勭悊锛�
if (isLargeGlass) {
TaskStepDetail step = createStepRecord(task, device, currentOrder);
-
- ScheduledFuture<?> largeGlassTask = startLargeGlassTimer(task, step, device, context);
- if (largeGlassTask != null) {
- registerScheduledTask(task.getTaskId(), largeGlassTask);
- stepSummaries.add(createStepSummary(device.getDeviceName(), true, "澶х悊鐗囩瀹氭椂鍣ㄥ凡鍚姩锛岄�昏緫澶勭悊涓�"));
- } else {
- stepSummaries.add(createStepSummary(device.getDeviceName(), false, "鍚姩瀹氭椂鍣ㄥけ璐�"));
- success = false;
- failureMessage = "澶х悊鐗囩璁惧鍚姩瀹氭椂鍣ㄥけ璐�";
- break;
- }
+
+ // 绛夎繘鐗囧ぇ杞︽楠ょ湡姝e畬鎴愬悗鍐嶅惎鍔ㄥぇ鐞嗙墖绗煎畾鏃跺櫒锛屼繚璇佹墽琛岄『搴忎负锛氳繘鐗囧ぇ杞� -> 澶х悊鐗囩
+ context.getSharedData().put("largeGlassStepId", step.getId());
+ context.getSharedData().put("largeGlassDeviceId", device.getId());
+ stepSummaries.add(createStepSummary(device.getDeviceName(), true, "宸插垱寤哄ぇ鐞嗙墖绗兼楠わ紝绛夊緟杩涚墖澶ц溅瀹屾垚鍚庡惎鍔ㄥ畾鏃跺櫒"));
currentOrder++;
continue;
}
@@ -723,14 +717,24 @@
taskStepDetailMapper.updateById(step);
notificationService.notifyStepUpdate(task.getTaskId(), step);
}
+ // 缁х画杞MES浠诲姟/纭鐘舵�侊紝鑻ES纭瀹屾垚浼氬湪鍐呴儴鏇存柊姝ラ涓篊OMPLETED
pollMesForVehicle(task, step, device, context);
+ // 濡傛灉杩涚墖澶ц溅姝ラ鍦ㄨ疆璇㈠悗宸插畬鎴愶紝鍒欏皾璇曞惎鍔ㄥぇ鐞嗙墖绗煎畾鏃跺櫒
+ if (TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus())) {
+ startLargeGlassTimerIfNeeded(task, context);
+ }
return;
}
}
// 濡傛灉澶ц溅宸茬粡瑁呰浇杩囩幓鐠冿紙RUNNING鐘舵�侊級锛岃疆璇ES浠诲姟/纭鐘舵��
if (TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) {
+ // 杞MES浠诲姟/纭鐘舵�侊紝鑻ES纭瀹屾垚浼氬湪鍐呴儴鏇存柊姝ラ涓篊OMPLETED
pollMesForVehicle(task, step, device, context);
+ // 濡傛灉杩涚墖澶ц溅姝ラ鍦ㄨ疆璇㈠悗宸插畬鎴愶紝鍒欏皾璇曞惎鍔ㄥぇ鐞嗙墖绗煎畾鏃跺櫒
+ if (TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus())) {
+ startLargeGlassTimerIfNeeded(task, context);
+ }
} else {
// 濡傛灉杩樻病鏈夎杞借繃鐜荤拑锛岀瓑寰呭崸杞珛杈撳嚭
if (!TaskStepDetail.Status.PENDING.name().equals(step.getStatus())) {
@@ -829,7 +833,9 @@
// 鍙湁鍦ㄤ换鍔″凡寮�濮嬫墽琛岋紙鏈変换鍔¤褰曪級鏃舵墠妫�鏌ES纭
DevicePlcVO.OperationResult mesResult = null;
try {
- mesResult = handler.execute(device, "checkMesConfirm", Collections.emptyMap());
+ Map<String, Object> confirmParams = new HashMap<>();
+ confirmParams.put("_taskContext", context);
+ mesResult = handler.execute(device, "checkMesConfirm", confirmParams);
} catch (Exception e) {
log.warn("杩涚墖澶ц溅璁惧妫�鏌ES纭鐘舵�佸紓甯�: taskId={}, deviceId={}, error={}",
task.getTaskId(), device.getId(), e.getMessage());
@@ -892,6 +898,11 @@
DeviceCoordinationService.DeviceStatus.FAILED, context);
}
}
+
+ // 褰撹繘鐗囧ぇ杞︽楠ょ湡姝e畬鎴愬悗锛屽啀鍚姩澶х悊鐗囩瀹氭椂鍣紝淇濊瘉鎵ц椤哄簭
+ if (TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus())) {
+ startLargeGlassTimerIfNeeded(task, context);
+ }
}
} catch (Exception e) {
log.error("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屽紓甯�: taskId={}, deviceId={}", task.getTaskId(), device.getId(), e);
@@ -917,11 +928,10 @@
TaskExecutionContext context) {
try {
final long MONITOR_INTERVAL_MS = 2_000; // 2绉掔洃鎺т竴娆�
-
+
log.debug("鍚姩鍑虹墖澶ц溅璁惧瀹氭椂鍣�: taskId={}, deviceId={}, interval={}s",
task.getTaskId(), device.getId(), MONITOR_INTERVAL_MS / 1000);
-
- // 鍚姩瀹氭椂浠诲姟
+
ScheduledFuture<?> future = scheduledExecutor.scheduleWithFixedDelay(() -> {
try {
if (isTaskCancelled(context)) {
@@ -929,183 +939,242 @@
task.getTaskId(), device.getId());
return;
}
- // 鍑虹墖澶ц溅璁惧锛氬彧鏈夊湪鐪熸寮�濮嬪鐞嗘椂鎵嶈缃负RUNNING
- // 妫�鏌ユ槸鍚︽湁宸插鐞嗙殑鐜荤拑淇℃伅锛堜粠澶х悊鐗囩鏉ョ殑锛�
- List<String> processedGlassIds = getProcessedGlassIds(context);
- boolean isRunning = TaskStepDetail.Status.RUNNING.name().equals(step.getStatus());
-
- // 濡傛灉娌℃湁宸插鐞嗙幓鐠冿紝鍒欎笉搴斾富鍔ㄦ妸姝ラ鎷夊埌RUNNING锛屽彧淇濇寔宸茶繍琛岀姸鎬�
- if (CollectionUtils.isEmpty(processedGlassIds)) {
- if (isRunning) {
- // 宸茬粡鍦ㄨ繍琛岀殑鎯呭喌涓嬶紝缁х画杞MES浠诲姟/纭锛岄伩鍏嶉敊杩囩‘璁�
- DeviceLogicHandler handler = handlerFactory.getHandler(device.getDeviceType());
- if (handler != null) {
- Map<String, Object> logicParams = parseLogicParams(device);
-
- // 鍏堟鏌ES浠诲姟锛堝鏋渕esSend=1锛屼細鍒涘缓浠诲姟骞跺紑濮嬫墽琛岋級
- DevicePlcVO.OperationResult mesTaskResult = null;
- try {
- mesTaskResult = handler.execute(device, "checkMesTask", Collections.emptyMap());
- if (mesTaskResult != null && Boolean.TRUE.equals(mesTaskResult.getSuccess())) {
- log.info("鍑虹墖澶ц溅璁惧宸叉鏌ES浠诲姟骞跺紑濮嬫墽琛�: taskId={}, deviceId={}, message={}",
- task.getTaskId(), device.getId(), mesTaskResult.getMessage());
- }
- } catch (Exception e) {
- log.warn("鍑虹墖澶ц溅璁惧妫�鏌ES浠诲姟寮傚父: taskId={}, deviceId={}, error={}",
- task.getTaskId(), device.getId(), e.getMessage());
- }
-
- // 鐒跺悗妫�鏌ES纭鐘舵�侊紙鍙湁鍦ㄤ换鍔″凡寮�濮嬫墽琛屾椂鎵嶆鏌ワ級
- DevicePlcVO.OperationResult mesResult = null;
- try {
- mesResult = handler.execute(device, "checkMesConfirm", Collections.emptyMap());
- } catch (Exception e) {
- log.warn("鍑虹墖澶ц溅璁惧妫�鏌ES纭鐘舵�佸紓甯�: taskId={}, deviceId={}, error={}",
- task.getTaskId(), device.getId(), e.getMessage());
- }
-
- // 鏇存柊姝ラ鐘舵�侊紙澶ц溅璁惧淇濇寔RUNNING锛岀洿鍒癕ES纭瀹屾垚鎴栦换鍔″彇娑堬級
- if (mesResult != null) {
- updateStepStatusForVehicle(task.getTaskId(), step, mesResult);
- boolean opSuccess = Boolean.TRUE.equals(mesResult.getSuccess());
- updateTaskProgress(task, step.getStepOrder(), opSuccess);
- if (!opSuccess) {
- deviceCoordinationService.syncDeviceStatus(device,
- DeviceCoordinationService.DeviceStatus.FAILED, context);
- }
- }
- }
- } else {
- // 鏈繍琛屼笖娌℃湁宸插鐞嗙幓鐠冿紝淇濇寔PENDING
- if (!TaskStepDetail.Status.PENDING.name().equals(step.getStatus())
- && !TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus())) {
- step.setStatus(TaskStepDetail.Status.PENDING.name());
- step.setSuccessMessage("绛夊緟澶х悊鐗囩澶勭悊瀹屾垚");
- taskStepDetailMapper.updateById(step);
- notificationService.notifyStepUpdate(task.getTaskId(), step);
- }
- log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣細鏆傛棤宸插鐞嗙殑鐜荤拑淇℃伅: taskId={}, deviceId={}",
- task.getTaskId(), device.getId());
- }
- return;
- }
-
- log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌宸插鐞嗙殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
- task.getTaskId(), device.getId(), processedGlassIds.size());
- // 闇�绛夊緟澶х悊鐗囩瀹屾垚鍏ㄩ儴鐜荤拑鐨勫鐞嗗悗鍐嶅嚭鐗�
- @SuppressWarnings("unchecked")
- List<String> initialGlassIds = (List<String>) context.getSharedData().get("initialGlassIds");
- if (!CollectionUtils.isEmpty(initialGlassIds)
- && !processedGlassIds.containsAll(initialGlassIds)) {
- // 閮ㄥ垎鐜荤拑灏氭湭鐢卞ぇ鐞嗙墖绗煎鐞嗗畬鎴愶紝淇濇寔绛夊緟
+ final String lastMsgKey = "outboundVehicleLastMessage:" + device.getId();
+
+ // 1) 鎬荤洰鏍囷細澶х悊鐗囩浜у嚭鐨勨�滃簲鍑虹墖鐜荤拑鍒楄〃鈥�
+ List<String> processedGlassIdsRaw = getProcessedGlassIds(context);
+ if (CollectionUtils.isEmpty(processedGlassIdsRaw)) {
+ // 灏氭湭鏈夊ぇ鐞嗙墖绗艰緭鍑猴紝淇濇寔绛夊緟
deviceCoordinationService.syncDeviceStatus(device,
DeviceCoordinationService.DeviceStatus.WAITING, context);
- if (!TaskStepDetail.Status.PENDING.name().equals(step.getStatus())) {
+ if (!TaskStepDetail.Status.PENDING.name().equals(step.getStatus())
+ && !TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus())) {
step.setStatus(TaskStepDetail.Status.PENDING.name());
- step.setSuccessMessage("绛夊緟澶х悊鐗囩澶勭悊鍏ㄩ儴鐜荤拑鍚庡啀鍑虹墖");
+ step.setSuccessMessage("绛夊緟澶х悊鐗囩澶勭悊瀹屾垚");
+ if (step.getStartTime() == null) {
+ step.setStartTime(new Date());
+ }
taskStepDetailMapper.updateById(step);
notificationService.notifyStepUpdate(task.getTaskId(), step);
}
- log.debug("鍑虹墖澶ц溅绛夊緟澶х悊鐗囩瀹屾垚鍏ㄩ儴鐜荤拑: taskId={}, deviceId={}, processed={}, initial={}",
- task.getTaskId(), device.getId(), processedGlassIds.size(), initialGlassIds.size());
return;
}
-
- // 鎵ц鍑虹墖鎿嶄綔
- Map<String, Object> checkParams = new HashMap<>();
- checkParams.put("glassIds", new ArrayList<>(processedGlassIds));
- checkParams.put("_taskContext", context);
-
+
+ // 2) 宸插畬鎴愮疮绉細outboundGlassIds锛堜换鍔′晶缁存姢锛屾寜mesConfirm=1绱姞锛�
+ Set<String> processedSet = new LinkedHashSet<>();
+ for (String id : processedGlassIdsRaw) {
+ if (StringUtils.hasText(id)) {
+ processedSet.add(id);
+ }
+ }
+ Set<String> outboundSet = new HashSet<>();
+ for (String id : getOutboundGlassIds(context)) {
+ if (StringUtils.hasText(id)) {
+ outboundSet.add(id);
+ }
+ }
+
+ List<String> remaining = new ArrayList<>();
+ for (String id : processedSet) {
+ if (!outboundSet.contains(id)) {
+ remaining.add(id);
+ }
+ }
+ int total = processedSet.size();
+ int done = total - remaining.size();
+
+ // 3) 鑻ュ凡鍏ㄩ儴瀹屾垚锛岀洿鎺ユ敹灏炬楠�
+ if (total > 0 && remaining.isEmpty()) {
+ if (!TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus())) {
+ step.setStatus(TaskStepDetail.Status.COMPLETED.name());
+ String lastMsg = null;
+ Object lastObj = context.getSharedData().get(lastMsgKey);
+ if (lastObj != null && StringUtils.hasText(String.valueOf(lastObj))) {
+ lastMsg = String.valueOf(lastObj);
+ }
+ step.setSuccessMessage(StringUtils.hasText(lastMsg)
+ ? String.format("鍑虹墖瀹屾垚锛�%d/%d锛�%s", done, total, lastMsg)
+ : String.format("鍑虹墖瀹屾垚锛�%d/%d", done, total));
+ step.setErrorMessage(null);
+ Date now = new Date();
+ if (step.getStartTime() == null) {
+ step.setStartTime(now);
+ }
+ if (step.getEndTime() == null) {
+ step.setEndTime(now);
+ }
+ if (step.getStartTime() != null && step.getEndTime() != null) {
+ step.setDurationMs(step.getEndTime().getTime() - step.getStartTime().getTime());
+ }
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+ checkAndCompleteTaskIfDone(step.getTaskId());
+ }
+ deviceCoordinationService.syncDeviceStatus(device,
+ DeviceCoordinationService.DeviceStatus.COMPLETED, context);
+ return;
+ }
+
+ // 4) 杩涘叆杩愯鎬侊紙鍙湪鐪熸寮�濮嬪嚭鐗囨椂锛�
+ if (!TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) {
+ step.setStatus(TaskStepDetail.Status.RUNNING.name());
+ if (step.getStartTime() == null) {
+ step.setStartTime(new Date());
+ }
+ }
+ // 鏇存柊杩涘害淇℃伅锛堜究浜庡墠绔疄鏃跺睍绀猴級
+ Date now = new Date();
+ if (step.getStartTime() != null) {
+ step.setDurationMs(now.getTime() - step.getStartTime().getTime());
+ }
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+
DeviceLogicHandler handler = handlerFactory.getHandler(device.getDeviceType());
- if (handler != null) {
- // 灏唋ogicParams鍚堝苟鍒癱heckParams涓�
- Map<String, Object> logicParams = parseLogicParams(device);
- if (logicParams != null && !logicParams.isEmpty()) {
- checkParams.put("_logicParams", logicParams);
- }
- // 绗竴姝ワ細鍐欏叆澶ц溅鍑虹墖璇锋眰
- DevicePlcVO.OperationResult feedResult = handler.execute(device, "feedGlass", checkParams);
-
- if (Boolean.TRUE.equals(feedResult.getSuccess())) {
- // 鐪熸寮�濮嬪鐞嗭紝璁剧疆涓篟UNNING
- deviceCoordinationService.syncDeviceStatus(device,
- DeviceCoordinationService.DeviceStatus.RUNNING, context);
- // 姝ラ鐘舵�佷篃璁剧疆涓篟UNNING
- if (!TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) {
- step.setStatus(TaskStepDetail.Status.RUNNING.name());
- if (step.getStartTime() == null) {
- step.setStartTime(new Date());
+ if (handler == null) {
+ log.warn("鏈壘鍒板嚭鐗囧ぇ杞andler: deviceId={}, deviceType={}", device.getId(), device.getDeviceType());
+ return;
+ }
+
+ Map<String, Object> logicParams = parseLogicParams(device);
+ Map<String, Object> baseParams = new HashMap<>();
+ baseParams.put("_taskContext", context);
+ if (logicParams != null && !logicParams.isEmpty()) {
+ baseParams.put("_logicParams", logicParams);
+ }
+
+ String latestInteractionMsg = null;
+
+ // 5) 鍏堟鏌ES浠诲姟锛坢esSend=1鏃朵細鎶婃湰鎵规鐜荤拑ID鍐欏叆currentMesBatchGlassIds锛�
+ DevicePlcVO.OperationResult mesTaskResult = null;
+ try {
+ mesTaskResult = handler.execute(device, "checkMesTask", new HashMap<>(baseParams));
+ } catch (Exception e) {
+ log.warn("鍑虹墖澶ц溅妫�鏌ES浠诲姟寮傚父: taskId={}, deviceId={}, error={}",
+ task.getTaskId(), device.getId(), e.getMessage());
+ }
+ if (mesTaskResult != null && StringUtils.hasText(mesTaskResult.getMessage())) {
+ latestInteractionMsg = mesTaskResult.getMessage();
+ }
+
+ // 浠巆heckMesTask杩斿洖鍊间腑璇诲彇鏈壒娆$幓鐠僆D锛堜笉渚濊禆璁惧渚у啓_taskContext锛�
+ try {
+ if (mesTaskResult != null && mesTaskResult.getData() != null) {
+ Object batchObj = mesTaskResult.getData().get("batchGlassIds");
+ if (batchObj instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<Object> raw = (List<Object>) batchObj;
+ List<String> batchIds = new ArrayList<>();
+ for (Object o : raw) {
+ if (o != null && StringUtils.hasText(String.valueOf(o))) {
+ batchIds.add(String.valueOf(o));
+ }
}
- taskStepDetailMapper.updateById(step);
- notificationService.notifyStepUpdate(task.getTaskId(), step);
- }
- log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屾垚鍔�: taskId={}, deviceId={}, glassCount={}",
- task.getTaskId(), device.getId(), processedGlassIds.size());
- // 娓呯┖宸插鐞嗙殑鐜荤拑ID鍒楄〃锛堝凡澶勭悊锛�
- clearProcessedGlassIds(context);
-
- // feedGlass鎴愬姛鍚庯紝鍏堟鏌ES浠诲姟锛坈heckMesTask锛夋潵寮�濮嬫墽琛屼换鍔�
- DevicePlcVO.OperationResult mesTaskResult = null;
- try {
- mesTaskResult = handler.execute(device, "checkMesTask", Collections.emptyMap());
- if (mesTaskResult != null && Boolean.TRUE.equals(mesTaskResult.getSuccess())) {
- log.info("鍑虹墖澶ц溅璁惧宸叉鏌ES浠诲姟骞跺紑濮嬫墽琛�: taskId={}, deviceId={}, message={}",
- task.getTaskId(), device.getId(), mesTaskResult.getMessage());
+ if (!batchIds.isEmpty()) {
+ context.getSharedData().put("currentMesBatchGlassIds", batchIds);
}
- } catch (Exception e) {
- log.warn("鍑虹墖澶ц溅璁惧妫�鏌ES浠诲姟寮傚父: taskId={}, deviceId={}, error={}",
- task.getTaskId(), device.getId(), e.getMessage());
}
- } else {
- // 娌℃湁鏁版嵁锛屼繚鎸乄AITING鐘舵�佸拰PENDING姝ラ鐘舵��
- deviceCoordinationService.syncDeviceStatus(device,
- DeviceCoordinationService.DeviceStatus.WAITING, context);
- if (!TaskStepDetail.Status.PENDING.name().equals(step.getStatus())) {
- step.setStatus(TaskStepDetail.Status.PENDING.name());
- step.setSuccessMessage("绛夊緟涓�");
- taskStepDetailMapper.updateById(step);
- notificationService.notifyStepUpdate(task.getTaskId(), step);
- }
- log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屽け璐�: taskId={}, deviceId={}, message={}",
- task.getTaskId(), device.getId(), feedResult.getMessage());
}
-
- // 绗簩姝ワ細妫�鏌ES纭鐘舵�侊紙濡傛灉澶ц溅澶勭悊鍣ㄦ敮鎸佺殑璇濓級
- // 鍙湁鍦ㄤ换鍔″凡寮�濮嬫墽琛岋紙鏈変换鍔¤褰曪級鏃舵墠妫�鏌ES纭
- DevicePlcVO.OperationResult mesResult = null;
+ } catch (Exception ignore) {
+ // 涓嶅奖鍝嶄富娴佺▼
+ }
+
+ boolean mesSendIsZero = false;
+ if (mesTaskResult != null && mesTaskResult.getData() != null) {
+ Object reason = mesTaskResult.getData().get("waitingReason");
+ if ("mesSend=0".equals(String.valueOf(reason))) {
+ mesSendIsZero = true;
+ }
+ } else if (mesTaskResult != null && StringUtils.hasText(mesTaskResult.getMessage())
+ && mesTaskResult.getMessage().contains("mesSend=0")) {
+ mesSendIsZero = true;
+ }
+
+ // 6) 鑻ES灏氭湭涓嬪彂浠诲姟锛坢esSend=0锛夛紝瑙﹀彂涓�娆″嚭鐗囪姹傦紙feedGlass锛�
+ if (mesSendIsZero && !remaining.isEmpty()) {
+ Map<String, Object> feedParams = new HashMap<>(baseParams);
+ feedParams.put("glassIds", new ArrayList<>(remaining));
try {
- mesResult = handler.execute(device, "checkMesConfirm", Collections.emptyMap());
+ DevicePlcVO.OperationResult feedResult = handler.execute(device, "feedGlass", feedParams);
+ if (feedResult != null && StringUtils.hasText(feedResult.getMessage())) {
+ latestInteractionMsg = feedResult.getMessage();
+ }
+ if (Boolean.TRUE.equals(feedResult.getSuccess())) {
+ deviceCoordinationService.syncDeviceStatus(device,
+ DeviceCoordinationService.DeviceStatus.RUNNING, context);
+ } else {
+ deviceCoordinationService.syncDeviceStatus(device,
+ DeviceCoordinationService.DeviceStatus.WAITING, context);
+ }
} catch (Exception e) {
- log.warn("鍑虹墖澶ц溅璁惧妫�鏌ES纭鐘舵�佸紓甯�: taskId={}, deviceId={}, error={}",
+ log.warn("鍑虹墖澶ц溅瑙﹀彂feedGlass寮傚父: taskId={}, deviceId={}, error={}",
task.getTaskId(), device.getId(), e.getMessage());
}
-
- // 鏇存柊姝ラ鐘舵�侊紙澶ц溅璁惧淇濇寔RUNNING锛岀洿鍒癕ES纭瀹屾垚鎴栦换鍔″彇娑堬級
- if (mesResult != null) {
- updateStepStatusForVehicle(task.getTaskId(), step, mesResult);
- boolean opSuccess = Boolean.TRUE.equals(mesResult.getSuccess());
- updateTaskProgress(task, step.getStepOrder(), opSuccess);
- if (!opSuccess) {
- deviceCoordinationService.syncDeviceStatus(device,
- DeviceCoordinationService.DeviceStatus.FAILED, context);
- }
- } else {
- updateStepStatusForVehicle(task.getTaskId(), step, feedResult);
- boolean opSuccess = Boolean.TRUE.equals(feedResult.getSuccess());
- updateTaskProgress(task, step.getStepOrder(), opSuccess);
- if (!opSuccess) {
- deviceCoordinationService.syncDeviceStatus(device,
- DeviceCoordinationService.DeviceStatus.FAILED, context);
- }
+ }
+
+ // 7) 鍐嶆鏌ES纭锛坢esConfirm=1琛ㄧず鏈浜や簰瀹屾垚锛�
+ DevicePlcVO.OperationResult mesConfirmResult = null;
+ try {
+ mesConfirmResult = handler.execute(device, "checkMesConfirm", new HashMap<>(baseParams));
+ } catch (Exception e) {
+ log.warn("鍑虹墖澶ц溅妫�鏌ES纭寮傚父: taskId={}, deviceId={}, error={}",
+ task.getTaskId(), device.getId(), e.getMessage());
+ }
+ if (mesConfirmResult != null && StringUtils.hasText(mesConfirmResult.getMessage())) {
+ // 纭鎻愮ず浼樺厛绾ф渶楂�
+ latestInteractionMsg = mesConfirmResult.getMessage();
+ }
+
+ boolean interactionCompleted = false;
+ if (mesConfirmResult != null && mesConfirmResult.getData() != null) {
+ Object completedFlag = mesConfirmResult.getData().get("completed");
+ if (completedFlag instanceof Boolean) {
+ interactionCompleted = (Boolean) completedFlag;
+ } else if (completedFlag != null) {
+ interactionCompleted = "true".equalsIgnoreCase(String.valueOf(completedFlag));
}
+ }
+
+ // 8) 鏇存柊鈥滄渶杩戜竴娆′氦浜掓彁绀衡�濅笌姝ラ鎻愮ず鏂囨锛堥伩鍏嶈绾繘搴﹁鐩栵級
+ if (StringUtils.hasText(latestInteractionMsg)) {
+ context.getSharedData().put(lastMsgKey, latestInteractionMsg);
+ }
+ String lastMsg = null;
+ Object lastObj = context.getSharedData().get(lastMsgKey);
+ if (lastObj != null && StringUtils.hasText(String.valueOf(lastObj))) {
+ lastMsg = String.valueOf(lastObj);
+ }
+ step.setSuccessMessage(StringUtils.hasText(lastMsg)
+ ? String.format("鍑虹墖杩涜涓細%d/%d锛�%s", done, total, lastMsg)
+ : String.format("鍑虹墖杩涜涓細%d/%d", done, total));
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+
+ if (interactionCompleted) {
+ // 鏈浜や簰瀹屾垚锛氬皢鏈壒娆�(currentMesBatchGlassIds)绱姞鍒板凡鍑虹墖(outboundGlassIds)
+ Object batchObj = context.getSharedData().get("currentMesBatchGlassIds");
+ if (batchObj instanceof List) {
+ @SuppressWarnings("unchecked")
+ List<String> batchIds = new ArrayList<>((List<String>) batchObj);
+ // 浠呯疮鍔犫�滅洰鏍囬泦鍚堚�濆唴鐨勭幓鐠冿紝閬垮厤鑴忔暟鎹�
+ List<String> filtered = new ArrayList<>();
+ for (String id : batchIds) {
+ if (StringUtils.hasText(id) && processedSet.contains(id)) {
+ filtered.add(id);
+ }
+ }
+ addOutboundGlassIds(context, filtered);
+ }
+ // 娓呯┖鏈壒娆¤褰曪紝閬垮厤涓嬩竴娆¤疆璇㈤噸澶嶄娇鐢ㄦ棫鎵规
+ context.getSharedData().put("currentMesBatchGlassIds", new ArrayList<>());
}
} catch (Exception e) {
log.error("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屽紓甯�: taskId={}, deviceId={}", task.getTaskId(), device.getId(), e);
}
}, 0, MONITOR_INTERVAL_MS, TimeUnit.MILLISECONDS);
-
- // 鍦ㄤ覆琛屾墽琛屾ā寮忎笅锛岃澶囧惎鍔ㄥ畾鏃跺櫒鏃跺厛璁剧疆涓� WAITING锛屽畾鏃跺櫒绗竴娆℃墽琛屾椂鍐嶈缃负 RUNNING
+
+ // 鍚姩鏃朵繚鎸乄AITING锛屽悗缁敱瀹氭椂鍣ㄩ�昏緫鍒囨崲涓篟UNNING/COMPLETED
deviceCoordinationService.syncDeviceStatus(device,
DeviceCoordinationService.DeviceStatus.WAITING, context);
return future;
@@ -1208,7 +1277,17 @@
Long processStartTime = getProcessStartTime(context);
if (processStartTime == null) {
// 绗竴娆℃娴嬪埌鐜荤拑锛岃褰曞紑濮嬪鐞嗘椂闂�
- setProcessStartTime(context, System.currentTimeMillis());
+ long now = System.currentTimeMillis();
+ setProcessStartTime(context, now);
+ // 琛ラ綈姝ラ鐨勫紑濮嬫椂闂翠笌鐘舵�侊紝纭繚鍓嶇鑰楁椂姝e父鏄剧ず
+ 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,8 +1313,21 @@
// 鏇存柊姝ラ鐘舵��
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);
+ // 閫氱煡鍓嶇鐘舵�佹洿鏂�
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
// 澶х悊鐗囩瀹屾垚鍚庡皾璇曡嚜鍔ㄦ敹灏炬暣涓换鍔�
checkAndCompleteTaskIfDone(step.getTaskId());
@@ -1290,17 +1382,16 @@
/**
* 璁剧疆宸茶杞界殑鐜荤拑ID鍒楄〃
+ * 瀵逛簬鍒嗘壒鍑虹墖鍦烘櫙锛屾瘡娆¤缃簲鏇挎崲涓哄綋鍓嶆壒娆$殑鐜荤拑ID
*/
private void setLoadedGlassIds(TaskExecutionContext context, List<String> glassIds) {
if (context != null) {
- // 绱姞璁板綍锛岄伩鍏嶅悗缁� containsAll 鍒ゆ柇鍥犺鐩栦涪澶卞巻鍙茬幓鐠冭�屽洖閫�涓虹瓑寰�
- List<String> merged = new ArrayList<>(getLoadedGlassIds(context)); // 纭繚鍙彉
+ // 鏇挎崲涓哄綋鍓嶆壒娆$殑鐜荤拑ID
+ List<String> currentBatch = new ArrayList<>();
if (glassIds != null) {
- merged.addAll(glassIds);
+ currentBatch.addAll(glassIds);
}
- // 鍘婚噸
- List<String> distinct = merged.stream().distinct().collect(java.util.stream.Collectors.toList());
- context.getSharedData().put("loadedGlassIds", distinct);
+ context.getSharedData().put("loadedGlassIds", currentBatch);
}
}
@@ -1343,6 +1434,33 @@
private void clearProcessedGlassIds(TaskExecutionContext context) {
if (context != null) {
context.getSharedData().put("processedGlassIds", new ArrayList<>());
+ }
+ }
+
+ /**
+ * 鑾峰彇宸插嚭鐗囩殑鐜荤拑ID鍒楄〃
+ */
+ @SuppressWarnings("unchecked")
+ private List<String> getOutboundGlassIds(TaskExecutionContext context) {
+ if (context == null) {
+ return Collections.emptyList();
+ }
+ Object glassIds = context.getSharedData().get("outboundGlassIds");
+ if (glassIds instanceof List) {
+ return new ArrayList<>((List<String>) glassIds);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * 娣诲姞宸插嚭鐗囩殑鐜荤拑ID鍒楄〃
+ */
+ private void addOutboundGlassIds(TaskExecutionContext context, List<String> glassIds) {
+ if (context != null && glassIds != null && !glassIds.isEmpty()) {
+ List<String> existing = getOutboundGlassIds(context);
+ Set<String> allOutbound = new HashSet<>(existing);
+ allOutbound.addAll(glassIds);
+ context.getSharedData().put("outboundGlassIds", new ArrayList<>(allOutbound));
}
}
@@ -1552,6 +1670,8 @@
// 鎵�鏈夋楠ら兘宸插畬鎴愶紝鏀跺熬浠诲姟
task.setStatus(MultiDeviceTask.Status.COMPLETED.name());
+ // 鍏抽敭锛氬悓姝ヨ繘搴﹀埌鏈�缁堝�硷紝閬垮厤鍓嶇浠嶆樉绀衡��3/5鈥濊繖绫绘棫杩涘害
+ task.setCurrentStep(totalSteps);
task.setEndTime(new Date());
multiDeviceTaskMapper.updateById(task);
@@ -1784,7 +1904,9 @@
// 鍏堟鏌ES浠诲姟锛堝鏋渕esSend=1锛屼細鍒涘缓浠诲姟骞跺紑濮嬫墽琛岋級
DevicePlcVO.OperationResult mesTaskResult = null;
try {
- mesTaskResult = handler.execute(device, "checkMesTask", Collections.emptyMap());
+ Map<String, Object> taskParams = new HashMap<>();
+ taskParams.put("_taskContext", context);
+ mesTaskResult = handler.execute(device, "checkMesTask", taskParams);
if (mesTaskResult != null && Boolean.TRUE.equals(mesTaskResult.getSuccess())) {
log.info("澶ц溅璁惧宸叉鏌ES浠诲姟骞跺紑濮嬫墽琛�: taskId={}, deviceId={}, message={}",
task.getTaskId(), device.getId(), mesTaskResult.getMessage());
@@ -1797,7 +1919,9 @@
// 鐒跺悗妫�鏌ES纭鐘舵��
DevicePlcVO.OperationResult mesResult = null;
try {
- mesResult = handler.execute(device, "checkMesConfirm", Collections.emptyMap());
+ Map<String, Object> checkParams = new HashMap<>();
+ checkParams.put("_taskContext", context);
+ mesResult = handler.execute(device, "checkMesConfirm", checkParams);
} catch (Exception e) {
log.warn("澶ц溅璁惧妫�鏌ES纭鐘舵�佸紓甯�: taskId={}, deviceId={}, error={}",
task.getTaskId(), device.getId(), e.getMessage());
@@ -2669,6 +2793,80 @@
}
/**
+ * 褰撹繘鐗囧ぇ杞︽楠ゅ畬鎴愬悗锛屽鏋滃瓨鍦ㄥぇ鐞嗙墖绗艰澶囦笖灏氭湭鍚姩鍏跺畾鏃跺櫒锛屽垯鍚姩澶х悊鐗囩瀹氭椂鍣�
+ * 淇濊瘉鎵ц椤哄簭涓猴細杩涚墖澶ц溅 -> 澶х悊鐗囩
+ */
+ private void startLargeGlassTimerIfNeeded(MultiDeviceTask task, TaskExecutionContext context) {
+ if (task == null || context == null) {
+ return;
+ }
+ // 闃叉閲嶅鍚姩
+ Object startedFlag = context.getSharedData().get("largeGlassTimerStarted");
+ if (startedFlag instanceof Boolean && (Boolean) startedFlag) {
+ return;
+ }
+
+ try {
+ // 浠庝笂涓嬫枃涓幏鍙栬澶囧垪琛�
+ @SuppressWarnings("unchecked")
+ List<DeviceConfig> devices = (List<DeviceConfig>) context.getSharedData().get("devices");
+ if (devices == null || devices.isEmpty()) {
+ return;
+ }
+
+ DeviceConfig largeGlassDevice = null;
+ for (DeviceConfig device : devices) {
+ if (DeviceConfig.DeviceType.LARGE_GLASS.equals(device.getDeviceType())) {
+ largeGlassDevice = device;
+ break;
+ }
+ }
+ if (largeGlassDevice == null) {
+ log.warn("鏈湪璁惧鍒楄〃涓壘鍒板ぇ鐞嗙墖绗艰澶�: taskId={}", task.getTaskId());
+ return;
+ }
+
+ // 閲嶆柊鍔犺浇澶х悊鐗囩姝ラ锛岀‘淇濇嬁鍒版渶鏂扮姸鎬侊紙鍙栬璁惧鏈�鏂扮殑涓�鏉℃楠よ褰曪級
+ List<TaskStepDetail> largeGlassSteps = taskStepDetailMapper.selectList(
+ Wrappers.<TaskStepDetail>lambdaQuery()
+ .eq(TaskStepDetail::getTaskId, task.getTaskId())
+ .eq(TaskStepDetail::getDeviceId, largeGlassDevice.getId())
+ .orderByDesc(TaskStepDetail::getStepOrder)
+ .last("LIMIT 1")
+ );
+ TaskStepDetail largeGlassStep = (largeGlassSteps != null && !largeGlassSteps.isEmpty())
+ ? largeGlassSteps.get(0)
+ : null;
+ if (largeGlassStep == null) {
+ log.warn("鏈壘鍒板ぇ鐞嗙墖绗兼楠よ褰�: taskId={}, deviceId={}", task.getTaskId(), largeGlassDevice.getId());
+ return;
+ }
+
+ // 濡傛灉姝ラ宸茬粡瀹屾垚鎴栧け璐ワ紝鍒欎笉鍐嶅惎鍔ㄥ畾鏃跺櫒
+ String status = largeGlassStep.getStatus();
+ if (TaskStepDetail.Status.COMPLETED.name().equals(status)
+ || TaskStepDetail.Status.FAILED.name().equals(status)) {
+ log.debug("澶х悊鐗囩姝ラ宸茬粨鏉燂紝涓嶅啀鍚姩瀹氭椂鍣�: taskId={}, stepId={}, status={}", task.getTaskId(), largeGlassStep.getId(), status);
+ context.getSharedData().put("largeGlassTimerStarted", true);
+ return;
+ }
+
+ ScheduledFuture<?> largeGlassTask = startLargeGlassTimer(task, largeGlassStep, largeGlassDevice, context);
+ if (largeGlassTask != null) {
+ registerScheduledTask(task.getTaskId(), largeGlassTask);
+ context.getSharedData().put("largeGlassTimerStarted", true);
+ log.info("宸插湪杩涚墖澶ц溅瀹屾垚鍚庡惎鍔ㄥぇ鐞嗙墖绗煎畾鏃跺櫒: taskId={}, largeGlassDeviceId={}, largeGlassStepId={}",
+ task.getTaskId(), largeGlassDevice.getId(), largeGlassStep.getId());
+ } else {
+ log.warn("鍦ㄨ繘鐗囧ぇ杞﹀畬鎴愬悗鍚姩澶х悊鐗囩瀹氭椂鍣ㄥけ璐�: taskId={}, largeGlassDeviceId={}, largeGlassStepId={}",
+ task.getTaskId(), largeGlassDevice.getId(), largeGlassStep.getId());
+ }
+ } catch (Exception e) {
+ log.warn("鍦ㄨ繘鐗囧ぇ杞﹀畬鎴愬悗鍚姩澶х悊鐗囩瀹氭椂鍣ㄥ紓甯�: taskId={}", task.getTaskId(), e);
+ }
+ }
+
+ /**
* 妫�鏌ュ崸杞珛璁惧鏄惁宸插畬鎴�
* 杩斿洖true琛ㄧず鍗ц浆绔嬪凡瀹屾垚锛圕OMPLETED锛夛紝鍙互鍒ゆ柇澶ц溅鏄惁瀹屾垚
* 杩斿洖false琛ㄧず鍗ц浆绔嬭繕鍦ㄨ繍琛屼腑锛圧UNNING锛夋垨绛夊緟涓紙PENDING锛夛紝涓嶅簲璇ユ爣璁板ぇ杞︿负瀹屾垚
--
Gitblit v1.8.0