#
Junjie
1 天以前 95a193eef12a217076be6ba280190b3104daf967
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<>();
    }
}