From 26784989e73fc36c6315e54939d1b13a50eb5020 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期四, 26 三月 2026 21:03:00 +0800
Subject: [PATCH] #

---
 src/test/java/com/zy/core/thread/impl/ZyStationV5ThreadTest.java                   |   60 ++++++++++
 src/main/java/com/zy/core/utils/StationOperateProcessUtils.java                    |   18 ++
 src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java                       |    5 
 src/test/java/com/zy/asrs/controller/StationControllerTest.java                    |   51 ++++++++
 src/main/java/com/zy/core/network/real/ZyStationV4RealConnect.java                 |   38 ++++++
 src/main/java/com/zy/core/thread/impl/ZyStationV5Thread.java                       |   40 ++++++
 src/main/java/com/zy/asrs/controller/StationController.java                        |   23 +++
 src/main/java/com/zy/core/thread/StationThread.java                                |    2 
 src/main/java/com/zy/core/network/ZyStationConnectDriver.java                      |    9 +
 src/main/java/com/zy/core/thread/impl/ZyStationThread.java                         |    5 
 src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java                       |    5 
 src/main/webapp/components/DevpCard.js                                             |    4 
 src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java                |   30 +++++
 src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java |   49 ++++++++
 src/main/java/com/zy/core/network/api/ZyStationConnectApi.java                     |    4 
 15 files changed, 342 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/zy/asrs/controller/StationController.java b/src/main/java/com/zy/asrs/controller/StationController.java
index 2a58b7c..1d3b63d 100644
--- a/src/main/java/com/zy/asrs/controller/StationController.java
+++ b/src/main/java/com/zy/asrs/controller/StationController.java
@@ -133,6 +133,29 @@
         return R.ok();
     }
 
+    @PostMapping("/command/clearPath")
+    public R commandClearPath(@RequestBody StationCommandMoveParam param) {
+        if (Cools.isEmpty(param) || Cools.isEmpty(param.getStationId()) || Cools.isEmpty(param.getTaskNo())) {
+            return R.error("缂哄皯鍙傛暟");
+        }
+
+        StationObjModel finalStation = findStation(param.getStationId());
+        if (finalStation == null) {
+            return R.error("绔欑偣涓嶅瓨鍦�");
+        }
+
+        StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, finalStation.getDeviceNo());
+        if (stationThread == null) {
+            return R.error("绾跨▼涓嶅瓨鍦�");
+        }
+
+        boolean cleared = stationThread.clearPath(param.getTaskNo());
+        if (!cleared) {
+            return R.error("鏈尮閰嶅埌鍙竻鐞嗚矾寰勬垨娓呯悊澶辫触");
+        }
+        return R.ok("娓呯悊璺緞鎴愬姛");
+    }
+
     private StationObjModel findStation(Integer stationId) {
         if (Cools.isEmpty(stationId)) {
             return null;
diff --git a/src/main/java/com/zy/core/network/ZyStationConnectDriver.java b/src/main/java/com/zy/core/network/ZyStationConnectDriver.java
index 9b16ece..184d4af 100644
--- a/src/main/java/com/zy/core/network/ZyStationConnectDriver.java
+++ b/src/main/java/com/zy/core/network/ZyStationConnectDriver.java
@@ -186,6 +186,15 @@
         return connectApi.sendOriginCommand(address, data);
     }
 
+    public boolean clearTaskBufferSlot(Integer stationId, Integer slotIdx) {
+        ZyStationConnectApi connectApi = zyStationConnectApi;
+        if (!connected || connecting || connectApi == null) {
+            return false;
+        }
+        CommandResponse response = connectApi.clearTaskBufferSlot(deviceConfig.getDeviceNo(), stationId, slotIdx);
+        return response != null && Boolean.TRUE.equals(response.getResult());
+    }
+
     public byte[] readOriginCommand(String address, int length) {
         ZyStationConnectApi connectApi = zyStationConnectApi;
         if (!connected || connecting || connectApi == null) {
diff --git a/src/main/java/com/zy/core/network/api/ZyStationConnectApi.java b/src/main/java/com/zy/core/network/api/ZyStationConnectApi.java
index 1212c53..3fef5df 100644
--- a/src/main/java/com/zy/core/network/api/ZyStationConnectApi.java
+++ b/src/main/java/com/zy/core/network/api/ZyStationConnectApi.java
@@ -16,6 +16,10 @@
 
     CommandResponse sendCommand(Integer deviceNo, StationCommand command);//涓嬪彂鍛戒护
 
+    default CommandResponse clearTaskBufferSlot(Integer deviceNo, Integer stationId, Integer slotIdx) {
+        return new CommandResponse(false, "褰撳墠杩炴帴涓嶆敮鎸佹竻鐞嗙紦瀛樺尯妲戒綅");
+    }
+
     CommandResponse sendOriginCommand(String address, short[] data);//鍘熷鍛戒护
 
     byte[] readOriginCommand(String address, int length);//璇诲彇鍘熷鏁版嵁
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 0737eff..efab225 100644
--- a/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
+++ b/src/main/java/com/zy/core/network/fake/ZyStationFakeSegConnect.java
@@ -10,6 +10,7 @@
 import com.zy.core.enums.StationCommandType;
 import com.zy.core.model.CommandResponse;
 import com.zy.core.model.command.StationCommand;
+import com.zy.core.model.protocol.StationTaskBufferItem;
 import com.zy.core.network.api.ZyStationConnectApi;
 import com.zy.core.network.entity.ZyStationStatusEntity;
 
@@ -139,6 +140,35 @@
     }
 
     @Override
+    public CommandResponse clearTaskBufferSlot(Integer deviceNo, Integer stationId, Integer slotIdx) {
+        if (deviceNo == null || stationId == null || slotIdx == null || slotIdx <= 0) {
+            return new CommandResponse(false, "娓呯悊缂撳瓨鍖烘Ы浣嶅弬鏁版棤鏁�");
+        }
+        List<ZyStationStatusEntity> statusList = deviceStatusMap.get(deviceNo);
+        if (statusList == null) {
+            return new CommandResponse(false, "鏈壘鍒拌澶囩姸鎬�");
+        }
+        for (ZyStationStatusEntity status : statusList) {
+            if (status == null || !stationId.equals(status.getStationId())) {
+                continue;
+            }
+            List<StationTaskBufferItem> taskBufferItems = status.getTaskBufferItems();
+            if (taskBufferItems == null || taskBufferItems.isEmpty()) {
+                return new CommandResponse(true, "缂撳瓨鍖烘Ы浣嶅凡涓虹┖");
+            }
+            for (StationTaskBufferItem item : taskBufferItems) {
+                if (item != null && slotIdx.equals(item.getSlotIdx())) {
+                    item.setTaskNo(0);
+                    item.setTargetStaNo(0);
+                    return new CommandResponse(true, "缂撳瓨鍖烘Ы浣嶆竻鐞嗘垚鍔�");
+                }
+            }
+            return new CommandResponse(false, "鏈壘鍒扮紦瀛樺尯妲戒綅");
+        }
+        return new CommandResponse(false, "鏈壘鍒扮珯鐐圭姸鎬�");
+    }
+
+    @Override
     public byte[] readOriginCommand(String address, int length) {
         return new byte[0];
     }
diff --git a/src/main/java/com/zy/core/network/real/ZyStationV4RealConnect.java b/src/main/java/com/zy/core/network/real/ZyStationV4RealConnect.java
index b5a45d8..6e91763 100644
--- a/src/main/java/com/zy/core/network/real/ZyStationV4RealConnect.java
+++ b/src/main/java/com/zy/core/network/real/ZyStationV4RealConnect.java
@@ -274,6 +274,44 @@
     }
 
     @Override
+    public CommandResponse clearTaskBufferSlot(Integer deviceNo, Integer stationId, Integer slotIdx) {
+        CommandResponse commandResponse = new CommandResponse(false);
+        if (stationId == null) {
+            commandResponse.setMessage("绔欑偣鍙蜂负绌�");
+            return commandResponse;
+        }
+        if (slotIdx == null || slotIdx <= 0 || slotIdx > TASK_AREA_SLOT_COUNT) {
+            commandResponse.setMessage("缂撳瓨鍖烘Ы浣嶆棤鏁�");
+            return commandResponse;
+        }
+
+        getStatus(deviceNo);
+
+        int stationIdx = findIndex(stationId);
+        if (stationIdx < 0) {
+            commandResponse.setMessage("鏈壘鍒扮珯鐐圭姸鎬�");
+            return commandResponse;
+        }
+
+        int slotBaseOffset = stationIdx * TASK_AREA_LENGTH + slotIdx * TASK_AREA_SLOT_SIZE;
+        CommandResponse clearTaskNo = sendOriginCommand("DB13." + slotBaseOffset, new short[]{0, 0});
+        if (clearTaskNo == null || !Boolean.TRUE.equals(clearTaskNo.getResult())) {
+            commandResponse.setMessage(clearTaskNo == null ? "娓呯┖浠诲姟鍙峰け璐�" : clearTaskNo.getMessage());
+            return commandResponse;
+        }
+
+        CommandResponse clearTarget = sendOriginCommand("DB13." + (slotBaseOffset + 6), new short[]{0});
+        if (clearTarget == null || !Boolean.TRUE.equals(clearTarget.getResult())) {
+            commandResponse.setMessage(clearTarget == null ? "娓呯┖鐩爣绔欏け璐�" : clearTarget.getMessage());
+            return commandResponse;
+        }
+
+        commandResponse.setResult(true);
+        commandResponse.setMessage("缂撳瓨鍖烘Ы浣嶆竻鐞嗘垚鍔�");
+        return commandResponse;
+    }
+
+    @Override
     public synchronized CommandResponse sendOriginCommand(String address, short[] data) {
         CommandResponse commandResponse = new CommandResponse(false);
         if (null == data || data.length == 0) {
diff --git a/src/main/java/com/zy/core/thread/StationThread.java b/src/main/java/com/zy/core/thread/StationThread.java
index 1e8ee61..c1ca9d4 100644
--- a/src/main/java/com/zy/core/thread/StationThread.java
+++ b/src/main/java/com/zy/core/thread/StationThread.java
@@ -40,6 +40,8 @@
         return getCommand(StationCommandType.MOVE, taskNo, stationId, targetStationId, palletSize, pathLenFactor);
     }
 
+    boolean clearPath(Integer taskNo);
+
     CommandResponse sendCommand(StationCommand command);
 
     CommandResponse sendOriginCommand(String address, short[] data);
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationThread.java b/src/main/java/com/zy/core/thread/impl/ZyStationThread.java
index 2fb578d..249ebbc 100644
--- a/src/main/java/com/zy/core/thread/impl/ZyStationThread.java
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationThread.java
@@ -259,4 +259,9 @@
     public byte[] readOriginCommand(String address, int length) {
         return zyStationConnectDriver.readOriginCommand(address, length);
     }
+
+    @Override
+    public boolean clearPath(Integer taskNo) {
+        return false;
+    }
 }
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java b/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
index bcbe804..9bf0843 100644
--- a/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationV3Thread.java
@@ -480,4 +480,9 @@
         } catch (Exception ignore) {
         }
     }
+
+    @Override
+    public boolean clearPath(Integer taskNo) {
+        return false;
+    }
 }
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java b/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java
index d8ec936..dcd7ae6 100644
--- a/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationV4Thread.java
@@ -563,4 +563,9 @@
         } catch (Exception ignore) {
         }
     }
+
+    @Override
+    public boolean clearPath(Integer taskNo) {
+        return false;
+    }
 }
diff --git a/src/main/java/com/zy/core/thread/impl/ZyStationV5Thread.java b/src/main/java/com/zy/core/thread/impl/ZyStationV5Thread.java
index c0eb09e..d2d97e6 100644
--- a/src/main/java/com/zy/core/thread/impl/ZyStationV5Thread.java
+++ b/src/main/java/com/zy/core/thread/impl/ZyStationV5Thread.java
@@ -28,6 +28,7 @@
 import com.zy.core.model.Task;
 import com.zy.core.model.command.StationCommand;
 import com.zy.core.model.protocol.StationProtocol;
+import com.zy.core.model.protocol.StationTaskBufferItem;
 import com.zy.core.network.DeviceConnectPool;
 import com.zy.core.network.ZyStationConnectDriver;
 import com.zy.core.network.entity.ZyStationStatusEntity;
@@ -354,6 +355,45 @@
     }
 
     @Override
+    public synchronized boolean clearPath(Integer taskNo) {
+        if (taskNo == null || taskNo <= 0) {
+            return false;
+        }
+        if (zyStationConnectDriver == null) {
+            return false;
+        }
+        List<StationProtocol> status = getStatus();
+        if (status == null || status.isEmpty()) {
+            return false;
+        }
+
+        boolean found = false;
+        boolean success = true;
+        for (StationProtocol stationProtocol : status) {
+            List<StationTaskBufferItem> taskBufferItems = stationProtocol == null ? null : stationProtocol.getTaskBufferItems();
+            if (taskBufferItems == null || taskBufferItems.isEmpty()) {
+                continue;
+            }
+            Integer stationId = stationProtocol.getStationId();
+            for (StationTaskBufferItem item : taskBufferItems) {
+                if (item == null || !Objects.equals(taskNo, item.getTaskNo())) {
+                    continue;
+                }
+                found = true;
+                if (!zyStationConnectDriver.clearTaskBufferSlot(stationId, item.getSlotIdx())) {
+                    success = false;
+                    log.warn("杈撻�佺珯缂撳瓨鍖烘畫鐣欒矾寰勬竻鐞嗗け璐ャ�俿tationId={}, slotIdx={}, taskNo={}",
+                            stationId, item.getSlotIdx(), item.getTaskNo());
+                    continue;
+                }
+                item.setTaskNo(0);
+                item.setTargetStaNo(0);
+            }
+        }
+        return found && success;
+    }
+
+    @Override
     public CommandResponse sendCommand(StationCommand command) {
         CommandResponse commandResponse = null;
         try {
diff --git a/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java b/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
index 71153a4..e3ece21 100644
--- a/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -382,10 +382,11 @@
 
                 boolean complete = false;
                 Integer targetDeviceNo = null;
+                StationThread stationThread = null;
                 BasStation basStation = basStationService.getOne(new QueryWrapper<BasStation>().eq("station_id", targetStaNo));
                 if (basStation != null) {
                     targetDeviceNo = basStation.getDeviceNo();
-                    StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
+                    stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
                     if (stationThread != null) {
                         Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
                         StationProtocol stationProtocol = statusMap.get(basStation.getStationId());
@@ -396,6 +397,7 @@
                 }
 
                 if (complete) {
+                    attemptClearTaskPath(stationThread, wrkNo);
                     completeStationRunTask(wrkMast, targetDeviceNo);
                 }
             }
@@ -404,6 +406,20 @@
         }
     }
 
+    private void attemptClearTaskPath(StationThread stationThread, Integer taskNo) {
+        if (stationThread == null || taskNo == null || taskNo <= 0) {
+            return;
+        }
+        try {
+            boolean cleared = stationThread.clearPath(taskNo);
+            if (cleared) {
+                News.info("杈撻�佺珯鐐逛换鍔¤繍琛屽畬鎴愬悗娓呯悊娈嬬暀璺緞锛屽伐浣滃彿={}", taskNo);
+            }
+        } catch (Exception e) {
+            News.error("杈撻�佺珯鐐逛换鍔¤繍琛屽畬鎴愬悗娓呯悊娈嬬暀璺緞寮傚父锛屽伐浣滃彿={}", taskNo, e);
+        }
+    }
+
     private void completeStationRunTask(WrkMast wrkMast, Integer deviceNo) {
         if (wrkMast == null || wrkMast.getWrkNo() == null) {
             return;
diff --git a/src/main/webapp/components/DevpCard.js b/src/main/webapp/components/DevpCard.js
index 118fcdb..77ddc73 100644
--- a/src/main/webapp/components/DevpCard.js
+++ b/src/main/webapp/components/DevpCard.js
@@ -33,6 +33,7 @@
           </label>
           <div class="mc-action-row">
             <button type="button" class="mc-btn" @click="controlCommand">涓嬪彂</button>
+            <button type="button" class="mc-btn mc-btn-soft" @click="clearPathCommand">娓呰矾寰�</button>
             <button type="button" class="mc-btn mc-btn-soft" @click="resetCommand">澶嶄綅</button>
             <button type="button" class="mc-btn mc-btn-ghost" @click="openStationTracePage">杩愯杞ㄨ抗</button>
             <button v-if="showFakeTraceEntry" type="button" class="mc-btn mc-btn-ghost" @click="openFakeTracePage">浠跨湡杞ㄨ抗</button>
@@ -484,6 +485,9 @@
     controlCommand: function () {
       this.postControl("/station/command/move", this.controlParam);
     },
+    clearPathCommand: function () {
+      this.postControl("/station/command/clearPath", this.controlParam);
+    },
     resetCommand: function () {
       this.postControl("/station/command/reset", this.controlParam);
     }
diff --git a/src/test/java/com/zy/asrs/controller/StationControllerTest.java b/src/test/java/com/zy/asrs/controller/StationControllerTest.java
new file mode 100644
index 0000000..5983e47
--- /dev/null
+++ b/src/test/java/com/zy/asrs/controller/StationControllerTest.java
@@ -0,0 +1,51 @@
+package com.zy.asrs.controller;
+
+import com.core.common.R;
+import com.zy.asrs.domain.param.StationCommandMoveParam;
+import com.zy.asrs.entity.BasDevp;
+import com.zy.asrs.service.BasDevpService;
+import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.SlaveType;
+import com.zy.core.thread.StationThread;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+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 StationControllerTest {
+
+    @Test
+    void commandClearPath_callsThreadClearPath() {
+        StationController controller = new StationController();
+        BasDevpService basDevpService = mock(BasDevpService.class);
+        StationThread stationThread = mock(StationThread.class);
+
+        ReflectionTestUtils.setField(controller, "basDevpService", basDevpService);
+
+        BasDevp basDevp = new BasDevp();
+        basDevp.setStationList("[{\"deviceNo\":1,\"stationId\":145}]");
+        when(basDevpService.list(any(com.baomidou.mybatisplus.core.conditions.Wrapper.class)))
+                .thenReturn(Collections.singletonList(basDevp));
+        when(stationThread.clearPath(10335)).thenReturn(true);
+
+        StationCommandMoveParam param = new StationCommandMoveParam();
+        param.setStationId(145);
+        param.setTaskNo(10335);
+
+        SlaveConnection.put(SlaveType.Devp, 1, stationThread);
+        try {
+            R result = controller.commandClearPath(param);
+
+            assertEquals(200, result.get("code"));
+            verify(stationThread).clearPath(10335);
+        } finally {
+            SlaveConnection.remove(SlaveType.Devp, 1);
+        }
+    }
+}
diff --git a/src/test/java/com/zy/core/thread/impl/ZyStationV5ThreadTest.java b/src/test/java/com/zy/core/thread/impl/ZyStationV5ThreadTest.java
new file mode 100644
index 0000000..bb1da07
--- /dev/null
+++ b/src/test/java/com/zy/core/thread/impl/ZyStationV5ThreadTest.java
@@ -0,0 +1,60 @@
+package com.zy.core.thread.impl;
+
+import com.zy.asrs.entity.DeviceConfig;
+import com.zy.common.utils.RedisUtil;
+import com.zy.core.model.protocol.StationProtocol;
+import com.zy.core.model.protocol.StationTaskBufferItem;
+import com.zy.core.network.ZyStationConnectDriver;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ZyStationV5ThreadTest {
+
+    @Test
+    void clearPath_delegatesPureSlotClearingToDriver() {
+        DeviceConfig deviceConfig = new DeviceConfig();
+        deviceConfig.setDeviceNo(1);
+        RedisUtil redisUtil = mock(RedisUtil.class);
+        ZyStationConnectDriver connectDriver = mock(ZyStationConnectDriver.class);
+        when(connectDriver.clearTaskBufferSlot(10, 2)).thenReturn(true);
+
+        ZyStationV5Thread thread = new ZyStationV5Thread(deviceConfig, redisUtil);
+        ReflectionTestUtils.setField(thread, "zyStationConnectDriver", connectDriver);
+
+        StationTaskBufferItem hitItem = new StationTaskBufferItem();
+        hitItem.setSlotIdx(2);
+        hitItem.setTaskNo(100);
+        hitItem.setTargetStaNo(88);
+
+        StationProtocol station20 = new StationProtocol();
+        station20.setStationId(20);
+        station20.setTaskBufferItems(Collections.emptyList());
+
+        StationProtocol station10 = new StationProtocol();
+        station10.setStationId(10);
+        station10.setTaskBufferItems(List.of(hitItem));
+
+        ReflectionTestUtils.setField(thread, "statusList", Arrays.asList(station20, station10));
+
+        boolean result = thread.clearPath(100);
+
+        assertTrue(result);
+        verify(connectDriver).clearTaskBufferSlot(eq(10), eq(2));
+        verify(redisUtil, never()).set(org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.anyLong());
+        verify(redisUtil, never()).del(org.mockito.ArgumentMatchers.any(String[].class));
+        assertEquals(0, hitItem.getTaskNo());
+        assertEquals(0, hitItem.getTargetStaNo());
+    }
+}
diff --git a/src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java b/src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java
index 05f033b..8abda6e 100644
--- a/src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java
+++ b/src/test/java/com/zy/core/utils/StationOperateProcessUtilsReroutePipelineTest.java
@@ -2,8 +2,10 @@
 
 import com.zy.asrs.entity.BasStationOpt;
 import com.zy.asrs.entity.BasDevp;
+import com.zy.asrs.entity.BasStation;
 import com.zy.asrs.entity.WrkMast;
 import com.zy.asrs.service.BasDevpService;
+import com.zy.asrs.service.BasStationService;
 import com.zy.asrs.service.BasStationOptService;
 import com.zy.asrs.service.WrkMastService;
 import com.zy.asrs.service.WrkAnalysisService;
@@ -766,6 +768,53 @@
     }
 
     @Test
+    void stationOutExecuteFinish_attemptsClearPathBeforeCompletingTask() {
+        StationOperateProcessUtils utils = new StationOperateProcessUtils();
+        WrkMastService wrkMastService = mock(WrkMastService.class);
+        BasStationService basStationService = mock(BasStationService.class);
+        WrkAnalysisService wrkAnalysisService = mock(WrkAnalysisService.class);
+        NotifyUtils notifyUtils = mock(NotifyUtils.class);
+        RedisUtil redisUtil = mock(RedisUtil.class);
+        StationMoveCoordinator coordinator = mock(StationMoveCoordinator.class);
+        StationThread stationThread = mock(StationThread.class);
+
+        ReflectionTestUtils.setField(utils, "wrkMastService", wrkMastService);
+        ReflectionTestUtils.setField(utils, "basStationService", basStationService);
+        ReflectionTestUtils.setField(utils, "wrkAnalysisService", wrkAnalysisService);
+        ReflectionTestUtils.setField(utils, "notifyUtils", notifyUtils);
+        ReflectionTestUtils.setField(utils, "redisUtil", redisUtil);
+        ReflectionTestUtils.setField(utils, "stationMoveCoordinator", coordinator);
+
+        WrkMast wrkMast = buildWrkMast(10335, 145);
+        wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
+        when(wrkMastService.list(any(com.baomidou.mybatisplus.core.conditions.Wrapper.class)))
+                .thenReturn(Collections.singletonList(wrkMast));
+        when(wrkMastService.updateById(wrkMast)).thenReturn(true);
+
+        BasStation basStation = new BasStation();
+        basStation.setStationId(145);
+        basStation.setDeviceNo(1);
+        when(basStationService.getOne(any(com.baomidou.mybatisplus.core.conditions.Wrapper.class)))
+                .thenReturn(basStation);
+
+        StationProtocol stationProtocol = buildStationProtocol(145, 10335, 145);
+        when(stationThread.getStatusMap()).thenReturn(Map.of(145, stationProtocol));
+        when(stationThread.clearPath(10335)).thenReturn(true);
+
+        SlaveConnection.put(SlaveType.Devp, 1, stationThread);
+        try {
+            utils.stationOutExecuteFinish();
+
+            verify(stationThread, times(1)).clearPath(10335);
+            verify(coordinator, times(1)).finishSession(10335);
+            verify(wrkMastService, times(1)).updateById(wrkMast);
+            assertEquals(WrkStsType.STATION_RUN_COMPLETE.sts, wrkMast.getWrkSts());
+        } finally {
+            SlaveConnection.remove(SlaveType.Devp, 1);
+        }
+    }
+
+    @Test
     void watchCircleStation_usesSessionArrivalStateWhenLegacyCommandMissing() {
         StationOperateProcessUtils utils = new StationOperateProcessUtils();
         BasDevpService basDevpService = mock(BasDevpService.class);

--
Gitblit v1.9.1