| | |
| | | persistState(state); |
| | | } |
| | | |
| | | public void updateLoopHint(Integer taskNo, |
| | | Boolean loopAlertActive, |
| | | String loopAlertType, |
| | | String loopAlertText, |
| | | Integer loopAlertCount, |
| | | Map<String, Object> details) { |
| | | ensureCacheLoaded(); |
| | | TraceTaskState state = taskStateMap.get(taskNo); |
| | | if (state == null) { |
| | | return; |
| | | } |
| | | state.updateLoopHint(loopAlertActive, loopAlertType, loopAlertText, loopAlertCount, details); |
| | | persistState(state); |
| | | } |
| | | |
| | | public List<StationTaskTraceVo> listLatestTraces() { |
| | | ensureCacheLoaded(); |
| | | cleanupExpired(); |
| | |
| | | private List<StationTaskTraceSegmentVo> segmentList = new ArrayList<>(); |
| | | private Integer issuedSegmentCount; |
| | | private Integer totalSegmentCount; |
| | | private Boolean loopAlertActive; |
| | | private String loopAlertType; |
| | | private String loopAlertText; |
| | | private Integer loopAlertCount; |
| | | private Long updatedAt; |
| | | private Long terminalExpireAt; |
| | | private List<StationTaskTraceEventVo> events = new ArrayList<>(); |
| | |
| | | private List<StationTaskTraceSegmentVo> segmentList = new ArrayList<>(); |
| | | private Integer issuedSegmentCount = 0; |
| | | private Integer totalSegmentCount = 0; |
| | | private Boolean loopAlertActive = Boolean.FALSE; |
| | | private String loopAlertType; |
| | | private String loopAlertText; |
| | | private Integer loopAlertCount; |
| | | private final List<StationTaskTraceEventVo> events = new ArrayList<>(); |
| | | private Long updatedAt = System.currentTimeMillis(); |
| | | private Long terminalExpireAt; |
| | |
| | | List<Integer> localPathStationIds, |
| | | List<StationTaskTraceSegmentVo> localSegmentList) { |
| | | TraceRegistration registration = new TraceRegistration(); |
| | | boolean firstPlan = this.traceVersion == null || this.traceVersion <= 0; |
| | | boolean rerouted = !isTerminalStatus(this.status) && this.traceVersion != null && this.traceVersion > 0; |
| | | int nextTraceVersion = rerouted ? this.traceVersion + 1 : 1; |
| | | int pathOffset = rerouted ? this.passedStationIds.size() : 0; |
| | |
| | | this.latestIssuedSegmentPath = new ArrayList<>(); |
| | | this.status = rerouted ? STATUS_REROUTED : STATUS_WAITING; |
| | | this.terminalExpireAt = null; |
| | | if (firstPlan) { |
| | | clearLoopHintState(); |
| | | } |
| | | rebuildProgress(planCurrentStationId); |
| | | this.updatedAt = System.currentTimeMillis(); |
| | | |
| | |
| | | details.put("segmentCount", this.totalSegmentCount); |
| | | details.put("pathOffset", pathOffset); |
| | | details.put("currentStationId", this.currentStationId); |
| | | appendLoopHintDetails(details); |
| | | appendEvent(rerouted ? "REROUTED" : "PLAN_READY", |
| | | rerouted ? "输送任务路径已重算并续接轨迹" : "输送任务分段计划已建立", |
| | | details); |
| | |
| | | } |
| | | this.status = terminalStatus; |
| | | this.blockedStationId = blockedStationId; |
| | | if (shouldClearPathOnTerminal(terminalStatus)) { |
| | | clearPathState(); |
| | | } |
| | | this.updatedAt = System.currentTimeMillis(); |
| | | this.terminalExpireAt = this.updatedAt + TERMINAL_KEEP_MS; |
| | | |
| | |
| | | appendEvent(eventType, message, nextDetails); |
| | | } |
| | | |
| | | private void clearPathState() { |
| | | this.fullPathStationIds = new ArrayList<>(); |
| | | this.issuedStationIds = new ArrayList<>(); |
| | | this.passedStationIds = new ArrayList<>(); |
| | | this.pendingStationIds = new ArrayList<>(); |
| | | this.latestIssuedSegmentPath = new ArrayList<>(); |
| | | this.segmentList = new ArrayList<>(); |
| | | this.issuedSegmentCount = 0; |
| | | this.totalSegmentCount = 0; |
| | | } |
| | | private synchronized void updateLoopHint(Boolean loopAlertActive, |
| | | String loopAlertType, |
| | | String loopAlertText, |
| | | Integer loopAlertCount, |
| | | Map<String, Object> details) { |
| | | boolean active = Boolean.TRUE.equals(loopAlertActive) |
| | | && loopAlertCount != null |
| | | && loopAlertCount > 1 |
| | | && loopAlertText != null |
| | | && !loopAlertText.trim().isEmpty(); |
| | | String nextType = active ? loopAlertType : null; |
| | | String nextText = active ? loopAlertText.trim() : null; |
| | | Integer nextCount = active ? loopAlertCount : null; |
| | | boolean changed = !Objects.equals(this.loopAlertActive, active) |
| | | || !Objects.equals(this.loopAlertType, nextType) |
| | | || !Objects.equals(this.loopAlertText, nextText) |
| | | || !Objects.equals(this.loopAlertCount, nextCount); |
| | | if (!changed) { |
| | | return; |
| | | } |
| | | |
| | | private boolean shouldClearPathOnTerminal(String terminalStatus) { |
| | | return STATUS_BLOCKED.equals(terminalStatus) |
| | | || STATUS_CANCELLED.equals(terminalStatus); |
| | | this.loopAlertActive = active; |
| | | this.loopAlertType = nextType; |
| | | this.loopAlertText = nextText; |
| | | this.loopAlertCount = nextCount; |
| | | this.updatedAt = System.currentTimeMillis(); |
| | | if (!active) { |
| | | return; |
| | | } |
| | | |
| | | Map<String, Object> nextDetails = copyDetails(details); |
| | | nextDetails.put("loopAlertActive", Boolean.TRUE); |
| | | nextDetails.put("loopAlertType", this.loopAlertType); |
| | | nextDetails.put("loopAlertText", this.loopAlertText); |
| | | nextDetails.put("loopAlertCount", this.loopAlertCount); |
| | | appendEvent("LOOP_REPEAT_ALERT", this.loopAlertText, nextDetails); |
| | | } |
| | | |
| | | private synchronized boolean shouldRemove(long now) { |
| | |
| | | vo.setSegmentList(copySegmentListWithIssued(segmentList, issuedSegmentCount)); |
| | | vo.setIssuedSegmentCount(issuedSegmentCount); |
| | | vo.setTotalSegmentCount(totalSegmentCount); |
| | | vo.setLoopAlertActive(loopAlertActive); |
| | | vo.setLoopAlertType(loopAlertType); |
| | | vo.setLoopAlertText(loopAlertText); |
| | | vo.setLoopAlertCount(loopAlertCount); |
| | | vo.setUpdatedAt(updatedAt); |
| | | vo.setEvents(copyEventList(events)); |
| | | return vo; |
| | |
| | | snapshot.setSegmentList(copySegmentList(segmentList)); |
| | | snapshot.setIssuedSegmentCount(issuedSegmentCount); |
| | | snapshot.setTotalSegmentCount(totalSegmentCount); |
| | | snapshot.setLoopAlertActive(loopAlertActive); |
| | | snapshot.setLoopAlertType(loopAlertType); |
| | | snapshot.setLoopAlertText(loopAlertText); |
| | | snapshot.setLoopAlertCount(loopAlertCount); |
| | | snapshot.setUpdatedAt(updatedAt); |
| | | snapshot.setTerminalExpireAt(terminalExpireAt); |
| | | snapshot.setEvents(copyEventList(events)); |
| | |
| | | state.segmentList = copySegmentList(snapshot.getSegmentList()); |
| | | state.issuedSegmentCount = snapshot.getIssuedSegmentCount() == null ? 0 : snapshot.getIssuedSegmentCount(); |
| | | state.totalSegmentCount = snapshot.getTotalSegmentCount() == null ? state.segmentList.size() : snapshot.getTotalSegmentCount(); |
| | | state.loopAlertActive = Boolean.TRUE.equals(snapshot.getLoopAlertActive()); |
| | | state.loopAlertType = snapshot.getLoopAlertType(); |
| | | state.loopAlertText = snapshot.getLoopAlertText(); |
| | | state.loopAlertCount = snapshot.getLoopAlertCount(); |
| | | state.updatedAt = snapshot.getUpdatedAt() == null ? System.currentTimeMillis() : snapshot.getUpdatedAt(); |
| | | state.terminalExpireAt = snapshot.getTerminalExpireAt(); |
| | | state.events.clear(); |
| | |
| | | this.pendingStationIds = copyIntegerList(fullPath.subList(currentIndex + 1, fullPath.size())); |
| | | } |
| | | |
| | | private void clearLoopHintState() { |
| | | this.loopAlertActive = Boolean.FALSE; |
| | | this.loopAlertType = null; |
| | | this.loopAlertText = null; |
| | | this.loopAlertCount = null; |
| | | } |
| | | |
| | | private void appendLoopHintDetails(Map<String, Object> details) { |
| | | if (details == null || !Boolean.TRUE.equals(this.loopAlertActive) || this.loopAlertCount == null || this.loopAlertCount <= 1) { |
| | | return; |
| | | } |
| | | details.put("loopAlertActive", Boolean.TRUE); |
| | | details.put("loopAlertType", this.loopAlertType); |
| | | details.put("loopAlertText", this.loopAlertText); |
| | | details.put("loopAlertCount", this.loopAlertCount); |
| | | } |
| | | |
| | | private boolean acceptTraceVersion(Integer incomingTraceVersion) { |
| | | return incomingTraceVersion != null |
| | | && this.traceVersion != null |