From 3c31d811aff765b8c5e67c22035b413e0cffb38f Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 24 三月 2026 13:07:30 +0800
Subject: [PATCH] #V5 beta
---
src/main/java/com/zy/core/utils/StationOperateProcessUtils.java | 205 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 197 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java b/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
index ec8a453..40e4e19 100644
--- a/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -19,6 +19,8 @@
import com.zy.common.service.CommonService;
import com.zy.common.utils.NavigateUtils;
import com.zy.common.utils.RedisUtil;
+import com.zy.core.move.StationMoveCoordinator;
+import com.zy.core.move.StationMoveSession;
import com.zy.core.News;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
@@ -74,6 +76,8 @@
private StationTaskLoopService stationTaskLoopService;
@Autowired
private WrkAnalysisService wrkAnalysisService;
+ @Autowired
+ private StationMoveCoordinator stationMoveCoordinator;
//鎵ц杈撻�佺珯鐐瑰叆搴撲换鍔�
public synchronized void stationInExecute() {
@@ -252,7 +256,16 @@
wrkMast.setModiTime(now);
if (wrkMastService.updateById(wrkMast)) {
wrkAnalysisService.markOutboundStationStart(wrkMast, now);
- offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
+ boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
+ if (offered && stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "crnStationOutExecute",
+ command,
+ false
+ );
+ }
News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠や笅鍙戞垚鍔燂紝绔欑偣鍙�={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
redisUtil.del(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
@@ -372,6 +385,9 @@
if (wrkMast == null || wrkMast.getWrkNo() == null) {
return;
}
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.finishSession(wrkMast.getWrkNo());
+ }
Date now = new Date();
wrkMast.setWrkSts(WrkStsType.STATION_RUN_COMPLETE.sts);
wrkMast.setIoTime(now);
@@ -419,6 +435,9 @@
}
if (complete) {
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.finishSession(wrkNo);
+ }
wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
wrkMast.setIoTime(new Date());
wrkMastService.updateById(wrkMast);
@@ -466,6 +485,20 @@
if (wrkMast.getIoType() == WrkIoType.IN.id && runBlockReassignLocStationList.contains(stationProtocol.getStationId())) {
//绔欑偣澶勪簬閲嶆柊鍒嗛厤搴撲綅鍖哄煙
+ int currentTaskBufferCommandCount = countCurrentTaskBufferCommands(
+ stationProtocol.getTaskBufferItems(),
+ stationProtocol.getTaskNo()
+ );
+ if (currentTaskBufferCommandCount > 0) {
+ News.info("杈撻�佺珯鐐硅繍琛屽牭濉為噸鍒嗛厤宸茶烦杩囷紝缂撳瓨鍖轰粛瀛樺湪褰撳墠浠诲姟鍛戒护銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽綋鍓嶄换鍔″懡浠ゆ暟={}",
+ stationProtocol.getStationId(),
+ stationProtocol.getTaskNo(),
+ currentTaskBufferCommandCount);
+ continue;
+ }
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.cancelSession(wrkMast.getWrkNo());
+ }
//杩愯鍫靛锛岄噸鏂扮敵璇蜂换鍔�
String response = wmsOperateUtils.applyReassignTaskLocNo(wrkMast.getWrkNo(), stationProtocol.getStationId());
if (Cools.isEmpty(response)) {
@@ -543,7 +576,19 @@
}
if (wrkMastService.updateById(wrkMast)) {
- offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "checkStationRunBlock_direct");
+ boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "checkStationRunBlock_direct");
+ if (!offered) {
+ continue;
+ }
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "checkStationRunBlock_direct",
+ command,
+ false
+ );
+ }
}
} else {
News.error("璇锋眰WMS鎺ュ彛澶辫触锛侊紒锛乺esponse锛歿}", response);
@@ -562,6 +607,10 @@
continue;
}
+ if (countCurrentTaskBufferCommands(stationProtocol.getTaskBufferItems(), stationProtocol.getTaskNo()) > 0) {
+ continue;
+ }
+
StationCommand command = stationThread.getRunBlockRerouteCommand(
wrkMast.getWrkNo(),
stationProtocol.getStationId(),
@@ -577,8 +626,24 @@
continue;
}
- offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "checkStationRunBlock_reroute");
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.cancelSession(wrkMast.getWrkNo());
+ }
+ resetSegmentMoveCommandsBeforeReroute(wrkMast.getWrkNo());
+ boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "checkStationRunBlock_reroute");
+ if (!offered) {
+ continue;
+ }
syncOutOrderWatchState(wrkMast, stationProtocol.getStationId(), outOrderStationIds, dispatchDecision, command);
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "checkStationRunBlock_reroute",
+ command,
+ dispatchDecision != null && dispatchDecision.isCircle()
+ );
+ }
News.info("杈撻�佺珯鐐瑰牭濉炲悗閲嶆柊璁$畻璺緞鍛戒护涓嬪彂鎴愬姛锛岀珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
}
}
@@ -677,7 +742,7 @@
continue;
}
- if (isWatchingCircleArrival(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
+ if (countCurrentTaskBufferCommands(stationProtocol.getTaskBufferItems(), stationProtocol.getTaskNo()) > 0) {
continue;
}
@@ -704,11 +769,28 @@
News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
continue;
}
+ if (stationMoveCoordinator != null
+ && stationMoveCoordinator.shouldSuppressDispatch(wrkMast.getWrkNo(), stationProtocol.getStationId(), command)) {
+ continue;
+ }
if (!tryAcquireOutOrderDispatchLock(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
continue;
}
+ resetSegmentMoveCommandsBeforeReroute(wrkMast.getWrkNo());
+ boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "checkStationOutOrder");
+ if (!offered) {
+ continue;
+ }
syncOutOrderWatchState(wrkMast, stationProtocol.getStationId(), outOrderStationIds, dispatchDecision, command);
- offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "checkStationOutOrder");
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "checkStationOutOrder",
+ command,
+ dispatchDecision != null && dispatchDecision.isCircle()
+ );
+ }
News.info(dispatchDecision.isCircle() ? "{}浠诲姟杩涜缁曞湀" : "{}浠诲姟鐩存帴鍘荤洰鏍囩偣", wrkMast.getWrkNo());
}
}
@@ -756,6 +838,9 @@
if (Objects.equals(stationProtocol.getStationId(), wrkMast.getStaNo())) {
continue;
}
+ if (countCurrentTaskBufferCommands(stationProtocol.getTaskBufferItems(), stationProtocol.getTaskNo()) > 0) {
+ continue;
+ }
Double pathLenFactor = resolveOutboundPathLenFactor(wrkMast);
OutOrderDispatchDecision dispatchDecision = resolveOutboundDispatchDecision(
@@ -780,11 +865,28 @@
News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
continue;
}
+ if (stationMoveCoordinator != null
+ && stationMoveCoordinator.shouldSuppressDispatch(wrkMast.getWrkNo(), stationProtocol.getStationId(), command)) {
+ continue;
+ }
if (!tryAcquireOutOrderDispatchLock(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
continue;
}
+ resetSegmentMoveCommandsBeforeReroute(wrkMast.getWrkNo());
+ boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "watchCircleStation");
+ if (!offered) {
+ continue;
+ }
syncOutOrderWatchState(wrkMast, stationProtocol.getStationId(), outOrderList, dispatchDecision, command);
- offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "watchCircleStation");
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "watchCircleStation",
+ command,
+ dispatchDecision != null && dispatchDecision.isCircle()
+ );
+ }
}
}
}
@@ -1255,8 +1357,39 @@
}
private boolean isWatchingCircleArrival(Integer wrkNo, Integer stationId) {
+ if (stationMoveCoordinator != null) {
+ StationMoveSession session = stationMoveCoordinator.loadSession(wrkNo);
+ if (session != null && session.isActive() && stationId != null) {
+ if (stationId.equals(session.getNextDecisionStationId())) {
+ return true;
+ }
+ if (session.containsStation(stationId)) {
+ return false;
+ }
+ }
+ }
StationCommand command = getWatchCircleCommand(wrkNo);
return command != null && stationId != null && stationId.equals(command.getTargetStaNo());
+ }
+
+ private boolean isWatchingCircleTransit(Integer wrkNo, Integer stationId) {
+ if (stationMoveCoordinator != null) {
+ StationMoveSession session = stationMoveCoordinator.loadSession(wrkNo);
+ if (session != null && session.isActive() && stationId != null) {
+ if (stationId.equals(session.getNextDecisionStationId())) {
+ return false;
+ }
+ if (session.containsStation(stationId)) {
+ return true;
+ }
+ }
+ }
+ StationCommand command = getWatchCircleCommand(wrkNo);
+ if (command == null || stationId == null || Objects.equals(stationId, command.getTargetStaNo())) {
+ return false;
+ }
+ List<Integer> navigatePath = command.getNavigatePath();
+ return navigatePath != null && navigatePath.contains(stationId);
}
private StationCommand getWatchCircleCommand(Integer wrkNo) {
@@ -1301,6 +1434,9 @@
}
StationTaskIdleTrack idleTrack = touchStationTaskIdleTrack(stationProtocol.getTaskNo(), stationProtocol.getStationId());
+ if (shouldSkipIdleRecoverForRecentDispatch(stationProtocol.getTaskNo(), stationProtocol.getStationId())) {
+ return;
+ }
if (idleTrack == null || !idleTrack.isTimeout(STATION_IDLE_RECOVER_SECONDS)) {
return;
}
@@ -1339,6 +1475,9 @@
return;
}
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.cancelSession(stationProtocol.getTaskNo());
+ }
redisUtil.set(RedisKeyType.CHECK_STATION_IDLE_RECOVER_LIMIT_.key + stationProtocol.getTaskNo(), "lock", STATION_IDLE_RECOVER_LIMIT_SECONDS);
resetSegmentMoveCommandsBeforeReroute(stationProtocol.getTaskNo());
int clearedCommandCount = clearIssuedMoveCommandsDuringIdleStay(idleTrack, stationProtocol.getTaskNo(), stationProtocol.getStationId());
@@ -1355,8 +1494,20 @@
return;
}
- offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "checkStationIdleRecover");
+ boolean offered = offerDevpCommandWithDedup(basDevp.getDevpNo(), command, "checkStationIdleRecover");
+ if (!offered) {
+ return;
+ }
syncOutOrderWatchState(wrkMast, stationProtocol.getStationId(), outOrderList, dispatchDecision, command);
+ if (stationMoveCoordinator != null) {
+ stationMoveCoordinator.recordDispatch(
+ wrkMast.getWrkNo(),
+ stationProtocol.getStationId(),
+ "checkStationIdleRecover",
+ command,
+ dispatchDecision != null && dispatchDecision.isCircle()
+ );
+ }
saveStationTaskIdleTrack(new StationTaskIdleTrack(wrkMast.getWrkNo(), stationProtocol.getStationId(), System.currentTimeMillis()));
News.info("杈撻�佺珯鐐逛换鍔″仠鐣檣}绉掓湭杩愯锛屽凡閲嶆柊璁$畻璺緞骞堕噸鍚繍琛岋紝绔欑偣鍙�={}锛岀洰鏍囩珯={}锛屽伐浣滃彿={}锛屾竻鐞嗘棫鍒嗘鍛戒护鏁�={}锛屽懡浠ゆ暟鎹�={}",
STATION_IDLE_RECOVER_SECONDS, stationProtocol.getStationId(), moveStaNo, wrkMast.getWrkNo(), clearedCommandCount, JSON.toJSONString(command));
@@ -1371,6 +1522,29 @@
}
return Objects.equals(wrkMast.getWrkSts(), WrkStsType.INBOUND_STATION_RUN.sts)
|| Objects.equals(wrkMast.getWrkSts(), WrkStsType.STATION_RUN.sts);
+ }
+
+ private boolean shouldSkipIdleRecoverForRecentDispatch(Integer taskNo, Integer stationId) {
+ if (stationMoveCoordinator == null || taskNo == null || taskNo <= 0 || stationId == null) {
+ return false;
+ }
+ StationMoveSession session = stationMoveCoordinator.loadSession(taskNo);
+ if (session == null || !session.isActive() || session.getLastIssuedAt() == null) {
+ return false;
+ }
+ if (!Objects.equals(stationId, session.getCurrentStationId())
+ && !Objects.equals(stationId, session.getDispatchStationId())) {
+ return false;
+ }
+ long elapsedMs = System.currentTimeMillis() - session.getLastIssuedAt();
+ long thresholdMs = STATION_IDLE_RECOVER_SECONDS * 1000L;
+ if (elapsedMs >= thresholdMs) {
+ return false;
+ }
+ saveStationTaskIdleTrack(new StationTaskIdleTrack(taskNo, stationId, System.currentTimeMillis()));
+ News.info("杈撻�佺珯鐐逛换鍔″垰瀹屾垚鍛戒护涓嬪彂锛屽凡璺宠繃鍋滅暀閲嶇畻銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛岃窛涓婃涓嬪彂={}ms锛宺outeVersion={}",
+ stationId, taskNo, elapsedMs, session.getRouteVersion());
+ return true;
}
private void resetSegmentMoveCommandsBeforeReroute(Integer taskNo) {
@@ -1432,8 +1606,23 @@
private String buildStationCommandDispatchDedupKey(Integer deviceNo, StationCommand command) {
return RedisKeyType.STATION_COMMAND_DISPATCH_DEDUP_.key
+ + deviceNo + "_"
+ command.getTaskNo() + "_"
- + command.getStationId();
+ + command.getStationId() + "_"
+ + (stationMoveCoordinator == null ? Integer.toHexString(buildFallbackPathSignature(command).hashCode())
+ : stationMoveCoordinator.buildPathSignatureHash(command));
+ }
+
+ private String buildFallbackPathSignature(StationCommand command) {
+ if (command == null) {
+ return "";
+ }
+ return String.valueOf(command.getCommandType())
+ + "_" + command.getStationId()
+ + "_" + command.getTargetStaNo()
+ + "_" + command.getNavigatePath()
+ + "_" + command.getLiftTransferPath()
+ + "_" + command.getOriginalNavigatePath();
}
private int clearIssuedMoveCommandsDuringIdleStay(StationTaskIdleTrack idleTrack,
--
Gitblit v1.9.1