From 5d5d6b55f439a9cb42d948e816a9db70e3fb2805 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 31 三月 2026 08:14:53 +0800
Subject: [PATCH] #堆垛机移动
---
src/test/java/com/zy/asrs/task/WrkAnalysisStationArrivalScannerTest.java | 224 ++++++++++++
src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java | 8
src/main/java/com/zy/asrs/service/impl/WrkAnalysisServiceImpl.java | 15
src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java | 206 +++++++++++
src/main/java/com/zy/asrs/task/WrkMastScheduler.java | 21 +
src/main/java/com/zy/core/service/WrkCommandRollbackService.java | 12
src/main/java/com/zy/core/enums/WrkStsType.java | 6
src/main/java/com/zy/core/enums/WrkIoType.java | 1
src/test/java/com/zy/core/utils/CrnOperateProcessUtilsTest.java | 397 ++++++++++++++++++++++
src/main/resources/sql/20260330_add_crn_move_task_type.sql | 27 +
src/main/java/com/zy/common/service/CommonService.java | 4
src/main/java/com/zy/asrs/task/WrkAnalysisStationArrivalScanner.java | 92 +++++
src/main/java/com/zy/core/plugin/FakeProcess.java | 2
src/test/java/com/zy/asrs/task/WrkMastSchedulerCrnMoveTest.java | 54 +++
14 files changed, 1,061 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java b/src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java
index 99b6d01..38efac2 100644
--- a/src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java
+++ b/src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java
@@ -1,5 +1,7 @@
package com.zy.asrs.domain.enums;
+import com.zy.core.enums.WrkIoType;
+
/**
* 鍫嗗灈鏈虹姸鎬佹灇涓�
*/
@@ -37,6 +39,12 @@
}
public static CrnStatusType process(Integer ioType){
+ if (ioType == null) {
+ return MACHINE_ERROR;
+ }
+ if (ioType.equals(WrkIoType.CRN_MOVE.id)) {
+ return MACHINE_SITE_MOVE;
+ }
if (ioType>100) {
return MACHINE_PAKOUT;
} else if (ioType < 100 && ioType!=3 && ioType!=6 && ioType!=11) {
diff --git a/src/main/java/com/zy/asrs/service/impl/WrkAnalysisServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/WrkAnalysisServiceImpl.java
index f647010..6bbaac2 100644
--- a/src/main/java/com/zy/asrs/service/impl/WrkAnalysisServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/WrkAnalysisServiceImpl.java
@@ -30,7 +30,8 @@
WrkStsType.SETTLE_INBOUND.sts,
WrkStsType.COMPLETE_OUTBOUND.sts,
WrkStsType.SETTLE_OUTBOUND.sts,
- WrkStsType.COMPLETE_LOC_MOVE.sts
+ WrkStsType.COMPLETE_LOC_MOVE.sts,
+ WrkStsType.COMPLETE_CRN_MOVE.sts
);
private static final String MODE_TASK = "TASK";
private static final String MODE_TIME = "TIME";
@@ -186,7 +187,9 @@
entity.setRgvNo(wrkMast.getRgvNo());
entity.setFinalWrkSts(wrkMast.getWrkSts());
entity.setUpdateTime(time);
- if (Objects.equals(wrkMast.getIoType(), WrkIoType.LOC_MOVE.id) && entity.getStationDurationMs() == null) {
+ if ((Objects.equals(wrkMast.getIoType(), WrkIoType.LOC_MOVE.id)
+ || Objects.equals(wrkMast.getIoType(), WrkIoType.CRN_MOVE.id))
+ && entity.getStationDurationMs() == null) {
entity.setStationDurationMs(0L);
}
this.updateById(entity);
@@ -225,7 +228,9 @@
if (entity.getAppeTime() != null) {
entity.setTotalDurationMs(durationMs(entity.getAppeTime(), time));
}
- if (Objects.equals(wrkMast.getIoType(), WrkIoType.LOC_MOVE.id) && entity.getStationDurationMs() == null) {
+ if ((Objects.equals(wrkMast.getIoType(), WrkIoType.LOC_MOVE.id)
+ || Objects.equals(wrkMast.getIoType(), WrkIoType.CRN_MOVE.id))
+ && entity.getStationDurationMs() == null) {
entity.setStationDurationMs(0L);
}
FaultSummary faultSummary = buildFaultSummary(wrkMast.getWrkNo(), time);
@@ -265,6 +270,7 @@
ioTypes.add(option("1", "IN", "鍏ュ簱", WrkIoType.IN.id));
ioTypes.add(option("2", "OUT", "鍑哄簱", WrkIoType.OUT.id));
ioTypes.add(option("3", "LOC_MOVE", "绉诲簱", WrkIoType.LOC_MOVE.id));
+ ioTypes.add(option("4", "CRN_MOVE", "鍫嗗灈鏈虹Щ鍔�", WrkIoType.CRN_MOVE.id));
List<Map<String, Object>> timeFields = new ArrayList<>();
timeFields.add(option(TIME_FIELD_FINISH, TIME_FIELD_FINISH, "瀹屾垚鏃堕棿", TIME_FIELD_FINISH));
timeFields.add(option(TIME_FIELD_APPE, TIME_FIELD_APPE, "鍒涘缓鏃堕棿", TIME_FIELD_APPE));
@@ -819,6 +825,9 @@
if (Objects.equals(ioType, WrkIoType.LOC_MOVE.id)) {
return "绉诲簱";
}
+ if (Objects.equals(ioType, WrkIoType.CRN_MOVE.id)) {
+ return "鍫嗗灈鏈虹Щ鍔�";
+ }
return String.valueOf(ioType);
}
diff --git a/src/main/java/com/zy/asrs/task/WrkAnalysisStationArrivalScanner.java b/src/main/java/com/zy/asrs/task/WrkAnalysisStationArrivalScanner.java
index cf33ff0..f299636 100644
--- a/src/main/java/com/zy/asrs/task/WrkAnalysisStationArrivalScanner.java
+++ b/src/main/java/com/zy/asrs/task/WrkAnalysisStationArrivalScanner.java
@@ -1,17 +1,27 @@
package com.zy.asrs.task;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.core.common.Cools;
+import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.BasStation;
import com.zy.asrs.entity.WrkMast;
+import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.BasStationService;
import com.zy.asrs.service.WrkAnalysisService;
import com.zy.asrs.service.WrkMastService;
+import com.zy.asrs.utils.Utils;
+import com.zy.common.entity.FindCrnNoResult;
+import com.zy.common.service.CommonService;
import com.zy.core.News;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.enums.WrkStsType;
+import com.zy.core.model.StationObjModel;
+import com.zy.core.move.StationMoveCoordinator;
+import com.zy.core.move.StationMoveSession;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.thread.StationThread;
+import com.zy.core.utils.CrnOperateProcessUtils;
import com.zy.core.utils.StationOperateProcessUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -19,6 +29,7 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
@Component
public class WrkAnalysisStationArrivalScanner {
@@ -27,15 +38,27 @@
private final BasStationService basStationService;
private final WrkAnalysisService wrkAnalysisService;
private final StationOperateProcessUtils stationOperateProcessUtils;
+ private final StationMoveCoordinator stationMoveCoordinator;
+ private final CommonService commonService;
+ private final BasCrnpService basCrnpService;
+ private final CrnOperateProcessUtils crnOperateProcessUtils;
public WrkAnalysisStationArrivalScanner(WrkMastService wrkMastService,
BasStationService basStationService,
WrkAnalysisService wrkAnalysisService,
- StationOperateProcessUtils stationOperateProcessUtils) {
+ StationOperateProcessUtils stationOperateProcessUtils,
+ StationMoveCoordinator stationMoveCoordinator,
+ CommonService commonService,
+ BasCrnpService basCrnpService,
+ CrnOperateProcessUtils crnOperateProcessUtils) {
this.wrkMastService = wrkMastService;
this.basStationService = basStationService;
this.wrkAnalysisService = wrkAnalysisService;
this.stationOperateProcessUtils = stationOperateProcessUtils;
+ this.stationMoveCoordinator = stationMoveCoordinator;
+ this.commonService = commonService;
+ this.basCrnpService = basCrnpService;
+ this.crnOperateProcessUtils = crnOperateProcessUtils;
}
@Scheduled(fixedDelay = 1000L)
@@ -66,6 +89,7 @@
}
Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(basStation.getStationId());
+ tryDispatchInboundCrnMove(wrkMast, stationProtocol);
boolean arrived = stationProtocol != null
&& wrkMast.getWrkNo().equals(stationProtocol.getTaskNo())
&& stationProtocol.isLoading();
@@ -78,4 +102,70 @@
}
}
}
+
+ private void tryDispatchInboundCrnMove(WrkMast wrkMast, StationProtocol targetStationProtocol) {
+ if (wrkMast == null || wrkMast.getWrkNo() == null || wrkMast.getStaNo() == null || Cools.isEmpty(wrkMast.getLocNo())) {
+ return;
+ }
+ if (targetStationProtocol != null
+ && targetStationProtocol.isLoading()
+ && targetStationProtocol.getTaskNo() > 0
+ && targetStationProtocol.isInEnable()) {
+ return;
+ }
+
+ StationMoveSession session = stationMoveCoordinator == null ? null : stationMoveCoordinator.loadSession(wrkMast.getWrkNo());
+ if (!isInboundCrnMoveDispatchWindow(wrkMast, session)) {
+ return;
+ }
+
+ FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(wrkMast.getLocNo());
+ if (findCrnNoResult == null || !Objects.equals(findCrnNoResult.getCrnType(), SlaveType.Crn) || findCrnNoResult.getCrnNo() == null) {
+ return;
+ }
+
+ BasCrnp basCrnp = basCrnpService.getOne(new QueryWrapper<BasCrnp>()
+ .eq("crn_no", findCrnNoResult.getCrnNo())
+ .last("limit 1"));
+ if (basCrnp == null) {
+ return;
+ }
+
+ for (StationObjModel stationObjModel : basCrnp.getInStationList$()) {
+ if (stationObjModel == null || !Objects.equals(stationObjModel.getStationId(), wrkMast.getStaNo())) {
+ continue;
+ }
+ if (stationObjModel.getDeviceRow() == null || stationObjModel.getDeviceBay() == null || stationObjModel.getDeviceLev() == null) {
+ continue;
+ }
+ String inletLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev());
+ boolean dispatched = crnOperateProcessUtils.dispatchCrnMove(findCrnNoResult.getCrnNo(), inletLocNo);
+ if (dispatched) {
+ News.info("鍏ュ簱浠诲姟鍗冲皢鍒拌揪鍏ュ簱鍙o紝宸茶Е鍙戝爢鍨涙満棰勭Щ杞︼紝宸ヤ綔鍙�={}锛屽爢鍨涙満鍙�={}锛屽叆搴撳彛浣嶇疆={}",
+ wrkMast.getWrkNo(), findCrnNoResult.getCrnNo(), inletLocNo);
+ }
+ return;
+ }
+ }
+
+ private boolean isInboundCrnMoveDispatchWindow(WrkMast wrkMast, StationMoveSession session) {
+ if (wrkMast == null || session == null || !session.isActive() || wrkMast.getStaNo() == null) {
+ return false;
+ }
+ List<Integer> fullPathStationIds = session.getFullPathStationIds();
+ Integer currentStationId = session.getCurrentStationId();
+ if (fullPathStationIds == null || fullPathStationIds.isEmpty() || currentStationId == null) {
+ return false;
+ }
+ int currentIndex = fullPathStationIds.lastIndexOf(currentStationId);
+ if (currentIndex < 0 || currentIndex >= fullPathStationIds.size() - 1) {
+ return false;
+ }
+ int remainingStationCount = fullPathStationIds.size() - currentIndex - 1;
+ if (remainingStationCount != 1) {
+ return false;
+ }
+ Integer nextStationId = fullPathStationIds.get(currentIndex + 1);
+ return Objects.equals(nextStationId, wrkMast.getStaNo());
+ }
}
diff --git a/src/main/java/com/zy/asrs/task/WrkMastScheduler.java b/src/main/java/com/zy/asrs/task/WrkMastScheduler.java
index 87dfaea..9ac3fac 100644
--- a/src/main/java/com/zy/asrs/task/WrkMastScheduler.java
+++ b/src/main/java/com/zy/asrs/task/WrkMastScheduler.java
@@ -205,6 +205,27 @@
@Scheduled(cron = "0/1 * * * * ? ")
@Transactional
+ public void executeCrnMove(){
+ List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>().eq("wrk_sts", WrkStsType.COMPLETE_CRN_MOVE.sts));
+ if (wrkMasts.isEmpty()) {
+ return;
+ }
+
+ for (WrkMast wrkMast : wrkMasts) {
+ if (!wrkMastLogService.save(wrkMast.getWrkNo())) {
+ log.info("淇濆瓨宸ヤ綔鍘嗗彶妗workNo={}]澶辫触", wrkMast.getWrkNo());
+ } else {
+ wrkAnalysisService.finishTask(wrkMast, resolveFinishTime(wrkMast));
+ }
+
+ if (!wrkMastService.removeById(wrkMast.getWrkNo())) {
+ log.info("鍒犻櫎宸ヤ綔涓绘。[workNo={}]澶辫触", wrkMast.getWrkNo());
+ }
+ }
+ }
+
+ @Scheduled(cron = "0/1 * * * * ? ")
+ @Transactional
public void executeCancelTask(){
List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>().eq("mk", "taskCancel"));
if (wrkMasts.isEmpty()) {
diff --git a/src/main/java/com/zy/common/service/CommonService.java b/src/main/java/com/zy/common/service/CommonService.java
index bf6fa7f..f03a253 100644
--- a/src/main/java/com/zy/common/service/CommonService.java
+++ b/src/main/java/com/zy/common/service/CommonService.java
@@ -113,6 +113,8 @@
wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
} else if (wrkMast.getIoType() == WrkIoType.LOC_MOVE.id) {
wrkMast.setWrkSts(WrkStsType.COMPLETE_LOC_MOVE.sts);
+ } else if (wrkMast.getIoType() == WrkIoType.CRN_MOVE.id) {
+ wrkMast.setWrkSts(WrkStsType.COMPLETE_CRN_MOVE.sts);
}
wrkMast.setModiTime(new Date());
@@ -144,6 +146,8 @@
cancelSuccess = true;
} else if (wrkMast.getIoType().equals(WrkIoType.LOC_MOVE.id) && !wrkMast.getWrkSts().equals(WrkStsType.NEW_LOC_MOVE.sts)) {
cancelSuccess = true;
+ } else if (wrkMast.getIoType().equals(WrkIoType.CRN_MOVE.id) && !wrkMast.getWrkSts().equals(WrkStsType.NEW_CRN_MOVE.sts)) {
+ cancelSuccess = true;
}
if (cancelSuccess) {
diff --git a/src/main/java/com/zy/core/enums/WrkIoType.java b/src/main/java/com/zy/core/enums/WrkIoType.java
index 9307c60..14d432a 100644
--- a/src/main/java/com/zy/core/enums/WrkIoType.java
+++ b/src/main/java/com/zy/core/enums/WrkIoType.java
@@ -7,6 +7,7 @@
IN(1, "鍏ュ簱"),
OUT(101, "鍑哄簱"),
LOC_MOVE(201, "绉诲簱浠诲姟"),
+ CRN_MOVE(301, "鍫嗗灈鏈虹Щ鍔ㄤ换鍔�"),
FAKE_TASK_NO(9999, "浠跨湡闅忔満宸ヤ綔鍙�"),
ENABLE_IN(9998, "鍚姩鍏ュ簱"),
STATION_BACK(9997, "绔欑偣鍥為��"),
diff --git a/src/main/java/com/zy/core/enums/WrkStsType.java b/src/main/java/com/zy/core/enums/WrkStsType.java
index 1c713c1..66789fb 100644
--- a/src/main/java/com/zy/core/enums/WrkStsType.java
+++ b/src/main/java/com/zy/core/enums/WrkStsType.java
@@ -27,6 +27,12 @@
LOC_MOVE_RUN_COMPLETE(503, "璁惧鎼繍瀹屾垚"),
LOC_MOVE_MANUAL(506, "绉诲簱寰呬汉宸ュ洖婊�"),
COMPLETE_LOC_MOVE(509, "绉诲簱瀹屾垚"),
+
+ NEW_CRN_MOVE(601, "鐢熸垚鍫嗗灈鏈虹Щ鍔ㄤ换鍔�"),
+ CRN_MOVE_RUN(602, "鍫嗗灈鏈虹Щ鍔ㄤ腑"),
+ CRN_MOVE_RUN_COMPLETE(603, "鍫嗗灈鏈虹Щ鍔ㄥ畬鎴�"),
+ CRN_MOVE_MANUAL(606, "鍫嗗灈鏈虹Щ鍔ㄥ緟浜哄伐鍥炴粴"),
+ COMPLETE_CRN_MOVE(609, "鍫嗗灈鏈虹Щ鍔ㄤ换鍔″畬鎴�"),
;
diff --git a/src/main/java/com/zy/core/plugin/FakeProcess.java b/src/main/java/com/zy/core/plugin/FakeProcess.java
index a136dd6..99a25f7 100644
--- a/src/main/java/com/zy/core/plugin/FakeProcess.java
+++ b/src/main/java/com/zy/core/plugin/FakeProcess.java
@@ -704,6 +704,8 @@
}
} else if (wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts) {
updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
+ } else if (wrkMast.getWrkSts() == WrkStsType.CRN_MOVE_RUN.sts) {
+ updateWrkSts = WrkStsType.COMPLETE_CRN_MOVE.sts;
} else {
News.error("鍫嗗灈鏈哄浜庣瓑寰呯‘璁や笖浠诲姟瀹屾垚鐘舵�侊紝浣嗗伐浣滅姸鎬佸紓甯搞�傚爢鍨涙満鍙�={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
continue;
diff --git a/src/main/java/com/zy/core/service/WrkCommandRollbackService.java b/src/main/java/com/zy/core/service/WrkCommandRollbackService.java
index 580fded..cd36992 100644
--- a/src/main/java/com/zy/core/service/WrkCommandRollbackService.java
+++ b/src/main/java/com/zy/core/service/WrkCommandRollbackService.java
@@ -168,7 +168,8 @@
private boolean isSingleCrnRunStatus(Long wrkSts) {
return Long.valueOf(WrkStsType.INBOUND_RUN.sts).equals(wrkSts)
|| Long.valueOf(WrkStsType.OUTBOUND_RUN.sts).equals(wrkSts)
- || Long.valueOf(WrkStsType.LOC_MOVE_RUN.sts).equals(wrkSts);
+ || Long.valueOf(WrkStsType.LOC_MOVE_RUN.sts).equals(wrkSts)
+ || Long.valueOf(WrkStsType.CRN_MOVE_RUN.sts).equals(wrkSts);
}
private Long getRollbackStatus(Long wrkSts) {
@@ -180,6 +181,9 @@
}
if (Long.valueOf(WrkStsType.LOC_MOVE_RUN.sts).equals(wrkSts)) {
return WrkStsType.NEW_LOC_MOVE.sts;
+ }
+ if (Long.valueOf(WrkStsType.CRN_MOVE_RUN.sts).equals(wrkSts)) {
+ return WrkStsType.NEW_CRN_MOVE.sts;
}
return null;
}
@@ -194,6 +198,9 @@
if (Long.valueOf(WrkStsType.LOC_MOVE_RUN.sts).equals(wrkSts)) {
return WrkStsType.LOC_MOVE_MANUAL.sts;
}
+ if (Long.valueOf(WrkStsType.CRN_MOVE_RUN.sts).equals(wrkSts)) {
+ return WrkStsType.CRN_MOVE_MANUAL.sts;
+ }
return null;
}
@@ -207,6 +214,9 @@
if (Long.valueOf(WrkStsType.LOC_MOVE_MANUAL.sts).equals(wrkSts)) {
return WrkStsType.NEW_LOC_MOVE.sts;
}
+ if (Long.valueOf(WrkStsType.CRN_MOVE_MANUAL.sts).equals(wrkSts)) {
+ return WrkStsType.NEW_CRN_MOVE.sts;
+ }
return null;
}
}
diff --git a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
index ec4c22d..614f005 100644
--- a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -40,8 +40,11 @@
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
@Component
public class CrnOperateProcessUtils {
@@ -83,11 +86,16 @@
//鍏ュ嚭搴� ===>> 鍫嗗灈鏈哄叆鍑哄簱浣滀笟涓嬪彂
public synchronized void crnIoExecuteNormal() {
+ Set<Integer> crnMoveBlockedCrnNos = executeCrnMoveTask();
+
List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
Map<Integer, BasCrnp> dispatchCrnMap = new HashMap<>();
Map<Integer, CrnThread> dispatchThreadMap = new HashMap<>();
Map<Integer, CrnProtocol> dispatchProtocolMap = new HashMap<>();
for (BasCrnp basCrnp : basCrnps) {
+ if (basCrnp == null || basCrnp.getCrnNo() == null || crnMoveBlockedCrnNos.contains(basCrnp.getCrnNo())) {
+ continue;
+ }
CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
if (crnThread == null) {
continue;
@@ -100,7 +108,7 @@
long runningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
.eq("crn_no", basCrnp.getCrnNo())
- .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts));
+ .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts, WrkStsType.CRN_MOVE_RUN.sts));
if (runningCount > 0) {
continue;
}
@@ -655,6 +663,8 @@
}else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){
updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null);
+ }else if(wrkMast.getWrkSts() == WrkStsType.CRN_MOVE_RUN.sts){
+ updateWrkSts = WrkStsType.COMPLETE_CRN_MOVE.sts;
}else{
News.error("鍫嗗灈鏈哄浜庣瓑寰呯‘璁や笖浠诲姟瀹屾垚鐘舵�侊紝浣嗗伐浣滅姸鎬佸紓甯搞�傚爢鍨涙満鍙�={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
continue;
@@ -677,9 +687,14 @@
}
public synchronized void plannerExecute() {
+ Set<Integer> crnMoveBlockedCrnNos = executeCrnMoveTask();
+
int nowSec = (int) (System.currentTimeMillis() / 1000);
List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
for (BasCrnp basCrnp : basCrnps) {
+ if (basCrnp == null || basCrnp.getCrnNo() == null || crnMoveBlockedCrnNos.contains(basCrnp.getCrnNo())) {
+ continue;
+ }
String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo();
List<Object> items = redisUtil.lGet(key, 0, -1);
if (items == null || items.isEmpty()) {
@@ -696,7 +711,7 @@
}
List<WrkMast> running = wrkMastService.list(new QueryWrapper<WrkMast>()
.eq("crn_no", basCrnp.getCrnNo())
- .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts)
+ .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts, WrkStsType.CRN_MOVE_RUN.sts)
);
if (!running.isEmpty()) {
continue;
@@ -827,6 +842,114 @@
return false;
}
+ private Set<Integer> executeCrnMoveTask() {
+ List<WrkMast> pendingTaskQueue = wrkMastService.list(new QueryWrapper<WrkMast>()
+ .eq("io_type", WrkIoType.CRN_MOVE.id)
+ .eq("wrk_sts", WrkStsType.NEW_CRN_MOVE.sts)
+ .orderByAsc("appe_time")
+ .orderByAsc("wrk_no"));
+ Set<Integer> blockedCrnNoSet = new HashSet<>();
+ for (WrkMast wrkMast : pendingTaskQueue) {
+ if (wrkMast != null && wrkMast.getCrnNo() != null) {
+ blockedCrnNoSet.add(wrkMast.getCrnNo());
+ }
+ }
+ if (blockedCrnNoSet.isEmpty()) {
+ return blockedCrnNoSet;
+ }
+
+ List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
+ Map<Integer, CrnThread> dispatchThreadMap = new HashMap<>();
+ Map<Integer, CrnProtocol> dispatchProtocolMap = new HashMap<>();
+ for (BasCrnp basCrnp : basCrnps) {
+ if (basCrnp == null || basCrnp.getCrnNo() == null) {
+ continue;
+ }
+
+ Integer crnNo = basCrnp.getCrnNo();
+ CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crnNo);
+ if (crnThread == null) {
+ continue;
+ }
+
+ CrnProtocol crnProtocol = crnThread.getStatus();
+ if (crnProtocol == null) {
+ continue;
+ }
+
+ long runningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
+ .eq("crn_no", crnNo)
+ .in("wrk_sts",
+ WrkStsType.INBOUND_RUN.sts,
+ WrkStsType.OUTBOUND_RUN.sts,
+ WrkStsType.LOC_MOVE_RUN.sts,
+ WrkStsType.CRN_MOVE_RUN.sts));
+ if (runningCount > 0) {
+ continue;
+ }
+
+ if (!Objects.equals(crnProtocol.getMode(), CrnModeType.AUTO.id)
+ || !Objects.equals(crnProtocol.getTaskNo(), 0)
+ || !Objects.equals(crnProtocol.getStatus(), CrnStatusType.IDLE.id)
+ || !Objects.equals(crnProtocol.getLoaded(), 0)
+ || !Objects.equals(crnProtocol.getForkPos(), 0)
+ || !Objects.equals(crnProtocol.getAlarm(), 0)) {
+ continue;
+ }
+
+ Object clearLock = redisUtil.get(RedisKeyType.CLEAR_CRN_TASK_LIMIT.key + crnNo);
+ if (clearLock != null) {
+ continue;
+ }
+
+ dispatchThreadMap.put(crnNo, crnThread);
+ dispatchProtocolMap.put(crnNo, crnProtocol);
+ }
+
+ if (dispatchThreadMap.isEmpty()) {
+ return blockedCrnNoSet;
+ }
+
+ List<WrkMast> taskQueue = wrkMastService.list(new QueryWrapper<WrkMast>()
+ .in("crn_no", new ArrayList<>(dispatchThreadMap.keySet()))
+ .eq("io_type", WrkIoType.CRN_MOVE.id)
+ .eq("wrk_sts", WrkStsType.NEW_CRN_MOVE.sts)
+ .orderByAsc("appe_time")
+ .orderByAsc("wrk_no"));
+
+ for (WrkMast wrkMast : taskQueue) {
+ if (wrkMast == null || wrkMast.getCrnNo() == null || Cools.isEmpty(wrkMast.getLocNo())) {
+ continue;
+ }
+
+ Integer crnNo = wrkMast.getCrnNo();
+ CrnThread crnThread = dispatchThreadMap.get(crnNo);
+ if (crnThread == null || dispatchProtocolMap.get(crnNo) == null) {
+ continue;
+ }
+
+ CrnCommand moveCommand = crnThread.getMoveCommand(wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
+ if (moveCommand == null) {
+ continue;
+ }
+
+ Date now = new Date();
+ wrkMast.setWrkSts(WrkStsType.CRN_MOVE_RUN.sts);
+ wrkMast.setCrnNo(crnNo);
+ wrkMast.setSystemMsg("");
+ wrkMast.setIoTime(now);
+ wrkMast.setModiTime(now);
+ if (wrkMastService.updateById(wrkMast)) {
+ wrkAnalysisService.markCraneStart(wrkMast, now);
+ MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, moveCommand));
+ News.info("鍫嗗灈鏈虹Щ鍔ㄥ懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屽伐浣滃彿={}锛岀洰鏍囦綅={}锛屼换鍔℃暟鎹�={}",
+ crnNo, wrkMast.getWrkNo(), wrkMast.getLocNo(), JSON.toJSON(moveCommand));
+ return blockedCrnNoSet;
+ }
+ }
+ return blockedCrnNoSet;
+ }
+
//妫�娴嬫祬搴撲綅鐘舵��
public synchronized boolean checkShallowLocStatus(String locNo, Integer taskNo) {
String checkDeepLocOutTaskBlockReport = "Y";
@@ -889,4 +1012,83 @@
return false;
}
+ //璋冨害鍫嗗灈鏈虹Щ鍔�
+ public synchronized boolean dispatchCrnMove(Integer crnNo, String targetLocNo) {
+ if (crnNo == null || Cools.isEmpty(targetLocNo)) {
+ return false;
+ }
+
+ int targetRow = Utils.getRow(targetLocNo);
+ int targetBay = Utils.getBay(targetLocNo);
+ int targetLev = Utils.getLev(targetLocNo);
+ try {
+ targetRow = Utils.getRow(targetLocNo);
+ targetBay = Utils.getBay(targetLocNo);
+ targetLev = Utils.getLev(targetLocNo);
+ } catch (Exception e) {
+ News.error("鐢熸垚鍫嗗灈鏈虹Щ鍔ㄤ换鍔″け璐ワ紝鐩爣浣�:{} 瑙f瀽寮傚父", targetLocNo);
+ return false;
+ }
+
+ CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crnNo);
+ if (crnThread == null) {
+ return false;
+ }
+
+ CrnProtocol crnProtocol = crnThread.getStatus();
+ if (crnProtocol == null) {
+ return false;
+ }
+
+ if (crnProtocol.getBay() == targetBay) {
+ return false;
+ }
+
+ if (crnProtocol.getLevel() == targetLev) {
+ return false;
+ }
+
+ long runningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
+ .eq("crn_no", crnNo)
+ .in("wrk_sts",
+ WrkStsType.INBOUND_RUN.sts,
+ WrkStsType.OUTBOUND_RUN.sts,
+ WrkStsType.LOC_MOVE_RUN.sts,
+ WrkStsType.CRN_MOVE_RUN.sts));
+ if (runningCount > 0) {
+ News.info("鍫嗗灈鏈�:{} 瀛樺湪鎵ц涓殑浠诲姟锛屾殏涓嶇敓鎴愮Щ鍔ㄤ换鍔�", crnNo);
+ return false;
+ }
+
+ WrkMast activeTask = wrkMastService.getOne(new QueryWrapper<WrkMast>()
+ .eq("crn_no", crnNo)
+ .eq("io_type", WrkIoType.CRN_MOVE.id)
+ .in("wrk_sts", WrkStsType.NEW_CRN_MOVE.sts, WrkStsType.CRN_MOVE_RUN.sts, WrkStsType.CRN_MOVE_MANUAL.sts)
+ .orderByDesc("appe_time")
+ .last("limit 1"));
+ if (activeTask != null) {
+ News.info("鍫嗗灈鏈�:{} 宸插瓨鍦ㄦ湭瀹屾垚绉诲姩浠诲姟锛屽伐浣滃彿={}", crnNo, activeTask.getWrkNo());
+ return false;
+ }
+
+ Date now = new Date();
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(commonService.getWorkNo(WrkIoType.CRN_MOVE.id));
+ wrkMast.setIoTime(now);
+ wrkMast.setWrkSts(WrkStsType.NEW_CRN_MOVE.sts);
+ wrkMast.setIoType(WrkIoType.CRN_MOVE.id);
+ wrkMast.setIoPri(0D);
+ wrkMast.setLocNo(targetLocNo);
+ wrkMast.setCrnNo(crnNo);
+ wrkMast.setAppeTime(now);
+ wrkMast.setModiTime(now);
+ wrkMast.setMemo("dispatchCrnMove");
+ if (!wrkMastService.save(wrkMast)) {
+ News.info("鐢熸垚鍫嗗灈鏈虹Щ鍔ㄤ换鍔″け璐ワ紝宸ヤ綔鍙�={}锛屼换鍔℃暟鎹�={}", wrkMast.getWrkNo(), JSON.toJSON(wrkMast));
+ return false;
+ }
+ wrkAnalysisService.initForTask(wrkMast);
+ return true;
+ }
+
}
diff --git a/src/main/resources/sql/20260330_add_crn_move_task_type.sql b/src/main/resources/sql/20260330_add_crn_move_task_type.sql
new file mode 100644
index 0000000..b791af6
--- /dev/null
+++ b/src/main/resources/sql/20260330_add_crn_move_task_type.sql
@@ -0,0 +1,27 @@
+INSERT INTO `asr_bas_wrk_iotype` (`io_type`, `io_pri`, `io_desc`, `modi_user`, `modi_time`, `appe_user`, `appe_time`)
+SELECT 301, NULL, '301.鍫嗗灈鏈虹Щ鍔ㄤ换鍔�', NULL, NOW(), NULL, NOW()
+WHERE NOT EXISTS (SELECT 1 FROM `asr_bas_wrk_iotype` WHERE `io_type` = 301);
+
+INSERT INTO `asr_wrk_lastno` (`wrk_mk`, `wrk_no`, `modi_user`, `modi_time`, `appe_user`, `appe_time`, `s_no`, `e_no`, `memo_m`)
+SELECT 301, 30000, NULL, NOW(), NULL, NOW(), 30001, 39999, '鍫嗗灈鏈虹Щ鍔ㄤ换鍔″彿娈�'
+WHERE NOT EXISTS (SELECT 1 FROM `asr_wrk_lastno` WHERE `wrk_mk` = 301);
+
+INSERT INTO `asr_bas_wrk_status` (`wrk_sts`, `wrk_desc`, `modi_user`, `modi_time`, `appe_user`, `appe_time`)
+SELECT 601, '601.鐢熸垚鍫嗗灈鏈虹Щ鍔ㄤ换鍔�', NULL, NOW(), NULL, NOW()
+WHERE NOT EXISTS (SELECT 1 FROM `asr_bas_wrk_status` WHERE `wrk_sts` = 601);
+
+INSERT INTO `asr_bas_wrk_status` (`wrk_sts`, `wrk_desc`, `modi_user`, `modi_time`, `appe_user`, `appe_time`)
+SELECT 602, '602.鍫嗗灈鏈虹Щ鍔ㄤ腑', NULL, NOW(), NULL, NOW()
+WHERE NOT EXISTS (SELECT 1 FROM `asr_bas_wrk_status` WHERE `wrk_sts` = 602);
+
+INSERT INTO `asr_bas_wrk_status` (`wrk_sts`, `wrk_desc`, `modi_user`, `modi_time`, `appe_user`, `appe_time`)
+SELECT 603, '603.鍫嗗灈鏈虹Щ鍔ㄥ畬鎴�', NULL, NOW(), NULL, NOW()
+WHERE NOT EXISTS (SELECT 1 FROM `asr_bas_wrk_status` WHERE `wrk_sts` = 603);
+
+INSERT INTO `asr_bas_wrk_status` (`wrk_sts`, `wrk_desc`, `modi_user`, `modi_time`, `appe_user`, `appe_time`)
+SELECT 606, '606.鍫嗗灈鏈虹Щ鍔ㄥ緟浜哄伐鍥炴粴', NULL, NOW(), NULL, NOW()
+WHERE NOT EXISTS (SELECT 1 FROM `asr_bas_wrk_status` WHERE `wrk_sts` = 606);
+
+INSERT INTO `asr_bas_wrk_status` (`wrk_sts`, `wrk_desc`, `modi_user`, `modi_time`, `appe_user`, `appe_time`)
+SELECT 609, '609.鍫嗗灈鏈虹Щ鍔ㄤ换鍔″畬鎴�', NULL, NOW(), NULL, NOW()
+WHERE NOT EXISTS (SELECT 1 FROM `asr_bas_wrk_status` WHERE `wrk_sts` = 609);
diff --git a/src/test/java/com/zy/asrs/task/WrkAnalysisStationArrivalScannerTest.java b/src/test/java/com/zy/asrs/task/WrkAnalysisStationArrivalScannerTest.java
index 076d862..0415228 100644
--- a/src/test/java/com/zy/asrs/task/WrkAnalysisStationArrivalScannerTest.java
+++ b/src/test/java/com/zy/asrs/task/WrkAnalysisStationArrivalScannerTest.java
@@ -2,21 +2,29 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.asrs.entity.BasStation;
+import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasStationService;
+import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.WrkAnalysisService;
import com.zy.asrs.service.WrkMastService;
+import com.zy.common.entity.FindCrnNoResult;
+import com.zy.common.service.CommonService;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.enums.StationCommandType;
import com.zy.core.enums.WrkStsType;
+import com.zy.core.move.StationMoveCoordinator;
+import com.zy.core.move.StationMoveSession;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.thread.StationThread;
+import com.zy.core.utils.CrnOperateProcessUtils;
import com.zy.core.utils.StationOperateProcessUtils;
import org.junit.jupiter.api.Test;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
@@ -25,6 +33,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -36,12 +45,20 @@
BasStationService basStationService = mock(BasStationService.class);
WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
StationOperateProcessUtils stationOperateProcessUtils = mock(StationOperateProcessUtils.class);
+ StationMoveCoordinator stationMoveCoordinator = mock(StationMoveCoordinator.class);
+ CommonService commonService = mock(CommonService.class);
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ CrnOperateProcessUtils crnOperateProcessUtils = mock(CrnOperateProcessUtils.class);
WrkAnalysisStationArrivalScanner scanner = new WrkAnalysisStationArrivalScanner(
wrkMastService,
basStationService,
wrkAnalysisService,
- stationOperateProcessUtils
+ stationOperateProcessUtils,
+ stationMoveCoordinator,
+ commonService,
+ basCrnpService,
+ crnOperateProcessUtils
);
WrkMast wrkMast = new WrkMast();
@@ -75,6 +92,211 @@
verify(wrkAnalysisService).completeInboundStationRun(any(WrkMast.class), any(Date.class));
}
+ @Test
+ void scanInboundStationArrival_dispatchesCrnMoveWhenOnlyFinalInletStationRemains() {
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ BasStationService basStationService = mock(BasStationService.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ StationOperateProcessUtils stationOperateProcessUtils = mock(StationOperateProcessUtils.class);
+ StationMoveCoordinator stationMoveCoordinator = mock(StationMoveCoordinator.class);
+ CommonService commonService = mock(CommonService.class);
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ CrnOperateProcessUtils crnOperateProcessUtils = mock(CrnOperateProcessUtils.class);
+
+ WrkAnalysisStationArrivalScanner scanner = new WrkAnalysisStationArrivalScanner(
+ wrkMastService,
+ basStationService,
+ wrkAnalysisService,
+ stationOperateProcessUtils,
+ stationMoveCoordinator,
+ commonService,
+ basCrnpService,
+ crnOperateProcessUtils
+ );
+
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(1002);
+ wrkMast.setIoType(1);
+ wrkMast.setWrkSts(WrkStsType.INBOUND_STATION_RUN.sts);
+ wrkMast.setStaNo(12);
+ wrkMast.setLocNo("5-6-7");
+
+ BasStation basStation = new BasStation();
+ basStation.setStationId(12);
+ basStation.setDeviceNo(3);
+
+ StationMoveSession session = new StationMoveSession();
+ session.setStatus(StationMoveSession.STATUS_RUNNING);
+ session.setCurrentStationId(11);
+ session.setFullPathStationIds(new ArrayList<>(List.of(10, 11, 12)));
+
+ FindCrnNoResult findCrnNoResult = new FindCrnNoResult();
+ findCrnNoResult.setCrnNo(1);
+ findCrnNoResult.setCrnType(SlaveType.Crn);
+
+ BasCrnp basCrnp = new BasCrnp();
+ basCrnp.setCrnNo(1);
+ basCrnp.setInStationList("[{\"stationId\":12,\"deviceRow\":2,\"deviceBay\":1,\"deviceLev\":1}]");
+
+ when(wrkMastService.list(any(QueryWrapper.class))).thenReturn(List.of(wrkMast));
+ when(basStationService.getOne(any())).thenReturn(basStation);
+ when(stationMoveCoordinator.loadSession(1002)).thenReturn(session);
+ when(commonService.findCrnNoByLocNo("5-6-7")).thenReturn(findCrnNoResult);
+ when(basCrnpService.getOne(any())).thenReturn(basCrnp);
+ when(crnOperateProcessUtils.dispatchCrnMove(1, "2-1-1")).thenReturn(true);
+
+ ArrivalAwareStationThread stationThread = new ArrivalAwareStationThread(false);
+ StationProtocol stationProtocol = new StationProtocol();
+ stationProtocol.setStationId(12);
+ stationProtocol.setTaskNo(0);
+ stationProtocol.setLoading(false);
+ stationThread.putStatus(stationProtocol);
+
+ SlaveConnection.put(SlaveType.Devp, 3, stationThread);
+ try {
+ scanner.scanInboundStationArrival();
+ } finally {
+ SlaveConnection.remove(SlaveType.Devp, 3);
+ }
+
+ verify(crnOperateProcessUtils).dispatchCrnMove(1, "2-1-1");
+ verify(wrkAnalysisService, never()).completeInboundStationRun(any(WrkMast.class), any(Date.class));
+ }
+
+ @Test
+ void scanInboundStationArrival_skipsCrnMoveWhenTargetInletHasLoadTaskAndInEnable() {
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ BasStationService basStationService = mock(BasStationService.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ StationOperateProcessUtils stationOperateProcessUtils = mock(StationOperateProcessUtils.class);
+ StationMoveCoordinator stationMoveCoordinator = mock(StationMoveCoordinator.class);
+ CommonService commonService = mock(CommonService.class);
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ CrnOperateProcessUtils crnOperateProcessUtils = mock(CrnOperateProcessUtils.class);
+
+ WrkAnalysisStationArrivalScanner scanner = new WrkAnalysisStationArrivalScanner(
+ wrkMastService,
+ basStationService,
+ wrkAnalysisService,
+ stationOperateProcessUtils,
+ stationMoveCoordinator,
+ commonService,
+ basCrnpService,
+ crnOperateProcessUtils
+ );
+
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(1003);
+ wrkMast.setIoType(1);
+ wrkMast.setWrkSts(WrkStsType.INBOUND_STATION_RUN.sts);
+ wrkMast.setStaNo(12);
+ wrkMast.setLocNo("5-6-7");
+
+ BasStation basStation = new BasStation();
+ basStation.setStationId(12);
+ basStation.setDeviceNo(3);
+
+ StationMoveSession session = new StationMoveSession();
+ session.setStatus(StationMoveSession.STATUS_RUNNING);
+ session.setCurrentStationId(11);
+ session.setFullPathStationIds(new ArrayList<>(List.of(10, 11, 12)));
+
+ when(wrkMastService.list(any(QueryWrapper.class))).thenReturn(List.of(wrkMast));
+ when(basStationService.getOne(any())).thenReturn(basStation);
+ when(stationMoveCoordinator.loadSession(1003)).thenReturn(session);
+
+ ArrivalAwareStationThread stationThread = new ArrivalAwareStationThread(false);
+ StationProtocol stationProtocol = new StationProtocol();
+ stationProtocol.setStationId(12);
+ stationProtocol.setTaskNo(9999);
+ stationProtocol.setLoading(true);
+ stationProtocol.setInEnable(true);
+ stationThread.putStatus(stationProtocol);
+
+ SlaveConnection.put(SlaveType.Devp, 3, stationThread);
+ try {
+ scanner.scanInboundStationArrival();
+ } finally {
+ SlaveConnection.remove(SlaveType.Devp, 3);
+ }
+
+ verify(crnOperateProcessUtils, never()).dispatchCrnMove(any(), any());
+ verify(commonService, never()).findCrnNoByLocNo(any());
+ verify(wrkAnalysisService, never()).completeInboundStationRun(any(WrkMast.class), any(Date.class));
+ }
+
+ @Test
+ void scanInboundStationArrival_dispatchesCrnMoveWhenTargetInletOnlyHasLoad() {
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ BasStationService basStationService = mock(BasStationService.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ StationOperateProcessUtils stationOperateProcessUtils = mock(StationOperateProcessUtils.class);
+ StationMoveCoordinator stationMoveCoordinator = mock(StationMoveCoordinator.class);
+ CommonService commonService = mock(CommonService.class);
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ CrnOperateProcessUtils crnOperateProcessUtils = mock(CrnOperateProcessUtils.class);
+
+ WrkAnalysisStationArrivalScanner scanner = new WrkAnalysisStationArrivalScanner(
+ wrkMastService,
+ basStationService,
+ wrkAnalysisService,
+ stationOperateProcessUtils,
+ stationMoveCoordinator,
+ commonService,
+ basCrnpService,
+ crnOperateProcessUtils
+ );
+
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(1004);
+ wrkMast.setIoType(1);
+ wrkMast.setWrkSts(WrkStsType.INBOUND_STATION_RUN.sts);
+ wrkMast.setStaNo(12);
+ wrkMast.setLocNo("5-6-7");
+
+ BasStation basStation = new BasStation();
+ basStation.setStationId(12);
+ basStation.setDeviceNo(3);
+
+ StationMoveSession session = new StationMoveSession();
+ session.setStatus(StationMoveSession.STATUS_RUNNING);
+ session.setCurrentStationId(11);
+ session.setFullPathStationIds(new ArrayList<>(List.of(10, 11, 12)));
+
+ FindCrnNoResult findCrnNoResult = new FindCrnNoResult();
+ findCrnNoResult.setCrnNo(1);
+ findCrnNoResult.setCrnType(SlaveType.Crn);
+
+ BasCrnp basCrnp = new BasCrnp();
+ basCrnp.setCrnNo(1);
+ basCrnp.setInStationList("[{\"stationId\":12,\"deviceRow\":2,\"deviceBay\":1,\"deviceLev\":1}]");
+
+ when(wrkMastService.list(any(QueryWrapper.class))).thenReturn(List.of(wrkMast));
+ when(basStationService.getOne(any())).thenReturn(basStation);
+ when(stationMoveCoordinator.loadSession(1004)).thenReturn(session);
+ when(commonService.findCrnNoByLocNo("5-6-7")).thenReturn(findCrnNoResult);
+ when(basCrnpService.getOne(any())).thenReturn(basCrnp);
+ when(crnOperateProcessUtils.dispatchCrnMove(1, "2-1-1")).thenReturn(true);
+
+ ArrivalAwareStationThread stationThread = new ArrivalAwareStationThread(false);
+ StationProtocol stationProtocol = new StationProtocol();
+ stationProtocol.setStationId(12);
+ stationProtocol.setTaskNo(0);
+ stationProtocol.setLoading(true);
+ stationProtocol.setInEnable(false);
+ stationThread.putStatus(stationProtocol);
+
+ SlaveConnection.put(SlaveType.Devp, 3, stationThread);
+ try {
+ scanner.scanInboundStationArrival();
+ } finally {
+ SlaveConnection.remove(SlaveType.Devp, 3);
+ }
+
+ verify(crnOperateProcessUtils).dispatchCrnMove(1, "2-1-1");
+ verify(wrkAnalysisService, never()).completeInboundStationRun(any(WrkMast.class), any(Date.class));
+ }
+
private static class ArrivalAwareStationThread implements StationThread {
private final boolean recentArrival;
diff --git a/src/test/java/com/zy/asrs/task/WrkMastSchedulerCrnMoveTest.java b/src/test/java/com/zy/asrs/task/WrkMastSchedulerCrnMoveTest.java
new file mode 100644
index 0000000..d08297b
--- /dev/null
+++ b/src/test/java/com/zy/asrs/task/WrkMastSchedulerCrnMoveTest.java
@@ -0,0 +1,54 @@
+package com.zy.asrs.task;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.zy.asrs.entity.WrkMast;
+import com.zy.asrs.service.LocMastService;
+import com.zy.asrs.service.WrkAnalysisService;
+import com.zy.asrs.service.WrkMastLogService;
+import com.zy.asrs.service.WrkMastService;
+import com.zy.asrs.utils.NotifyUtils;
+import com.zy.core.enums.WrkIoType;
+import com.zy.core.enums.WrkStsType;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class WrkMastSchedulerCrnMoveTest {
+
+ @Test
+ void executeCrnMove_archivesAndRemovesCompletedCrnMoveTask() {
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ WrkMastLogService wrkMastLogService = mock(WrkMastLogService.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ LocMastService locMastService = mock(LocMastService.class);
+ NotifyUtils notifyUtils = mock(NotifyUtils.class);
+
+ WrkMastScheduler scheduler = new WrkMastScheduler(
+ wrkMastService,
+ wrkMastLogService,
+ wrkAnalysisService,
+ locMastService,
+ notifyUtils
+ );
+
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(30001);
+ wrkMast.setIoType(WrkIoType.CRN_MOVE.id);
+ wrkMast.setWrkSts(WrkStsType.COMPLETE_CRN_MOVE.sts);
+
+ when(wrkMastService.list(any(QueryWrapper.class))).thenReturn(List.of(wrkMast));
+ when(wrkMastLogService.save(30001)).thenReturn(true);
+ when(wrkMastService.removeById(30001)).thenReturn(true);
+
+ scheduler.executeCrnMove();
+
+ verify(wrkMastLogService).save(30001);
+ verify(wrkAnalysisService).finishTask(any(WrkMast.class), any());
+ verify(wrkMastService).removeById(30001);
+ }
+}
diff --git a/src/test/java/com/zy/core/utils/CrnOperateProcessUtilsTest.java b/src/test/java/com/zy/core/utils/CrnOperateProcessUtilsTest.java
new file mode 100644
index 0000000..3fab458
--- /dev/null
+++ b/src/test/java/com/zy/core/utils/CrnOperateProcessUtilsTest.java
@@ -0,0 +1,397 @@
+package com.zy.core.utils;
+
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.zy.asrs.entity.BasCrnp;
+import com.zy.asrs.entity.LocMast;
+import com.zy.asrs.entity.WrkMast;
+import com.zy.asrs.service.BasCrnpService;
+import com.zy.asrs.service.LocMastService;
+import com.zy.asrs.service.WrkAnalysisService;
+import com.zy.asrs.service.WrkMastService;
+import com.zy.asrs.utils.NotifyUtils;
+import com.zy.common.service.CommonService;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.cache.MessageQueue;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.CrnModeType;
+import com.zy.core.enums.CrnStatusType;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.enums.WrkIoType;
+import com.zy.core.enums.WrkStsType;
+import com.zy.core.model.Task;
+import com.zy.core.model.command.CrnCommand;
+import com.zy.core.model.protocol.CrnProtocol;
+import com.zy.core.thread.CrnThread;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class CrnOperateProcessUtilsTest {
+
+ @AfterEach
+ void tearDown() {
+ safeClearQueue(1);
+ safeClearQueue(2);
+ SlaveConnection.remove(SlaveType.Crn, 1);
+ SlaveConnection.remove(SlaveType.Crn, 2);
+ SlaveConnection.remove(SlaveType.Devp, 101);
+ }
+
+ @Test
+ void dispatchCrnMove_createsFormalTaskOnly() {
+ CrnOperateProcessUtils utils = new CrnOperateProcessUtils();
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ CommonService commonService = mock(CommonService.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ CrnThread crnThread = mock(CrnThread.class);
+
+ ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService);
+ ReflectionTestUtils.setField(utils, "commonService", commonService);
+ ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService);
+
+ when(wrkMastService.count(any())).thenReturn(0L);
+ when(wrkMastService.getOne(any())).thenReturn(null);
+ when(commonService.getWorkNo(WrkIoType.CRN_MOVE.id)).thenReturn(30001);
+ AtomicReference<WrkMast> savedSnapshot = new AtomicReference<>();
+ when(wrkMastService.save(any(WrkMast.class))).thenAnswer(invocation -> {
+ WrkMast source = invocation.getArgument(0);
+ WrkMast snapshot = new WrkMast();
+ snapshot.setWrkNo(source.getWrkNo());
+ snapshot.setIoType(source.getIoType());
+ snapshot.setWrkSts(source.getWrkSts());
+ snapshot.setLocNo(source.getLocNo());
+ snapshot.setCrnNo(source.getCrnNo());
+ savedSnapshot.set(snapshot);
+ return true;
+ });
+
+ MessageQueue.init(SlaveType.Crn, 1);
+ CrnProtocol protocol = buildProtocol(1, CrnStatusType.IDLE.id, 0);
+ protocol.setBay(8);
+ protocol.setLevel(3);
+ when(crnThread.getStatus()).thenReturn(protocol);
+ SlaveConnection.put(SlaveType.Crn, 1, crnThread);
+
+ boolean dispatched = utils.dispatchCrnMove(1, "2-1-1");
+
+ assertTrue(dispatched);
+
+ verify(wrkMastService).save(any(WrkMast.class));
+ WrkMast saved = savedSnapshot.get();
+ assertNotNull(saved);
+ assertEquals(30001, saved.getWrkNo());
+ assertEquals(WrkIoType.CRN_MOVE.id, saved.getIoType());
+ assertEquals(WrkStsType.NEW_CRN_MOVE.sts, saved.getWrkSts());
+ assertEquals("2-1-1", saved.getLocNo());
+ assertEquals(1, saved.getCrnNo());
+
+ verify(wrkMastService, never()).updateById(any(WrkMast.class));
+ verify(wrkAnalysisService, never()).markCraneStart(any(WrkMast.class), any());
+ assertNull(MessageQueue.peek(SlaveType.Crn, 1));
+ }
+
+ @Test
+ void dispatchCrnMove_returnsFalseWhenOtherTaskRunning() {
+ CrnOperateProcessUtils utils = new CrnOperateProcessUtils();
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ CommonService commonService = mock(CommonService.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+
+ ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService);
+ ReflectionTestUtils.setField(utils, "commonService", commonService);
+ ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService);
+
+ when(wrkMastService.count(any())).thenReturn(1L);
+ when(wrkMastService.getOne(any())).thenReturn(null);
+ when(wrkMastService.save(any(WrkMast.class))).thenReturn(true);
+ when(commonService.getWorkNo(WrkIoType.CRN_MOVE.id)).thenReturn(30001);
+
+ boolean dispatched = utils.dispatchCrnMove(1, "2-1-1");
+
+ assertFalse(dispatched);
+ verify(wrkMastService, never()).save(any(WrkMast.class));
+ verify(commonService, never()).getWorkNo(anyInt());
+ verify(wrkAnalysisService, never()).initForTask(any(WrkMast.class));
+ }
+
+ @Test
+ void crnIoExecuteNormal_prioritizesCrnMoveTask() {
+ CrnOperateProcessUtils utils = new CrnOperateProcessUtils();
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ RedisUtil redisUtil = mock(RedisUtil.class);
+ LocMastService locMastService = mock(LocMastService.class);
+ NotifyUtils notifyUtils = mock(NotifyUtils.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ CrnThread crnThread = mock(CrnThread.class);
+
+ ReflectionTestUtils.setField(utils, "basCrnpService", basCrnpService);
+ ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService);
+ ReflectionTestUtils.setField(utils, "redisUtil", redisUtil);
+ ReflectionTestUtils.setField(utils, "locMastService", locMastService);
+ ReflectionTestUtils.setField(utils, "notifyUtils", notifyUtils);
+ ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService);
+
+ when(basCrnpService.list(anyWrapper())).thenReturn(List.of(buildBasCrnp(1, "[[2,3]]", "[2]")));
+ when(redisUtil.get(anyString())).thenReturn(null);
+ when(wrkMastService.count(any())).thenReturn(0L);
+ when(wrkMastService.updateById(any(WrkMast.class))).thenReturn(true);
+
+ WrkMast crnMoveTask = new WrkMast();
+ crnMoveTask.setWrkNo(30001);
+ crnMoveTask.setCrnNo(1);
+ crnMoveTask.setIoType(WrkIoType.CRN_MOVE.id);
+ crnMoveTask.setWrkSts(WrkStsType.NEW_CRN_MOVE.sts);
+ crnMoveTask.setLocNo("2-1-1");
+ crnMoveTask.setIoPri(999D);
+
+ WrkMast locMoveTask = new WrkMast();
+ locMoveTask.setWrkNo(20001);
+ locMoveTask.setCrnNo(1);
+ locMoveTask.setIoType(WrkIoType.LOC_MOVE.id);
+ locMoveTask.setWrkSts(WrkStsType.NEW_LOC_MOVE.sts);
+ locMoveTask.setSourceLocNo("3-1-1");
+ locMoveTask.setLocNo("4-1-1");
+ locMoveTask.setIoPri(1D);
+
+ when(wrkMastService.list(anyWrapper()))
+ .thenReturn(new ArrayList<>(List.of(crnMoveTask)))
+ .thenReturn(new ArrayList<>(List.of(locMoveTask, crnMoveTask)));
+
+ LocMast sourceLoc = new LocMast();
+ sourceLoc.setLocNo("3-1-1");
+ sourceLoc.setLocSts("R");
+ LocMast targetLoc = new LocMast();
+ targetLoc.setLocNo("4-1-1");
+ targetLoc.setLocSts("S");
+ when(locMastService.getById("3-1-1")).thenReturn(sourceLoc);
+ when(locMastService.getById("4-1-1")).thenReturn(targetLoc);
+
+ CrnProtocol protocol = buildProtocol(1, CrnStatusType.IDLE.id, 0);
+ protocol.setBay(1);
+ protocol.setLevel(1);
+ when(crnThread.getStatus()).thenReturn(protocol);
+
+ CrnCommand moveCommand = new CrnCommand();
+ moveCommand.setCrnNo(1);
+ moveCommand.setTaskNo(30001);
+ when(crnThread.getMoveCommand("2-1-1", 30001, 1)).thenReturn(moveCommand);
+
+ CrnCommand locMoveCommand = new CrnCommand();
+ locMoveCommand.setCrnNo(1);
+ locMoveCommand.setTaskNo(20001);
+ when(crnThread.getPickAndPutCommand("3-1-1", "4-1-1", 20001, 1)).thenReturn(locMoveCommand);
+
+ MessageQueue.init(SlaveType.Crn, 1);
+ SlaveConnection.put(SlaveType.Crn, 1, crnThread);
+
+ utils.crnIoExecuteNormal();
+
+ ArgumentCaptor<WrkMast> updateCaptor = ArgumentCaptor.forClass(WrkMast.class);
+ verify(wrkMastService).updateById(updateCaptor.capture());
+ assertEquals(30001, updateCaptor.getValue().getWrkNo());
+ assertEquals(WrkStsType.CRN_MOVE_RUN.sts, updateCaptor.getValue().getWrkSts());
+ verify(wrkAnalysisService).markCraneStart(any(WrkMast.class), any());
+
+ Task task = MessageQueue.peek(SlaveType.Crn, 1);
+ assertNotNull(task);
+ assertSame(moveCommand, task.getData());
+ }
+
+ @Test
+ void crnIoExecuteNormal_allowsOtherCraneToRunWhenOneCraneHasMoveTask() {
+ CrnOperateProcessUtils utils = new CrnOperateProcessUtils();
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ RedisUtil redisUtil = mock(RedisUtil.class);
+ LocMastService locMastService = mock(LocMastService.class);
+ NotifyUtils notifyUtils = mock(NotifyUtils.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ CrnThread crnThread1 = mock(CrnThread.class);
+ CrnThread crnThread2 = mock(CrnThread.class);
+
+ ReflectionTestUtils.setField(utils, "basCrnpService", basCrnpService);
+ ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService);
+ ReflectionTestUtils.setField(utils, "redisUtil", redisUtil);
+ ReflectionTestUtils.setField(utils, "locMastService", locMastService);
+ ReflectionTestUtils.setField(utils, "notifyUtils", notifyUtils);
+ ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService);
+
+ when(basCrnpService.list(anyWrapper())).thenReturn(List.of(
+ buildBasCrnp(1, "[[2,3]]", "[2]"),
+ buildBasCrnp(2, "[[4,5]]", "[4]")
+ ));
+ when(redisUtil.get(anyString())).thenReturn(null);
+ when(wrkMastService.count(any())).thenReturn(0L);
+ when(wrkMastService.updateById(any(WrkMast.class))).thenReturn(true);
+
+ WrkMast crnMoveTask = new WrkMast();
+ crnMoveTask.setWrkNo(30001);
+ crnMoveTask.setCrnNo(1);
+ crnMoveTask.setIoType(WrkIoType.CRN_MOVE.id);
+ crnMoveTask.setWrkSts(WrkStsType.NEW_CRN_MOVE.sts);
+ crnMoveTask.setLocNo("2-1-1");
+
+ WrkMast locMoveTask = new WrkMast();
+ locMoveTask.setWrkNo(20002);
+ locMoveTask.setCrnNo(2);
+ locMoveTask.setIoType(WrkIoType.LOC_MOVE.id);
+ locMoveTask.setWrkSts(WrkStsType.NEW_LOC_MOVE.sts);
+ locMoveTask.setSourceLocNo("4-1-1");
+ locMoveTask.setLocNo("5-1-1");
+ locMoveTask.setIoPri(1D);
+
+ when(wrkMastService.list(anyWrapper()))
+ .thenReturn(new ArrayList<>(List.of(crnMoveTask)))
+ .thenReturn(new ArrayList<>(List.of(crnMoveTask)))
+ .thenReturn(new ArrayList<>(List.of(locMoveTask)));
+
+ LocMast sourceLoc = new LocMast();
+ sourceLoc.setLocNo("4-1-1");
+ sourceLoc.setLocSts("R");
+ LocMast targetLoc = new LocMast();
+ targetLoc.setLocNo("5-1-1");
+ targetLoc.setLocSts("S");
+ when(locMastService.getById("4-1-1")).thenReturn(sourceLoc);
+ when(locMastService.getById("5-1-1")).thenReturn(targetLoc);
+
+ CrnProtocol protocol1 = buildProtocol(1, CrnStatusType.IDLE.id, 0);
+ when(crnThread1.getStatus()).thenReturn(protocol1);
+ CrnProtocol protocol2 = buildProtocol(2, CrnStatusType.IDLE.id, 0);
+ when(crnThread2.getStatus()).thenReturn(protocol2);
+
+ CrnCommand moveCommand = new CrnCommand();
+ moveCommand.setCrnNo(1);
+ moveCommand.setTaskNo(30001);
+ when(crnThread1.getMoveCommand("2-1-1", 30001, 1)).thenReturn(moveCommand);
+
+ CrnCommand locMoveCommand = new CrnCommand();
+ locMoveCommand.setCrnNo(2);
+ locMoveCommand.setTaskNo(20002);
+ when(crnThread2.getPickAndPutCommand("4-1-1", "5-1-1", 20002, 2)).thenReturn(locMoveCommand);
+
+ MessageQueue.init(SlaveType.Crn, 1);
+ MessageQueue.init(SlaveType.Crn, 2);
+ SlaveConnection.put(SlaveType.Crn, 1, crnThread1);
+ SlaveConnection.put(SlaveType.Crn, 2, crnThread2);
+
+ utils.crnIoExecuteNormal();
+
+ ArgumentCaptor<WrkMast> updateCaptor = ArgumentCaptor.forClass(WrkMast.class);
+ verify(wrkMastService, times(2)).updateById(updateCaptor.capture());
+ List<WrkMast> updatedList = updateCaptor.getAllValues();
+ assertEquals(30001, updatedList.get(0).getWrkNo());
+ assertEquals(WrkStsType.CRN_MOVE_RUN.sts, updatedList.get(0).getWrkSts());
+ assertEquals(20002, updatedList.get(1).getWrkNo());
+ assertEquals(WrkStsType.LOC_MOVE_RUN.sts, updatedList.get(1).getWrkSts());
+
+ Task task1 = MessageQueue.peek(SlaveType.Crn, 1);
+ assertNotNull(task1);
+ assertSame(moveCommand, task1.getData());
+
+ Task task2 = MessageQueue.peek(SlaveType.Crn, 2);
+ assertNotNull(task2);
+ assertSame(locMoveCommand, task2.getData());
+ }
+
+ @Test
+ void crnIoExecuteFinish_marksCrnMoveTaskComplete() {
+ CrnOperateProcessUtils utils = new CrnOperateProcessUtils();
+ BasCrnpService basCrnpService = mock(BasCrnpService.class);
+ WrkMastService wrkMastService = mock(WrkMastService.class);
+ RedisUtil redisUtil = mock(RedisUtil.class);
+ WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+ CrnThread crnThread = mock(CrnThread.class);
+
+ ReflectionTestUtils.setField(utils, "basCrnpService", basCrnpService);
+ ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService);
+ ReflectionTestUtils.setField(utils, "redisUtil", redisUtil);
+ ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService);
+
+ when(basCrnpService.list(anyWrapper())).thenReturn(List.of(buildBasCrnp(1, "[[2,3]]", "[2]")));
+ when(redisUtil.get(anyString())).thenReturn(null);
+ when(wrkMastService.updateById(any(WrkMast.class))).thenReturn(true);
+
+ CrnProtocol protocol = buildProtocol(1, CrnStatusType.WAITING.id, 30001);
+ when(crnThread.getStatus()).thenReturn(protocol);
+
+ WrkMast wrkMast = new WrkMast();
+ wrkMast.setWrkNo(30001);
+ wrkMast.setIoType(WrkIoType.CRN_MOVE.id);
+ wrkMast.setWrkSts(WrkStsType.CRN_MOVE_RUN.sts);
+ wrkMast.setCrnNo(1);
+ when(wrkMastService.selectByWorkNo(30001)).thenReturn(wrkMast);
+
+ CrnCommand resetCommand = new CrnCommand();
+ resetCommand.setCrnNo(1);
+ resetCommand.setTaskNo(30001);
+ when(crnThread.getResetCommand(30001, 1)).thenReturn(resetCommand);
+
+ MessageQueue.init(SlaveType.Crn, 1);
+ SlaveConnection.put(SlaveType.Crn, 1, crnThread);
+
+ utils.crnIoExecuteFinish();
+
+ ArgumentCaptor<WrkMast> updateCaptor = ArgumentCaptor.forClass(WrkMast.class);
+ verify(wrkMastService, times(1)).updateById(updateCaptor.capture());
+ assertEquals(WrkStsType.COMPLETE_CRN_MOVE.sts, updateCaptor.getValue().getWrkSts());
+ verify(wrkAnalysisService).markCraneComplete(any(WrkMast.class), any(), eq(WrkStsType.COMPLETE_CRN_MOVE.sts));
+
+ Task task = MessageQueue.peek(SlaveType.Crn, 1);
+ assertNotNull(task);
+ assertSame(resetCommand, task.getData());
+ }
+
+ private BasCrnp buildBasCrnp(int crnNo, String controlRows, String deepRows) {
+ BasCrnp basCrnp = new BasCrnp();
+ basCrnp.setCrnNo(crnNo);
+ basCrnp.setControlRows(controlRows);
+ basCrnp.setDeepRows(deepRows);
+ return basCrnp;
+ }
+
+ private CrnProtocol buildProtocol(int crnNo, int status, int taskNo) {
+ CrnProtocol protocol = new CrnProtocol();
+ protocol.setCrnNo(crnNo);
+ protocol.setMode(CrnModeType.AUTO.id);
+ protocol.setTaskNo(taskNo);
+ protocol.setStatus(status);
+ protocol.setLoaded(0);
+ protocol.setForkPos(0);
+ protocol.setAlarm(0);
+ return protocol;
+ }
+
+ private void safeClearQueue(int crnNo) {
+ try {
+ MessageQueue.clear(SlaveType.Crn, crnNo);
+ } catch (Exception ignore) {
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> Wrapper<T> anyWrapper() {
+ return any(Wrapper.class);
+ }
+}
--
Gitblit v1.9.1