diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java index 3602914db..8648298af 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/CTCLogicLoop.java @@ -1,8 +1,17 @@ package club.joylink.rtss.simulation.cbtc.CTC; +import club.joylink.rtss.constants.ProjectCode; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService; -import club.joylink.rtss.simulation.cbtc.CTC.data.*; -import club.joylink.rtss.simulation.cbtc.CTC.data.vo.*; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcEffectRepository; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog; +import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence; +import club.joylink.rtss.simulation.cbtc.CTC.data.TrackView; +import club.joylink.rtss.simulation.cbtc.CTC.data.vo.BusyBoardVO; +import club.joylink.rtss.simulation.cbtc.CTC.data.vo.CtcStationRunPlanLogVO; +import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RailDispatchCommandVO; +import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RouteSequenceVO; +import club.joylink.rtss.simulation.cbtc.CTC.data.vo.TrackViewVO; import club.joylink.rtss.simulation.cbtc.CTC.rail.dcmd.service.DisCmdSendService; import club.joylink.rtss.simulation.cbtc.CTC.service.CTCService; import club.joylink.rtss.simulation.cbtc.CTC.service.CtcDispatchCommandService; @@ -21,426 +30,464 @@ import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.factory.SocketMessageFactory; import club.joylink.rtss.websocket.StompMessageService; import club.joylink.rtss.websocket.WebSocketMessage; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; -import java.time.LocalDateTime; -import java.util.*; -import java.util.stream.Collectors; - @Slf4j @Component public class CTCLogicLoop { - public static final String LOGIC_NAME = "CTC"; //逻辑循环任务名称 - public static final int LOGIC_RATE = 1000; //逻辑循环频率 - public static final String MESSAGE_NAME = "CTC_MESSAGE"; //消息发送任务名称 - public static final int MESSAGE_RATE = 1000; //消息发送频率 - @Autowired - private StompMessageService stompMessageService; - @Autowired - private CTCService ctcService; - @Autowired - private CtcDispatchCommandService ctcDispatchCommandService; - @Autowired - private DisCmdSendService disCmdService; - @Autowired - private AtsTrainLoadService atsTrainLoadService; + public static final String LOGIC_NAME = "CTC"; //逻辑循环任务名称 + public static final int LOGIC_RATE = 1000; //逻辑循环频率 + public static final String MESSAGE_NAME = "CTC_MESSAGE"; //消息发送任务名称 + public static final int MESSAGE_RATE = 1000; //消息发送频率 - public void run(Simulation simulation) { - updateRunPlanLog(simulation); - routeSequenceUpdate(simulation); - trackViewUpdate(simulation); - // 加载已签收行车日志, - loadSignRunPlanTrain(simulation); + @Autowired + private StompMessageService stompMessageService; + @Autowired + private CTCService ctcService; + @Autowired + private CtcDispatchCommandService ctcDispatchCommandService; + @Autowired + private DisCmdSendService disCmdService; + @Autowired + private AtsTrainLoadService atsTrainLoadService; + + public void run(Simulation simulation) { + updateRunPlanLog(simulation); + routeSequenceUpdate(simulation); + trackViewUpdate(simulation); + // 加载已签收行车日志, + loadSignRunPlanTrain(simulation); + } + + public void sendMessage(Simulation simulation) { + sendTrackViewMessage(simulation); + sendRouteSequenceMessage(simulation); + // 发送运行计划变化消息 + sendRunPlanChangeMessage(simulation); + sendRunPlanRemoveMessage(simulation); + // 下发计划 + sendZoneRunPlanSend(simulation); + // 发送计划按钮是否闪烁 + sendRunPlanConfirmActiveMessage(simulation); + } + + public void sendMessageWhenSubscribeCtc(Simulation simulation, String userId) { + sendAllBusyBoardMessage(simulation, userId); + //dis cmd v1 + sendUnreadDispatchCommand(simulation, userId); + //dis cmd v2 + disCmdService.autoSendUnread(simulation, userId); + } + + private void sendAllBusyBoardMessage(Simulation simulation, String userId) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + List list = new ArrayList<>(); + Map trackViewVOMap = ctcRepository.getTrackViewVOMap(); + Map routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap(); + HashSet stationCodes = new HashSet<>(trackViewVOMap.keySet()); + stationCodes.addAll(routeSequenceVOMap.keySet()); + for (String stationCode : stationCodes) { + TrackViewVO trackViewVO = trackViewVOMap.get(stationCode); + RouteSequenceVO routeSequenceVO = routeSequenceVOMap.get(stationCode); + BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, routeSequenceVO, trackViewVO); + list.add(busyBoardVO); } - public void sendMessage(Simulation simulation) { - sendTrackViewMessage(simulation); - sendRouteSequenceMessage(simulation); - // 发送运行计划变化消息 - sendRunPlanChangeMessage(simulation); - sendRunPlanRemoveMessage(simulation); - // 下发计划 - sendZoneRunPlanSend(simulation); - // 发送计划按钮是否闪烁 - sendRunPlanConfirmActiveMessage(simulation); - } + SocketMessageVO> message + = SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list); + stompMessageService.sendToUser(userId, message); + } - public void sendMessageWhenSubscribeCtc(Simulation simulation, String userId) { - sendAllBusyBoardMessage(simulation, userId); - //dis cmd v1 - sendUnreadDispatchCommand(simulation, userId); - //dis cmd v2 - disCmdService.autoSendUnread(simulation,userId); - } - - private void sendAllBusyBoardMessage(Simulation simulation, String userId) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - List list = new ArrayList<>(); - Map trackViewVOMap = ctcRepository.getTrackViewVOMap(); - Map routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap(); - HashSet stationCodes = new HashSet<>(trackViewVOMap.keySet()); - stationCodes.addAll(routeSequenceVOMap.keySet()); - for (String stationCode : stationCodes) { - TrackViewVO trackViewVO = trackViewVOMap.get(stationCode); - RouteSequenceVO routeSequenceVO = routeSequenceVOMap.get(stationCode); - BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, routeSequenceVO, trackViewVO); - list.add(busyBoardVO); - } - - SocketMessageVO> message - = SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list); + /** + * 发送该成员所属受令方的未读的调度命令 + */ + private void sendUnreadDispatchCommand(Simulation simulation, String userId) { + SimulationMember member = simulation.querySimulationMemberByUserId(userId); + if (member != null) { + List unreadCommands = ctcDispatchCommandService.queryUnreadDispatchCommand( + simulation, member); + for (RailDispatchCommandVO unreadCommand : unreadCommands) { + WebSocketMessage messageBody + = new WebSocketMessage<>(RailDispatchCommandVO.WsMsgType.ADD, unreadCommand); + SocketMessageVO> message + = SocketMessageFactory.buildDispatchCommandMessage(simulation.getId(), messageBody); stompMessageService.sendToUser(userId, message); + } } + } - /** - * 发送该成员所属受令方的未读的调度命令 - */ - private void sendUnreadDispatchCommand(Simulation simulation, String userId) { - SimulationMember member = simulation.querySimulationMemberByUserId(userId); - if (member != null) { - List unreadCommands = ctcDispatchCommandService.queryUnreadDispatchCommand(simulation, member); - for (RailDispatchCommandVO unreadCommand : unreadCommands) { - WebSocketMessage messageBody - = new WebSocketMessage<>(RailDispatchCommandVO.WsMsgType.ADD, unreadCommand); - SocketMessageVO> message - = SocketMessageFactory.buildDispatchCommandMessage(simulation.getId(), messageBody); - stompMessageService.sendToUser(userId, message); + private void trackViewUpdate(Simulation simulation) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + for (TrackView trackView : ctcRepository.getTrackViewMap().values()) { + for (Map lineMap : trackView.getTrackLineMap().values()) { + Iterator lineIterator = lineMap.values().iterator(); + while (lineIterator.hasNext()) { + TrackView.Line line = lineIterator.next(); + int remain = line.getRemain2Delete(); + if (remain == -1) { + TrackView.Process process = line.getProcess(); + if (TrackView.Process.FINISH.equals(process)) { + line.startDelayDelete(); } - } - } - - private void trackViewUpdate(Simulation simulation) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - for (TrackView trackView : ctcRepository.getTrackViewMap().values()) { - for (Map lineMap : trackView.getTrackLineMap().values()) { - Iterator lineIterator = lineMap.values().iterator(); - while (lineIterator.hasNext()) { - TrackView.Line line = lineIterator.next(); - int remain = line.getRemain2Delete(); - if (remain == -1) { - TrackView.Process process = line.getProcess(); - if (TrackView.Process.FINISH.equals(process)) { - line.startDelayDelete(); - } - } else { - remain -= LOGIC_RATE; - if (remain <= 0) { - lineIterator.remove(); - } else { - line.setRemain2Delete(remain); - } - } - } - } - } - } - - /** - * 进路序列更新与自触 - */ - private void routeSequenceUpdate(Simulation simulation) { - LocalDateTime correctSystemTime = simulation.getCorrectSystemTime(); - SimulationDataRepository repository = simulation.getRepository(); - for (Map.Entry entry : simulation.getCtcRepository().getRouteSequenceMap().entrySet()) { - String stationCode = entry.getKey(); - Station station = repository.getByCode(stationCode, Station.class); - RouteSequence routeSequence = entry.getValue(); - for (RouteSequence.Line line : routeSequence.getLines()) { - //更新触发/正在触发状态 - if (line.isTriggered()) - continue; - Route route = line.getRoute(); - if (route == null) - continue; - if (Objects.equals(line.getTripNumber(), route.getTripNumber())) { - if (route.isLock()) { - line.setTriggered(true); - continue; - } else { - line.setSetting(route.isSetting()); - if (line.isSetting()) - continue; - } - } - //自动触发 - if (station.isInterlockControl() || !line.isAutoTrigger()) //非常站控或者没有设置自触 - continue; - TrainInfo trainInfo = repository.findSupervisedTrainByTrip("", line.getTripNumber()); - if (line.isDeparture()) { //发车进路需列车停稳并到达计划时间 - if (correctSystemTime.isBefore(line.getPlanDateTime())) - continue; - if (trainInfo != null && trainInfo.isStop() && Objects.equals(trainInfo.getPhysicalSection(), line.getTrackCode())) - ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); - } else { - if (!correctSystemTime.isBefore(line.getPlanDateTime())) - ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); - else if (trainInfo != null && line.isTriggerSection(trainInfo.getPhysicalSection())) - ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); - } - } - } - } - - /** - * 更新行车日志状态 - */ - private void updateRunPlanLog(Simulation simulation) { - SimulationDataRepository repository = simulation.getRepository(); - String actualTime = simulation.getCorrectSystemTime().toLocalTime().toString(); - int index = actualTime.indexOf("."); - if (index != -1) { - actualTime = actualTime.substring(0, index); - } - CtcRepository ctcRepository = simulation.getCtcRepository(); - for (TrainInfo trainInfo : repository.getSuperviseTrainList()) { - VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber()); - SectionPosition headPosition = train.getHeadPosition(); - Section headSection = headPosition.getSection(); - Station station = headSection.getDeviceStation(); - String tripNumber = trainInfo.getTripNumber(); - CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), tripNumber); - if (runPlan == null) - continue; - // 接车计划到点:列车占压区段与接车计划股道一致,且列车是停站状态 - CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan(); - if (arriveRunPlan != null) { - if (!arriveRunPlan.isFinish()) { - if (headSection.equals(arriveRunPlan.getTrackSection()) && train.isParkingAt()) { - arriveRunPlan.setActualTime(actualTime); - arriveRunPlan.setFinish(true); - //设置上一站的<邻站到达> - Station previousStation = runPlan.findPreviousStation(); - if (previousStation != null) { - CtcStationRunPlanLog previousRunPlan = ctcRepository.findRunPlan(previousStation.getCode(), tripNumber); - if (previousRunPlan != null) { - CtcStationRunPlanLog.RunPlanItem previousDeparturePlan = previousRunPlan.getDepartRunPlan(); - if (previousDeparturePlan != null) { - previousDeparturePlan.setAdjacentDepart(actualTime); - } - } - } - } - } - } - // 发车计划发点:列车位置越过出站信号机 - CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan(); - if (departRunPlan != null) { - if (!departRunPlan.isFinish()) { //实际发车时间没填 - Section trackSection = departRunPlan.getTrackSection(); - Signal signal = trackSection.getSignalOf(departRunPlan.isRight()); - if (headPosition.isAheadOf(signal.getPosition(), departRunPlan.isRight())) { //车头越过出站信号机 - departRunPlan.setActualTime(actualTime); - departRunPlan.setFinish(true); - //设置下一站的<邻站出发> - Station nextStation = runPlan.findNextStation(); - if (nextStation != null) { - CtcStationRunPlanLog nextRunPlan = ctcRepository.findRunPlan(nextStation.getCode(), tripNumber); - if (nextRunPlan != null) { - CtcStationRunPlanLog.RunPlanItem nextArriveRunPlan = nextRunPlan.getArriveRunPlan(); - if (nextArriveRunPlan != null) { - nextArriveRunPlan.setAdjacentDepart(actualTime); - } - } - } - } - } - } - } - } - - private void sendTrackViewMessage(Simulation simulation) { - List list = new ArrayList<>(); - CtcRepository ctcRepository = simulation.getCtcRepository(); - Map trackViewMap = ctcRepository.getTrackViewMap(); - Map trackViewVOMap = ctcRepository.getTrackViewVOMap(); - for (Map.Entry trackViewEntry : trackViewMap.entrySet()) { - String stationCode = trackViewEntry.getKey(); - TrackView trackView = trackViewEntry.getValue(); - TrackViewVO trackViewVO = trackViewVOMap.get(stationCode); - TrackViewVO changedViewVO; - if (trackViewVO == null) { - trackViewVO = new TrackViewVO(trackView); - trackViewVOMap.put(stationCode, trackViewVO); - changedViewVO = trackViewVO; + } else { + remain -= LOGIC_RATE; + if (remain <= 0) { + lineIterator.remove(); } else { - changedViewVO = trackViewVO.updateAndReturnChanged(trackView); - } - if (changedViewVO != null) { - BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, null, changedViewVO); - list.add(busyBoardVO); + line.setRemain2Delete(remain); } + } } - if (!CollectionUtils.isEmpty(list)) { - SocketMessageVO> message - = SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list); - stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); - } + } } + } - /** - * 发送进路序列消息 - */ - private void sendRouteSequenceMessage(Simulation simulation) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - Map routeSequenceMap = ctcRepository.getRouteSequenceMap(); - Map routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap(); - List list = new ArrayList<>(); - if (CollectionUtils.isEmpty(routeSequenceVOMap)) { - for (RouteSequence routeSequence : routeSequenceMap.values()) { - RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence); - routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO); - BusyBoardVO busyBoardVO = new BusyBoardVO(routeSequenceVO.getStationCode(), routeSequenceVO, null); - list.add(busyBoardVO); + /** + * 进路序列更新与自触 + */ + private void routeSequenceUpdate(Simulation simulation) { + LocalDateTime correctSystemTime = simulation.getCorrectSystemTime(); + SimulationDataRepository repository = simulation.getRepository(); + for (Map.Entry entry : simulation.getCtcRepository() + .getRouteSequenceMap().entrySet()) { + String stationCode = entry.getKey(); + Station station = repository.getByCode(stationCode, Station.class); + RouteSequence routeSequence = entry.getValue(); + for (RouteSequence.Line line : routeSequence.getLines()) { + //更新触发/正在触发状态 + if (line.isTriggered()) { + continue; + } + Route route = line.getRoute(); + if (route == null) { + continue; + } + if (Objects.equals(line.getTripNumber(), route.getTripNumber())) { + if (route.isLock()) { + line.setTriggered(true); + continue; + } else { + line.setSetting(route.isSetting()); + if (line.isSetting()) { + continue; } + } + } + //自动触发 + if (station.isInterlockControl() || !line.isAutoTrigger()) //非常站控或者没有设置自触 + { + continue; + } + TrainInfo trainInfo = repository.findSupervisedTrainByTrip("", line.getTripNumber()); + if (line.isDeparture()) { //发车进路需列车停稳并到达计划时间 + if (correctSystemTime.isBefore(line.getPlanDateTime())) { + continue; + } + if (trainInfo != null && trainInfo.isStop() && Objects.equals( + trainInfo.getPhysicalSection(), line.getTrackCode())) { + ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); + } } else { - for (RouteSequence routeSequence : routeSequenceMap.values()) { - RouteSequenceVO vo = routeSequenceVOMap.get(routeSequence.getStationCode()); - RouteSequenceVO changed = vo.updateAndReturnChanged(routeSequence); - if (changed != null) { - BusyBoardVO busyBoardVO = new BusyBoardVO(vo.getStationCode(), changed, null); - list.add(busyBoardVO); + if (!correctSystemTime.isBefore(line.getPlanDateTime())) { + ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); + } else if (trainInfo != null && line.isTriggerSection(trainInfo.getPhysicalSection())) { + ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); + } + } + } + } + } + + /** + * 更新行车日志状态 + */ + private void updateRunPlanLog(Simulation simulation) { + SimulationDataRepository repository = simulation.getRepository(); + String actualTime = simulation.getCorrectSystemTime().toLocalTime().toString(); + int index = actualTime.indexOf("."); + if (index != -1) { + actualTime = actualTime.substring(0, index); + } + CtcRepository ctcRepository = simulation.getCtcRepository(); + for (TrainInfo trainInfo : repository.getSuperviseTrainList()) { + VirtualRealityTrain train = repository.getOnlineTrainBy(trainInfo.getGroupNumber()); + SectionPosition headPosition = train.getHeadPosition(); + Section headSection = headPosition.getSection(); + Station station = headSection.getDeviceStation(); + String tripNumber = trainInfo.getTripNumber(); + CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), tripNumber); + if (runPlan == null) { + continue; + } + // 接车计划到点:列车占压区段与接车计划股道一致,且列车是停站状态 + CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan(); + if (arriveRunPlan != null) { + if (!arriveRunPlan.isFinish()) { + if (headSection.equals(arriveRunPlan.getTrackSection()) && train.isParkingAt()) { + arriveRunPlan.setActualTime(actualTime); + arriveRunPlan.setFinish(true); + //设置上一站的<邻站到达> + Station previousStation = runPlan.findPreviousStation(); + if (previousStation != null) { + CtcStationRunPlanLog previousRunPlan = ctcRepository.findRunPlan( + previousStation.getCode(), tripNumber); + if (previousRunPlan != null) { + CtcStationRunPlanLog.RunPlanItem previousDeparturePlan = previousRunPlan.getDepartRunPlan(); + if (previousDeparturePlan != null) { + previousDeparturePlan.setAdjacentDepart(actualTime); } + } } + } } - if (!CollectionUtils.isEmpty(list)) { - SocketMessageVO> message - = SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list); - stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); - } - } - - public void addJobs(Simulation simulation) { - simulation.addJob(LOGIC_NAME, () -> this.run(simulation), LOGIC_RATE); - simulation.addFixedRateJob(MESSAGE_NAME, () -> this.sendMessage(simulation), MESSAGE_RATE); - } - - /** - * 行车区段运行计划下发 - */ - public void sendZoneRunPlanSend(Simulation simulation) { - List allList = simulation.getCtcRepository().getCtcEffectRepository().getChangeStageRunPlan(); - if (!CollectionUtils.isEmpty(allList)) { - sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_RAILWAY_RUN_PLAN_SEND, simulation.getSimulationUserIds()); - } - } - - /** - * 运行计划发送变化事件 - */ - private void sendRunPlanChangeMessage(Simulation simulation) { - Map ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap(); - List allRunPlanList = simulation.getCtcRepository().getAllRunPlanList(); - List messageList = new ArrayList<>(); - allRunPlanList.forEach(runPlan -> { - String mapKey = runPlan.getStation().getCode() + "_" + runPlan.getCode(); - CtcStationRunPlanLogVO runPlanVO = ctcRunPlanVOMap.get(mapKey); - if (runPlanVO == null) { - ctcRunPlanVOMap.put(mapKey, new CtcStationRunPlanLogVO(runPlan)); - messageList.add(ctcRunPlanVOMap.get(mapKey)); - } else { - CtcStationRunPlanLogVO changeCtcStationRunPlanLogVo = runPlanVO.compareAndChange(runPlan); - if (changeCtcStationRunPlanLogVo != null) { - messageList.add(changeCtcStationRunPlanLogVo); + } + // 发车计划发点:列车位置越过出站信号机 + CtcStationRunPlanLog.RunPlanItem departRunPlan = runPlan.getDepartRunPlan(); + if (departRunPlan != null) { + if (!departRunPlan.isFinish()) { //实际发车时间没填 + Section trackSection = departRunPlan.getTrackSection(); + Signal signal = trackSection.getSignalOf(departRunPlan.isRight()); + if (headPosition.isAheadOf(signal.getPosition(), departRunPlan.isRight())) { //车头越过出站信号机 + departRunPlan.setActualTime(actualTime); + departRunPlan.setFinish(true); + //设置下一站的<邻站出发> + Station nextStation = runPlan.findNextStation(); + if (nextStation != null) { + CtcStationRunPlanLog nextRunPlan = ctcRepository.findRunPlan(nextStation.getCode(), + tripNumber); + if (nextRunPlan != null) { + CtcStationRunPlanLog.RunPlanItem nextArriveRunPlan = nextRunPlan.getArriveRunPlan(); + if (nextArriveRunPlan != null) { + nextArriveRunPlan.setAdjacentDepart(actualTime); } + } } - }); - if (!CollectionUtils.isEmpty(messageList)) { - sendCtcMessage(simulation.getId(), messageList - , WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CHANGE, simulation.getSimulationUserIds()); + } } + } } + } - /** - * 运行计划移除时清除垃圾数据 - * - * @param simulation 仿真实体 - */ - public void sendRunPlanRemoveMessage(Simulation simulation) { - Map ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap(); - List ctcStationRunPlanLogVOList = ctcRunPlanVOMap.values().stream() - .filter(vo -> simulation.getCtcRepository().getRunPlanByRunPlanCodeAndStationCode(vo.getStationCode(), vo.getCode()) == null) - .map(vo -> new CtcStationRunPlanLogVO(vo.getStationCode(), vo.getCode())) - .collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(ctcStationRunPlanLogVOList)) { - // 移除已删除的数据 - ctcStationRunPlanLogVOList.forEach(vo -> ctcRunPlanVOMap.remove(vo.getStationCode() + "_" + vo.getCode())); - sendCtcMessage(simulation.getId(), ctcStationRunPlanLogVOList - , WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_REMOVE, simulation.getSimulationUserIds()); + private void sendTrackViewMessage(Simulation simulation) { + List list = new ArrayList<>(); + CtcRepository ctcRepository = simulation.getCtcRepository(); + Map trackViewMap = ctcRepository.getTrackViewMap(); + Map trackViewVOMap = ctcRepository.getTrackViewVOMap(); + for (Map.Entry trackViewEntry : trackViewMap.entrySet()) { + String stationCode = trackViewEntry.getKey(); + TrackView trackView = trackViewEntry.getValue(); + TrackViewVO trackViewVO = trackViewVOMap.get(stationCode); + TrackViewVO changedViewVO; + if (trackViewVO == null) { + trackViewVO = new TrackViewVO(trackView); + trackViewVOMap.put(stationCode, trackViewVO); + changedViewVO = trackViewVO; + } else { + changedViewVO = trackViewVO.updateAndReturnChanged(trackView); + } + if (changedViewVO != null) { + BusyBoardVO busyBoardVO = new BusyBoardVO(stationCode, null, changedViewVO); + list.add(busyBoardVO); + } + } + if (!CollectionUtils.isEmpty(list)) { + SocketMessageVO> message + = SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list); + stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); + } + } + + /** + * 发送进路序列消息 + */ + private void sendRouteSequenceMessage(Simulation simulation) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + Map routeSequenceMap = ctcRepository.getRouteSequenceMap(); + Map routeSequenceVOMap = ctcRepository.getRouteSequenceVOMap(); + List list = new ArrayList<>(); + if (CollectionUtils.isEmpty(routeSequenceVOMap)) { + for (RouteSequence routeSequence : routeSequenceMap.values()) { + RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence); + routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO); + BusyBoardVO busyBoardVO = new BusyBoardVO(routeSequenceVO.getStationCode(), routeSequenceVO, + null); + list.add(busyBoardVO); + } + } else { + for (RouteSequence routeSequence : routeSequenceMap.values()) { + RouteSequenceVO vo = routeSequenceVOMap.get(routeSequence.getStationCode()); + RouteSequenceVO changed = vo.updateAndReturnChanged(routeSequence); + if (changed != null) { + BusyBoardVO busyBoardVO = new BusyBoardVO(vo.getStationCode(), changed, null); + list.add(busyBoardVO); } + } } + if (!CollectionUtils.isEmpty(list)) { + SocketMessageVO> message + = SocketMessageFactory.buildCtcBusyBoardMessage(simulation.getId(), list); + stompMessageService.sendToUser(simulation.getSimulationUserIds(), message); + } + } - /** - * 运行计划发送计划 - */ - public void sendRunPlanConfirmActiveMessage(Simulation simulation) { - Map changeMap = new HashMap<>(); - simulation.getCtcRepository().getSimulationRunPlanMap().forEach((k, v) -> { - boolean isChange = v.values().stream().anyMatch(CtcStationRunPlanLog::isChange); - if (isChange) { - changeMap.put(k, Boolean.TRUE); + public void addJobs(Simulation simulation) { + simulation.addJob(LOGIC_NAME, () -> this.run(simulation), LOGIC_RATE); + simulation.addFixedRateJob(MESSAGE_NAME, () -> this.sendMessage(simulation), MESSAGE_RATE); + } + + /** + * 行车区段运行计划下发 + */ + public void sendZoneRunPlanSend(Simulation simulation) { + List allList = simulation.getCtcRepository() + .getCtcEffectRepository().getChangeStageRunPlan(); + if (!CollectionUtils.isEmpty(allList)) { + sendCtcMessage(simulation.getId(), allList, + WebSocketMessageType.SIMULATION_RAILWAY_RUN_PLAN_SEND, simulation.getSimulationUserIds()); + } + } + + /** + * 运行计划发送变化事件 + */ + private void sendRunPlanChangeMessage(Simulation simulation) { + Map ctcRunPlanVOMap = simulation.getCtcRepository() + .getRunPlanStatusVOMap(); + List allRunPlanList = simulation.getCtcRepository().getAllRunPlanList(); + List messageList = new ArrayList<>(); + allRunPlanList.forEach(runPlan -> { + String mapKey = runPlan.getStation().getCode() + "_" + runPlan.getCode(); + CtcStationRunPlanLogVO runPlanVO = ctcRunPlanVOMap.get(mapKey); + if (runPlanVO == null) { + ctcRunPlanVOMap.put(mapKey, new CtcStationRunPlanLogVO(runPlan)); + messageList.add(ctcRunPlanVOMap.get(mapKey)); + } else { + CtcStationRunPlanLogVO changeCtcStationRunPlanLogVo = runPlanVO.compareAndChange(runPlan); + if (changeCtcStationRunPlanLogVo != null) { + messageList.add(changeCtcStationRunPlanLogVo); + } + } + }); + if (!CollectionUtils.isEmpty(messageList)) { + sendCtcMessage(simulation.getId(), messageList + , WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CHANGE, simulation.getSimulationUserIds()); + } + } + + /** + * 运行计划移除时清除垃圾数据 + * + * @param simulation 仿真实体 + */ + public void sendRunPlanRemoveMessage(Simulation simulation) { + Map ctcRunPlanVOMap = simulation.getCtcRepository() + .getRunPlanStatusVOMap(); + List ctcStationRunPlanLogVOList = ctcRunPlanVOMap.values().stream() + .filter(vo -> simulation.getCtcRepository() + .getRunPlanByRunPlanCodeAndStationCode(vo.getStationCode(), vo.getCode()) == null) + .map(vo -> new CtcStationRunPlanLogVO(vo.getStationCode(), vo.getCode())) + .collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(ctcStationRunPlanLogVOList)) { + // 移除已删除的数据 + ctcStationRunPlanLogVOList.forEach( + vo -> ctcRunPlanVOMap.remove(vo.getStationCode() + "_" + vo.getCode())); + sendCtcMessage(simulation.getId(), ctcStationRunPlanLogVOList + , WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_REMOVE, simulation.getSimulationUserIds()); + } + } + + /** + * 运行计划发送计划 + */ + public void sendRunPlanConfirmActiveMessage(Simulation simulation) { + Map changeMap = new HashMap<>(); + simulation.getCtcRepository().getSimulationRunPlanMap().forEach((k, v) -> { + boolean isChange = v.values().stream().anyMatch(CtcStationRunPlanLog::isChange); + if (isChange) { + changeMap.put(k, Boolean.TRUE); + } + }); + // 为空时 + if (!Objects.equals(simulation.getCtcRepository().getRunPlanSendOut(), changeMap.isEmpty()) + || !changeMap.isEmpty()) { + simulation.getCtcRepository().setRunPlanSendOut(changeMap.isEmpty()); + sendCtcMessage(simulation.getId(), changeMap, + WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CONFIRM_SEND + , simulation.getSimulationUserIds()); + } + } + + /** + * 发送CTC运行计划消息 + * + * @param simulationId 仿真ID + * @param messageInfo 运行计划列表 + * @param type 消息类型 + * @param userIds 用户ID + */ + public void sendCtcMessage(String simulationId, T messageInfo, WebSocketMessageType type, + Set userIds) { + if (messageInfo != null) { + SocketMessageVO messageVO = SocketMessageFactory.build(type, simulationId, messageInfo); + stompMessageService.sendToUser(userIds, messageVO); + } + } + + + /** + * 加载已签收至占线板上的列车 + * + * @param simulation 仿真信息 + */ + private void loadSignRunPlanTrain(Simulation simulation) { + if (!simulation.isPlanRunning() || ProjectCode.THAILAND_SANDBOX.equals( + simulation.getProject())) { //泰国沙盘项目不能随意指定列车上线,所以禁用此逻辑,后续考虑用地图配置 + return; + } + // 没有加载过计划、始发计划、已发送至占线板、当前时间晚于计划时间提前5分钟 + simulation.getCtcRepository().getAllRunPlanList().stream() + .filter(r -> r.getDepartRunPlan() != null && (r.isStartRunPlan() || ( + r.getArriveRunPlan() == null && r.getDepartRunPlan() != null))) + .filter(r -> { + boolean valid = !r.isLoad() && r.isSign() && r.getStatus() != -1 + && simulation.getCorrectSystemTime() + .isAfter(r.getDepartRunPlan().getPlanTime().minusMinutes(5)); + if (valid) { + valid = !simulation.getRepository().getTrainInfoMap().values().stream() + .anyMatch(trainInfo -> r.getDepartRunPlan().getTripNumber() + .equals(trainInfo.getTripNumber())); + if (!valid) { // 如果列车已经上线,则直接修改状态 + r.setLoad(true); } + } + return valid; + }) + .sorted((r1, r2) -> + r1.getDepartRunPlan().getPlanTime().isBefore(r2.getDepartRunPlan().getPlanTime()) ? -1 + : 1) + .forEach(r -> { + Section section = r.getDepartRunPlan().getTrackSection(); + if (section.isFree()) { + String tripNumber = r.getDepartRunPlan().getTripNumber(); + int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48; + atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, section.getCode(), + lastNum % 2 == 0); + r.setLoad(true); // 已上线 + } }); - // 为空时 - if (!Objects.equals(simulation.getCtcRepository().getRunPlanSendOut(), changeMap.isEmpty()) || !changeMap.isEmpty()) { - simulation.getCtcRepository().setRunPlanSendOut(changeMap.isEmpty()); - sendCtcMessage(simulation.getId(), changeMap, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CONFIRM_SEND - , simulation.getSimulationUserIds()); - } - } - - /** - * 发送CTC运行计划消息 - * - * @param simulationId 仿真ID - * @param messageInfo 运行计划列表 - * @param type 消息类型 - * @param userIds 用户ID - */ - public void sendCtcMessage(String simulationId, T messageInfo, WebSocketMessageType type, Set userIds) { - if (messageInfo != null) { - SocketMessageVO messageVO = SocketMessageFactory.build(type, simulationId, messageInfo); - stompMessageService.sendToUser(userIds, messageVO); - } - } - - - /** - * 加载已签收至占线板上的列车 - * - * @param simulation 仿真信息 - */ - private void loadSignRunPlanTrain(Simulation simulation) { - if (!simulation.isPlanRunning()) { - return; - } - // 没有加载过计划、始发计划、已发送至占线板、当前时间晚于计划时间提前5分钟 - simulation.getCtcRepository().getAllRunPlanList().stream() - .filter(r -> r.getDepartRunPlan() != null && (r.isStartRunPlan() || (r.getArriveRunPlan() == null && r.getDepartRunPlan() != null))) - .filter(r -> { - boolean valid = !r.isLoad() && r.isSign() && r.getStatus() != -1 - && simulation.getCorrectSystemTime().isAfter(r.getDepartRunPlan().getPlanTime().minusMinutes(5)); - if (valid) { - valid = !simulation.getRepository().getTrainInfoMap().values().stream() - .anyMatch(trainInfo -> r.getDepartRunPlan().getTripNumber().equals(trainInfo.getTripNumber())); - if (!valid) { // 如果列车已经上线,则直接修改状态 - r.setLoad(true); - } - } - return valid; - }) - .sorted((r1, r2) -> r1.getDepartRunPlan().getPlanTime().isBefore(r2.getDepartRunPlan().getPlanTime()) ? -1 : 1) - .forEach(r -> { - Section section = r.getDepartRunPlan().getTrackSection(); - if (section.isFree()) { - String tripNumber = r.getDepartRunPlan().getTripNumber(); - int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48; - atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, section.getCode(), lastNum % 2 == 0); - r.setLoad(true); // 已上线 - } - }); - } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/service/CTCService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/service/CTCService.java index b8d8bb3ee..f3dbbde61 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/service/CTCService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/service/CTCService.java @@ -2,261 +2,264 @@ package club.joylink.rtss.simulation.cbtc.CTC.service; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.CI.CiApiService; -import club.joylink.rtss.simulation.cbtc.CTC.data.*; +import club.joylink.rtss.simulation.cbtc.CTC.data.CascoControl; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog; +import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence; import club.joylink.rtss.simulation.cbtc.Simulation; -import club.joylink.rtss.simulation.cbtc.data.map.*; -import club.joylink.rtss.simulation.cbtc.exception.SimulationException; -import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; +import club.joylink.rtss.simulation.cbtc.data.map.Route; +import club.joylink.rtss.simulation.cbtc.data.map.Section; +import club.joylink.rtss.simulation.cbtc.data.map.Station; +import club.joylink.rtss.simulation.cbtc.data.map.Switch; +import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import javax.annotation.Resource; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - @Component public class CTCService { - @Autowired - private CiApiService ciApiService; - @Resource - private CascoControlService cascoControlService; - /** - * 创建了新的运行计划item - */ - public void runPlanItemCreate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) { - regenerateRouteSequenceAndTrackView(simulation, station); -// CtcRepository ctcRepository = simulation.getCtcRepository(); -// //进路序列 -// RouteSequence routeSequence = ctcRepository.getRouteSequence(station.getCode()); -// AtomicInteger idGenerator = ctcRepository.getRouteSequenceIdGenerator(); -// RouteSequence.Line line = RouteSequence.buildLine(item, departure, idGenerator); -// routeSequence.addLine(line); -// //股道视图 -// TrackView trackView = ctcRepository.getTrackView(station.getCode()); -// if (departure) { -// trackView.addDepartureLine(line); -// } else { -// trackView.addReceivingLine(line); -// } - } - /** - * 运行计划item更新了 - */ - public void runPlanItemUpdate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) { - regenerateRouteSequenceAndTrackView(simulation, station); -// CtcRepository ctcRepository = simulation.getCtcRepository(); -// RouteSequence.Line routeSequenceLine = ctcRepository.getRouteSequenceLine(station.getCode(), item.getTripNumber(), departure); -// -// String oldTc = routeSequenceLine.getTrackCode(); -// String oldTn = routeSequenceLine.getTripNumber(); -// -// routeSequenceLine.update(); -// -// ctcRepository.updateTrackView(station.getCode(), oldTc, oldTn, routeSequenceLine); - } + @Autowired + private CiApiService ciApiService; + @Resource + private CascoControlService cascoControlService; - /** - * 重新生成进路序列和股道视图 - * 该方法应该在车务终端发送阶段计划之后调用 - */ - public void regenerateRouteSequenceAndTrackView(Simulation simulation, Station station) { - if (simulation.getRepository().getConfig().isHasCTC()) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - ctcRepository.buildRouteSequence(station); - ctcRepository.buildTrackViewData(station); + /** + * 重新生成进路序列和股道视图 该方法应该在车务终端发送阶段计划之后调用 + */ + public void regenerateRouteSequenceAndTrackView(Simulation simulation, Station station) { + if (simulation.getRepository().getConfig().isHasCTC()) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + ctcRepository.buildRouteSequence(station); + ctcRepository.buildTrackViewData(station); + } + } + + /** + * 完成接预 + */ + public void finishReceivingNotice(Simulation simulation, String stationCode, String tripNumber) { + CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); + plan.finishReceivingNotice(); + String systemTime = simulation.getCorrectSystemTime() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); + plan.getArriveRunPlan().setAdjacentMessageTime(systemTime); + } + + /** + * 取消接预 + */ + public void cancelReceivingNotice(Simulation simulation, String stationCode, String tripNumber) { + + } + + /** + * 完成发预 + */ + public void finishDepartureNotice(Simulation simulation, String stationCode, String tripNumber) { + CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); + plan.finishDepartureNotice(); + String systemTime = simulation.getCorrectSystemTime() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); + plan.getDepartRunPlan().setAdjacentMessageTime(systemTime); + } + + public void cancelDepartureNotice(Simulation simulation, String stationCode, String tripNumber) { + + } + + public void finishArrive(Simulation simulation, String stationCode, String tripNumber, + LocalTime time) { + CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); + if (time == null) { + time = simulation.getCorrectSystemTime().toLocalTime(); + } + plan.finishArrive(time); + } + + public void cancelArrive(Simulation simulation, String stationCode, String tripNumber) { + CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); + plan.cancelArrive(); + } + + public void finishDeparture(Simulation simulation, String stationCode, String tripNumber, + LocalTime time) { + CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); + if (time == null) { + time = simulation.getCorrectSystemTime().toLocalTime(); + } + plan.finishDeparture(time); + } + + public void cancelDeparture(Simulation simulation, String stationCode, String tripNumber) { + CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); + plan.cancelDeparture(); + } + + /** + * 发送发车预告 + */ + public void sendDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) { + CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, + stationCode, runPlanCode); + Station nextStation = currentStationPlan.getNextStation(); + CtcStationRunPlanLog nextStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, + nextStation.getCode(), runPlanCode); + currentStationPlan.sendDepartureNotice(); + nextStationPlan.receiveDepartureNotice(); + } + + /** + * 同意发车预告 + */ + public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) { + CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, + stationCode, runPlanCode); + Station previousStation = currentStationPlan.getPreviousStation(); + CtcStationRunPlanLog previousStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, + previousStation.getCode(), runPlanCode); + currentStationPlan.finishReceivingNotice(); + previousStationPlan.finishDepartureNotice(); + String systemTime = simulation.getCorrectSystemTime() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); + currentStationPlan.getArriveRunPlan().setAdjacentMessageTime(systemTime); + previousStationPlan.getDepartRunPlan().setAdjacentMessageTime(systemTime); + } + + /** + * 进路自触 + */ + public void routeAutoTrigger(Simulation simulation, String stationCode, String tripNumber, + String routeCode, boolean trigger) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + RouteSequence.Line line = ctcRepository.getRouteSequenceLine(stationCode, tripNumber, + routeCode); + line.setAutoTrigger(trigger); + } + + private List cascoControl(CascoControl cc, boolean force) { + if (Objects.equals(true, force)) { + return Collections.emptyList(); + } + return this.cascoControlService.checkCascoControlRoute(cc); + } + + /** + * @param simulation + * @param routeCode + * @param tripNumber + * @param force + * @param duration + * @return + */ + public List setRoute(Simulation simulation, String routeCode, String tripNumber, + Boolean force, Integer duration) { + Route route = simulation.getRepository().getByCode(routeCode, Route.class); + if (force == null || !force) { // 非强制办理 + // 存在分路不良的区段 + boolean isBadShut = route.getSectionList().stream().anyMatch(Section::isBadShunt); + if (isBadShut) { + throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception("进路不能办理,存在分路不良区段"); + } + } + Station station = route.getStart().getStation(); + if (station == null) { + station = route.getStart().getDeviceStation(); + } + + List conflictInfo = new ArrayList<>(); + CtcRepository ctcRepository = simulation.getCtcRepository(); + CascoControl cc = new CascoControl(simulation, station, route, tripNumber); + List errCCMsg = this.cascoControl(cc, + Objects.isNull(force) ? false : force.booleanValue());//站细卡控 + if (Objects.equals(false, CollectionUtils.isEmpty(errCCMsg))) { + //站细检测错误的信息 + return errCCMsg; + } + if (StringUtils.hasText(tripNumber) && !Objects.equals(true, force)) { //列车进路防错办 + List lines = ctcRepository.findRouteSequenceLines(station.getCode(), + tripNumber); + if (!CollectionUtils.isEmpty(lines)) { + boolean b = lines.stream() + .noneMatch(line -> Objects.equals(line.getRouteCode(), routeCode)); + if (b) { + conflictInfo.add( + String.format("车次[%s]的进路序列中不包含进路[name:%s]", tripNumber, route.getName())); + } + } + } + if (duration != null && !Objects.equals(true, force)) { //调车进路防错办 + Set
sections = new HashSet<>(route.getSectionList()); + Map switchMap = new HashMap<>(); + List switchList = route.getSwitchList(); + if (!CollectionUtils.isEmpty(switchList)) { + switchMap = switchList.stream() + .collect(Collectors.toMap(SwitchElement::getASwitch, Function.identity())); + } + LocalTime endTime = simulation.getCorrectSystemTime().plusSeconds(duration).toLocalTime(); + List lines = ctcRepository.findRouteSequenceLineThatLessThan( + station.getCode(), endTime); + out: + for (RouteSequence.Line line : lines) { + Route lineRoute = line.getRoute(); + if (lineRoute == null) { + continue; + } + for (Section section : lineRoute.getSectionList()) { + if (sections.contains(section)) { + conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突", + route.getName(), line.getTripNumber(), lineRoute.getName())); + continue out; + } } - } - - /** - * 完成接预 - */ - public void finishReceivingNotice(Simulation simulation, String stationCode, String tripNumber) { - CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); - plan.finishReceivingNotice(); - String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); - plan.getArriveRunPlan().setAdjacentMessageTime(systemTime); - } - - /** - * 取消接预 - */ - public void cancelReceivingNotice(Simulation simulation, String stationCode, String tripNumber) { - - } - - /** - * 完成发预 - */ - public void finishDepartureNotice(Simulation simulation, String stationCode, String tripNumber) { - CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); - plan.finishDepartureNotice(); - String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); - plan.getDepartRunPlan().setAdjacentMessageTime(systemTime); - } - - public void cancelDepartureNotice(Simulation simulation, String stationCode, String tripNumber) { - - } - - public void finishArrive(Simulation simulation, String stationCode, String tripNumber, LocalTime time) { - CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); - if (time == null) - time = simulation.getCorrectSystemTime().toLocalTime(); - plan.finishArrive(time); - } - - public void cancelArrive(Simulation simulation, String stationCode, String tripNumber) { - CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); - plan.cancelArrive(); - } - - public void finishDeparture(Simulation simulation, String stationCode, String tripNumber, LocalTime time) { - CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); - if (time == null) - time = simulation.getCorrectSystemTime().toLocalTime(); - plan.finishDeparture(time); - } - - public void cancelDeparture(Simulation simulation, String stationCode, String tripNumber) { - CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); - plan.cancelDeparture(); - } - - /** - * 发送发车预告 - */ - public void sendDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) { - CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, stationCode, runPlanCode); - Station nextStation = currentStationPlan.getNextStation(); - CtcStationRunPlanLog nextStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, nextStation.getCode(), runPlanCode); - currentStationPlan.sendDepartureNotice(); - nextStationPlan.receiveDepartureNotice(); - } - - /** - * 同意发车预告 - */ - public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) { - CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, stationCode, runPlanCode); - Station previousStation = currentStationPlan.getPreviousStation(); - CtcStationRunPlanLog previousStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, previousStation.getCode(), runPlanCode); - currentStationPlan.finishReceivingNotice(); - previousStationPlan.finishDepartureNotice(); - String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); - currentStationPlan.getArriveRunPlan().setAdjacentMessageTime(systemTime); - previousStationPlan.getDepartRunPlan().setAdjacentMessageTime(systemTime); - } - - /** - * 进路自触 - */ - public void routeAutoTrigger(Simulation simulation, String stationCode, String tripNumber, String routeCode, boolean trigger) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - RouteSequence.Line line = ctcRepository.getRouteSequenceLine(stationCode, tripNumber, routeCode); - line.setAutoTrigger(trigger); - } - - private List cascoControl(CascoControl cc,boolean force){ - if(Objects.equals(true,force)){ - return Collections.emptyList(); - } - return this.cascoControlService.checkCascoControlRoute(cc); - } - /** - * - * @param simulation - * @param routeCode - * @param tripNumber - * @param force - * @param duration - * @return - */ - public List setRoute(Simulation simulation, String routeCode, String tripNumber, Boolean force, Integer duration) { - Route route = simulation.getRepository().getByCode(routeCode, Route.class); - if (force == null || !force) { // 非强制办理 - // 存在分路不良的区段 - boolean isBadShut = route.getSectionList().stream().anyMatch(Section::isBadShunt); - if (isBadShut) { - throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception("进路不能办理,存在分路不良区段"); + List sl = lineRoute.getSwitchList(); + if (!CollectionUtils.isEmpty(sl)) { + for (SwitchElement element : sl) { + SwitchElement e = switchMap.get(element.getASwitch()); + if (e != null && !element.equals(e)) { + conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突", + route.getName(), line.getTripNumber(), lineRoute.getName())); + continue out; } + } } - Station station = route.getStart().getStation(); - if (station == null) - station = route.getStart().getDeviceStation(); - - List conflictInfo = new ArrayList<>(); - CtcRepository ctcRepository = simulation.getCtcRepository(); - CascoControl cc = new CascoControl(simulation,station,route,tripNumber); - List errCCMsg = this.cascoControl(cc,Objects.isNull(force) ? false:force.booleanValue());//站细卡控 - if(Objects.equals(false,CollectionUtils.isEmpty(errCCMsg))){ - //站细检测错误的信息 - return errCCMsg; - } - if (StringUtils.hasText(tripNumber) && !Objects.equals(true, force)) { //列车进路防错办 - List lines = ctcRepository.findRouteSequenceLines(station.getCode(), tripNumber); - if (!CollectionUtils.isEmpty(lines)) { - boolean b = lines.stream().noneMatch(line -> Objects.equals(line.getRouteCode(), routeCode)); - if (b) - conflictInfo.add(String.format("车次[%s]的进路序列中不包含进路[name:%s]", tripNumber, route.getName())); - } - } - if (duration != null && !Objects.equals(true, force)) { //调车进路防错办 - Set
sections = new HashSet<>(route.getSectionList()); - Map switchMap = new HashMap<>(); - List switchList = route.getSwitchList(); - if (!CollectionUtils.isEmpty(switchList)) { - switchMap = switchList.stream().collect(Collectors.toMap(SwitchElement::getASwitch, Function.identity())); - } - LocalTime endTime = simulation.getCorrectSystemTime().plusSeconds(duration).toLocalTime(); - List lines = ctcRepository.findRouteSequenceLineThatLessThan(station.getCode(), endTime); - out: - for (RouteSequence.Line line : lines) { - Route lineRoute = line.getRoute(); - if (lineRoute == null) - continue; - for (Section section : lineRoute.getSectionList()) { - if (sections.contains(section)) { - conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突", - route.getName(), line.getTripNumber(), lineRoute.getName())); - continue out; - } - } - List sl = lineRoute.getSwitchList(); - if (!CollectionUtils.isEmpty(sl)) { - for (SwitchElement element : sl) { - SwitchElement e = switchMap.get(element.getASwitch()); - if (e != null && !element.equals(e)) { - conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突", - route.getName(), line.getTripNumber(), lineRoute.getName())); - continue out; - } - } - } - } - } - if (!conflictInfo.isEmpty()) - return conflictInfo; - - Route.CheckFailMessage checkFailMessage = ciApiService.settingRoute(simulation, routeCode); - if (checkFailMessage != null) - throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception(checkFailMessage.debugStr()); - route.setTripNumber(tripNumber); - return null; + } } + if (!conflictInfo.isEmpty()) { + return conflictInfo; + } - private CtcStationRunPlanLog getCtcStationRunPlan(Simulation simulation, String stationCode, String tripNumber) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - return ctcRepository.getRunPlan(stationCode, tripNumber); - } + Route.CheckFailMessage checkFailMessage = ciApiService.settingRoute(simulation, routeCode); + if (checkFailMessage != null) { + throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception(checkFailMessage.debugStr()); + } + route.setTripNumber(tripNumber); + return null; + } - private CtcStationRunPlanLog getCtcStationRunPlanByRunPlanCode(Simulation simulation, String stationCode, String runPlanCode) { - CtcRepository ctcRepository = simulation.getCtcRepository(); - return ctcRepository.getRunPlanByRunPlanCode(stationCode, runPlanCode); - } + private CtcStationRunPlanLog getCtcStationRunPlan(Simulation simulation, String stationCode, + String tripNumber) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + return ctcRepository.getRunPlan(stationCode, tripNumber); + } + + private CtcStationRunPlanLog getCtcStationRunPlanByRunPlanCode(Simulation simulation, + String stationCode, String runPlanCode) { + CtcRepository ctcRepository = simulation.getCtcRepository(); + return ctcRepository.getRunPlanByRunPlanCode(stationCode, runPlanCode); + } }