| | |
| | | import com.zy.asrs.domain.vo.StationTaskTraceEventVo; |
| | | import com.zy.asrs.domain.vo.StationTaskTraceSegmentVo; |
| | | import com.zy.asrs.domain.vo.StationTaskTraceVo; |
| | | import com.zy.asrs.entity.WrkMast; |
| | | import com.zy.asrs.service.WrkMastService; |
| | | import com.zy.common.utils.RedisUtil; |
| | | import com.zy.core.enums.WrkStsType; |
| | | import com.zy.core.model.command.StationCommand; |
| | | import com.zy.core.enums.RedisKeyType; |
| | | import lombok.Data; |
| | |
| | | |
| | | @Autowired |
| | | private RedisUtil redisUtil; |
| | | |
| | | @Autowired |
| | | private WrkMastService wrkMastService; |
| | | |
| | | private final Map<Integer, TraceTaskState> taskStateMap = new ConcurrentHashMap<>(); |
| | | private volatile boolean loadedFromRedis = false; |
| | |
| | | public List<StationTaskTraceVo> listLatestTraces() { |
| | | ensureCacheLoaded(); |
| | | cleanupExpired(); |
| | | reconcileInactiveBusinessTasks(); |
| | | List<StationTaskTraceVo> result = new ArrayList<>(); |
| | | for (TraceTaskState state : taskStateMap.values()) { |
| | | if (state != null) { |
| | |
| | | return result; |
| | | } |
| | | |
| | | public List<StationTaskTraceVo> listActiveTraces() { |
| | | List<StationTaskTraceVo> latestTraces = listLatestTraces(); |
| | | List<StationTaskTraceVo> result = new ArrayList<>(); |
| | | for (StationTaskTraceVo traceVo : latestTraces) { |
| | | if (traceVo == null) { |
| | | continue; |
| | | } |
| | | String status = traceVo.getStatus(); |
| | | if (STATUS_WAITING.equals(status) |
| | | || STATUS_RUNNING.equals(status) |
| | | || STATUS_REROUTED.equals(status)) { |
| | | result.add(traceVo); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private void cleanupExpired() { |
| | | long now = System.currentTimeMillis(); |
| | | for (Map.Entry<Integer, TraceTaskState> entry : taskStateMap.entrySet()) { |
| | |
| | | removePersistedState(entry.getKey()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void reconcileInactiveBusinessTasks() { |
| | | if (wrkMastService == null) { |
| | | return; |
| | | } |
| | | for (TraceTaskState state : taskStateMap.values()) { |
| | | if (state == null || state.isTerminal()) { |
| | | continue; |
| | | } |
| | | WrkMast wrkMast; |
| | | try { |
| | | wrkMast = wrkMastService.selectByWorkNo(state.taskNo); |
| | | } catch (Exception ignore) { |
| | | continue; |
| | | } |
| | | if (wrkMast == null) { |
| | | Integer currentStationId = state.currentStationId != null ? state.currentStationId : state.finalTargetStationId; |
| | | Map<String, Object> details = new LinkedHashMap<>(); |
| | | details.put("reason", "wrk_missing"); |
| | | state.markTerminal(state.traceVersion, STATUS_FINISHED, currentStationId, null, |
| | | "AUTO_FINISHED", "输送任务档已不存在,轨迹自动结束", details); |
| | | persistState(state); |
| | | continue; |
| | | } |
| | | if (isStationTraceActiveWrkStatus(wrkMast.getWrkSts())) { |
| | | continue; |
| | | } |
| | | Integer currentStationId = state.currentStationId != null ? state.currentStationId : state.finalTargetStationId; |
| | | Map<String, Object> details = new LinkedHashMap<>(); |
| | | details.put("reason", "wrk_status_transition"); |
| | | details.put("wrkSts", wrkMast.getWrkSts()); |
| | | details.put("wrkStsDesc", wrkMast.getWrkSts$()); |
| | | if (isManualWrkStatus(wrkMast.getWrkSts())) { |
| | | state.markTerminal(state.traceVersion, STATUS_CANCELLED, currentStationId, null, |
| | | "AUTO_CANCELLED", "输送任务已退出运行,轨迹自动结束", details); |
| | | } else { |
| | | state.markTerminal(state.traceVersion, STATUS_FINISHED, currentStationId, null, |
| | | "AUTO_FINISHED", "输送任务已结束,轨迹自动结束", details); |
| | | } |
| | | persistState(state); |
| | | } |
| | | } |
| | | |
| | | private boolean isStationTraceActiveWrkStatus(Long wrkSts) { |
| | | return Objects.equals(wrkSts, WrkStsType.INBOUND_DEVICE_RUN.sts) |
| | | || Objects.equals(wrkSts, WrkStsType.STATION_RUN.sts); |
| | | } |
| | | |
| | | private boolean isManualWrkStatus(Long wrkSts) { |
| | | return Objects.equals(wrkSts, WrkStsType.INBOUND_MANUAL.sts) |
| | | || Objects.equals(wrkSts, WrkStsType.OUTBOUND_MANUAL.sts) |
| | | || Objects.equals(wrkSts, WrkStsType.LOC_MOVE_MANUAL.sts); |
| | | } |
| | | |
| | | private void ensureCacheLoaded() { |
| | |
| | | return terminalExpireAt != null && terminalExpireAt <= now; |
| | | } |
| | | |
| | | private synchronized boolean isTerminal() { |
| | | return isTerminalStatus(this.status); |
| | | } |
| | | |
| | | private synchronized StationTaskTraceVo toVo() { |
| | | StationTaskTraceVo vo = new StationTaskTraceVo(); |
| | | vo.setTaskNo(taskNo); |