From 8b07b202870c7bbf6838b1a332acedf322655978 Mon Sep 17 00:00:00 2001
From: Administrator <1051256694@qq.com>
Date: 星期四, 19 三月 2026 19:20:10 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java | 984 ++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 647 insertions(+), 337 deletions(-)
diff --git a/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java b/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
index 4530d45..2f2c744 100644
--- a/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
+++ b/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.core.common.SpringUtils;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
@@ -11,41 +12,51 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.network.api.ZyStationConnectApi;
import com.zy.core.network.entity.ZyStationStatusEntity;
+
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Random;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
-import java.util.Map;
-import java.util.Arrays;
public class ZyStationFakeSegConnect implements ZyStationConnectApi {
- // 绔欑偣绾ч攣锛氭瘡涓珯鐐圭嫭绔嬩竴鎶婇攣锛屾彁鍗囧苟鍙戞�ц兘
- private final Map<Integer, ReentrantLock> stationLocks = new ConcurrentHashMap<>();
- private HashMap<Integer, List<ZyStationStatusEntity>> deviceStatusMap = new HashMap<>();
- private HashMap<Integer, DeviceConfig> deviceConfigMap = new HashMap<>();
- private RedisUtil redisUtil;
- private final Map<Integer, BlockingQueue<StationCommand>> taskQueues = new ConcurrentHashMap<>();
- private final Map<Integer, Long> taskLastUpdateTime = new ConcurrentHashMap<>();
- private final Map<Integer, Boolean> taskRunning = new ConcurrentHashMap<>();
+ private static final long DEFAULT_FAKE_RUN_BLOCK_TIMEOUT_MS = 10000L;
+ private static final long WAIT_SEGMENT_TIMEOUT_MS = 30000L;
+
+ private static final String STATUS_WAITING = "WAITING";
+ private static final String STATUS_RUNNING = "RUNNING";
+ private static final String STATUS_BLOCKED = "BLOCKED";
+ private static final String STATUS_CANCELLED = "CANCELLED";
+ private static final String STATUS_TIMEOUT = "TIMEOUT";
+ private static final String STATUS_FINISHED = "FINISHED";
+
+ private final Map<Integer, ReentrantLock> stationLocks = new ConcurrentHashMap<Integer, ReentrantLock>();
+ private final Map<Integer, List<ZyStationStatusEntity>> deviceStatusMap = new ConcurrentHashMap<Integer, List<ZyStationStatusEntity>>();
+ private final Map<Integer, DeviceConfig> deviceConfigMap = new ConcurrentHashMap<Integer, DeviceConfig>();
+ private final Map<Integer, BlockingQueue<StationCommand>> taskQueues = new ConcurrentHashMap<Integer, BlockingQueue<StationCommand>>();
+ private final Map<Integer, Long> taskLastUpdateTime = new ConcurrentHashMap<Integer, Long>();
+ private final Map<Integer, Boolean> taskRunning = new ConcurrentHashMap<Integer, Boolean>();
private final ExecutorService executor = Executors.newCachedThreadPool();
+
+ private RedisUtil redisUtil;
public void addFakeConnect(DeviceConfig deviceConfig, RedisUtil redisUtil) {
this.redisUtil = redisUtil;
-
if (deviceConfigMap.containsKey(deviceConfig.getDeviceNo())) {
return;
}
deviceConfigMap.put(deviceConfig.getDeviceNo(), deviceConfig);
- deviceStatusMap.put(deviceConfig.getDeviceNo(), new CopyOnWriteArrayList<>());
+ deviceStatusMap.put(deviceConfig.getDeviceNo(), new CopyOnWriteArrayList<ZyStationStatusEntity>());
}
@Override
@@ -63,10 +74,11 @@
public List<ZyStationStatusEntity> getStatus(Integer deviceNo) {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
if (statusList == null) {
- return new ArrayList<>();
+ return new ArrayList<ZyStationStatusEntity>();
}
+
DeviceConfig deviceConfig = deviceConfigMap.get(deviceNo);
- if (statusList.isEmpty()) {
+ if (statusList.isEmpty() && deviceConfig != null) {
List<ZyStationStatusEntity> init = JSON.parseArray(deviceConfig.getFakeInitStatus(),
ZyStationStatusEntity.class);
if (init != null) {
@@ -96,228 +108,29 @@
return new CommandResponse(false, "浠诲姟鍙蜂负绌�");
}
- // 澶勭悊闈炵Щ鍔ㄥ懡浠�
if (command.getCommandType() != StationCommandType.MOVE) {
handleCommand(deviceNo, command);
- } else {
- // 灏嗙Щ鍔ㄥ懡浠よ拷鍔犲埌浠诲姟闃熷垪锛堟敮鎸佸垎娈典笅鍙戯級
- taskQueues.computeIfAbsent(taskNo, k -> new LinkedBlockingQueue<>()).offer(command);
- taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
+ return new CommandResponse(true, "鍛戒护宸插彈鐞嗭紙寮傛鎵ц锛�");
+ }
- // 鍙湁浠诲姟鏈惎鍔ㄦ椂鎵嶅惎鍔ㄦ墽琛屽櫒锛屽悗缁垎娈靛懡浠や粎杩藉姞鍒伴槦鍒�
- if (taskRunning.putIfAbsent(taskNo, true) == null) {
- executor.submit(() -> runTaskLoop(deviceNo, taskNo));
- }
- // 鍚庣画鍒嗘鍛戒护涓嶅啀杩斿洖閿欒锛屾甯歌拷鍔犲埌闃熷垪
+ if (isDirectMoveCommand(command)) {
+ handleDirectMoveCommand(deviceNo, command);
+ return new CommandResponse(true, "鍛戒护宸插彈鐞嗭紙寮傛鎵ц锛�");
+ }
+
+ taskQueues.computeIfAbsent(taskNo, key -> new LinkedBlockingQueue<StationCommand>()).offer(command);
+ taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
+
+ if (taskRunning.putIfAbsent(taskNo, true) == null) {
+ executor.submit(new Runnable() {
+ @Override
+ public void run() {
+ runTaskLoop(deviceNo, taskNo);
+ }
+ });
}
return new CommandResponse(true, "鍛戒护宸插彈鐞嗭紙寮傛鎵ц锛�");
- }
-
- private void runTaskLoop(Integer deviceNo, Integer taskNo) {
- try {
- // 寰呮墽琛岀殑璺緞闃熷垪锛堝瓨鍌ㄧ珯鐐笽D搴忓垪锛�
- LinkedBlockingQueue<Integer> pendingPathQueue = new LinkedBlockingQueue<>();
- // 褰撳墠鎵�鍦ㄧ珯鐐笽D
- Integer currentStationId = null;
- // 鏈�缁堢洰鏍囩珯鐐笽D
- Integer finalTargetStationId = null;
- // 鏄惁闇�瑕佺敓鎴愭潯鐮�
- boolean generateBarcode = false;
- // 鏄惁宸插垵濮嬪寲璧风偣
- boolean initialized = false;
- // 涓婁竴姝ユ墽琛屾椂闂达紙鐢ㄤ簬鍫靛妫�娴嬶級
- long stepExecuteTime = System.currentTimeMillis();
-
- while (true) {
- if (Thread.currentThread().isInterrupted()) {
- break;
- }
-
- BlockingQueue<StationCommand> commandQueue = taskQueues.get(taskNo);
- if (commandQueue == null) {
- break;
- }
-
- // 灏濊瘯鑾峰彇鏂扮殑鍒嗘鍛戒护
- StationCommand command = commandQueue.poll(100, TimeUnit.MILLISECONDS);
- if (command != null) {
- taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
-
- // 棣栨鎺ユ敹鍛戒护鏃跺垵濮嬪寲
- if (finalTargetStationId == null) {
- finalTargetStationId = command.getTargetStaNo();
- if (checkTaskNoInArea(taskNo)) {
- generateBarcode = true;
- }
- }
-
- // 灏嗘柊璺緞杩藉姞鍒板緟鎵ц闃熷垪
- List<Integer> newPath = command.getNavigatePath();
- if (newPath != null && !newPath.isEmpty()) {
- // 鑾峰彇闃熷垪涓渶鍚庝竴涓珯鐐癸紙鐢ㄤ簬琛旀帴鐐瑰幓閲嶏級
- Integer lastInQueue = getLastInQueue(pendingPathQueue);
- if (lastInQueue == null) {
- lastInQueue = currentStationId;
- }
-
- int startIndex = 0;
- // 濡傛灉鏂拌矾寰勭殑璧风偣涓庡綋鍓嶄綅缃垨闃熷垪鏈熬閲嶅锛屽垯璺宠繃
- if (lastInQueue != null && !newPath.isEmpty() && newPath.get(0).equals(lastInQueue)) {
- startIndex = 1;
- }
-
- for (int i = startIndex; i < newPath.size(); i++) {
- pendingPathQueue.offer(newPath.get(i));
- }
-
- News.info("[WCS Debug] 浠诲姟{}杩藉姞璺緞娈�: {} -> 闃熷垪澶у皬: {}", taskNo, newPath, pendingPathQueue.size());
- }
- }
-
- // 鎵ц绉诲姩閫昏緫
- if (!pendingPathQueue.isEmpty()) {
- Integer nextStationId = pendingPathQueue.peek();
-
- // 濡傛灉灏氭湭鍒濆鍖栬捣鐐�
- if (!initialized && currentStationId == null) {
- // 浼樺厛鏌ユ壘鎵樼洏褰撳墠瀹為檯浣嶇疆锛堟敮鎸佸牭濉炲悗閲嶈矾鐢卞満鏅級
- Integer actualCurrentStationId = findCurrentStationIdByTask(taskNo);
- if (actualCurrentStationId != null) {
- // 鎵惧埌浜嗗綋鍓嶆墭鐩樹綅缃紝浣跨敤瀹為檯浣嶇疆浣滀负璧风偣
- currentStationId = actualCurrentStationId;
- initialized = true;
-
- // 娓呴櫎璇ョ珯鐐圭殑 runBlock 鏍囪锛堝牭濉炴仮澶嶏級
- Integer deviceId = getDeviceNoByStationId(currentStationId);
- if (deviceId != null) {
- clearRunBlock(currentStationId, deviceId);
- }
-
- // 濡傛灉璺緞璧风偣涓庡綋鍓嶄綅缃浉鍚岋紝绉婚櫎璧风偣閬垮厤閲嶅
- if (nextStationId.equals(currentStationId)) {
- pendingPathQueue.poll();
- }
-
- stepExecuteTime = System.currentTimeMillis();
- News.info("[WCS Debug] 浠诲姟{}鎭㈠鎵ц锛屽綋鍓嶄綅缃�: {}", taskNo, currentStationId);
- continue;
- }
-
- // 鏈壘鍒板綋鍓嶄綅缃紙棣栨鎵ц锛夛紝棣栦釜绔欑偣灏辨槸璧风偣
- currentStationId = nextStationId;
- Integer deviceId = getDeviceNoByStationId(currentStationId);
- if (deviceId != null) {
- boolean result = initStationMove(taskNo, currentStationId, deviceId, taskNo,
- finalTargetStationId, true, null);
- if (result) {
- initialized = true;
- pendingPathQueue.poll(); // 绉婚櫎璧风偣
- stepExecuteTime = System.currentTimeMillis();
- News.info("[WCS Debug] 浠诲姟{}鍒濆鍖栬捣鐐�: {}", taskNo, currentStationId);
- }
- }
- sleep(500);
- continue;
- }
-
- // 鎵ц浠庡綋鍓嶇珯鐐瑰埌涓嬩竴绔欑偣鐨勭Щ鍔�
- Integer currentDeviceNo = getDeviceNoByStationId(currentStationId);
- Integer nextDeviceNo = getDeviceNoByStationId(nextStationId);
-
- if (currentDeviceNo != null && nextDeviceNo != null) {
- boolean moveSuccess = stationMoveToNext(taskNo, currentStationId, currentDeviceNo,
- nextStationId, nextDeviceNo, taskNo, finalTargetStationId);
- if (moveSuccess) {
- currentStationId = nextStationId;
- pendingPathQueue.poll();
- stepExecuteTime = System.currentTimeMillis();
- News.info("[WCS Debug] 浠诲姟{}绉诲姩鍒扮珯鐐�: {}, 鍓╀綑闃熷垪: {}", taskNo, currentStationId,
- pendingPathQueue.size());
- sleep(1000); // 妯℃嫙绉诲姩鑰楁椂
- } else {
- // 绉诲姩澶辫触锛屾鏌ユ槸鍚﹀牭濉�
- if (!checkTaskNoInArea(taskNo)) {
- boolean fakeAllowCheckBlock = getFakeAllowCheckBlock();
-
- if (fakeAllowCheckBlock && System.currentTimeMillis() - stepExecuteTime > 10000) {
- // 璁ゅ畾鍫靛
- boolean result = runBlockStation(taskNo, currentStationId, currentDeviceNo, taskNo,
- currentStationId);
- if (result) {
- News.info("[WCS Debug] 浠诲姟{}鍦ㄧ珯鐐箋}琚爣璁颁负鍫靛", taskNo, currentStationId);
- pendingPathQueue.clear();
- break;
- }
- }
- }
- sleep(500); // 澶辫触閲嶈瘯绛夊緟
- }
- } else {
- // 鏃犳硶鑾峰彇璁惧鍙凤紝璺宠繃璇ョ珯鐐�
- pendingPathQueue.poll();
- }
- } else {
- // 璺緞闃熷垪涓虹┖锛岀瓑寰呮柊鐨勫垎娈靛懡浠�
- if (currentStationId != null && finalTargetStationId != null
- && currentStationId.equals(finalTargetStationId)) {
- // 宸插埌杈炬渶缁堢洰鏍囷紝姝e父缁撴潫
- if (generateBarcode) {
- Integer targetDeviceNo = getDeviceNoByStationId(finalTargetStationId);
- if (targetDeviceNo != null) {
- generateStationBarcode(taskNo, finalTargetStationId, targetDeviceNo);
- News.info("[WCS Debug] 浠诲姟{}鍒拌揪鐩爣{}骞剁敓鎴愭潯鐮�", taskNo, finalTargetStationId);
- }
- }
- break;
- }
-
- // 鏈埌杈炬渶缁堢洰鏍囷紝绛夊緟鏂扮殑鍒嗘鍛戒护
- Long lastTime = taskLastUpdateTime.get(taskNo);
- if (lastTime != null && System.currentTimeMillis() - lastTime > 30000) {
- // 瓒呮椂锛�30绉掑唴娌℃湁鏀跺埌鏂板垎娈靛懡浠�
- News.info("[WCS Debug] 浠诲姟{}绛夊緟鍒嗘瓒呮椂锛屽綋鍓嶄綅缃�: {}, 鐩爣: {}", taskNo, currentStationId,
- finalTargetStationId);
- break;
- }
- // 缁х画绛夊緟鏂板垎娈靛懡浠わ紙涓嶅仛浠讳綍浜嬫儏锛屼笅涓�杞惊鐜細灏濊瘯鑾峰彇鏂板懡浠わ級
- }
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } finally {
- taskQueues.remove(taskNo);
- taskLastUpdateTime.remove(taskNo);
- taskRunning.remove(taskNo);
- News.info("[WCS Debug] 浠诲姟{}鎵ц缁撴潫骞舵竻鐞嗚祫婧�", taskNo);
- }
- }
-
- /**
- * 鑾峰彇闃熷垪涓渶鍚庝竴涓厓绱狅紙涓嶇Щ闄わ級
- */
- private Integer getLastInQueue(LinkedBlockingQueue<Integer> queue) {
- Integer last = null;
- for (Integer item : queue) {
- last = item;
- }
- return last;
- }
-
- /**
- * 鑾峰彇鏄惁鍏佽妫�鏌ュ牭濉炵殑閰嶇疆
- */
- private boolean getFakeAllowCheckBlock() {
- boolean fakeAllowCheckBlock = true;
- Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
- if (systemConfigMapObj != null) {
- HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
- String value = systemConfigMap.get("fakeAllowCheckBlock");
- if (value != null && !value.equals("Y")) {
- fakeAllowCheckBlock = false;
- }
- }
- return fakeAllowCheckBlock;
}
@Override
@@ -330,44 +143,476 @@
return new byte[0];
}
+ private boolean isDirectMoveCommand(StationCommand command) {
+ if (command == null || command.getCommandType() != StationCommandType.MOVE) {
+ return false;
+ }
+ List<Integer> path = command.getNavigatePath();
+ return (path == null || path.isEmpty()) && command.getStationId() != null
+ && command.getStationId().equals(command.getTargetStaNo());
+ }
+
+ private void handleDirectMoveCommand(Integer deviceNo, StationCommand command) {
+ Integer taskNo = command.getTaskNo();
+ Integer stationId = command.getStationId();
+ Integer targetStationId = command.getTargetStaNo();
+ if (taskNo != null && taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId != null
+ && stationId.equals(targetStationId)) {
+ generateStationData(deviceNo, taskNo, stationId, targetStationId);
+ }
+
+ TaskRuntimeContext context = new TaskRuntimeContext(taskNo, getThreadImpl(deviceNo));
+ context.startStationId = stationId;
+ context.currentStationId = stationId;
+ context.finalTargetStationId = targetStationId;
+ context.initialized = true;
+ context.status = STATUS_RUNNING;
+ context.appendStitchedPath(Arrays.asList(stationId));
+ context.addPassedStation(stationId);
+ context.generateBarcode = checkTaskNoInArea(taskNo);
+
+ traceEvent(deviceNo, context, "MOVE_INIT", "鍚岀珯鐐逛换鍔$洿鎺ュ埌浣�", buildDetails("stationId", stationId), false);
+ if (context.generateBarcode) {
+ generateStationBarcode(taskNo, stationId, deviceNo);
+ }
+ traceEvent(deviceNo, context, "ARRIVED", "浠诲姟宸插湪璧风偣绔欑偣瀹屾垚", buildDetails("barcodeGenerated",
+ context.generateBarcode, "stationId", stationId), false);
+ context.status = STATUS_FINISHED;
+ traceEvent(deviceNo, context, "TASK_END", "浠诲姟鎵ц瀹屾垚", buildDetails("reason", STATUS_FINISHED), true);
+ }
+
+ private void runTaskLoop(Integer deviceNo, Integer taskNo) {
+ TaskRuntimeContext context = new TaskRuntimeContext(taskNo, getThreadImpl(deviceNo));
+ try {
+ while (true) {
+ if (Thread.currentThread().isInterrupted()) {
+ if (!isTerminalStatus(context.status)) {
+ context.status = STATUS_CANCELLED;
+ }
+ break;
+ }
+
+ if (hasTaskReset(taskNo)) {
+ context.status = STATUS_CANCELLED;
+ break;
+ }
+
+ BlockingQueue<StationCommand> commandQueue = taskQueues.get(taskNo);
+ if (commandQueue == null) {
+ break;
+ }
+
+ StationCommand command = commandQueue.poll(100, TimeUnit.MILLISECONDS);
+ if (command != null) {
+ taskLastUpdateTime.put(taskNo, System.currentTimeMillis());
+ context.lastCommandAt = System.currentTimeMillis();
+ handleIncomingSegment(deviceNo, context, command);
+ }
+
+ if (!context.pendingPathQueue.isEmpty()) {
+ if (!context.initialized || context.currentStationId == null) {
+ initializeTaskPosition(deviceNo, context);
+ continue;
+ }
+
+ if (!executeNextMove(deviceNo, context)) {
+ break;
+ }
+ continue;
+ }
+
+ if (handleIdleState(deviceNo, context)) {
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ if (!isTerminalStatus(context.status)) {
+ context.status = STATUS_CANCELLED;
+ }
+ } finally {
+ taskQueues.remove(taskNo);
+ taskLastUpdateTime.remove(taskNo);
+ taskRunning.remove(taskNo);
+
+ if (!isTerminalStatus(context.status)) {
+ context.status = STATUS_FINISHED;
+ }
+ traceEvent(deviceNo, context, "TASK_END", "浠诲姟鎵ц缁撴潫骞舵竻鐞嗚祫婧�",
+ buildDetails("reason", context.status), true);
+ News.info("[WCS Debug] 浠诲姟{}鎵ц缁撴潫骞舵竻鐞嗚祫婧愶紝鐘舵��={}", taskNo, context.status);
+ }
+ }
+
+ private void handleIncomingSegment(Integer deviceNo, TaskRuntimeContext context, StationCommand command) {
+ List<Integer> newPath = normalizePath(command.getNavigatePath());
+ Integer lastInQueue = getLastInQueue(context.pendingPathQueue);
+ int startIndex = getPathAppendStartIndex(newPath, context.currentStationId, lastInQueue);
+
+ context.setStartStationIdIfAbsent(command.getStationId());
+ if (!context.generateBarcode && checkTaskNoInArea(context.taskNo)) {
+ context.generateBarcode = true;
+ }
+
+ traceEvent(deviceNo, context, "SEGMENT_RECEIVED", "鏀跺埌鏂扮殑璺緞鍒嗘鍛戒护",
+ buildDetails("segmentPath", newPath, "appendStartIndex", startIndex, "currentStationId",
+ context.currentStationId, "queueTailStationId", lastInQueue, "commandStationId",
+ command.getStationId(), "commandTargetStationId", command.getTargetStaNo()),
+ false);
+
+ Integer commandTargetStationId = command.getTargetStaNo();
+ if (commandTargetStationId != null) {
+ if (!commandTargetStationId.equals(context.finalTargetStationId)) {
+ traceEvent(deviceNo, context, "TARGET_SWITCHED",
+ "浠诲姟鐩爣绔欏彂鐢熷垏鎹�: " + context.finalTargetStationId + " -> " + commandTargetStationId,
+ buildDetails("fromTargetStationId", context.finalTargetStationId, "toTargetStationId",
+ commandTargetStationId),
+ false);
+ context.arrivalHandled = false;
+ }
+ context.finalTargetStationId = commandTargetStationId;
+ syncCurrentStationTarget(context.taskNo, context.currentStationId, context.finalTargetStationId);
+ }
+
+ if (!newPath.isEmpty() && startIndex < 0) {
+ traceEvent(deviceNo, context, "SEGMENT_IGNORED", "璺緞鍒嗘鏃犳硶涓庡綋鍓嶈繍琛屼笂涓嬫枃琛旀帴锛屽凡蹇界暐",
+ buildDetails("segmentPath", newPath, "currentStationId", context.currentStationId,
+ "queueTailStationId", lastInQueue, "ignoreReason", "PATH_NOT_CONNECTED"),
+ false);
+ context.latestAppendedPath.clear();
+ return;
+ }
+
+ List<Integer> appendedPath = new ArrayList<Integer>();
+ for (int i = startIndex; i < newPath.size(); i++) {
+ Integer stationId = newPath.get(i);
+ context.pendingPathQueue.offer(stationId);
+ appendedPath.add(stationId);
+ }
+ context.appendStitchedPath(appendedPath);
+
+ if (!appendedPath.isEmpty()) {
+ traceEvent(deviceNo, context, "SEGMENT_APPENDED",
+ "璺緞鍒嗘宸茶拷鍔犲埌寰呮墽琛岄槦鍒楋紝闃熷垪闀垮害=" + context.pendingPathQueue.size(),
+ buildDetails("segmentPath", newPath, "appendedPath", appendedPath, "appendStartIndex",
+ startIndex, "queueSize", context.pendingPathQueue.size()),
+ false);
+ }
+ }
+
+ private void initializeTaskPosition(Integer deviceNo, TaskRuntimeContext context) {
+ Integer nextStationId = context.pendingPathQueue.peek();
+ if (nextStationId == null) {
+ return;
+ }
+
+ if (context.currentStationId == null) {
+ Integer actualCurrentStationId = findCurrentStationIdByTask(context.taskNo);
+ if (actualCurrentStationId != null) {
+ context.currentStationId = actualCurrentStationId;
+ context.initialized = true;
+ context.status = STATUS_RUNNING;
+ context.blockedStationId = null;
+
+ Integer actualDeviceNo = getDeviceNoByStationId(actualCurrentStationId);
+ if (actualDeviceNo != null) {
+ clearRunBlock(actualCurrentStationId, actualDeviceNo);
+ }
+
+ trimPendingPathToCurrent(context.pendingPathQueue, actualCurrentStationId);
+ if (actualCurrentStationId.equals(context.pendingPathQueue.peek())) {
+ context.pendingPathQueue.poll();
+ }
+
+ context.addPassedStation(actualCurrentStationId);
+ context.lastStepAt = System.currentTimeMillis();
+ traceEvent(deviceNo, context, "MOVE_INIT", "浠诲姟浠庡綋鍓嶅疄闄呯珯鐐规仮澶嶆墽琛�",
+ buildDetails("stationId", actualCurrentStationId, "recovered", true), false);
+ return;
+ }
+ }
+
+ context.currentStationId = nextStationId;
+ Integer currentDeviceNo = getDeviceNoByStationId(context.currentStationId);
+ if (currentDeviceNo == null) {
+ context.pendingPathQueue.poll();
+ return;
+ }
+
+ boolean result = initStationMove(context.taskNo, context.currentStationId, currentDeviceNo, context.taskNo,
+ context.finalTargetStationId, true, null);
+ if (!result) {
+ sleep(200);
+ return;
+ }
+
+ context.initialized = true;
+ context.status = STATUS_RUNNING;
+ context.pendingPathQueue.poll();
+ context.addPassedStation(context.currentStationId);
+ context.lastStepAt = System.currentTimeMillis();
+ traceEvent(deviceNo, context, "MOVE_INIT", "浠诲姟鍒濆鍖栬捣鐐圭珯鐐�",
+ buildDetails("stationId", context.currentStationId, "recovered", false), false);
+ sleep(500);
+ }
+
+ private boolean executeNextMove(Integer deviceNo, TaskRuntimeContext context) {
+ Integer nextStationId = context.pendingPathQueue.peek();
+ if (nextStationId == null || context.currentStationId == null) {
+ return true;
+ }
+
+ Integer currentDeviceNo = getDeviceNoByStationId(context.currentStationId);
+ Integer nextDeviceNo = getDeviceNoByStationId(nextStationId);
+ if (currentDeviceNo == null || nextDeviceNo == null) {
+ context.pendingPathQueue.poll();
+ return true;
+ }
+
+ boolean moveSuccess = stationMoveToNext(context.taskNo, context.currentStationId, currentDeviceNo,
+ nextStationId, nextDeviceNo, context.taskNo, context.finalTargetStationId);
+ if (moveSuccess) {
+ Integer previousStationId = context.currentStationId;
+ context.currentStationId = nextStationId;
+ context.pendingPathQueue.poll();
+ context.addPassedStation(nextStationId);
+ context.arrivalHandled = false;
+ context.blockedStationId = null;
+ context.status = STATUS_RUNNING;
+ context.lastStepAt = System.currentTimeMillis();
+ traceEvent(deviceNo, context, "MOVE_STEP_OK", "浠诲姟瀹屾垚涓�姝ョ珯鐐圭Щ鍔�",
+ buildDetails("fromStationId", previousStationId, "toStationId", nextStationId,
+ "remainingPendingPath", context.getPendingStationIds()),
+ false);
+ sleep(1000);
+ return true;
+ }
+
+ if (!checkTaskNoInArea(context.taskNo) && getFakeAllowCheckBlock()
+ && System.currentTimeMillis() - context.lastStepAt > getFakeRunBlockTimeoutMs()) {
+ boolean blocked = runBlockStation(context.taskNo, context.currentStationId, currentDeviceNo, context.taskNo,
+ context.currentStationId);
+ if (blocked) {
+ context.blockedStationId = context.currentStationId;
+ context.status = STATUS_BLOCKED;
+ context.pendingPathQueue.clear();
+ traceEvent(deviceNo, context, "RUN_BLOCKED", "浠诲姟鍦ㄥ綋鍓嶇珯鐐硅鏍囪涓哄牭濉�",
+ buildDetails("blockedStationId", context.currentStationId), false);
+ return false;
+ }
+ }
+
+ sleep(500);
+ return true;
+ }
+
+ private boolean handleIdleState(Integer deviceNo, TaskRuntimeContext context) {
+ if (context.currentStationId != null && context.finalTargetStationId != null
+ && context.currentStationId.equals(context.finalTargetStationId)) {
+ if (!context.arrivalHandled) {
+ boolean barcodeGenerated = false;
+ if (context.generateBarcode) {
+ Integer targetDeviceNo = getDeviceNoByStationId(context.finalTargetStationId);
+ if (targetDeviceNo != null) {
+ barcodeGenerated = generateStationBarcode(context.taskNo, context.finalTargetStationId,
+ targetDeviceNo);
+ }
+ }
+ context.arrivalHandled = true;
+ traceEvent(deviceNo, context, "ARRIVED", "浠诲姟鍒拌揪鏈�缁堢洰鏍囩珯鐐�",
+ buildDetails("stationId", context.currentStationId, "barcodeGenerated", barcodeGenerated),
+ false);
+ }
+ context.status = STATUS_FINISHED;
+ return true;
+ }
+
+ Long lastTime = taskLastUpdateTime.get(context.taskNo);
+ if (lastTime != null && System.currentTimeMillis() - lastTime > WAIT_SEGMENT_TIMEOUT_MS) {
+ context.status = STATUS_TIMEOUT;
+ traceEvent(deviceNo, context, "WAIT_TIMEOUT", "绛夊緟鏂扮殑璺緞鍒嗘瓒呮椂",
+ buildDetails("timeoutMs", WAIT_SEGMENT_TIMEOUT_MS, "currentStationId", context.currentStationId,
+ "targetStationId", context.finalTargetStationId),
+ false);
+ return true;
+ }
+ return false;
+ }
+
+ private List<Integer> normalizePath(List<Integer> path) {
+ List<Integer> result = new ArrayList<Integer>();
+ if (path == null) {
+ return result;
+ }
+ for (Integer stationId : path) {
+ if (stationId != null) {
+ result.add(stationId);
+ }
+ }
+ return result;
+ }
+
+ private void trimPendingPathToCurrent(LinkedBlockingQueue<Integer> queue, Integer currentStationId) {
+ if (queue == null || currentStationId == null || queue.isEmpty()) {
+ return;
+ }
+ List<Integer> snapshot = new ArrayList<Integer>(queue);
+ int index = snapshot.indexOf(currentStationId);
+ if (index <= 0) {
+ return;
+ }
+ for (int i = 0; i < index; i++) {
+ queue.poll();
+ }
+ }
+
+ private boolean hasTaskReset(Integer taskNo) {
+ if (redisUtil == null || taskNo == null) {
+ return false;
+ }
+ Object cancel = redisUtil.get(RedisKeyType.DEVICE_STATION_MOVE_RESET.key + taskNo);
+ return cancel != null;
+ }
+
+ private Integer getLastInQueue(LinkedBlockingQueue<Integer> queue) {
+ Integer last = null;
+ for (Integer item : queue) {
+ last = item;
+ }
+ return last;
+ }
+
+ private int getPathAppendStartIndex(List<Integer> newPath, Integer currentStationId, Integer lastInQueue) {
+ if (newPath == null || newPath.isEmpty()) {
+ return 0;
+ }
+
+ if (lastInQueue != null) {
+ int idx = newPath.lastIndexOf(lastInQueue);
+ if (idx >= 0) {
+ return idx + 1;
+ }
+ }
+
+ if (currentStationId != null) {
+ int idx = newPath.lastIndexOf(currentStationId);
+ if (idx >= 0) {
+ return idx + 1;
+ }
+ return -1;
+ }
+
+ if (lastInQueue != null) {
+ return -1;
+ }
+
+ return 0;
+ }
+
+ private void syncCurrentStationTarget(Integer taskNo, Integer currentStationId, Integer targetStationId) {
+ if (currentStationId == null || targetStationId == null) {
+ return;
+ }
+ Integer currentDeviceNo = getDeviceNoByStationId(currentStationId);
+ if (currentDeviceNo == null) {
+ return;
+ }
+
+ lockStations(currentStationId);
+ try {
+ List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentDeviceNo);
+ if (statusList == null) {
+ return;
+ }
+
+ ZyStationStatusEntity currentStatus = statusList.stream()
+ .filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
+ if (currentStatus == null) {
+ return;
+ }
+
+ if (currentStatus.getTaskNo() != null && currentStatus.getTaskNo() > 0
+ && !currentStatus.getTaskNo().equals(taskNo) && currentStatus.isLoading()) {
+ return;
+ }
+
+ updateStationDataInternal(currentStationId, currentDeviceNo, taskNo, targetStationId, null, null, null);
+ } finally {
+ unlockStations(currentStationId);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean getFakeAllowCheckBlock() {
+ boolean fakeAllowCheckBlock = true;
+ Object systemConfigMapObj = redisUtil == null ? null : redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+ if (systemConfigMapObj instanceof Map) {
+ Map<String, String> systemConfigMap = (Map<String, String>) systemConfigMapObj;
+ String value = systemConfigMap.get("fakeAllowCheckBlock");
+ if (value != null && !"Y".equals(value)) {
+ fakeAllowCheckBlock = false;
+ }
+ }
+ return fakeAllowCheckBlock;
+ }
+
+ private long getFakeRunBlockTimeoutMs() {
+ long timeoutMs = DEFAULT_FAKE_RUN_BLOCK_TIMEOUT_MS;
+ Object systemConfigMapObj = redisUtil == null ? null : redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+ if (systemConfigMapObj instanceof Map) {
+ Map<?, ?> systemConfigMap = (Map<?, ?>) systemConfigMapObj;
+ Object value = systemConfigMap.get("fakeRunBlockTimeoutMs");
+ if (value != null) {
+ try {
+ long parsed = Long.parseLong(String.valueOf(value).trim());
+ if (parsed > 0) {
+ timeoutMs = parsed;
+ }
+ } catch (Exception ignore) {
+ }
+ }
+ }
+ return timeoutMs;
+ }
+
private void handleCommand(Integer deviceNo, StationCommand command) {
News.info("[WCS Debug] 绔欑偣浠跨湡妯℃嫙(V3)宸插惎鍔紝鍛戒护鏁版嵁={}", JSON.toJSONString(command));
Integer taskNo = command.getTaskNo();
Integer stationId = command.getStationId();
Integer targetStationId = command.getTargetStaNo();
- boolean generateBarcode = false;
if (command.getCommandType() == StationCommandType.RESET) {
resetStation(deviceNo, stationId);
return;
}
- if (checkTaskNoInArea(taskNo)) {
- generateBarcode = true;
- }
-
if (command.getCommandType() == StationCommandType.WRITE_INFO) {
+ if (command.getBarcode() != null) {
+ updateStationBarcode(deviceNo, stationId, command.getBarcode());
+ return;
+ }
if (taskNo == 9998 && targetStationId == 0) {
- // 鐢熸垚鍑哄簱绔欑偣浠跨湡鏁版嵁
generateFakeOutStationData(deviceNo, stationId);
return;
}
}
- if (taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId == targetStationId) {
+ if (taskNo != null && taskNo > 0 && taskNo != 9999 && taskNo != 9998 && stationId != null
+ && stationId.equals(targetStationId)) {
generateStationData(deviceNo, taskNo, stationId, targetStationId);
}
- // 娉ㄦ剰锛歁OVE 绫诲瀷鐨勫懡浠ょ幇宸插湪 sendCommand 涓鐞嗭紝handleCommand 浠呭鐞嗛潪 MOVE 鍛戒护
}
private void generateFakeOutStationData(Integer deviceNo, Integer stationId) {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
+ if (statusList == null) {
+ return;
+ }
ZyStationStatusEntity status = statusList.stream()
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
if (status == null) {
return;
}
-
synchronized (status) {
status.setLoading(true);
}
@@ -375,12 +620,14 @@
private void generateStationData(Integer deviceNo, Integer taskNo, Integer stationId, Integer targetStationId) {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
+ if (statusList == null) {
+ return;
+ }
ZyStationStatusEntity status = statusList.stream()
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
if (status == null) {
return;
}
-
synchronized (status) {
status.setTaskNo(taskNo);
status.setTargetStaNo(targetStationId);
@@ -389,12 +636,14 @@
private void resetStation(Integer deviceNo, Integer stationId) {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
+ if (statusList == null) {
+ return;
+ }
ZyStationStatusEntity status = statusList.stream()
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
if (status == null) {
return;
}
-
synchronized (status) {
status.setTaskNo(0);
status.setLoading(false);
@@ -402,17 +651,30 @@
}
}
- // segmentedPathCommand 鏂规硶宸插垹闄わ紝鍔熻兘宸叉暣鍚堝埌 runTaskLoop
+ private void updateStationBarcode(Integer deviceNo, Integer stationId, String barcode) {
+ List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
+ if (statusList == null) {
+ return;
+ }
+ ZyStationStatusEntity status = statusList.stream()
+ .filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
+ if (status == null) {
+ return;
+ }
+ synchronized (status) {
+ status.setBarcode(barcode);
+ }
+ }
private Integer getDeviceNoByStationId(Integer stationId) {
- for (Integer devNo : deviceStatusMap.keySet()) {
- List<ZyStationStatusEntity> list = deviceStatusMap.get(devNo);
+ for (Map.Entry<Integer, List<ZyStationStatusEntity>> entry : deviceStatusMap.entrySet()) {
+ List<ZyStationStatusEntity> list = entry.getValue();
if (list == null) {
continue;
}
- for (ZyStationStatusEntity e : list) {
- if (e.getStationId() != null && e.getStationId().equals(stationId)) {
- return devNo;
+ for (ZyStationStatusEntity entity : list) {
+ if (entity.getStationId() != null && entity.getStationId().equals(stationId)) {
+ return entry.getKey();
}
}
}
@@ -420,21 +682,18 @@
}
private Integer findCurrentStationIdByTask(Integer taskNo) {
- for (Integer devNo : deviceStatusMap.keySet()) {
- List<ZyStationStatusEntity> list = deviceStatusMap.get(devNo);
+ for (List<ZyStationStatusEntity> list : deviceStatusMap.values()) {
if (list == null) {
continue;
}
- for (ZyStationStatusEntity e : list) {
- if (e.getTaskNo() != null && e.getTaskNo().equals(taskNo) && e.isLoading()) {
- return e.getStationId();
+ for (ZyStationStatusEntity entity : list) {
+ if (entity.getTaskNo() != null && entity.getTaskNo().equals(taskNo) && entity.isLoading()) {
+ return entity.getStationId();
}
}
}
return null;
}
-
- // stationMoveByPathIds 鏂规硶宸插垹闄わ紝鍔熻兘宸叉暣鍚堝埌 runTaskLoop
private void sleep(long ms) {
try {
@@ -444,16 +703,10 @@
}
}
- /**
- * 鑾峰彇绔欑偣閿侊紝濡傛灉涓嶅瓨鍦ㄥ垯鍒涘缓
- */
private ReentrantLock getStationLock(Integer stationId) {
- return stationLocks.computeIfAbsent(stationId, k -> new ReentrantLock());
+ return stationLocks.computeIfAbsent(stationId, key -> new ReentrantLock());
}
- /**
- * 鎸夐『搴忛攣瀹氬涓珯鐐癸紙閬垮厤姝婚攣锛�
- */
private void lockStations(Integer... stationIds) {
Integer[] sorted = Arrays.copyOf(stationIds, stationIds.length);
Arrays.sort(sorted);
@@ -462,9 +715,6 @@
}
}
- /**
- * 鎸夐�嗗簭瑙i攣澶氫釜绔欑偣
- */
private void unlockStations(Integer... stationIds) {
Integer[] sorted = Arrays.copyOf(stationIds, stationIds.length);
Arrays.sort(sorted);
@@ -473,19 +723,14 @@
}
}
- /**
- * 鏇存柊绔欑偣鏁版嵁锛堣皟鐢ㄥ墠蹇呴』宸叉寔鏈夎绔欑偣鐨勯攣锛�
- */
private boolean updateStationDataInternal(Integer stationId, Integer deviceNo, Integer taskNo, Integer targetStaNo,
Boolean isLoading, String barcode, Boolean runBlock) {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
if (statusList == null) {
return false;
}
-
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
-
if (currentStatus == null) {
return false;
}
@@ -493,28 +738,21 @@
if (taskNo != null) {
currentStatus.setTaskNo(taskNo);
}
-
if (targetStaNo != null) {
currentStatus.setTargetStaNo(targetStaNo);
}
-
if (isLoading != null) {
currentStatus.setLoading(isLoading);
}
-
if (barcode != null) {
currentStatus.setBarcode(barcode);
}
-
if (runBlock != null) {
currentStatus.setRunBlock(runBlock);
}
return true;
}
- /**
- * 鍒濆鍖栫珯鐐圭Щ鍔紙浣跨敤绔欑偣绾ч攣锛�
- */
public boolean initStationMove(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo,
Integer taskNo, Integer targetStationId, Boolean isLoading, String barcode) {
lockStations(currentStationId);
@@ -523,18 +761,14 @@
if (statusList == null) {
return false;
}
-
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
-
if (currentStatus == null) {
return false;
}
-
- if (currentStatus.getTaskNo() > 0) {
- if (!currentStatus.getTaskNo().equals(taskNo) && currentStatus.isLoading()) {
- return false;
- }
+ if (currentStatus.getTaskNo() != null && currentStatus.getTaskNo() > 0
+ && !currentStatus.getTaskNo().equals(taskNo) && currentStatus.isLoading()) {
+ return false;
}
return updateStationDataInternal(currentStationId, currentStationDeviceNo, taskNo, targetStationId,
@@ -544,35 +778,24 @@
}
}
- /**
- * 绔欑偣绉诲姩鍒颁笅涓�涓綅缃紙浣跨敤绔欑偣绾ч攣锛屾寜ID椤哄簭鑾峰彇閿侀伩鍏嶆閿侊級
- */
public boolean stationMoveToNext(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo,
Integer nextStationId, Integer nextStationDeviceNo, Integer taskNo, Integer targetStaNo) {
- // 鍚屾椂閿佸畾褰撳墠绔欑偣鍜屼笅涓�涓珯鐐癸紙鎸塈D椤哄簭锛岄伩鍏嶆閿侊級
lockStations(currentStationId, nextStationId);
try {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo);
- if (statusList == null) {
- return false;
- }
-
List<ZyStationStatusEntity> nextStatusList = deviceStatusMap.get(nextStationDeviceNo);
- if (nextStatusList == null) {
+ if (statusList == null || nextStatusList == null) {
return false;
}
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
-
ZyStationStatusEntity nextStatus = nextStatusList.stream()
.filter(item -> item.getStationId().equals(nextStationId)).findFirst().orElse(null);
-
if (currentStatus == null || nextStatus == null) {
return false;
}
-
- if (nextStatus.getTaskNo() > 0 || nextStatus.isLoading()) {
+ if (nextStatus.getTaskNo() != null && nextStatus.getTaskNo() > 0 || nextStatus.isLoading()) {
return false;
}
@@ -581,53 +804,35 @@
if (!result) {
return false;
}
-
- boolean result2 = updateStationDataInternal(currentStationId, currentStationDeviceNo, 0, 0, false, "",
- false);
- if (!result2) {
- return false;
- }
-
- return true;
+ return updateStationDataInternal(currentStationId, currentStationDeviceNo, 0, 0, false, "", false);
} finally {
unlockStations(currentStationId, nextStationId);
}
}
- /**
- * 鐢熸垚绔欑偣鏉$爜锛堜娇鐢ㄧ珯鐐圭骇閿侊級
- */
- public boolean generateStationBarcode(Integer lockTaskNo, Integer currentStationId,
- Integer currentStationDeviceNo) {
+ public boolean generateStationBarcode(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo) {
lockStations(currentStationId);
try {
List<ZyStationStatusEntity> statusList = deviceStatusMap.get(currentStationDeviceNo);
if (statusList == null) {
return false;
}
-
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
-
if (currentStatus == null) {
return false;
}
Random random = new Random();
-
String barcodeTime = String.valueOf(System.currentTimeMillis());
String barcode = String.valueOf(random.nextInt(10)) + String.valueOf(random.nextInt(10))
+ barcodeTime.substring(7);
-
return updateStationDataInternal(currentStationId, currentStationDeviceNo, null, null, null, barcode, null);
} finally {
unlockStations(currentStationId);
}
}
- /**
- * 娓呴櫎绔欑偣鏁版嵁锛堜娇鐢ㄧ珯鐐圭骇閿侊級
- */
public boolean clearStation(Integer deviceNo, Integer lockTaskNo, Integer currentStationId) {
lockStations(currentStationId);
try {
@@ -635,23 +840,17 @@
if (statusList == null) {
return false;
}
-
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
-
if (currentStatus == null) {
return false;
}
-
return updateStationDataInternal(currentStationId, deviceNo, 0, 0, false, "", false);
} finally {
unlockStations(currentStationId);
}
}
- /**
- * 鏍囪绔欑偣鍫靛锛堜娇鐢ㄧ珯鐐圭骇閿侊級
- */
public boolean runBlockStation(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo,
Integer taskNo, Integer blockStationId) {
lockStations(currentStationId);
@@ -660,14 +859,11 @@
if (statusList == null) {
return false;
}
-
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(currentStationId)).findFirst().orElse(null);
-
if (currentStatus == null) {
return false;
}
-
return updateStationDataInternal(currentStationId, currentStationDeviceNo, taskNo, blockStationId, true, "",
true);
} finally {
@@ -675,9 +871,6 @@
}
}
- /**
- * 娓呴櫎绔欑偣鍫靛鏍囪锛堝牭濉炴仮澶嶆椂浣跨敤锛�
- */
public void clearRunBlock(Integer stationId, Integer deviceNo) {
lockStations(stationId);
try {
@@ -685,14 +878,11 @@
if (statusList == null) {
return;
}
-
ZyStationStatusEntity currentStatus = statusList.stream()
.filter(item -> item.getStationId().equals(stationId)).findFirst().orElse(null);
-
if (currentStatus == null) {
return;
}
-
if (currentStatus.isRunBlock()) {
currentStatus.setRunBlock(false);
News.info("[WCS Debug] 绔欑偣{}鍫靛鏍囪宸叉竻闄�", stationId);
@@ -703,6 +893,10 @@
}
private boolean checkTaskNoInArea(Integer taskNo) {
+ if (taskNo == null || redisUtil == null) {
+ return false;
+ }
+
Object fakeTaskNoAreaObj = redisUtil.get(RedisKeyType.FAKE_TASK_NO_AREA.key);
if (fakeTaskNoAreaObj == null) {
return false;
@@ -711,11 +905,127 @@
JSONObject data = JSON.parseObject(String.valueOf(fakeTaskNoAreaObj));
Integer start = data.getInteger("start");
Integer end = data.getInteger("end");
+ if (start == null || end == null) {
+ return false;
+ }
+ return taskNo >= start && taskNo <= end;
+ }
- if (taskNo >= start && taskNo <= end) {
- return true;
+ private Map<String, Object> buildDetails(Object... keyValues) {
+ Map<String, Object> details = new LinkedHashMap<String, Object>();
+ if (keyValues == null) {
+ return details;
+ }
+ for (int i = 0; i + 1 < keyValues.length; i += 2) {
+ Object key = keyValues[i];
+ if (key != null) {
+ details.put(String.valueOf(key), keyValues[i + 1]);
+ }
+ }
+ return details;
+ }
+
+ private void traceEvent(Integer deviceNo, TaskRuntimeContext context, String eventType, String message,
+ Map<String, Object> details, boolean terminal) {
+ if (context == null || context.taskNo == null) {
+ return;
+ }
+ try {
+ FakeTaskTraceRegistry registry = SpringUtils.getBean(FakeTaskTraceRegistry.class);
+ if (registry == null) {
+ return;
+ }
+ registry.record(context.taskNo, context.threadImpl != null ? context.threadImpl : getThreadImpl(deviceNo),
+ context.status, context.startStationId, context.currentStationId, context.finalTargetStationId,
+ context.blockedStationId, context.getStitchedPathStationIds(), context.getPassedStationIds(),
+ context.getPendingStationIds(), context.getLatestAppendedPath(), eventType, message, details,
+ terminal);
+ } catch (Exception ignore) {
+ }
+ }
+
+ private String getThreadImpl(Integer deviceNo) {
+ DeviceConfig deviceConfig = deviceConfigMap.get(deviceNo);
+ return deviceConfig == null ? "" : deviceConfig.getThreadImpl();
+ }
+
+ private boolean isTerminalStatus(String status) {
+ return STATUS_BLOCKED.equals(status) || STATUS_CANCELLED.equals(status) || STATUS_TIMEOUT.equals(status)
+ || STATUS_FINISHED.equals(status);
+ }
+
+ private static class TaskRuntimeContext {
+
+ private final Integer taskNo;
+ private final String threadImpl;
+ private final LinkedBlockingQueue<Integer> pendingPathQueue = new LinkedBlockingQueue<Integer>();
+ private final List<Integer> stitchedPathStationIds = new ArrayList<Integer>();
+ private final List<Integer> passedStationIds = new ArrayList<Integer>();
+ private final List<Integer> latestAppendedPath = new ArrayList<Integer>();
+
+ private Integer startStationId;
+ private Integer currentStationId;
+ private Integer finalTargetStationId;
+ private Integer blockedStationId;
+ private boolean generateBarcode;
+ private boolean initialized;
+ private boolean arrivalHandled;
+ private long lastStepAt = System.currentTimeMillis();
+ private long lastCommandAt = System.currentTimeMillis();
+ private String status = STATUS_WAITING;
+
+ private TaskRuntimeContext(Integer taskNo, String threadImpl) {
+ this.taskNo = taskNo;
+ this.threadImpl = threadImpl;
}
- return false;
+ private void setStartStationIdIfAbsent(Integer stationId) {
+ if (startStationId == null && stationId != null) {
+ startStationId = stationId;
+ }
+ }
+
+ private void appendStitchedPath(List<Integer> path) {
+ latestAppendedPath.clear();
+ if (path == null) {
+ return;
+ }
+ for (Integer stationId : path) {
+ if (stationId == null) {
+ continue;
+ }
+ latestAppendedPath.add(stationId);
+ if (stitchedPathStationIds.isEmpty()
+ || !stationId.equals(stitchedPathStationIds.get(stitchedPathStationIds.size() - 1))) {
+ stitchedPathStationIds.add(stationId);
+ }
+ }
+ }
+
+ private void addPassedStation(Integer stationId) {
+ if (stationId == null) {
+ return;
+ }
+ if (passedStationIds.isEmpty()
+ || !stationId.equals(passedStationIds.get(passedStationIds.size() - 1))) {
+ passedStationIds.add(stationId);
+ }
+ }
+
+ private List<Integer> getPendingStationIds() {
+ return new ArrayList<Integer>(pendingPathQueue);
+ }
+
+ private List<Integer> getPassedStationIds() {
+ return new ArrayList<Integer>(passedStationIds);
+ }
+
+ private List<Integer> getStitchedPathStationIds() {
+ return new ArrayList<Integer>(stitchedPathStationIds);
+ }
+
+ private List<Integer> getLatestAppendedPath() {
+ return new ArrayList<Integer>(latestAppendedPath);
+ }
}
}
--
Gitblit v1.9.1