From d62f97dabd206364220b74dfa0bb065d4e64dc7b Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期五, 20 三月 2026 18:16:56 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java |  206 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 195 insertions(+), 11 deletions(-)

diff --git a/src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java
index f79dda5..08525e5 100644
--- a/src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java
@@ -2,7 +2,7 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.zy.asrs.domain.vo.StationCycleCapacityVo;
 import com.zy.asrs.domain.vo.StationCycleLoopVo;
 import com.zy.asrs.entity.BasDevp;
@@ -12,8 +12,10 @@
 import com.zy.asrs.service.DeviceConfigService;
 import com.zy.asrs.service.StationCycleCapacityService;
 import com.zy.common.model.NavigateNode;
+import com.zy.common.utils.RedisUtil;
 import com.zy.common.utils.NavigateSolution;
 import com.zy.core.cache.SlaveConnection;
+import com.zy.core.enums.RedisKeyType;
 import com.zy.core.enums.SlaveType;
 import com.zy.core.model.StationObjModel;
 import com.zy.core.model.protocol.StationProtocol;
@@ -37,6 +39,7 @@
 @Service("stationCycleCapacityService")
 @Slf4j
 public class StationCycleCapacityServiceImpl implements StationCycleCapacityService {
+    private static final long LOOP_LOAD_RESERVE_EXPIRE_MILLIS = 120_000L;
 
     @Autowired
     private BasMapService basMapService;
@@ -44,6 +47,8 @@
     private DeviceConfigService deviceConfigService;
     @Autowired
     private BasDevpService basDevpService;
+    @Autowired
+    private RedisUtil redisUtil;
 
     private final AtomicReference<StationCycleCapacityVo> snapshotRef = new AtomicReference<>(new StationCycleCapacityVo());
 
@@ -69,7 +74,9 @@
 
     private StationCycleCapacityVo buildSnapshot() {
         GraphContext context = buildStationGraph();
-        Map<Integer, Integer> workNoMap = buildStationWorkNoMap();
+        StationOccupancyContext occupancyContext = buildStationOccupancyContext();
+        Map<Integer, Integer> workNoMap = occupancyContext.workNoMap;
+        Set<Integer> manualStationSet = occupancyContext.manualStationSet;
 
         Set<Integer> availableStationSet = new HashSet<>(context.graph.keySet());
         availableStationSet.removeAll(context.excludeStationSet);
@@ -92,6 +99,9 @@
         int loopNo = 1;
         int totalStationCount = 0;
         int taskStationCount = 0;
+        int manualStationCount = 0;
+        int occupiedStationCount = 0;
+        Set<Integer> actualWorkNoSet = new HashSet<>();
 
         for (Set<Integer> scc : sccList) {
             if (!isCycleScc(scc, filteredGraph)) {
@@ -106,11 +116,17 @@
 
                 List<Integer> workNoList = new ArrayList<>();
                 int currentLoopTaskCount = 0;
+                int currentLoopManualStationCount = 0;
                 for (Integer stationId : stationIdList) {
                     Integer workNo = workNoMap.get(stationId);
                     if (workNo != null && workNo > 0) {
                         workNoList.add(workNo);
                         currentLoopTaskCount++;
+                        actualWorkNoSet.add(workNo);
+                        continue;
+                    }
+                    if (manualStationSet.contains(stationId)) {
+                        currentLoopManualStationCount++;
                     }
                 }
 
@@ -120,22 +136,181 @@
                 loopVo.setWorkNoList(workNoList);
                 loopVo.setStationCount(stationIdList.size());
                 loopVo.setTaskCount(currentLoopTaskCount);
-                loopVo.setCurrentLoad(calcCurrentLoad(currentLoopTaskCount, stationIdList.size()));
+                loopVo.setManualStationCount(currentLoopManualStationCount);
+                loopVo.setOccupiedStationCount(currentLoopTaskCount + currentLoopManualStationCount);
+                loopVo.setCurrentLoad(calcCurrentLoad(toNonNegative(loopVo.getOccupiedStationCount()), stationIdList.size()));
                 loopList.add(loopVo);
 
                 totalStationCount += stationIdList.size();
                 taskStationCount += currentLoopTaskCount;
+                manualStationCount += currentLoopManualStationCount;
+                occupiedStationCount += toNonNegative(loopVo.getOccupiedStationCount());
             }
         }
+
+        int reserveTaskCount = mergeReserveTaskCount(loopList, actualWorkNoSet);
+        taskStationCount += reserveTaskCount;
+        occupiedStationCount += reserveTaskCount;
 
         StationCycleCapacityVo vo = new StationCycleCapacityVo();
         vo.setLoopList(loopList);
         vo.setLoopCount(loopList.size());
         vo.setTotalStationCount(totalStationCount);
         vo.setTaskStationCount(taskStationCount);
-        vo.setCurrentLoad(calcCurrentLoad(taskStationCount, totalStationCount));
+        vo.setManualStationCount(manualStationCount);
+        vo.setOccupiedStationCount(occupiedStationCount);
+        vo.setCurrentLoad(calcCurrentLoad(occupiedStationCount, totalStationCount));
         vo.setRefreshTime(new Date());
         return vo;
+    }
+
+    private int mergeReserveTaskCount(List<StationCycleLoopVo> loopList, Set<Integer> actualWorkNoSet) {
+        if (loopList == null || loopList.isEmpty()) {
+            return 0;
+        }
+
+        Map<Object, Object> reserveMap = redisUtil.hmget(RedisKeyType.STATION_CYCLE_LOAD_RESERVE.key);
+        if (reserveMap == null || reserveMap.isEmpty()) {
+            return 0;
+        }
+
+        Map<Integer, StationCycleLoopVo> loopMap = new HashMap<>();
+        Map<Integer, StationCycleLoopVo> stationLoopMap = new HashMap<>();
+        for (StationCycleLoopVo loopVo : loopList) {
+            if (loopVo != null && loopVo.getLoopNo() != null) {
+                loopMap.put(loopVo.getLoopNo(), loopVo);
+            }
+            if (loopVo == null || loopVo.getStationIdList() == null) {
+                continue;
+            }
+            for (Integer stationId : loopVo.getStationIdList()) {
+                if (stationId != null) {
+                    stationLoopMap.put(stationId, loopVo);
+                }
+            }
+        }
+
+        long now = System.currentTimeMillis();
+        int mergedCount = 0;
+        List<Object> removeFieldList = new ArrayList<>();
+
+        for (Map.Entry<Object, Object> entry : reserveMap.entrySet()) {
+            ReserveRecord record = parseReserveRecord(entry.getKey(), entry.getValue());
+            if (record == null) {
+                removeFieldList.add(entry.getKey());
+                continue;
+            }
+
+            if (actualWorkNoSet.contains(record.wrkNo)) {
+                removeFieldList.add(entry.getKey());
+                continue;
+            }
+
+            if (record.createTime <= 0 || now - record.createTime > LOOP_LOAD_RESERVE_EXPIRE_MILLIS) {
+                removeFieldList.add(entry.getKey());
+                continue;
+            }
+
+            StationCycleLoopVo loopVo = loopMap.get(record.loopNo);
+            if (loopVo == null && record.hitStationId != null) {
+                loopVo = stationLoopMap.get(record.hitStationId);
+            }
+            if (loopVo == null) {
+                removeFieldList.add(entry.getKey());
+                continue;
+            }
+
+            List<Integer> workNoList = loopVo.getWorkNoList();
+            if (workNoList == null) {
+                workNoList = new ArrayList<>();
+                loopVo.setWorkNoList(workNoList);
+            }
+            if (workNoList.contains(record.wrkNo)) {
+                continue;
+            }
+
+            workNoList.add(record.wrkNo);
+            Collections.sort(workNoList);
+
+            int mergedTaskCount = toNonNegative(loopVo.getTaskCount()) + 1;
+            int mergedOccupiedCount = toNonNegative(loopVo.getOccupiedStationCount()) + 1;
+            loopVo.setTaskCount(mergedTaskCount);
+            loopVo.setOccupiedStationCount(mergedOccupiedCount);
+            loopVo.setCurrentLoad(calcCurrentLoad(mergedOccupiedCount, toNonNegative(loopVo.getStationCount())));
+            mergedCount++;
+        }
+
+        if (!removeFieldList.isEmpty()) {
+            redisUtil.hdel(RedisKeyType.STATION_CYCLE_LOAD_RESERVE.key, removeFieldList.toArray());
+        }
+        return mergedCount;
+    }
+
+    private ReserveRecord parseReserveRecord(Object fieldObj, Object valueObj) {
+        if (fieldObj == null || valueObj == null) {
+            return null;
+        }
+
+        Integer fieldWrkNo = parseInteger(String.valueOf(fieldObj));
+        if (fieldWrkNo == null || fieldWrkNo <= 0) {
+            return null;
+        }
+
+        JSONObject jsonObject;
+        try {
+            jsonObject = JSON.parseObject(String.valueOf(valueObj));
+        } catch (Exception e) {
+            return null;
+        }
+        if (jsonObject == null) {
+            return null;
+        }
+
+        Integer wrkNo = jsonObject.getInteger("wrkNo");
+        Integer loopNo = jsonObject.getInteger("loopNo");
+        Integer hitStationId = jsonObject.getInteger("hitStationId");
+        Long createTime = jsonObject.getLong("createTime");
+        if (wrkNo == null || wrkNo <= 0) {
+            wrkNo = fieldWrkNo;
+        }
+        if ((loopNo == null || loopNo <= 0) && (hitStationId == null || hitStationId <= 0)) {
+            return null;
+        }
+        if (createTime == null || createTime <= 0) {
+            return null;
+        }
+
+        ReserveRecord record = new ReserveRecord();
+        record.wrkNo = wrkNo;
+        record.loopNo = loopNo;
+        record.hitStationId = hitStationId;
+        record.createTime = createTime;
+        return record;
+    }
+
+    private Integer parseInteger(String value) {
+        if (value == null || value.trim().isEmpty()) {
+            return null;
+        }
+        try {
+            return Integer.parseInt(value.trim());
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private int toNonNegative(Integer value) {
+        if (value == null || value < 0) {
+            return 0;
+        }
+        return value;
+    }
+
+    private static class ReserveRecord {
+        private Integer wrkNo;
+        private Integer loopNo;
+        private Integer hitStationId;
+        private Long createTime;
     }
 
     private double calcCurrentLoad(int taskCount, int stationCount) {
@@ -219,7 +394,7 @@
     }
 
     private void appendExcludeStationsFromDeviceConfig(Set<Integer> excludeStationSet) {
-        List<BasDevp> basDevpList = basDevpService.selectList(new EntityWrapper<>());
+        List<BasDevp> basDevpList = basDevpService.list(new QueryWrapper<>());
         if (basDevpList == null || basDevpList.isEmpty()) {
             return;
         }
@@ -259,12 +434,12 @@
                 || (isBarcodeStation != null && isBarcodeStation == 1);
     }
 
-    private Map<Integer, Integer> buildStationWorkNoMap() {
-        Map<Integer, Integer> workNoMap = new HashMap<>();
-        List<DeviceConfig> devpList = deviceConfigService.selectList(new EntityWrapper<DeviceConfig>()
+    private StationOccupancyContext buildStationOccupancyContext() {
+        StationOccupancyContext context = new StationOccupancyContext();
+        List<DeviceConfig> devpList = deviceConfigService.list(new QueryWrapper<DeviceConfig>()
                 .eq("device_type", String.valueOf(SlaveType.Devp)));
         if (devpList == null || devpList.isEmpty()) {
-            return workNoMap;
+            return context;
         }
 
         for (DeviceConfig deviceConfig : devpList) {
@@ -283,11 +458,15 @@
                 }
                 Integer taskNo = protocol.getTaskNo();
                 if (taskNo != null && taskNo > 0) {
-                    workNoMap.put(protocol.getStationId(), taskNo);
+                    context.workNoMap.put(protocol.getStationId(), taskNo);
+                    continue;
+                }
+                if (!protocol.isAutoing()) {
+                    context.manualStationSet.add(protocol.getStationId());
                 }
             }
         }
-        return workNoMap;
+        return context;
     }
 
     private List<Set<Integer>> findStrongConnectedComponents(Map<Integer, Set<Integer>> graph) {
@@ -463,4 +642,9 @@
         private final Map<Integer, Set<Integer>> graph = new HashMap<>();
         private final Set<Integer> excludeStationSet = new HashSet<>();
     }
+
+    private static class StationOccupancyContext {
+        private final Map<Integer, Integer> workNoMap = new HashMap<>();
+        private final Set<Integer> manualStationSet = new HashSet<>();
+    }
 }

--
Gitblit v1.9.1