From 2bba23eb20021363fbc70535a8dd09e3314ae0d5 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 04 三月 2026 17:10:10 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java |  157 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 157 insertions(+), 0 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..493238d 100644
--- a/src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/StationCycleCapacityServiceImpl.java
@@ -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());
 
@@ -92,6 +97,7 @@
         int loopNo = 1;
         int totalStationCount = 0;
         int taskStationCount = 0;
+        Set<Integer> actualWorkNoSet = new HashSet<>();
 
         for (Set<Integer> scc : sccList) {
             if (!isCycleScc(scc, filteredGraph)) {
@@ -111,6 +117,7 @@
                     if (workNo != null && workNo > 0) {
                         workNoList.add(workNo);
                         currentLoopTaskCount++;
+                        actualWorkNoSet.add(workNo);
                     }
                 }
 
@@ -128,6 +135,9 @@
             }
         }
 
+        int reserveTaskCount = mergeReserveTaskCount(loopList, actualWorkNoSet);
+        taskStationCount += reserveTaskCount;
+
         StationCycleCapacityVo vo = new StationCycleCapacityVo();
         vo.setLoopList(loopList);
         vo.setLoopCount(loopList.size());
@@ -138,6 +148,153 @@
         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;
+            loopVo.setTaskCount(mergedTaskCount);
+            loopVo.setCurrentLoad(calcCurrentLoad(mergedTaskCount, 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) {
         if (stationCount <= 0 || taskCount <= 0) {
             return 0.0;

--
Gitblit v1.9.1