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/main/java/com/zy/core/utils/CrnOperateProcessUtils.java |  472 +++++++++++++++++++++++++---------------------------------
 1 files changed, 204 insertions(+), 268 deletions(-)

diff --git a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
index eb997b1..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;
             }
@@ -217,215 +225,6 @@
         return wrkMast != null
                 && Integer.valueOf(WrkIoType.OUT.id).equals(wrkMast.getIoType())
                 && !Cools.isEmpty(wrkMast.getBatch());
-    }
-
-    private synchronized boolean crnExecuteIn(BasCrnp basCrnp, CrnThread crnThread) {
-        CrnProtocol crnProtocol = crnThread.getStatus();
-        if(crnProtocol == null){
-            return false;
-        }
-
-        if(!basCrnp.getInEnable().equals("Y")){
-            News.info("鍫嗗灈鏈�:{} 鍙叆淇″彿涓嶆弧瓒�", basCrnp.getCrnNo());
-            return false;
-        }
-
-        List<StationObjModel> inStationList = basCrnp.getInStationList$();
-        if(inStationList.isEmpty()){
-            News.info("鍫嗗灈鏈�:{} 鍏ュ簱绔欑偣鏈缃�", basCrnp.getCrnNo());
-            return false;
-        }
-
-        Integer crnNo = basCrnp.getCrnNo();
-
-        for (StationObjModel stationObjModel : inStationList) {
-            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
-            if (stationThread == null) {
-                continue;
-            }
-
-            Map<Integer, StationProtocol> stationProtocolMap = stationThread.getStatusMap();
-            StationProtocol stationProtocol = stationProtocolMap.get(stationObjModel.getStationId());
-            if (stationProtocol == null) {
-                continue;
-            }
-
-            if (!stationProtocol.isAutoing()) {
-                continue;
-            }
-
-            if (!stationProtocol.isLoading()) {
-                continue;
-            }
-
-            if (stationProtocol.getTaskNo() <= 0) {
-                continue;
-            }
-
-            if (!stationProtocol.isInEnable()) {
-                News.taskInfo(stationProtocol.getTaskNo(), "鍙栬揣绔欑偣:{} 娌℃湁鍙叆淇″彿", stationObjModel.getStationId());
-                continue;
-            }
-
-            // 鑾峰彇浠诲姟
-            WrkMast wrkMast = wrkMastService.selectByWorkNo(stationProtocol.getTaskNo());
-            if (null == wrkMast) {
-                News.taskInfo(stationProtocol.getTaskNo(), "宸ヤ綔鍙�:{} 浠诲姟淇℃伅涓嶅瓨鍦�", stationProtocol.getTaskNo());
-                continue;
-            }
-
-            if (!wrkMast.getCrnNo().equals(basCrnp.getCrnNo())) {
-                continue;
-            }
-
-            if(wrkMast.getWrkSts() != WrkStsType.INBOUND_STATION_RUN_COMPLETE.sts){
-                continue;
-            }
-
-            // 鑾峰彇搴撲綅淇℃伅
-            LocMast locMast = locMastService.getById(wrkMast.getLocNo());
-            if (locMast == null) {
-                News.taskInfo(wrkMast.getWrkNo(), "鐩爣搴撲綅:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getLocNo());
-                continue;
-            }
-
-            if (!locMast.getLocSts().equals("S")) {
-                News.taskInfo(wrkMast.getWrkNo(), "鐩爣搴撲綅:{} 鐘舵�佸紓甯�", wrkMast.getLocNo());
-                continue;
-            }
-
-            //妫�娴嬫祬搴撲綅鐘舵��
-            boolean checkStatus = checkShallowLocStatus(locMast.getLocNo(), wrkMast.getWrkNo());
-            if (!checkStatus) {
-                News.taskInfo(wrkMast.getWrkNo(), "鍥犳祬搴撲綅鍫靛鏃犳硶鎵ц");
-                continue;
-            }
-
-            String sourceLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev());
-
-            CrnCommand command = crnThread.getPickAndPutCommand(sourceLocNo, wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
-
-            Date now = new Date();
-            wrkMast.setWrkSts(WrkStsType.INBOUND_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, command));
-                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_RUN, null);
-                News.info("鍫嗗灈鏈哄懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", crnNo, JSON.toJSON(command));
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private synchronized boolean crnExecuteOut(BasCrnp basCrnp, CrnThread crnThread) {
-        CrnProtocol crnProtocol = crnThread.getStatus();
-        if(crnProtocol == null){
-            return false;
-        }
-
-        if(!basCrnp.getOutEnable().equals("Y")){
-            News.info("鍫嗗灈鏈�:{} 鍙嚭淇″彿涓嶆弧瓒�", basCrnp.getCrnNo());
-            return false;
-        }
-
-        List<StationObjModel> outStationList = basCrnp.getOutStationList$();
-        if(outStationList.isEmpty()){
-            News.info("鍫嗗灈鏈�:{} 鍑哄簱绔欑偣鏈缃�", basCrnp.getCrnNo());
-            return false;
-        }
-
-        if (isOutboundStationTaskLimitReached()) {
-            return false;
-        }
-
-        Integer crnNo = basCrnp.getCrnNo();
-
-        List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
-                .eq("crn_no", crnNo)
-                .eq("wrk_sts", WrkStsType.NEW_OUTBOUND.sts)
-                .orderBy(true, true, "batch_seq")
-        );
-
-        for (WrkMast wrkMast : wrkMasts) {
-            if (isOutboundTargetStationTaskLimitReached(wrkMast)) {
-                continue;
-            }
-            if (!allowBatchOutboundExecute(wrkMast)) {
-                continue;
-            }
-            for (StationObjModel stationObjModel : outStationList) {
-                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
-                if (stationThread == null) {
-                    continue;
-                }
-
-                Map<Integer, StationProtocol> stationProtocolMap = stationThread.getStatusMap();
-                StationProtocol stationProtocol = stationProtocolMap.get(stationObjModel.getStationId());
-                if (stationProtocol == null) {
-                    continue;
-                }
-
-                if (!stationProtocol.isAutoing()) {
-                    continue;
-                }
-
-                if (stationProtocol.isLoading()) {
-                    continue;
-                }
-
-                if (stationProtocol.getTaskNo() != 0) {
-                    continue;
-                }
-
-                if (isRequireOutboundStationOutEnable() && !stationProtocol.isOutEnable()) {
-                    News.taskInfo(wrkMast.getWrkNo(), "鏀捐揣绔欑偣:{} 娌℃湁鍙嚭淇″彿", stationObjModel.getStationId());
-                    continue;
-                }
-
-                // 鑾峰彇搴撲綅淇℃伅
-                LocMast locMast = locMastService.getById(wrkMast.getSourceLocNo());
-                if (locMast == null) {
-                    News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getSourceLocNo());
-                    continue;
-                }
-
-                if (!locMast.getLocSts().equals("R")) {
-                    News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 鐘舵�佸紓甯�", wrkMast.getSourceLocNo());
-                    continue;
-                }
-
-                //妫�娴嬫祬搴撲綅鐘舵��
-                boolean checkStatus = checkShallowLocStatus(locMast.getLocNo(), wrkMast.getWrkNo());
-                if (!checkStatus) {
-                    News.taskInfo(wrkMast.getWrkNo(), "鍥犳祬搴撲綅鍫靛鏃犳硶鎵ц");
-                    continue;
-                }
-
-                String targetLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev());
-
-                CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), targetLocNo, wrkMast.getWrkNo(), crnNo);
-
-                Date now = new Date();
-                wrkMast.setWrkSts(WrkStsType.OUTBOUND_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, command));
-                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_RUN, null);
-                    News.info("鍫嗗灈鏈哄懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", crnNo, JSON.toJSON(command));
-                    return true;
-                }
-            }
-        }
-        return false;
     }
 
     private synchronized boolean crnExecuteInPlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
@@ -808,63 +607,6 @@
         return defaultValue;
     }
 
-    private synchronized boolean crnExecuteLocTransfer(BasCrnp basCrnp, CrnThread crnThread) {
-        CrnProtocol crnProtocol = crnThread.getStatus();
-        if(crnProtocol == null){
-            return false;
-        }
-
-        Integer crnNo = basCrnp.getCrnNo();
-
-        List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
-                .eq("crn_no", crnNo)
-                .eq("wrk_sts", WrkStsType.NEW_LOC_MOVE.sts)
-        );
-
-        for (WrkMast wrkMast : wrkMasts) {
-            // 鑾峰彇婧愬簱浣嶄俊鎭�
-            LocMast sourceLocMast = locMastService.getById(wrkMast.getSourceLocNo());
-            if (sourceLocMast == null) {
-                News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getSourceLocNo());
-                continue;
-            }
-
-            if(!sourceLocMast.getLocSts().equals("R")){
-                News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 鐘舵�佸紓甯革紝涓嶅睘浜庡嚭搴撻绾︾姸鎬�", wrkMast.getSourceLocNo());
-                continue;
-            }
-            
-            // 鑾峰彇搴撲綅淇℃伅
-            LocMast locMast = locMastService.getById(wrkMast.getLocNo());
-            if (locMast == null) {
-                News.taskInfo(wrkMast.getWrkNo(), "搴撲綅:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getLocNo());
-                continue;
-            }
-
-            if (!locMast.getLocSts().equals("S")) {
-                News.taskInfo(wrkMast.getWrkNo(), "搴撲綅:{} 鐘舵�佸紓甯革紝涓嶅睘浜庡叆搴撻绾︾姸鎬�", wrkMast.getLocNo());
-                continue;
-            }
-
-            CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
-
-            Date now = new Date();
-            wrkMast.setWrkSts(WrkStsType.LOC_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, command));
-                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_RUN, null);
-                News.info("鍫嗗灈鏈哄懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", crnNo, JSON.toJSON(command));
-                return true;
-            }
-        }
-        return false;
-    }
-
     //鍫嗗灈鏈轰换鍔℃墽琛屽畬鎴�
     public synchronized void crnIoExecuteFinish() {
         List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
@@ -921,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;
@@ -943,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()) {
@@ -962,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;
@@ -1093,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";
@@ -1155,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;
+    }
+
 }

--
Gitblit v1.9.1