Junjie
2 天以前 63b01db83d9aad8a15276b4236a9a22e4aeef065
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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<Integer> 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<Integer> specialStationIds = new HashSet<>();
 
        BasDevpService basDevpService = SpringUtils.getBean(BasDevpService.class);
        List<BasDevp> 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<BasCrnp> 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<BasDualCrnp> 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<String, String> systemConfigMap = (Map<String, String>) 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;
    }
}