package com.zy.core.network.fake; import com.zy.asrs.entity.BasCrnp; import com.zy.asrs.entity.BasDevp; import com.zy.asrs.entity.BasDualCrnp; import com.zy.asrs.service.BasCrnpService; import com.zy.asrs.service.BasDevpService; import com.zy.asrs.service.BasDualCrnpService; import com.zy.core.News; import com.zy.core.enums.RedisKeyType; import com.zy.core.model.StationObjModel; import com.zy.core.network.entity.ZyStationStatusEntity; import com.zy.common.utils.RedisUtil; import com.core.common.SpringUtils; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * 仿真堵塞管理器 * 管理 fakeBlockedStations 集合,并通过 FakeStationStateManager 统一维护站点 runBlock 状态 * 提供堵塞判定配置读取(fakeAllowCheckBlock、fakeRunBlockTimeoutMs) */ public class FakeStationBlockManager { private static final long DEFAULT_FAKE_RUN_BLOCK_TIMEOUT_MS = 20000L; // 仿真内部堵塞站点集合,用于仿真侧快速判定 // 站点 runBlock 仍通过 FakeStationStateManager 统一写入,避免绕过集中状态管理 private final Set fakeBlockedStations = ConcurrentHashMap.newKeySet(); private final FakeStationStateManager stateManager; public FakeStationBlockManager(FakeStationStateManager stateManager) { this.stateManager = stateManager; } public boolean isBlocked(Integer stationId) { return stationId != null && fakeBlockedStations.contains(stationId); } public void markBlocked(Integer stationId) { if (stationId != null) { fakeBlockedStations.add(stationId); } } public void clearBlocked(Integer stationId) { if (stationId != null) { fakeBlockedStations.remove(stationId); } } /** * 标记站点为堵塞状态 * 仿真场景也同步设置 runBlock=true,确保堵塞重算路径、更换库位等业务逻辑可生效。 */ public boolean runBlockStation(Integer lockTaskNo, Integer currentStationId, Integer currentStationDeviceNo, Integer taskNo, Integer blockStationId) { boolean updated = stateManager.updateStationDataInternal( currentStationId, currentStationDeviceNo, taskNo, blockStationId, true, "", true); if (updated) { fakeBlockedStations.add(currentStationId); stateManager.publishTaskLocation(taskNo, currentStationDeviceNo, currentStationId, true, true); News.info("[WCS Debug] 仿真站点堵塞上报,站点号={},设备号={},任务号={},阻塞目标站={},runBlock=true", currentStationId, currentStationDeviceNo, taskNo, blockStationId); } return updated; } /** * 清除站点堵塞状态 * 同时清除内部 fakeBlockedStations,并通过 FakeStationStateManager 统一清除 runBlock 标记 */ public void clearRunBlock(Integer stationId, Integer deviceNo) { ZyStationStatusEntity status = stateManager.findStationStatus(deviceNo, stationId); if (status == null) { fakeBlockedStations.remove(stationId); return; } if (status.isRunBlock()) { stateManager.updateStationDataInternal(stationId, deviceNo, null, null, null, null, false); stateManager.syncTaskLocation(deviceNo, stationId); News.info("[WCS Debug] 站点{}堵塞标记已清除", stationId); } fakeBlockedStations.remove(stationId); } public boolean isSpecialStation(Integer stationId) { if (stationId == null) { return false; } Set specialStationIds = new HashSet<>(); BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class); List basDevps = basDevpService.list(); for (BasDevp basDevp : basDevps) { for (StationObjModel station : basDevp.getInStationList$()) { specialStationIds.add(station.getStationId()); } for (StationObjModel station : basDevp.getOutStationList$()) { specialStationIds.add(station.getStationId()); } for (StationObjModel station : basDevp.getBarcodeStationList$()) { specialStationIds.add(station.getStationId()); } } BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class); List basCrnps = basCrnpService.list(); for (BasCrnp basCrnp : basCrnps) { for (StationObjModel station : basCrnp.getInStationList$()) { specialStationIds.add(station.getStationId()); } for (StationObjModel station : basCrnp.getOutStationList$()) { specialStationIds.add(station.getStationId()); } } BasDualCrnpService basDualCrnpService = SpringUtils.getBean(BasDualCrnpService.class); List basDualCrnps = basDualCrnpService.list(); for (BasDualCrnp basDualCrnp : basDualCrnps) { for (StationObjModel station : basDualCrnp.getInStationList$()) { specialStationIds.add(station.getStationId()); } for (StationObjModel station : basDualCrnp.getOutStationList$()) { specialStationIds.add(station.getStationId()); } } return specialStationIds.contains(stationId); } @SuppressWarnings("unchecked") public boolean getFakeAllowCheckBlock(RedisUtil redisUtil) { boolean fakeAllowCheckBlock = true; Object systemConfigMapObj = redisUtil == null ? null : redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); if (systemConfigMapObj instanceof Map) { Map systemConfigMap = (Map) systemConfigMapObj; String value = systemConfigMap.get("fakeAllowCheckBlock"); if (value != null && !"Y".equals(value)) { fakeAllowCheckBlock = false; } } return fakeAllowCheckBlock; } public long getFakeRunBlockTimeoutMs(RedisUtil redisUtil) { long timeoutMs = DEFAULT_FAKE_RUN_BLOCK_TIMEOUT_MS; Object systemConfigMapObj = redisUtil == null ? null : redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key); if (systemConfigMapObj instanceof Map) { Map systemConfigMap = (Map) systemConfigMapObj; Object value = systemConfigMap.get("fakeRunBlockTimeoutMs"); if (value != null) { try { long parsed = Long.parseLong(String.valueOf(value).trim()); if (parsed > 0) { timeoutMs = parsed; } } catch (Exception ignore) { } } } return timeoutMs; } }