From 628aa6a42e587e9f337e213f87f922fc2ab2af02 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期二, 02 十二月 2025 17:00:39 +0800
Subject: [PATCH] 修改卧转立扫码到卧转立任务流转,卧转立判断玻璃超时时间
---
mes-web/src/views/plcTest/components/MultiDeviceTest/ExecutionMonitor.vue | 19 ++
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java | 5
mes-processes/mes-plcSend/src/main/java/com/mes/task/service/impl/MultiDeviceTaskServiceImpl.java | 7 +
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java | 8 +
mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java | 152 ++++++++++++++++++++++---
mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java | 4
mes-web/src/views/plcTest/MultiDeviceWorkbench.vue | 4
mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java | 50 ++++++++
mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java | 56 +++++++-
mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue | 2
10 files changed, 272 insertions(+), 35 deletions(-)
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java
index 76e5cc1..754420b 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/entity/GlassInfo.java
@@ -86,8 +86,10 @@
// 鐘舵�佸父閲�
public static final class Status {
- public static final String ACTIVE = "ACTIVE"; // 娲昏穬
+ public static final String ACTIVE = "ACTIVE"; // 鍏煎鏃ф暟鎹�
public static final String ARCHIVED = "ARCHIVED"; // 宸插綊妗�
+ public static final String PENDING = "PENDING"; // 寰呭崸杞珛澶勭悊
+ public static final String PROCESSED = "PROCESSED"; // 宸插鐞�
}
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
index 827d87c..202de49 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/GlassInfoService.java
@@ -70,5 +70,10 @@
* @return 鐜荤拑ID鍒楄〃
*/
List<String> getRecentScannedGlassIds(Integer minutesAgo, Integer maxCount, String workLine);
+
+ /**
+ * 鎵归噺鏇存柊鐜荤拑鐘舵��
+ */
+ boolean updateGlassStatus(List<String> glassIds, String status);
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
index 2e81b91..5546da4 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
@@ -1,12 +1,14 @@
package com.mes.device.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.device.entity.GlassInfo;
import com.mes.device.mapper.DeviceGlassInfoMapper;
import com.mes.device.service.GlassInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
import java.util.Collections;
import java.util.Date;
@@ -100,8 +102,35 @@
GlassInfo existing = baseMapper.selectByGlassId(glassInfo.getGlassId());
if (existing != null) {
glassInfo.setId(existing.getId());
+ // 淇濈暀鍘熷鍒涘缓淇℃伅
+ if (glassInfo.getCreatedTime() == null) {
+ glassInfo.setCreatedTime(existing.getCreatedTime());
+ }
+ if (glassInfo.getCreatedBy() == null) {
+ glassInfo.setCreatedBy(existing.getCreatedBy());
+ }
+ // 鏇存柊涓哄綋鍓嶆椂闂�
+ if (glassInfo.getUpdatedTime() == null) {
+ glassInfo.setUpdatedTime(new Date());
+ }
+ if (glassInfo.getUpdatedBy() == null) {
+ glassInfo.setUpdatedBy("system");
+ }
return updateById(glassInfo);
} else {
+ Date now = new Date();
+ if (glassInfo.getCreatedTime() == null) {
+ glassInfo.setCreatedTime(now);
+ }
+ if (glassInfo.getUpdatedTime() == null) {
+ glassInfo.setUpdatedTime(now);
+ }
+ if (glassInfo.getCreatedBy() == null) {
+ glassInfo.setCreatedBy("system");
+ }
+ if (glassInfo.getUpdatedBy() == null) {
+ glassInfo.setUpdatedBy("system");
+ }
return save(glassInfo);
}
} catch (Exception e) {
@@ -136,7 +165,7 @@
Date timeThreshold = new Date(System.currentTimeMillis() - minutes * 60 * 1000L);
LambdaQueryWrapper<GlassInfo> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(GlassInfo::getStatus, GlassInfo.Status.ACTIVE)
+ wrapper.eq(GlassInfo::getStatus, GlassInfo.Status.PENDING)
.ge(GlassInfo::getCreatedTime, timeThreshold)
.orderByDesc(GlassInfo::getCreatedTime)
.last("LIMIT " + limit);
@@ -160,5 +189,24 @@
return Collections.emptyList();
}
}
+
+ @Override
+ public boolean updateGlassStatus(List<String> glassIds, String status) {
+ if (CollectionUtils.isEmpty(glassIds) || status == null) {
+ return true;
+ }
+ try {
+ LambdaUpdateWrapper<GlassInfo> wrapper = new LambdaUpdateWrapper<>();
+ wrapper.in(GlassInfo::getGlassId, glassIds);
+ GlassInfo update = new GlassInfo();
+ update.setStatus(status);
+ update.setUpdatedTime(new Date());
+ update.setUpdatedBy("system");
+ return this.update(update, wrapper);
+ } catch (Exception e) {
+ log.error("鎵归噺鏇存柊鐜荤拑鐘舵�佸け璐�, glassIds={}, status={}", glassIds, status, e);
+ return false;
+ }
+ }
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java
index fd1c2a1..71ad7f1 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/scanner/handler/HorizontalScannerLogicHandler.java
@@ -18,6 +18,7 @@
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -273,10 +274,15 @@
if (height != null) {
glassInfo.setGlassLength(height); // 闀�
}
- glassInfo.setStatus(GlassInfo.Status.ACTIVE);
+ glassInfo.setStatus(GlassInfo.Status.PENDING);
if (workLine != null) {
glassInfo.setDescription("workLine=" + workLine);
}
+ Date now = new Date();
+ glassInfo.setCreatedTime(now);
+ glassInfo.setUpdatedTime(now);
+ glassInfo.setCreatedBy("system");
+ glassInfo.setUpdatedBy("system");
return glassInfo;
}
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java
index 85b9dc3..c942e41 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/interaction/workstation/transfer/handler/HorizontalTransferLogicHandler.java
@@ -83,7 +83,9 @@
switch (operation) {
case "checkAndProcess":
case "process":
- return handleCheckAndProcess(deviceConfig, config, logicParams);
+ // 杩欓噷蹇呴』鎶� params 浼犺繘鍘伙紝浠ヤ究鍦ㄥ璁惧浠诲姟娴佺▼涓�
+ // 鑳藉閫氳繃 _taskContext 灏嗗崸杞珛杈撳嚭鐨勭幓鐠僆D鍐欏叆浠诲姟涓婁笅鏂�
+ return handleCheckAndProcess(deviceConfig, config, logicParams, params);
case "startMonitor":
return handleStartMonitor(deviceConfig, config, logicParams);
case "stopMonitor":
@@ -109,7 +111,8 @@
private DevicePlcVO.OperationResult handleCheckAndProcess(
DeviceConfig deviceConfig,
WorkstationLogicConfig config,
- Map<String, Object> logicParams) {
+ Map<String, Object> logicParams,
+ Map<String, Object> params) {
String deviceId = deviceConfig.getDeviceId();
EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig);
@@ -129,9 +132,13 @@
log.info("鏌ヨ鍒版渶杩戞壂鐮佺殑鐜荤拑: deviceId={}, count={}",
deviceId, recentGlasses.size());
- // 2. 鏇存柊缂撳啿闃熷垪鍜屾渶鍚庢壂鐮佹椂闂�
- updateBuffer(deviceId, recentGlasses);
- lastScanTime.put(deviceId, new AtomicLong(System.currentTimeMillis()));
+ // 2. 鏇存柊缂撳啿闃熷垪锛涗粎鍦ㄦ湁鈥滄柊鐜荤拑鈥濆姞鍏ョ紦鍐叉椂鎵嶆洿鏂版渶鍚庢壂鐮佹椂闂�
+ boolean hasNewGlass = updateBuffer(deviceId, recentGlasses);
+ if (hasNewGlass) {
+ lastScanTime
+ .computeIfAbsent(deviceId, k -> new AtomicLong())
+ .set(System.currentTimeMillis());
+ }
// 3. 妫�鏌ユ槸鍚﹂渶瑕佺珛鍗冲鐞嗭紙瀹归噺宸叉弧鎴�30s鍐呮棤鏂扮幓鐠冿級
List<GlassBufferItem> buffer = glassBuffer.get(deviceId);
@@ -162,8 +169,34 @@
return writeResult;
}
- // 7. 浠庣紦鍐查槦鍒椾腑绉婚櫎宸插鐞嗙殑鐜荤拑
+ // 鍗ц浆绔嬫壒娆″凡鎴愬姛鍐欏叆PLC锛屽皢鏈壒娆$幓鐠僆D鍐欏叆浠诲姟涓婁笅鏂囷紝渚涘ぇ杞﹁繘鐗囦娇鐢�
+ try {
+ if (params != null) {
+ Object ctxObj = params.get("_taskContext");
+ if (ctxObj instanceof com.mes.task.model.TaskExecutionContext) {
+ com.mes.task.model.TaskExecutionContext ctx =
+ (com.mes.task.model.TaskExecutionContext) ctxObj;
+ List<String> batchGlassIds = batch.stream()
+ .map(GlassInfo::getGlassId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ if (!batchGlassIds.isEmpty()) {
+ ctx.getSharedData().put("transferReadyGlassIds",
+ new java.util.ArrayList<>(batchGlassIds));
+ log.info("鍗ц浆绔嬪凡杈撳嚭鎵规鐜荤拑鍒颁换鍔′笂涓嬫枃: deviceId={}, glassIds={}",
+ deviceConfig.getId(), batchGlassIds);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.warn("鍗ц浆绔嬪啓鍏ヤ换鍔′笂涓嬫枃transferReadyGlassIds澶辫触: deviceId={}", deviceConfig.getId(), e);
+ }
+
+ // 7. 浠庣紦鍐查槦鍒椾腑绉婚櫎宸插鐞嗙殑鐜荤拑骞舵洿鏂扮姸鎬�
removeProcessedGlasses(deviceId, batch);
+ glassInfoService.updateGlassStatus(
+ batch.stream().map(GlassInfo::getGlassId).collect(Collectors.toList()),
+ GlassInfo.Status.PROCESSED);
String msg = String.format("鎵规宸插啓鍏LC: glassCount=%d, glassIds=%s",
batch.size(),
@@ -197,7 +230,7 @@
Date twoMinutesAgo = new Date(System.currentTimeMillis() - 120000);
LambdaQueryWrapper<GlassInfo> wrapper = new LambdaQueryWrapper<>();
- wrapper.eq(GlassInfo::getStatus, GlassInfo.Status.ACTIVE)
+ wrapper.in(GlassInfo::getStatus, GlassInfo.Status.PENDING, GlassInfo.Status.ACTIVE)
.ge(GlassInfo::getCreatedTime, twoMinutesAgo)
.orderByDesc(GlassInfo::getCreatedTime)
.last("LIMIT 20"); // 闄愬埗鏌ヨ鏁伴噺锛岄伩鍏嶈繃澶�
@@ -223,8 +256,9 @@
/**
* 鏇存柊缂撳啿闃熷垪
+ * @return 鏄惁鏈夋柊鐨勭幓鐠冭鍔犲叆缂撳啿锛堢敤浜庡垽鏂槸鍚﹀埛鏂� lastScanTime锛�
*/
- private void updateBuffer(String deviceId, List<GlassInfo> newGlasses) {
+ private boolean updateBuffer(String deviceId, List<GlassInfo> newGlasses) {
List<GlassBufferItem> buffer = glassBuffer.computeIfAbsent(
deviceId, k -> new CopyOnWriteArrayList<>());
@@ -232,13 +266,16 @@
.map(item -> item.glassInfo.getGlassId())
.collect(Collectors.toSet());
+ boolean hasNewGlass = false;
for (GlassInfo glass : newGlasses) {
if (!existingIds.contains(glass.getGlassId())) {
buffer.add(new GlassBufferItem(glass, System.currentTimeMillis()));
+ hasNewGlass = true;
log.debug("娣诲姞鐜荤拑鍒扮紦鍐查槦鍒�: deviceId={}, glassId={}",
deviceId, glass.getGlassId());
}
}
+ return hasNewGlass;
}
/**
@@ -375,7 +412,8 @@
// 鍚姩鐩戞帶浠诲姟
ScheduledFuture<?> future = monitorExecutor.scheduleWithFixedDelay(() -> {
try {
- handleCheckAndProcess(deviceConfig, config, logicParams);
+ // 鐩戞帶浠诲姟涓嶅湪澶氳澶囦换鍔′笂涓嬫枃涓繍琛岋紝杩欓噷涓嶉渶瑕佷紶鍏� params/_taskContext
+ handleCheckAndProcess(deviceConfig, config, logicParams, null);
} catch (Exception e) {
log.error("鐩戞帶浠诲姟鎵ц寮傚父: deviceId={}", deviceId, e);
}
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 986a06b..2156e46 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
@@ -165,6 +165,12 @@
log.info("妫�娴嬪埌鎵爜璁惧锛屽噯澶囧惎鍔ㄥ畾鏃跺櫒: deviceId={}, deviceType={}, deviceName={}",
device.getId(), device.getDeviceType(), device.getDeviceName());
TaskStepDetail step = createStepRecord(task, device, currentOrder);
+ // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
+ step.setStatus(TaskStepDetail.Status.RUNNING.name());
+ step.setStartTime(new Date());
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+
ScheduledFuture<?> scannerTask = startScannerTimer(task, step, device, context);
if (scannerTask != null) {
registerScheduledTask(task.getTaskId(), scannerTask);
@@ -187,6 +193,12 @@
log.info("妫�娴嬪埌鍗ц浆绔嬭澶囷紝鍑嗗鍚姩瀹氭椂鍣�: deviceId={}, deviceType={}, deviceName={}",
device.getId(), device.getDeviceType(), device.getDeviceName());
TaskStepDetail step = createStepRecord(task, device, currentOrder);
+ // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
+ step.setStatus(TaskStepDetail.Status.RUNNING.name());
+ step.setStartTime(new Date());
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+
ScheduledFuture<?> transferTask = startTransferTimer(task, step, device, context);
if (transferTask != null) {
registerScheduledTask(task.getTaskId(), transferTask);
@@ -209,6 +221,12 @@
boolean isInboundVehicle = currentLoadVehicleIndex == 1; // 绗竴涓ぇ杞︽槸杩涚墖澶ц溅
TaskStepDetail step = createStepRecord(task, device, currentOrder);
+ // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
+ step.setStatus(TaskStepDetail.Status.RUNNING.name());
+ step.setStartTime(new Date());
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+
ScheduledFuture<?> vehicleTask;
if (isInboundVehicle) {
// 杩涚墖澶ц溅锛氱洃鎺у閲忥紝鍔ㄦ�佸垽鏂�
@@ -242,6 +260,12 @@
// 4. 澶х悊鐗囩璁惧锛氬惎鍔ㄥ畾鏃跺櫒閫昏緫澶勭悊锛堜笉娑夊強PLC浜や簰锛屽彧璐熻矗閫昏緫澶勭悊锛�
if (isLargeGlass) {
TaskStepDetail step = createStepRecord(task, device, currentOrder);
+ // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
+ step.setStatus(TaskStepDetail.Status.RUNNING.name());
+ step.setStartTime(new Date());
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+
ScheduledFuture<?> largeGlassTask = startLargeGlassTimer(task, step, device, context);
if (largeGlassTask != null) {
registerScheduledTask(task.getTaskId(), largeGlassTask);
@@ -392,6 +416,17 @@
log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒瀹屾垚: taskId={}, deviceId={}, processed={}/{}, success={}, fail={}",
task.getTaskId(), device.getId(), processedCount.get(), glassIds.size(),
successCount.get(), failCount.get());
+ // 鑻ヤ箣鍓嶆湭鍑虹幇澶辫触锛屽啀灏嗙姸鎬佺疆涓哄畬鎴�
+ boolean alreadyFailed = TaskStepDetail.Status.FAILED.name().equals(step.getStatus());
+ if (!alreadyFailed) {
+ step.setStatus(TaskStepDetail.Status.COMPLETED.name());
+ step.setSuccessMessage(String.format("宸插畬鎴愭壂鎻�: 鎴愬姛=%d, 澶辫触=%d", successCount.get(), failCount.get()));
+ if (step.getEndTime() == null) {
+ step.setEndTime(new Date());
+ }
+ taskStepDetailMapper.updateById(step);
+ notificationService.notifyStepUpdate(task.getTaskId(), step);
+ }
deviceCoordinationService.syncDeviceStatus(device,
DeviceCoordinationService.DeviceStatus.COMPLETED, context);
return;
@@ -492,15 +527,21 @@
if (handler != null) {
DevicePlcVO.OperationResult result = handler.execute(device, "checkAndProcess", params);
- // 鏇存柊姝ラ鐘舵��
- updateStepStatus(step, result);
+ // 鏇存柊姝ラ鐘舵�侊紙鍖哄垎绛夊緟涓拰鐪熸瀹屾垚锛�
+ updateStepStatusForTransfer(step, result);
// 閫氱煡姝ラ鏇存柊锛堣鍓嶇瀹炴椂鐪嬪埌姝ラ鐘舵�侊級
notificationService.notifyStepUpdate(task.getTaskId(), step);
boolean opSuccess = Boolean.TRUE.equals(result.getSuccess());
updateTaskProgress(task, step.getStepOrder(), opSuccess);
if (opSuccess) {
- log.debug("鍗ц浆绔嬭澶囧畾鏃跺櫒鎵ц鎴愬姛: taskId={}, deviceId={}, message={}",
- task.getTaskId(), device.getId(), result.getMessage());
+ String message = result.getMessage();
+ if (message != null && message.contains("鎵规宸插啓鍏LC")) {
+ log.info("鍗ц浆绔嬭澶囧畾鏃跺櫒鎵ц鎴愬姛锛堝凡鍐欏叆PLC锛�: taskId={}, deviceId={}, message={}",
+ task.getTaskId(), device.getId(), message);
+ } else {
+ log.debug("鍗ц浆绔嬭澶囧畾鏃跺櫒绛夊緟涓�: taskId={}, deviceId={}, message={}",
+ task.getTaskId(), device.getId(), message);
+ }
} else {
log.warn("鍗ц浆绔嬭澶囧畾鏃跺櫒鎵ц澶辫触: taskId={}, deviceId={}, message={}",
task.getTaskId(), device.getId(), result.getMessage());
@@ -544,28 +585,27 @@
task.getTaskId(), device.getId());
return;
}
- // 妫�鏌ユ槸鍚︽湁宸叉壂鎻忕殑鐜荤拑淇℃伅
- List<String> scannedGlassIds = getScannedGlassIds(context);
- if (CollectionUtils.isEmpty(scannedGlassIds)) {
- // 娌℃湁宸叉壂鎻忕殑鐜荤拑锛岀‘淇濆崸杞珛鎵爜缁х画杩愯
- setScannerPause(context, false);
+ // 妫�鏌ユ槸鍚︽湁鍗ц浆绔嬩富浣撳凡杈撳嚭銆佸噯澶囦笂澶ц溅鐨勭幓鐠冧俊鎭�
+ List<String> readyGlassIds = getTransferReadyGlassIds(context);
+ if (CollectionUtils.isEmpty(readyGlassIds)) {
+ // 娌℃湁鍗ц浆绔嬭緭鍑虹殑鐜荤拑锛岀户缁瓑寰�
return;
}
// 濡傛灉鐜荤拑ID鏁伴噺娌℃湁鍙樺寲锛岃鏄庢病鏈夋柊鐨勭幓鐠冿紝缁х画绛夊緟
- int currentCount = scannedGlassIds.size();
+ int currentCount = readyGlassIds.size();
if (currentCount == lastProcessedCount.get()) {
log.debug("澶ц溅璁惧瀹氭椂鍣細鐜荤拑ID鏁伴噺鏈彉鍖栵紝缁х画绛夊緟: taskId={}, deviceId={}, count={}",
task.getTaskId(), device.getId(), currentCount);
return;
}
- log.info("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌鏂扮殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
+ log.info("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌鍗ц浆绔嬭緭鍑虹殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
task.getTaskId(), device.getId(), currentCount);
// 妫�鏌ュ閲�
Map<String, Object> checkParams = new HashMap<>();
- checkParams.put("glassIds", new ArrayList<>(scannedGlassIds));
+ checkParams.put("glassIds", new ArrayList<>(readyGlassIds));
checkParams.put("_taskContext", context);
DeviceLogicHandler handler = handlerFactory.getHandler(device.getDeviceType());
@@ -579,19 +619,18 @@
if (Boolean.TRUE.equals(result.getSuccess())) {
log.info("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屾垚鍔�: taskId={}, deviceId={}, glassCount={}",
- task.getTaskId(), device.getId(), scannedGlassIds.size());
+ task.getTaskId(), device.getId(), readyGlassIds.size());
// 灏嗗凡瑁呰浇鐨勭幓鐠僆D淇濆瓨鍒板叡浜暟鎹腑锛堜緵澶х悊鐗囩浣跨敤锛�
- setLoadedGlassIds(context, new ArrayList<>(scannedGlassIds));
- // 娓呯┖宸叉壂鎻忕殑鐜荤拑ID鍒楄〃锛堝凡澶勭悊锛�
- clearScannedGlassIds(context);
+ setLoadedGlassIds(context, new ArrayList<>(readyGlassIds));
+ // 娓呯┖鍗ц浆绔嬭緭鍑虹殑鐜荤拑ID鍒楄〃锛堝凡澶勭悊锛�
+ clearTransferReadyGlassIds(context);
lastProcessedCount.set(0);
// 纭繚鍗ц浆绔嬫壂鐮佺户缁繍琛�
setScannerPause(context, false);
} else {
- // 瑁呬笉涓嬶紝閫氱煡鍗ц浆绔嬫壂鐮佹殏鍋�
- log.warn("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄥ閲忎笉瓒�: taskId={}, deviceId={}, message={}, 宸查�氱煡鍗ц浆绔嬫壂鐮佹殏鍋�",
+ // 瑁呬笉涓嬶紝璁板綍瀹归噺涓嶈冻锛堟槸鍚﹂渶瑕佸奖鍝嶆壂鐮佺敱宸ヨ壓鍐嶅喅瀹氾級
+ log.warn("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄥ閲忎笉瓒�: taskId={}, deviceId={}, message={}",
task.getTaskId(), device.getId(), result.getMessage());
- setScannerPause(context, true);
lastProcessedCount.set(currentCount); // 璁板綍褰撳墠鏁伴噺锛岄伩鍏嶉噸澶嶆鏌�
}
@@ -942,6 +981,30 @@
context.getSharedData().put("scannedGlassIds", new ArrayList<>());
}
}
+
+ /**
+ * 鑾峰彇鍗ц浆绔嬩富浣撳凡杈撳嚭銆佸噯澶囦笂澶ц溅鐨勭幓鐠僆D鍒楄〃
+ */
+ @SuppressWarnings("unchecked")
+ private List<String> getTransferReadyGlassIds(TaskExecutionContext context) {
+ if (context == null) {
+ return Collections.emptyList();
+ }
+ Object glassIds = context.getSharedData().get("transferReadyGlassIds");
+ if (glassIds instanceof List) {
+ return new ArrayList<>((List<String>) glassIds);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * 娓呯┖鍗ц浆绔嬩富浣撳凡杈撳嚭鐨勭幓鐠僆D鍒楄〃
+ */
+ private void clearTransferReadyGlassIds(TaskExecutionContext context) {
+ if (context != null) {
+ context.getSharedData().put("transferReadyGlassIds", new ArrayList<>());
+ }
+ }
/**
* 娉ㄥ唽瀹氭椂鍣ㄤ换鍔�
@@ -1025,15 +1088,66 @@
if (success) {
// 鎴愬姛鏃讹紝濡傛灉鏈夋秷鎭垯淇濆瓨锛堢敤浜庢彁绀轰俊鎭級锛屽惁鍒欐竻绌�
step.setSuccessMessage(StringUtils.hasText(message) ? message : null);
+ // 濡傛灉鐘舵�佸彉涓哄畬鎴愶紝璁剧疆缁撴潫鏃堕棿
+ if (TaskStepDetail.Status.COMPLETED.name().equals(step.getStatus()) && step.getEndTime() == null) {
+ step.setEndTime(new Date());
+ }
} else {
// 澶辫触鏃朵繚瀛橀敊璇秷鎭�
step.setErrorMessage(message);
+ // 濡傛灉鐘舵�佸彉涓哄け璐ワ紝璁剧疆缁撴潫鏃堕棿
+ if (TaskStepDetail.Status.FAILED.name().equals(step.getStatus()) && step.getEndTime() == null) {
+ step.setEndTime(new Date());
+ }
}
step.setOutputData(toJson(result));
taskStepDetailMapper.updateById(step);
}
/**
+ * 鏇存柊鍗ц浆绔嬭澶囨楠ょ姸鎬侊紙鍖哄垎绛夊緟涓拰鐪熸瀹屾垚锛�
+ */
+ private void updateStepStatusForTransfer(TaskStepDetail step, DevicePlcVO.OperationResult result) {
+ if (step == null || result == null) {
+ return;
+ }
+ boolean success = Boolean.TRUE.equals(result.getSuccess());
+ String message = result.getMessage();
+
+ // 鍒ゆ柇鏄惁鐪熸瀹屾垚锛堝彧鏈夊啓鍏LC鎵嶇畻瀹屾垚锛�
+ boolean isRealCompleted = success && message != null && message.contains("鎵规宸插啓鍏LC");
+
+ if (isRealCompleted) {
+ // 鐪熸瀹屾垚锛氳缃负瀹屾垚鐘舵�侊紝骞惰缃粨鏉熸椂闂�
+ step.setStatus(TaskStepDetail.Status.COMPLETED.name());
+ step.setSuccessMessage(message);
+ if (step.getEndTime() == null) {
+ step.setEndTime(new Date());
+ }
+ } else if (success) {
+ // 绛夊緟涓細淇濇寔杩愯鐘舵�侊紝鍙洿鏂版秷鎭�
+ if (!TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) {
+ step.setStatus(TaskStepDetail.Status.RUNNING.name());
+ }
+ step.setSuccessMessage(message);
+ // 纭繚寮�濮嬫椂闂村凡璁剧疆
+ if (step.getStartTime() == null) {
+ step.setStartTime(new Date());
+ }
+ } else {
+ // 澶辫触锛氳缃负澶辫触鐘舵�侊紝骞惰缃粨鏉熸椂闂�
+ step.setStatus(TaskStepDetail.Status.FAILED.name());
+ step.setErrorMessage(message);
+ if (step.getEndTime() == null) {
+ step.setEndTime(new Date());
+ }
+ }
+
+ step.setOutputData(toJson(result));
+ taskStepDetailMapper.updateById(step);
+ }
+
+ /**
* 鍒涘缓姝ラ鎽樿
*/
private Map<String, Object> createStepSummary(String deviceName, boolean success, String message) {
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/impl/MultiDeviceTaskServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/impl/MultiDeviceTaskServiceImpl.java
index c2d2e35..278a68f 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/impl/MultiDeviceTaskServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/impl/MultiDeviceTaskServiceImpl.java
@@ -197,9 +197,14 @@
if (task == null) {
return false;
}
- if (!MultiDeviceTask.Status.RUNNING.name().equals(task.getStatus())) {
+ // 鍏佽鍦� RUNNING 鎴� FAILED 鐘舵�佷笅鎵ц鍙栨秷鎿嶄綔
+ String status = task.getStatus();
+ boolean cancellable = MultiDeviceTask.Status.RUNNING.name().equals(status)
+ || MultiDeviceTask.Status.FAILED.name().equals(status);
+ if (!cancellable) {
return false;
}
+ // 鏍囪浠诲姟鍙栨秷骞跺仠姝㈡墍鏈夊畾鏃跺櫒
taskExecutionEngine.requestTaskCancellation(taskId);
task.setStatus(MultiDeviceTask.Status.CANCELLED.name());
task.setEndTime(new Date());
diff --git a/mes-web/src/views/plcTest/MultiDeviceWorkbench.vue b/mes-web/src/views/plcTest/MultiDeviceWorkbench.vue
index 3472ea8..1c2dd81 100644
--- a/mes-web/src/views/plcTest/MultiDeviceWorkbench.vue
+++ b/mes-web/src/views/plcTest/MultiDeviceWorkbench.vue
@@ -80,6 +80,10 @@
// 濡傛灉浼犲叆浜嗕换鍔′俊鎭紝鍙互鑷姩閫変腑
if (task && task.taskId) {
selectedTaskId.value = task.taskId
+ // 绋嶅悗鑷姩鎵撳紑璇ヤ换鍔$殑姝ラ璇︽儏鎶藉眽
+ setTimeout(() => {
+ monitorRef.value?.openTaskDrawer?.(task.taskId)
+ }, 600)
}
}
diff --git a/mes-web/src/views/plcTest/components/MultiDeviceTest/ExecutionMonitor.vue b/mes-web/src/views/plcTest/components/MultiDeviceTest/ExecutionMonitor.vue
index 1502b50..a221de2 100644
--- a/mes-web/src/views/plcTest/components/MultiDeviceTest/ExecutionMonitor.vue
+++ b/mes-web/src/views/plcTest/components/MultiDeviceTest/ExecutionMonitor.vue
@@ -86,7 +86,7 @@
鏌ョ湅璇︽儏
</el-button>
<el-button
- v-if="row.status === 'RUNNING'"
+ v-if="row.status === 'RUNNING' || row.status === 'FAILED'"
link
type="danger"
size="small"
@@ -421,6 +421,20 @@
}
}
+// 鏍规嵁taskId鎵撳紑浠诲姟璇︽儏鎶藉眽锛堜緵鐖剁粍浠惰皟鐢級
+const openTaskDrawer = async (taskId) => {
+ if (!taskId) return
+ // 濡傛灉浠诲姟鍒楄〃涓虹┖锛屽厛鍔犺浇涓�娆�
+ if (!tasks.value || tasks.value.length === 0) {
+ await fetchTasks()
+ }
+ const task = tasks.value.find(t => t.taskId === taskId)
+ if (!task) {
+ return
+ }
+ await handleRowClick(task)
+}
+
const statusType = (status) => {
switch ((status || '').toUpperCase()) {
case 'COMPLETED':
@@ -562,7 +576,8 @@
defineExpose({
fetchTasks,
connectSSE,
- disconnectSSE
+ disconnectSSE,
+ openTaskDrawer
})
</script>
diff --git a/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue b/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
index 649cd93..0d7d3a7 100644
--- a/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
+++ b/mes-web/src/views/plcTest/components/MultiDeviceTest/TaskOrchestration.vue
@@ -110,7 +110,7 @@
const form = reactive({
glassIntervalSeconds: 10, // 鍗曠墖闂撮殧锛岄粯璁�10绉�
executionInterval: 1000,
- timeoutMinutes: 30,
+ timeoutMinutes: 1,
retryCount: 3
})
--
Gitblit v1.8.0