diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcManageOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcManageOperateHandler.java new file mode 100644 index 000000000..42a98cc28 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcManageOperateHandler.java @@ -0,0 +1,93 @@ +package club.joylink.rtss.simulation.cbtc.ATS.operation.handler; + +import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; +import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler; +import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandlerMapping; +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.ATS.service.runplan.CtcManageService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +/** + * 车务管理终端操作 + */ +@OperateHandler +@Slf4j +public class CtcManageOperateHandler { + + @Autowired + private CtcManageService ctcManageService; + + /** + * 保存行车日志到编辑区 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + * @param runPlanParamList 运行计划 + */ + @OperateHandlerMapping(type = Operation.Type.CTC_ADD_RUN_PLAN_LIST_TO_EDIT_AREA) + public void saveRunPlanListToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { + ctcManageService.saveRunPlanListToEditArea(simulation, stationCode, runPlanParamList); + } + + + /** + * 将车站编辑区的行车日志发布至生效区 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + */ + @OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION) + public void releaseRunPlanToSimulation(Simulation simulation, String stationCode) { + ctcManageService.releaseRunPlanToEffectAreaMap(simulation, stationCode); + } + + /** + * 导入覆盖车站编辑区行车日志 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + * @param runPlanParamList 运行计划 + */ + @OperateHandlerMapping(type = Operation.Type.CTC_COVER_RUN_PLAN_LIST_TO_EDIT_AREA) + public void coverRunPlanToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { + ctcManageService.coverRunPlanToEditArea(simulation, stationCode, runPlanParamList); + } + + /** + * 将车站编辑区中删除车次内容 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + * @param runPlanCode 车次 + */ + @OperateHandlerMapping(type = Operation.Type.CTC_REMOVE_RUN_PLAN_FROM_EDIT_AREA) + public void removeRunPlanFromEditArea(Simulation simulation, String stationCode, String runPlanCode) { + ctcManageService.removeRunPlanFromEditArea(simulation, stationCode, runPlanCode); + } + + /** + * 清空车站编辑区内容 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + */ + @OperateHandlerMapping(type = Operation.Type.CTC_CLEAR_RUN_PLAN_FROM_EDIT_AREA) + public void clearRunPlanFromEditArea(Simulation simulation, String stationCode) { + ctcManageService.clearRunPlanFromEditArea(simulation, stationCode); + } + + /** + * 将车站编辑区的行车日志发布至生效区 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + */ + @OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION) + public void effectRunPlanToSimulation(Simulation simulation, String stationCode) { + ctcManageService.releaseRunPlanToStation(simulation, stationCode); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcStationRunPlanOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcStationRunPlanOperateHandler.java index 53cdc60cd..97a838c2e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcStationRunPlanOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcStationRunPlanOperateHandler.java @@ -92,63 +92,6 @@ public class CtcStationRunPlanOperateHandler { ctcStationRunPlanLogService.removeRunPlan(simulation, stationCode, runPlanCode); } - /** - * 添加行车日志到编辑区 - * - * @param simulation 仿真实体 - * @param runPlanParamList 运行计划 - */ - @OperateHandlerMapping(type = Operation.Type.CTC_ADD_RUN_PLAN_LIST_TO_EDIT_AREA) - public void addRunPlanToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { - ctcStationRunPlanLogService.addRunPlanListToEditArea(simulation, stationCode, runPlanParamList); - } - - /** - * 将车站编辑区的行车日志发布至生效区 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - */ - @OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION) - public void releaseRunPlanToSimulation(Simulation simulation, String stationCode) { - ctcStationRunPlanLogService.releaseRunPlanToSimulation(simulation, stationCode); - } - - /** - * 导入覆盖车站编辑区行车日志 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - * @param runPlanParamList 运行计划列表 - */ - @OperateHandlerMapping(type = Operation.Type.CTC_COVER_RUN_PLAN_LIST_TO_EDIT_AREA) - public void coverRunPlanToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { - ctcStationRunPlanLogService.coverRunPlanToEditArea(simulation, stationCode, runPlanParamList); - } - - /** - * 将车站编辑区中删除车次内容 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - * @param runPlanCode 车次 - */ - @OperateHandlerMapping(type = Operation.Type.CTC_REMOVE_RUN_PLAN_FROM_EDIT_AREA) - public void removeRunPlanFromEditArea(Simulation simulation, String stationCode, String runPlanCode) { - ctcStationRunPlanLogService.removeRunPlanFromEditArea(simulation, stationCode, runPlanCode); - } - - /** - * 清空车站编辑区内容 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - */ - @OperateHandlerMapping(type = Operation.Type.CTC_CLEAR_RUN_PLAN_FROM_EDIT_AREA) - public void clearRunPlanFromEditArea(Simulation simulation, String stationCode) { - ctcStationRunPlanLogService.clearRunPlanFromEditArea(simulation, stationCode); - } - /** * CTC行车日志:发送发车预告 */ @@ -167,13 +110,13 @@ public class CtcStationRunPlanOperateHandler { /** - * 将CTC生效区发布至车站 + * 签收阶段计划 * - * @param simulation 仿真实体 - * @param stationCode 车站编码 + * @param simulation 仿真 + * @param stationCode 车站 */ - @OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_EFFECT_AREA_TO_STATION) - public void effectAreaToStation(Simulation simulation, String stationCode) { - ctcStationRunPlanLogService.effectAreaToStation(simulation, stationCode); + public void signForRunPlan(Simulation simulation, String stationCode) { + ctcStationRunPlanLogService.signForRunPlan(simulation, stationCode); } + } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcZoneOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcZoneOperateHandler.java new file mode 100644 index 000000000..393ed71e3 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/CtcZoneOperateHandler.java @@ -0,0 +1,70 @@ +package club.joylink.rtss.simulation.cbtc.ATS.operation.handler; + +import club.joylink.rtss.simulation.cbtc.ATS.operation.annotation.OperateHandler; +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.ATS.service.runplan.CtcZoneService; +import club.joylink.rtss.simulation.cbtc.Simulation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * 区段行驶计划集中调度 + */ +@OperateHandler +@Slf4j +public class CtcZoneOperateHandler { + + @Autowired + private CtcZoneService ctcZoneService; + + /** + * 行车线保存行车计划 + * + * @param simulation 仿真 + * @param zoneCode 区间编码 + * @param planParam 行车计划 + */ + public void saveRunPlan(Simulation simulation, String zoneCode, CtcRunPlanParam planParam) { + ctcZoneService.saveRunPlan(simulation, zoneCode, planParam); + } + + /** + * 删除行车线中的行车计划(状态删除) + * + * @param simulation 仿真 + * @param zoneCode 区间编码 + * @param runPlanCode 行车计划编码 + */ + public void deleteRunPlan(Simulation simulation, String zoneCode, String stationCode, String runPlanCode) { + ctcZoneService.delRunPlan(simulation, zoneCode, stationCode, runPlanCode); + } + + /** + * 行车线发送行车计划 + * + * @param simulation 仿真 + * @param zoneCode 区间编码 + */ + public void releaseRunPlan(Simulation simulation, String zoneCode) { + ctcZoneService.releaseRunPlan(simulation, zoneCode); + } + + /** + * 发布车站的行车计划 + * + * @param simulation 仿真 + * @param stationCode 车站编码 + */ + public void releaseStationRunPlan(Simulation simulation, String stationCode) { + ctcZoneService.releaseStationRunPlan(simulation, stationCode); + } + + /** + * 发布所有的行车计划 + * + * @param simulation 仿真 + */ + public void releaseAllRunPlan(Simulation simulation) { + ctcZoneService.releaseAllRunPlan(simulation); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/vo/CtcRunPlanParam.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/vo/CtcRunPlanParam.java index 98a6bc4ec..7fb2a3946 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/vo/CtcRunPlanParam.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/vo/CtcRunPlanParam.java @@ -26,6 +26,11 @@ public class CtcRunPlanParam implements Cloneable { */ private String stationCode; + /** + * 班别 + */ + private String groupNumber; + /** * 运行计划车次信息 */ @@ -46,11 +51,21 @@ public class CtcRunPlanParam implements Cloneable { */ private String departSectionCode; + /** + * 到达计划时间 + */ + private LocalTime arrivePlanTime; + /** * 到达时间 */ private LocalTime arriveTime; + /** + * 发车计划时间 + */ + private LocalTime departPlanTime; + /** * 发车时间 */ @@ -152,13 +167,11 @@ public class CtcRunPlanParam implements Cloneable { /** * 生成主键 - * - * @return 主键 */ - public String generateId() { - return this.getTripNumber() - + (StringUtils.isEmpty(this.arriveDirectionCode) ? "_" : this.arriveDirectionCode) - + (StringUtils.isEmpty(this.departDirectionCode) ? "_" : this.departDirectionCode); + public void generateRunPlanCodeAndTripNumber() { + this.tripNumber = StringUtils.isEmpty(this.tripNumber) ? + (StringUtils.isEmpty(this.arriveTripNumber) ? this.departTripNumber : this.arriveTripNumber) : this.tripNumber; + this.runPlanCode = StringUtils.isEmpty(this.runPlanCode) ? (this.groupNumber + this.tripNumber) : this.runPlanCode; } public CtcRunPlanParam compareAndChange(CtcRunPlanParam modify) { @@ -175,6 +188,11 @@ public class CtcRunPlanParam implements Cloneable { runPlanParam.setTripNumber(modify.getTripNumber()); change = true; } + if (!Objects.equals(this.groupNumber, modify.getGroupNumber())) { + this.groupNumber = modify.getGroupNumber(); + runPlanParam.setGroupNumber(this.getGroupNumber()); + change = true; + } if (!Objects.equals(this.trackSectionCode, modify.getTrackSectionCode())) { this.trackSectionCode = modify.getTrackSectionCode(); runPlanParam.setTrackSectionCode(modify.getTrackSectionCode()); @@ -190,11 +208,21 @@ public class CtcRunPlanParam implements Cloneable { runPlanParam.setDepartSectionCode(modify.getDepartSectionCode()); change = true; } + if (!Objects.equals(this.arrivePlanTime, modify.getArrivePlanTime())) { + this.arrivePlanTime = modify.getArrivePlanTime(); + runPlanParam.setArrivePlanTime(modify.getArrivePlanTime()); + change = true; + } if (!Objects.equals(this.arriveTime, modify.getArriveTime())) { this.arriveTime = modify.getArriveTime(); runPlanParam.setArriveTime(modify.getArriveTime()); change = true; } + if (!Objects.equals(this.departPlanTime, modify.getDepartPlanTime())) { + this.departPlanTime = modify.getDepartPlanTime(); + runPlanParam.setDepartPlanTime(modify.getDepartPlanTime()); + change = true; + } if (!Objects.equals(this.departTime, modify.getDepartTime())) { this.departTime = modify.getDepartTime(); runPlanParam.setDepartTime(modify.getDepartTime()); @@ -220,7 +248,6 @@ public class CtcRunPlanParam implements Cloneable { runPlanParam.setDepartStationCode(modify.getDepartStationCode()); change = true; } - if (!Objects.equals(this.arriveDirectionCode, modify.getArriveDirectionCode())) { this.arriveDirectionCode = modify.getArriveDirectionCode(); runPlanParam.setArriveDirectionCode(modify.getArriveDirectionCode()); diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcManageService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcManageService.java new file mode 100644 index 000000000..c0b750164 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcManageService.java @@ -0,0 +1,157 @@ +package club.joylink.rtss.simulation.cbtc.ATS.service.runplan; + +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcManageRepository; +import club.joylink.rtss.simulation.cbtc.Simulation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class CtcManageService { + + @Autowired + private CtcStationRunPlanLogService ctcStationRunPlanLogService; + + /** + * 往行车线保存行车计划 + * + * @param simulation 仿真 + * @param stationCode 车站 + * @param runPlanParamList 行车计划 + */ + public void saveRunPlanListToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { + CtcManageRepository manageRepository = getManageRepository(simulation, stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository); + for (CtcRunPlanParam p : runPlanParamList) { + long num = manageRepository.editExitTripNumberNum(p.getArriveTripNumber(), p.getDepartTripNumber()); + p.setGroupNumber(String.valueOf(num + 1)); + p.generateRunPlanCodeAndTripNumber(); + if (StringUtils.isEmpty(p.getDepartSectionCode())) { + p.setDepartSectionCode(p.getTrackSectionCode()); + } + if (StringUtils.isEmpty(p.getArriveSectionCode())) { + p.setArriveSectionCode(p.getTrackSectionCode()); + } + manageRepository.saveRunPlanToEditArea(p); + } + } + + /** + * 将车站编辑区的行车日志发布至生效区 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + */ + public void releaseRunPlanToEffectAreaMap(Simulation simulation, String stationCode) { + CtcManageRepository manageRepository = getManageRepository(simulation, stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository); + // 获取编辑区的固定路径数据 + CtcManageRepository.StationRunPlanRepository editRepository = manageRepository.getStationRunPlanRepository(true); + // 编辑区版本 + 1 + int version = editRepository.getVersion().incrementAndGet(); + // 生成新的计划数据 + Map runPlanParamMap = editRepository.getRunPlanParamMap().values().stream() + .map(CtcRunPlanParam::clone).collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, p -> p)); + // 获取生效区实体 + CtcManageRepository.StationRunPlanRepository effectRepository = manageRepository.getStationRunPlanRepository(false); + // 版本覆盖\计划清空\导入计划 + manageRepository.releaseEffectArea(simulation.getCorrectSystemTime(), version, runPlanParamMap); + } + + + /** + * 覆盖编辑区行车计划 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + * @param runPlanParamList 行车计划 + */ + public void coverRunPlanToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { + CtcManageRepository manageRepository = getManageRepository(simulation, stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository); + // 获取固定路径数据 + CtcManageRepository.StationRunPlanRepository runPlanRepository = manageRepository.getStationRunPlanRepository(true); + Map runPlanParamMap = runPlanParamList.stream().map(p -> { + p.generateRunPlanCodeAndTripNumber(); + if (StringUtils.isEmpty(p.getDepartSectionCode())) { + p.setDepartSectionCode(p.getTrackSectionCode()); + } + if (StringUtils.isEmpty(p.getArriveSectionCode())) { + p.setArriveSectionCode(p.getTrackSectionCode()); + } + return p; + }).collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, p -> p)); + // 清空 + runPlanRepository.getRunPlanParamMap().clear(); + // 覆盖 + runPlanRepository.getRunPlanParamMap().putAll(runPlanParamMap); + } + + /** + * 将车站编辑区中删除车次内容 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + * @param runPlanCode 车次 + */ + public void removeRunPlanFromEditArea(Simulation simulation, String stationCode, String runPlanCode) { + CtcManageRepository manageRepository = getManageRepository(simulation, stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository); + // 获取编辑区的固定路径数据 + CtcManageRepository.StationRunPlanRepository runPlanRepository = manageRepository.getStationRunPlanRepository(true); + runPlanRepository.getRunPlanParamMap().remove(runPlanCode); + } + + /** + * 全部清空 + * + * @param simulation 仿真修改 + * @param stationCode 车站编码 + */ + public void clearRunPlanFromEditArea(Simulation simulation, String stationCode) { + CtcManageRepository manageRepository = getManageRepository(simulation, stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository); + // 获取固定路径数据 + CtcManageRepository.StationRunPlanRepository runPlanRepository = manageRepository.getStationRunPlanRepository(true); + // 清空 + runPlanRepository.getRunPlanParamMap().clear(); + } + + /** + * 将车站编辑区的行车日志发布至生效区 + * + * @param simulation 仿真实体 + * @param stationCode 车站编码 + */ + public void releaseRunPlanToStation(Simulation simulation, String stationCode) { + CtcManageRepository manageRepository = getManageRepository(simulation, stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(manageRepository); + Map runPlanParamMap = manageRepository.getRunPlanMap(false); + if (!CollectionUtils.isEmpty(runPlanParamMap)) { + ctcStationRunPlanLogService.modifyBatchRunPlan(simulation, stationCode, new ArrayList<>(runPlanParamMap.values()), 1); + } + } + + /** + * 获取关联车站的车务管理端数据实体 + * + * @param simulation 仿真 + * @param stationCode 车站 + * @return 车务管理终端 + */ + private CtcManageRepository getManageRepository(Simulation simulation, String stationCode) { + CtcManageRepository ctcManageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(ctcManageRepository); + return ctcManageRepository; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java index e23b4157c..f9ab1ed9c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcStationRunPlanLogService.java @@ -1,42 +1,34 @@ package club.joylink.rtss.simulation.cbtc.ATS.service.runplan; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; -import club.joylink.rtss.simulation.cbtc.CTC.CTCLogicLoop; import club.joylink.rtss.simulation.cbtc.CTC.CTCService; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcManageRepository; import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcZoneRepository; import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence; import club.joylink.rtss.simulation.cbtc.Simulation; 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.StationDirection; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; -import club.joylink.rtss.websocket.StompMessageService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.time.LocalTime; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; @Component @Slf4j public class CtcStationRunPlanLogService { - @Autowired - private StompMessageService stompMessageService; - - @Autowired - private ApplicationContext applicationContext; - - @Autowired - private CTCLogicLoop ctcLogicLoop; - @Autowired private CTCService ctcService; @@ -97,116 +89,6 @@ public class CtcStationRunPlanLogService { }); } - /** - * 批量往编辑区添加运行计划 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - * @param runPlanParamList 运行计划列表 - */ - public void addRunPlanListToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { - Map stationRunPlanMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap() - .getOrDefault(stationCode, new ConcurrentHashMap<>(64)); - boolean isEmpty = CollectionUtils.isEmpty(stationRunPlanMap); - runPlanParamList.forEach(p -> { - String tripNumber = StringUtils.isEmpty(p.getArriveTripNumber()) ? p.getDepartTripNumber() : p.getArriveTripNumber(); - p.setTripNumber(tripNumber); - p.setRunPlanCode(tripNumber); - if (StringUtils.isEmpty(p.getDepartSectionCode())) { - p.setDepartSectionCode(p.getTrackSectionCode()); - } - if (StringUtils.isEmpty(p.getArriveSectionCode())) { - p.setArriveSectionCode(p.getTrackSectionCode()); - } - if (stationRunPlanMap.containsKey(tripNumber)) { - modifyRunPlanParam(stationRunPlanMap.get(tripNumber), p); - } else { - stationRunPlanMap.put(tripNumber, p); - } - }); - if (isEmpty) { - simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().put(stationCode, stationRunPlanMap); - } - } - - /** - * 将车站编辑区中删除车次内容 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - * @param runPlanCode 车次 - */ - public void removeRunPlanFromEditArea(Simulation simulation, String stationCode, String runPlanCode) { - Map stationRunLogTripNumberMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().get(stationCode); - if (!CollectionUtils.isEmpty(stationRunLogTripNumberMap)) { - stationRunLogTripNumberMap.remove(runPlanCode); - } - } - - /** - * 全部清空 - * - * @param simulation 仿真修改 - * @param stationCode 车站编码 - */ - public void clearRunPlanFromEditArea(Simulation simulation, String stationCode) { - simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().remove(stationCode); - } - - /** - * 覆盖编辑区中的运行计划 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - * @param runPlanParamList 运行计划列表 - */ - public void coverRunPlanToEditArea(Simulation simulation, String stationCode, List runPlanParamList) { - // 运行计划 - runPlanParamList.forEach(p -> { - String tripNumber = StringUtils.isEmpty(p.getArriveTripNumber()) - ? p.getDepartTripNumber() : p.getArriveTripNumber(); - p.setTripNumber(tripNumber); - p.setRunPlanCode(tripNumber); - }); - Map planParamMap - = runPlanParamList.stream().collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, (p) -> p)); - simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().put(stationCode, planParamMap); - } - - /** - * 将车站编辑区的行车日志发布至生效区 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - */ - public void releaseRunPlanToSimulation(Simulation simulation, String stationCode) { - // 编辑区信息 - Map planParamMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap() - .getOrDefault(stationCode, new ConcurrentHashMap<>()); - // 编辑区版本 + 1 - AtomicInteger editVersion = simulation.getCtcRepository().getStationEditAreaVersion() - .getOrDefault(stationCode, new AtomicInteger(0)); - editVersion.decrementAndGet(); - simulation.getCtcRepository().getStationEditAreaVersion().put(stationCode, editVersion); - // 发布至生效区中 - simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap().put(stationCode, planParamMap); - AtomicInteger effectVersion = new AtomicInteger(editVersion.get()); // 覆盖生效区版本 - simulation.getCtcRepository().getStationEffectAreaVersion().put(stationCode, effectVersion); - } - - /** - * 【生效至车站】操作中 - * - * @param simulation 仿真实体 - * @param stationCode 车站编码 - */ - public void effectAreaToStation(Simulation simulation, String stationCode) { - Map runPlanParamMap = simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap() - .get(stationCode); - if (!CollectionUtils.isEmpty(runPlanParamMap)) { - modifyBatchRunPlan(simulation, stationCode, new ArrayList<>(runPlanParamMap.values()), 1); - } - } /** * 人工上报行车日志的到点时间 @@ -300,6 +182,24 @@ public class CtcStationRunPlanLogService { } } + /** + * 签收阶段计划 + * + * @param simulation 仿真实体 + * @param stationCode 要签收的车站 + */ + public void signForRunPlan(Simulation simulation, String stationCode) { + CtcZoneRepository ctcZoneRepository = simulation.getCtcRepository().getZoneRepository().values().stream() + .filter(c -> c.getStationMap().containsKey(stationCode)).findFirst().orElse(null); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(ctcZoneRepository); + CtcManageRepository.StationRunPlanRepository repository = ctcZoneRepository.getEffectRunPlanMap().get(stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(repository); + Map runPlanParamMap = repository.getRunPlanParamMap(); + if (!CollectionUtils.isEmpty(runPlanParamMap)) { + modifyBatchRunPlan(simulation, stationCode, new ArrayList<>(runPlanParamMap.values()), 1); + } + } + /** * 修改原始数据,并返回修改属性的对象 * @@ -363,6 +263,11 @@ public class CtcStationRunPlanLogService { private boolean modifyRunPlanItemInfo(Simulation simulation, CtcStationRunPlanLog.RunPlanItem runPlanItem, CtcRunPlanParam paramInfo, boolean arrive) { boolean change = false; if (runPlanItem != null) { + // 计划时间 + LocalTime planTime = arrive ? paramInfo.getArrivePlanTime() : paramInfo.getDepartPlanTime(); + if (planTime != null && !Objects.equals(planTime, runPlanItem.getPlanTime())) { + runPlanItem.setPlanTime(planTime); + } // 实际时间 LocalTime actualTime = arrive ? paramInfo.getArriveTime() : paramInfo.getDepartTime(); if (actualTime != null && !Objects.equals(actualTime.toString(), runPlanItem.getActualTime())) { @@ -391,6 +296,14 @@ public class CtcStationRunPlanLogService { runPlanItem.setStation(station); } } + // 到达口 + String directionCode = arrive ? paramInfo.getArriveDirectionCode() : paramInfo.getDepartDirectionCode(); + if (!StringUtils.isEmpty(directionCode)) { + StationDirection stationDirection = simulation.getRepository().getByCode(directionCode, StationDirection.class); + if (!Objects.equals(stationDirection, runPlanItem.getStationDirection())) { + runPlanItem.setStationDirection(stationDirection); + } + } } return change; } @@ -404,11 +317,8 @@ public class CtcStationRunPlanLogService { * @return 行车日志 */ private CtcStationRunPlanLog createRunPlanLog(Simulation simulation, String stationCode, CtcRunPlanParam paramInfo) { + paramInfo.generateRunPlanCodeAndTripNumber(); String tripNumber = paramInfo.getTripNumber(); - if (StringUtils.isEmpty(tripNumber)) { - tripNumber = StringUtils.isEmpty(paramInfo.getArriveTripNumber()) ? paramInfo.getDepartTripNumber() : paramInfo.getArriveTripNumber(); - } - paramInfo.setTripNumber(tripNumber); CtcStationRunPlanLog ctcStationRunPlanLog = new CtcStationRunPlanLog(paramInfo); ctcStationRunPlanLog.setCode(tripNumber); Station station = simulation.getRepository().getByCode(stationCode, Station.class); @@ -417,79 +327,4 @@ public class CtcStationRunPlanLogService { ctcStationRunPlanLog.setDepartRunPlan(CtcStationRunPlanLog.createRunPlanItem(simulation, paramInfo, false)); return ctcStationRunPlanLog; } - - /** - * 编辑运行计划参数 - * - * @param original 原始参数 - * @param modify 修改参数 - */ - private void modifyRunPlanParam(CtcRunPlanParam original, CtcRunPlanParam modify) { - if (modify.getStationCode() != null - && !Objects.equals(original.getStationCode(), modify.getStationCode())) { - original.setStationCode(modify.getStationCode()); - } - if (modify.getTripNumber() != null - && !Objects.equals(original.getTripNumber(), modify.getTripNumber())) { - original.setTripNumber(modify.getTripNumber()); - } - if (modify.getTrackSectionCode() != null - && !Objects.equals(original.getTrackSectionCode(), modify.getTrackSectionCode())) { - original.setTrackSectionCode(modify.getTrackSectionCode()); - } - if (modify.getArriveSectionCode() != null - && !Objects.equals(original.getArriveSectionCode(), modify.getArriveSectionCode())) { - original.setArriveSectionCode(modify.getArriveSectionCode()); - } - if (modify.getDepartSectionCode() != null - && !Objects.equals(original.getDepartSectionCode(), modify.getDepartSectionCode())) { - original.setDepartSectionCode(modify.getDepartSectionCode()); - } - if (modify.getArriveTime() != null - && !Objects.equals(original.getArriveTime(), modify.getArriveTime())) { - original.setArriveTime(modify.getArriveTime()); - } - if (modify.getDepartTime() != null - && !Objects.equals(original.getDepartTime(), modify.getDepartTime())) { - original.setDepartTime(modify.getDepartTime()); - } - if (modify.getArriveTripNumber() != null - && !Objects.equals(original.getArriveTripNumber(), modify.getArriveTripNumber())) { - original.setArriveTripNumber(modify.getArriveTripNumber()); - } - if (modify.getDepartTripNumber() != null - && !Objects.equals(original.getDepartTripNumber(), modify.getDepartTripNumber())) { - original.setDepartTripNumber(modify.getDepartTripNumber()); - } - if (modify.getArriveStationCode() != null - && !Objects.equals(original.getArriveStationCode(), modify.getArriveStationCode())) { - original.setArriveStationCode(modify.getArriveStationCode()); - } - if (modify.getDepartStationCode() != null - && !Objects.equals(original.getDepartStationCode(), modify.getDepartStationCode())) { - original.setDepartStationCode(modify.getDepartStationCode()); - } - - if (modify.getArriveDirectionCode() != null - && !Objects.equals(original.getArriveDirectionCode(), modify.getArriveDirectionCode())) { - original.setArriveDirectionCode(modify.getArriveDirectionCode()); - } - if (modify.getDepartDirectionCode() != null - && !Objects.equals(original.getDepartDirectionCode(), modify.getDepartDirectionCode())) { - original.setDepartDirectionCode(modify.getDepartDirectionCode()); - } - // 存在不一样的选项 - Map modifyMap = new HashMap<>(); - modify.getRunPlanTaskMap().forEach((k, v) -> { - if (!original.getRunPlanTaskMap().containsKey(k) && !Objects.equals(original.getRunPlanTaskMap().get(k), v)) { - modifyMap.put(k, v); - } - }); - if (original.getRunPlanTaskMap().size() != modify.getRunPlanTaskMap().size() || !CollectionUtils.isEmpty(modifyMap)) { - original.getRunPlanTaskMap().putAll(modify.getRunPlanTaskMap()); - } - if (!Objects.equals(original.getStatus(), modify.getStatus())) { - original.setStatus(modify.getStatus()); - } - } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcZoneService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcZoneService.java new file mode 100644 index 000000000..b0581c324 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/service/runplan/CtcZoneService.java @@ -0,0 +1,83 @@ +package club.joylink.rtss.simulation.cbtc.ATS.service.runplan; + +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcManageRepository; +import club.joylink.rtss.simulation.cbtc.CTC.data.CtcZoneRepository; +import club.joylink.rtss.simulation.cbtc.Simulation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@Slf4j +public class CtcZoneService { + + /** + * 往行车线保存行车计划 + * + * @param simulation 仿真 + * @param zoneCode 区间编码 + * @param planParam 行车计划 + */ + public void saveRunPlan(Simulation simulation, String zoneCode, CtcRunPlanParam planParam) { + CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().get(zoneCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository); + // 初始化运行计划编码、车次信息 + planParam.generateRunPlanCodeAndTripNumber(); + railwayRepository.saveRunPlan(planParam); + } + + /** + * 删除行车线中的行车计划(状态删除) + * + * @param simulation 仿真 + * @param zoneCode 区间编码 + * @param runPlanCode 行车计划编码 + */ + public void delRunPlan(Simulation simulation, String zoneCode, String stationCode, String runPlanCode) { + CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().get(zoneCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository); + railwayRepository.delRunPlan(stationCode, runPlanCode); + } + + /** + * 行车线发送行车计划 + * + * @param simulation 仿真 + * @param zoneCode 区间编码 + */ + public void releaseRunPlan(Simulation simulation, String zoneCode) { + CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().get(zoneCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository); + // 发布至生效区 + railwayRepository.releaseRunPlan(simulation.getCorrectSystemTime()); + } + + /** + * 发布车站的行车计划 + * + * @param simulation 仿真 + * @param stationCode 车站编码 + */ + public void releaseStationRunPlan(Simulation simulation, String stationCode) { + CtcZoneRepository railwayRepository = simulation.getCtcRepository().getZoneRepository().values().stream() + .filter(r -> r.getStationMap().containsKey(stationCode)).findFirst().orElse(null); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(railwayRepository); + railwayRepository.releaseRunPlanByStationCode(stationCode, simulation.getCorrectSystemTime()); + } + + /** + * 全量发布 + * + * @param simulation 仿真 + */ + public void releaseAllRunPlan(Simulation simulation) { + Map stagePlanMap = simulation.getCtcRepository().getManageRepositoryMap(); + simulation.getCtcRepository().getZoneRepository().forEach((zoneCode, railwayRepository) -> { + // 发布至生效区 + railwayRepository.releaseRunPlan(simulation.getCorrectSystemTime()); + }); + } +} 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 2e61ef290..4d76c9000 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 @@ -46,11 +46,9 @@ public class CTCLogicLoop { sendRunPlanChangeMessage(simulation); sendRunPlanRemoveMessage(simulation); // 发送车务管理端消息(编辑区) - sendCtcManageChangeMessage(simulation); - sendCtcManageRemoveMessage(simulation); - // 车务管理端消息(生效区) - sendCtcManageEffectChangeMessage(simulation); - sendCtcManageEffectRemoveMessage(simulation); + sendManageChange(simulation); + sendManageRemove(simulation); + } public void sendAllMessage(Simulation simulation) { @@ -234,8 +232,79 @@ public class CTCLogicLoop { simulation.addFixedRateJob(MESSAGE_NAME, () -> this.sendMessage(simulation), MESSAGE_RATE); } + /** - * 发送CTC初始变化 + * 发送铁路局、行车区段信息列表 + * + * @param simulation 仿真 + * @param userIds 用户 + */ + public void sendAllRailwayInfo(Simulation simulation, Set userIds) { + List ctcZoneVOList = simulation.getCtcRepository().getZoneRepository().values().stream() + .map(r -> new CtcZoneVO(r.getCtcZone())).collect(Collectors.toList()); + sendCtcMessage(simulation.getId(), ctcZoneVOList, WebSocketMessageType.SIMULATION_CTC_ZONE, simulation.getSimulationUserIds()); + } + + /** + * 初始时发送 + * + * @param simulation 仿真 + * @param userIds 用户 + */ + public void sendAllManageChange(Simulation simulation, Set userIds) { + CtcManageRepositoryVO ctcManageRepositoryVO = simulation.getCtcRepository().getCtcManageRepositoryVO(); + synchronized (ctcManageRepositoryVO) { + List allList = new ArrayList<>(); + if (ctcManageRepositoryVO.getEditAreaCtcRunPlanParamVOMap().isEmpty()) { + simulation.getCtcRepository().getManageRepositoryMap().forEach((k, v) -> { + allList.addAll(ctcManageRepositoryVO.compareAndReturnChangeRunPlan(v.getEditAreaMap().getRunPlanRepository(), true)); + }); + } else { + allList.addAll(ctcManageRepositoryVO.getEditAreaCtcRunPlanParamVOMap().values()); + } + if (!CollectionUtils.isEmpty(allList)) { + sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_INIT + , userIds); + } + } + } + + /** + * 发送管理端【编辑区】变更数据 + * + * @param simulation 仿真数据 + */ + public void sendManageChange(Simulation simulation) { + CtcManageRepositoryVO ctcManageRepositoryVO = simulation.getCtcRepository().getCtcManageRepositoryVO(); + List allList = new ArrayList<>(); + simulation.getCtcRepository().getManageRepositoryMap().forEach((k, v) -> { + allList.addAll(ctcManageRepositoryVO.compareAndReturnChangeRunPlan(v.getEditAreaMap().getRunPlanRepository(), true)); + }); + if (!CollectionUtils.isEmpty(allList)) { + sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_CHANGE + , simulation.getSimulationUserIds()); + } + } + + /** + * 发送管理端【编辑区数据】删除数据 + * + * @param simulation 仿真数据 + */ + public void sendManageRemove(Simulation simulation) { + CtcManageRepositoryVO ctcManageRepositoryVO = simulation.getCtcRepository().getCtcManageRepositoryVO(); + List allList = new ArrayList<>(); + simulation.getCtcRepository().getManageRepositoryMap().forEach((k, v) -> { + allList.addAll(ctcManageRepositoryVO.compareAndReturnRemoveRunPlan(v.getEditAreaMap().getRunPlanRepository(), true)); + }); + if (!CollectionUtils.isEmpty(allList)) { + sendCtcMessage(simulation.getId(), allList + , WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_REMOVE, simulation.getSimulationUserIds()); + } + } + + /** + * 发送CTC初始行车日志变化 * * @param simulation 仿真实体 * @param userIds 用户ID @@ -310,150 +379,6 @@ public class CTCLogicLoop { } } - /** - * @param simulation 仿真实体 - * @param userIds 用户ID - */ - public void initCtcManageMessage(Simulation simulation, Set userIds) { - synchronized (this) { - Map editAreaStatusVOMap = simulation.getCtcRepository().getEditAreaStatusVOMap(); - List allList = new ArrayList<>(); - if (CollectionUtils.isEmpty(editAreaStatusVOMap)) { - simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().forEach((k, v) -> { - v.values().stream().forEach(p -> { - String mapKey = p.getStationCode() + "_" + p.getRunPlanCode(); - editAreaStatusVOMap.put(mapKey, p.clone()); - allList.add(p); - }); - }); - } else { - allList.addAll(editAreaStatusVOMap.values()); - } - if (!CollectionUtils.isEmpty(allList)) { - sendCtcMessage(simulation.getId(), allList - , WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_INIT, userIds); - } - } - } - - /** - * 发送管理端信息变更消息 - * - * @param simulation 仿真实体 - */ - public void sendCtcManageChangeMessage(Simulation simulation) { - Map editAreaStatusVOMap = simulation.getCtcRepository().getEditAreaStatusVOMap(); - List allList = new ArrayList<>(); - simulation.getCtcRepository().getSimulationRunPlanEditAreaMap().forEach((k, v) -> { - v.values().stream().forEach(p -> { - String mapKey = p.getStationCode() + "_" + p.getRunPlanCode(); - CtcRunPlanParam param = editAreaStatusVOMap.get(mapKey); - CtcRunPlanParam changeCtcRunPlanVo = null; - if (param == null) { - changeCtcRunPlanVo = p.clone(); - editAreaStatusVOMap.put(mapKey, changeCtcRunPlanVo); - allList.add(editAreaStatusVOMap.get(mapKey)); - } else { - changeCtcRunPlanVo = param.compareAndChange(p); - if (changeCtcRunPlanVo != null) { - allList.add(changeCtcRunPlanVo); - } - } - }); - }); - if (!CollectionUtils.isEmpty(allList)) { - sendCtcMessage(simulation.getId(), allList - , WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_CHANGE, simulation.getSimulationUserIds()); - } - } - - /** - * 发送管理端信息删除消息 - * - * @param simulation 仿真实体 - */ - public void sendCtcManageRemoveMessage(Simulation simulation) { - // 状态,key:车站_车次 - Map editAreaStatusVOMap = simulation.getCtcRepository().getEditAreaStatusVOMap(); - // 编辑区,key:车站 key:车次 - Map> editeAreaMap = simulation.getCtcRepository().getSimulationRunPlanEditAreaMap(); - List messageInfo = editAreaStatusVOMap.values().stream().filter(vo -> { - Map map = editeAreaMap.get(vo.getStationCode()); - if (map == null) { - return true; - } - CtcRunPlanParam p = map.get(vo.getRunPlanCode()); - if (p == null) { - return true; - } - return false; - }).map(vo -> vo.buildRemoveParam()).collect(Collectors.toList()); - if (messageInfo != null && !messageInfo.isEmpty()) { - // 移除已删除状态 - messageInfo.forEach(vo -> editAreaStatusVOMap.remove(vo.getStationCode() + "_" + vo.getRunPlanCode())); - sendCtcMessage(simulation.getId(), messageInfo - , WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EDIT_REMOVE, simulation.getSimulationUserIds()); - } - } - - /** - * 发送生效区变化消息 - * - * @param simulation 仿真实体 - */ - public void sendCtcManageEffectChangeMessage(Simulation simulation) { - Map editAreaStatusVOMap = simulation.getCtcRepository().getEffectAreaStatusVOMap(); - List allList = new ArrayList<>(); - simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap().forEach((k, v) -> { - v.values().stream().forEach(p -> { - String mapKey = p.getStationCode() + "_" + p.getRunPlanCode(); - CtcRunPlanParam param = editAreaStatusVOMap.get(mapKey); - CtcRunPlanParam changeCtcRunPlanVo = null; - if (param == null) { - changeCtcRunPlanVo = p.clone(); - editAreaStatusVOMap.put(mapKey, changeCtcRunPlanVo); - allList.add(editAreaStatusVOMap.get(mapKey)); - } else { - changeCtcRunPlanVo = param.compareAndChange(p); - if (changeCtcRunPlanVo != null) { - allList.add(changeCtcRunPlanVo); - } - } - }); - }); - if (!CollectionUtils.isEmpty(allList)) { - sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EFFECT_CHANGE - , simulation.getSimulationUserIds()); - } - } - - /** - * 发送生效区移除消息 - * - * @param simulation 仿真实体 - */ - public void sendCtcManageEffectRemoveMessage(Simulation simulation) { - Map effectAreaStatusVOMap = simulation.getCtcRepository().getEffectAreaStatusVOMap(); - Map> effectAreaMap = simulation.getCtcRepository().getSimulationRunPlanEffectAreaMap(); - List messageInfo = effectAreaStatusVOMap.values().stream().filter(vo -> { - Map map = effectAreaMap.get(vo.getStationCode()); - if (map == null) { - return true; - } - CtcRunPlanParam p = map.get(vo.getRunPlanCode()); - if (p == null) { - return true; - } - return false; - }).map(vo -> vo.buildRemoveParam()).collect(Collectors.toList()); - if (!CollectionUtils.isEmpty(messageInfo)) { - // 移除已删除状态 - messageInfo.forEach(vo -> effectAreaStatusVOMap.remove(vo.getStationCode() + "_" + vo.getRunPlanCode())); - sendCtcMessage(simulation.getId(), messageInfo - , WebSocketMessageType.SIMULATION_CTC_MANAGER_RUN_PLAN_EFFECT_REMOVE, simulation.getSimulationUserIds()); - } - } - /** * 发送调度台消息 * diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcManageRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcManageRepository.java new file mode 100644 index 000000000..5993a34ec --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcManageRepository.java @@ -0,0 +1,248 @@ +package club.joylink.rtss.simulation.cbtc.CTC.data; + +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.data.map.StationDirection; +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 车务管理端数据(调度台、区段) + */ +@Getter +@Setter +public class CtcManageRepository { + /** + * 车站编码 + */ + private String stationCode; + + /** + * 编辑区 + */ + private ManageDataWorkspace editAreaMap; + + /** + * 生效区 + */ + private ManageDataWorkspace effectAreaMap; + + public CtcManageRepository(String stationCode) { + this.stationCode = stationCode; + this.editAreaMap = new ManageDataWorkspace(stationCode); + this.effectAreaMap = new ManageDataWorkspace(stationCode); + } + + /** + * 行车计划保存在编辑区 + * + * @param runPlanParam 行车计划 + */ + public void saveRunPlanToEditArea(CtcRunPlanParam runPlanParam) { + this.editAreaMap.saveRunPlan(runPlanParam); + } + + /** + * 行车计划保存在生效区 + * + * @param runPlanParam 行车计划 + */ + public void saveRunPlanToEffectArea(CtcRunPlanParam runPlanParam) { + this.effectAreaMap.saveRunPlan(runPlanParam); + } + + /** + * 获取行车日志实体 + * + * @param isEdit 是否编辑区 + * @return 日志实体 + */ + public StationRunPlanRepository getStationRunPlanRepository(boolean isEdit) { + return isEdit ? this.editAreaMap.getRunPlanRepository() : this.effectAreaMap.getRunPlanRepository(); + } + + /** + * 获取运行计划 + * + * @param isEdit 是否编辑区 + * @return 运行计划 + */ + public Map getRunPlanMap(boolean isEdit) { + StationRunPlanRepository runPlanRepository = isEdit ? this.editAreaMap.getRunPlanRepository() : this.effectAreaMap.getRunPlanRepository(); + return runPlanRepository.getRunPlanParamMap(); + } + + + /** + * 发布运行计划数据至生效区 + * + * @param updateDateTime 发布时间 + * @param version 版本 + * @param runPlanParamMap 发布内容 + */ + public void releaseEffectArea(LocalDateTime updateDateTime, Integer version, Map runPlanParamMap) { + StationRunPlanRepository effectRepository = this.getEffectAreaMap().getRunPlanRepository(); + if (version == null) { + effectRepository.getVersion().incrementAndGet(); // 生效区版本 +1 + } else { + effectRepository.getVersion().set(version); + } + effectRepository.getRunPlanParamMap().clear(); // 计划清空 + effectRepository.setUpdateTime(updateDateTime); // 更新时间 + effectRepository.getRunPlanParamMap().putAll(runPlanParamMap); + } + + /** + * 查看是否存在车次 + * + * @param arriver 到车次(优先) + * @param depart 发车次 + * @return 个数 + */ + public long editExitTripNumberNum(String arriver, String depart) { + String tripNumber = StringUtils.isEmpty(arriver) ? depart : arriver; + return this.getEffectAreaMap().getRunPlanRepository().getRunPlanParamMap().values().stream() + .filter(r -> r.getTripNumber().equals(tripNumber)).count(); + } + + public void rest() { + + } + + /** + * 管理端工作区 + */ + @Setter + @Getter + public class ManageDataWorkspace { + private String stationCode; + + /** + * 股道集合 + * 车站key + */ + private final StationTrackSectionRepository trackSectionRepository = new StationTrackSectionRepository(); + + /** + * 出入口集合 + * 车站key + */ + private final StationDoorRepository doorRepository = new StationDoorRepository(); + + /** + * 固定径路集合 + * 车站key + */ + private final StationRunPlanRepository runPlanRepository = new StationRunPlanRepository(); + + public ManageDataWorkspace(String stationCode) { + this.stationCode = stationCode; + this.trackSectionRepository.setStationCode(stationCode); + this.doorRepository.setStationCode(stationCode); + this.runPlanRepository.setStationCode(stationCode); + } + + /** + * 保存运行计划至车站 + * 车站编码 + * + * @param runPlanParam 保存运行计划 + */ + public void saveRunPlan(CtcRunPlanParam runPlanParam) { + this.runPlanRepository.saveRunPlan(runPlanParam); + } + + public void rest() { + + } + } + + /** + * 工作区信息公共字段以及公共方法 + */ + @Getter + @Setter + public abstract static class AbstractWorkspaceRepository { + /** + * 车站编码 + */ + protected String stationCode; + + /** + * 当前数据版本 + */ + protected AtomicInteger version; + + /** + * 最近变更时间 + */ + protected LocalDateTime updateTime; + } + + /** + * 车站股道数据 + */ + @Setter + @Getter + public static class StationTrackSectionRepository extends AbstractWorkspaceRepository { + private final Map trackSectionMap = new ConcurrentHashMap<>(); + + public void rest() { + + } + } + + /** + * 车站出入口 + */ + @Setter + @Getter + public static class StationDoorRepository extends AbstractWorkspaceRepository { + private final Map trackSectionMap = new ConcurrentHashMap<>(); + + public void rest() { + + } + } + + /** + * 固定进路信息 + */ + @Setter + @Getter + public static class StationRunPlanRepository extends AbstractWorkspaceRepository { + private final Map runPlanParamMap = new ConcurrentHashMap<>(); + + /** + * 保存运行计划 + * + * @param runPlanParam 运行计划 + */ + public void saveRunPlan(CtcRunPlanParam runPlanParam) { + this.runPlanParamMap.put(runPlanParam.getRunPlanCode(), runPlanParam); + } + + /** + * 是否存在 + * + * @param code 编码 + * @return 存在 + */ + public boolean isExit(String code) { + return this.runPlanParamMap.containsKey(code); + } + + public StationRunPlanRepository() { + this.version = new AtomicInteger(0); + } + + public void rest() { + + } + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcManageRepositoryVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcManageRepositoryVO.java new file mode 100644 index 000000000..b25653da3 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcManageRepositoryVO.java @@ -0,0 +1,108 @@ +package club.joylink.rtss.simulation.cbtc.CTC.data; + +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 车务管理端数据状态 + */ +@Getter +@Setter +public class CtcManageRepositoryVO { + /** + * 编辑区股道版本状态 + */ + private final Map editAreaTrackSectionVersionMap = new HashMap<>(); + + /** + * 编辑区股道状态 + */ + private final Map editAreaTrackSectionVOMap = new HashMap<>(); + + /** + * 编辑区运行计划版本状态 + */ + private final Map editAreaCtcRunPlanVersionMap = new HashMap<>(); + + /** + * 编辑区行车计划状态 + */ + private final Map editAreaCtcRunPlanParamVOMap = new HashMap<>(); + + + /** + * 生效区股道版本状态 + */ + private final Map effectAreaTrackSectionVersionMap = new HashMap<>(); + + /** + * 生效区股道状态 + */ + private final Map effectAreaTrackSectionVOMap = new HashMap<>(); + + /** + * 生效区运行计划版本状态 + */ + private final Map effectAreaCtcRunPlanVersionMap = new HashMap<>(); + + /** + * 生效区行车计划状态 + */ + private final Map effectAreaCtcRunPlanParamVOMap = new HashMap<>(); + + + /** + * 比较并返回变化过的运行计划 + * + * @param runPlanRepository 运行计划 + * @param isEdit 编辑区 + * @return 变化过的 + */ + public List compareAndReturnChangeRunPlan(CtcManageRepository.StationRunPlanRepository runPlanRepository, boolean isEdit) { + List allList = new ArrayList<>(runPlanRepository.getRunPlanParamMap().size()); + Map runPlanMap = isEdit ? this.editAreaCtcRunPlanParamVOMap : this.effectAreaCtcRunPlanParamVOMap; + runPlanRepository.getRunPlanParamMap().forEach((k, p) -> { + String mapKey = p.getStationCode() + "_" + p.getRunPlanCode(); + CtcRunPlanParam param = runPlanMap.get(mapKey); + CtcRunPlanParam changeCtcRunPlanVo = null; + if (param == null) { + changeCtcRunPlanVo = p.clone(); + runPlanMap.put(mapKey, changeCtcRunPlanVo); + allList.add(changeCtcRunPlanVo); + } else { + changeCtcRunPlanVo = param.compareAndChange(p); + if (changeCtcRunPlanVo != null) { + allList.add(changeCtcRunPlanVo); + } + } + }); + return allList; + } + + /** + * 比较并返回删除的运行计划 + * + * @param runPlanRepository 运行计划 + * @param isEdit 编辑区 + * @return 删除的 + */ + public List compareAndReturnRemoveRunPlan(CtcManageRepository.StationRunPlanRepository runPlanRepository, boolean isEdit) { + Map runPlanMap = isEdit ? this.editAreaCtcRunPlanParamVOMap : this.effectAreaCtcRunPlanParamVOMap; + List messageInfo = runPlanMap.values().stream() + .filter(vo -> vo.getStationCode().equals(runPlanRepository.getStationCode()) && !runPlanRepository.isExit(vo.getRunPlanCode())) + .map(vo -> vo.buildRemoveParam()).collect(Collectors.toList()); + // 移除数据 + if (!CollectionUtils.isEmpty(messageInfo)) { + messageInfo.forEach(vo -> runPlanMap.remove(vo.getStationCode() + "_" + vo.getRunPlanCode())); + } + return messageInfo; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java index f078955c9..9e2146b64 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcRepository.java @@ -1,7 +1,6 @@ package club.joylink.rtss.simulation.cbtc.CTC.data; import club.joylink.rtss.exception.BusinessExceptionAssertEnum; -import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; import lombok.Getter; import java.util.HashMap; @@ -9,22 +8,54 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +/** + * 铁路局CTC 车务管理终端 + * | + * |下发计划至生效区 + * | + * 生效区 + * 【manageRepositoryMap.CtcManageRepository.effectAreaMap】 + * | + * | 拉取计划至车站终端 + * | + * 车站终端更新计划 + */ @Getter public class CtcRepository { + /** + * 铁路局的数据,包含区段信息、用户信息、设置的默认信息等 + */ + + + /** + * 运行区段数据 + */ + private final Map zoneRepository = new ConcurrentHashMap<>(); + /******************************************* 以下为车站终端数据:车站为单位 *******************************************/ + /** + * 车务管理终端数据 + * 车站为key + */ + private final Map manageRepositoryMap = new ConcurrentHashMap<>(); + + /** + * 管理终端数据状态 + */ + private final CtcManageRepositoryVO ctcManageRepositoryVO = new CtcManageRepositoryVO(); + /** * 车站-进路序列。每个车站都应该有 * k - stationCode */ - private final Map routeSequenceMap = new HashMap<>(); + private final Map routeSequenceMap = new ConcurrentHashMap<>(); /** * 进路序列状态 * k - stationCode */ - private final Map routeSequenceVOMap = new HashMap<>(); + private final Map routeSequenceVOMap = new ConcurrentHashMap<>(); /** * k - stationCode @@ -53,53 +84,18 @@ public class CtcRepository { */ private final Map> simulationRunPlanMap = new ConcurrentHashMap<>(); - /** - * 编辑区版本 - */ - private final Map stationEditAreaVersion = new HashMap<>(); - - /** - * 管理区编辑区 - * 车次为KEY - */ - private final Map> simulationRunPlanEditAreaMap = new ConcurrentHashMap<>(); - - /** - * 生效区版本 - */ - private final Map stationEffectAreaVersion = new HashMap<>(); - - /** - * 管理区生效区 - * 车次为KEY - */ - private final Map> simulationRunPlanEffectAreaMap = new ConcurrentHashMap<>(); - /** * 运行日志消息状态 */ - private final Map runPlanStatusVOMap = new HashMap<>(); - - /** - * 车务管理端运行计划状态 - */ - private final Map editAreaStatusVOMap = new HashMap<>(); - - /** - * 车务管理端生效区运行计划状态 - */ - private final Map effectAreaStatusVOMap = new HashMap<>(); + private final Map runPlanStatusVOMap = new ConcurrentHashMap<>(); + /******************************************* 以上为车站终端数据:车站为单位 *******************************************/ public void reset() { routeSequenceMap.clear(); routeSequenceVOMap.clear(); trackViewMap.clear(); trackViewVOMap.clear(); - // 编辑区清空 - this.simulationRunPlanEditAreaMap.clear(); - // 生效区清空 - this.simulationRunPlanEffectAreaMap.clear(); // 仿真运行数据直接清空 this.simulationRunPlanMap.clear(); this.allRunPlanList.clear(); @@ -110,8 +106,6 @@ public class CtcRepository { })); // 运行计划状态清除 this.runPlanStatusVOMap.clear(); - this.editAreaStatusVOMap.clear(); - this.effectAreaStatusVOMap.clear(); } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java index 93f94f5be..2d4c4d635 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcStationRunPlanLog.java @@ -38,6 +38,11 @@ public class CtcStationRunPlanLog { */ private Station station; + /** + * 列车班别:存在同车次情况 + */ + private String groupNumber; + /** * 车次号 */ @@ -402,9 +407,14 @@ public class CtcStationRunPlanLog { runPlanItem.setStation(adjacentStation); runPlanItem.setDefaultStation(adjacentStation); runPlanItem.setTripNumber(tripNumber); - // 实际时间 - LocalTime planTime = arrive ? paramInfo.getArriveTime() : paramInfo.getDepartTime(); + // 计划时间 + LocalTime planTime = arrive ? paramInfo.getArrivePlanTime() : paramInfo.getDepartPlanTime(); runPlanItem.setPlanTime(planTime); + // 实际时间 + LocalTime actualTime = arrive ? paramInfo.getArriveTime() : paramInfo.getDepartTime(); + if (actualTime != null) { + runPlanItem.setActualTime(actualTime.toString()); + } // 股道编码 String sectionCode = arrive ? paramInfo.getArriveSectionCode() : paramInfo.getDepartSectionCode(); if (StringUtils.isEmpty(sectionCode)) { // 没有指定获取默认股道 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZone.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZone.java new file mode 100644 index 000000000..290a45fe6 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZone.java @@ -0,0 +1,29 @@ +package club.joylink.rtss.simulation.cbtc.CTC.data; + +import club.joylink.rtss.simulation.cbtc.data.map.Station; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 行驶区间(行驶线路) + */ +@Setter +@Getter +public class CtcZone { + /** + * 编码 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 车站列表 + */ + private List stationList; +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZoneRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZoneRepository.java new file mode 100644 index 000000000..155d391b8 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZoneRepository.java @@ -0,0 +1,103 @@ +package club.joylink.rtss.simulation.cbtc.CTC.data; + +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; +import club.joylink.rtss.simulation.cbtc.data.map.Station; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * CTC行车区间关联数据信息 + */ +@Setter +@Getter +public class CtcZoneRepository { + /** + * 行车区间编码 + */ + private CtcZone ctcZone; + + /** + * 包含车站 + */ + private Map stationMap = new HashMap<>(); + + /** + * 运行计划 + */ + private final Map zoneRunPlanMap = new ConcurrentHashMap<>(); + + /** + * 下发计划 + */ + private final Map effectRunPlanMap = new ConcurrentHashMap<>(); + + public CtcZoneRepository(CtcZone ctcZone) { + this.ctcZone = ctcZone; + } + + /** + * 保存运行计划信息 + * + * @param runPlanParam 运行计划 + */ + public void saveRunPlan(CtcRunPlanParam runPlanParam) { + if (!this.zoneRunPlanMap.containsKey(runPlanParam.getStationCode())) { + CtcManageRepository.StationRunPlanRepository repository = new CtcManageRepository.StationRunPlanRepository(); + repository.setStationCode(runPlanParam.getStationCode()); + this.zoneRunPlanMap.put(runPlanParam.getStationCode(), repository); + } + this.zoneRunPlanMap.get(runPlanParam.getStationCode()).saveRunPlan(runPlanParam); + } + + /** + * 删除运行计划(状态删除) + * + * @param runPlanCode + */ + public void delRunPlan(String stationCode, String runPlanCode) { + CtcManageRepository.StationRunPlanRepository repository = this.zoneRunPlanMap.get(stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(repository); + CtcRunPlanParam runPlanParam = repository.getRunPlanParamMap().get(runPlanCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(runPlanParam); + runPlanParam.setStatus(-1); + } + + /** + * 发布下达运行计划 + * + * @param updateDateTime 更新时间 + */ + public void releaseRunPlan(LocalDateTime updateDateTime) { + this.zoneRunPlanMap.forEach((k, v) -> releaseRunPlanByStationCode(k, updateDateTime)); + } + + /** + * 单车站发布 + * + * @param stationCode 车站编码 + * @param updateDateTime 更新时间 + */ + public void releaseRunPlanByStationCode(String stationCode, LocalDateTime updateDateTime) { + CtcManageRepository.StationRunPlanRepository repository = this.zoneRunPlanMap.get(stationCode); + BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(repository); + CtcManageRepository.StationRunPlanRepository effectRepository = this.effectRunPlanMap.get(stationCode); + if (effectRepository == null) { + effectRepository = new CtcManageRepository.StationRunPlanRepository(); + effectRepository.setStationCode(stationCode); + this.effectRunPlanMap.put(stationCode, effectRepository); + } + effectRepository.setUpdateTime(updateDateTime); + effectRepository.getVersion().incrementAndGet(); + // 重新赋值 + Map ctcRunPlanParamMap = repository.getRunPlanParamMap().values().stream() + .map(CtcRunPlanParam::clone).collect(Collectors.toMap(CtcRunPlanParam::getRunPlanCode, c -> c)); + effectRepository.getRunPlanParamMap().putAll(ctcRunPlanParamMap); + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZoneVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZoneVO.java new file mode 100644 index 000000000..7da6b8183 --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CTC/data/CtcZoneVO.java @@ -0,0 +1,64 @@ +package club.joylink.rtss.simulation.cbtc.CTC.data; + +import club.joylink.rtss.simulation.cbtc.data.map.Station; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * 行车区间状态 + */ +@Setter +@Getter +public class CtcZoneVO { + /** + * 编码 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 车站列表 + */ + private List stationCodeList; + + public CtcZoneVO(String code) { + this.code = code; + } + + public CtcZoneVO(CtcZone ctcZone) { + this.code = ctcZone.getCode(); + this.name = ctcZone.getName(); + this.stationCodeList = ctcZone.getStationList().stream().map(Station::getCode).collect(Collectors.toList()); + } + + /** + * 比较并返回变化字段 + * + * @param ctcZone 铁路局详细信息 + * @return 变化对象 + */ + public CtcZoneVO compareAndReturnChange(CtcZone ctcZone) { + CtcZoneVO ctcZoneVO = new CtcZoneVO(ctcZone.getCode()); + boolean change = false; + if (!Objects.equals(this.name, ctcZone.getName())) { + this.name = ctcZone.getName(); + ctcZoneVO.setName(ctcZone.getName()); + change = true; + } + List stationList = ctcZone.getStationList().stream().map(Station::getCode).collect(Collectors.toList()); + if (!Objects.equals(this.stationCodeList, stationList)) { + this.stationCodeList = stationList; + ctcZoneVO.setStationCodeList(stationList); + change = true; + } + return change ? ctcZoneVO : null; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java index 07f1874a6..37828228e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/SimulationBuilder.java @@ -2,9 +2,7 @@ package club.joylink.rtss.simulation.cbtc.build; import club.joylink.rtss.entity.Ibp; import club.joylink.rtss.simulation.cbtc.ATS.operation.vo.CtcRunPlanParam; -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.*; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.CalculateService; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; @@ -100,8 +98,9 @@ public class SimulationBuilder { loadDepotInOutRoutePath(simulation); // CTC行车日志数据结构构建 if (simulation.getRepository().getConfig().isHasCTC()) { + buildCtcRailwayInfo(simulation); + buildCtcStationRunPlanLog(simulation); LocalDateTime now = LocalDateTime.now(); - buildCtcStationRunPlanLog(simulation, simulation.getRepository().getServiceTripsMap()); System.out.println("CTC行车日志耗时:" + Duration.between(now, LocalDateTime.now()).getSeconds()); now = LocalDateTime.now(); generateRouteSequence(simulation); @@ -357,13 +356,36 @@ public class SimulationBuilder { } } + /** + * 构建铁路局(调度台、区段)等数据 + * + * @param simulation 仿真 + */ + public static void buildCtcRailwayInfo(Simulation simulation) { + String code = "Station32295_Station58852_Station47980"; // 后期数据录入 + // 铁路局(调度台、区段) + CtcZone ctcZone = new CtcZone(); + ctcZone.setCode(code); + ctcZone.setName("标准线"); + ctcZone.setStationList(simulation.getRepository().getStationList()); + // 铁路局(调度台、区段)数据 + CtcZoneRepository ctcZoneRepository = new CtcZoneRepository(ctcZone); + ctcZone.getStationList().forEach(s -> { + ctcZoneRepository.getStationMap().put(s.getCode(), s); + // 车务管理终端数据 + simulation.getCtcRepository().getManageRepositoryMap().put(s.getCode(), new CtcManageRepository(s.getCode())); + }); + // 集中中心各数据 + simulation.getCtcRepository().getZoneRepository().put(code, ctcZoneRepository); + } + /** * 根据行车计划构建行车日志 * - * @param simulation 仿真实体 - * @param serverTripMap 行车计划 + * @param simulation 仿真实体 */ - public static void buildCtcStationRunPlanLog(Simulation simulation, Map> serverTripMap) { + public static void buildCtcStationRunPlanLog(Simulation simulation) { + Map> serverTripMap = simulation.getRepository().getServiceTripsMap(); if (CollectionUtils.isEmpty(serverTripMap)) { return; } @@ -381,6 +403,8 @@ public class SimulationBuilder { ctcRunPlanParam.setRunPlanCode(codePrefix); // 目前将到达、出发车次一直 ctcRunPlanParam.setTripNumber(tripPlan.getTripNumber()); + ctcRunPlanParam.setGroupNumber(tripPlan.getServiceNumber()); + ctcRunPlanParam.generateRunPlanCodeAndTripNumber(); ctcRunPlanParam.setArriveTripNumber(tripPlan.getTripNumber()); ctcRunPlanParam.setDepartTripNumber(tripPlan.getTripNumber()); ctcRunPlanParam.setStationCode(stationPlan.getStation().getCode()); @@ -400,7 +424,16 @@ public class SimulationBuilder { } }); }); + String code = "Station32295_Station58852_Station47980"; // 后期数据录入 + // 集中中心一份 + CtcZoneRepository ctcZoneRepository = simulation.getCtcRepository().getZoneRepository().get(code); ctcRunPlanParamList.forEach(param -> { + // 集中中心增加 + ctcZoneRepository.saveRunPlan(param.clone()); + // 车务管理终端一份 + CtcManageRepository ctcManageRepository = simulation.getCtcRepository().getManageRepositoryMap().get(param.getStationCode()); + ctcManageRepository.saveRunPlanToEditArea(param.clone()); + ctcManageRepository.saveRunPlanToEffectArea(param.clone()); CtcStationRunPlanLog runPlanLog = new CtcStationRunPlanLog(param); runPlanLog.setCode(param.getRunPlanCode()); runPlanLog.setTripNumber(param.getTripNumber()); @@ -423,12 +456,12 @@ public class SimulationBuilder { StationDirection.ReceiveAndDeliverModel defaultRunStatus; if (arriveFlag) { defaultRunStatus = StationDirection.ReceiveAndDeliverModel.R; - ctcRunPlanParam.setArriveTime(stationPlan.getArriveTime()); + ctcRunPlanParam.setArrivePlanTime(stationPlan.getArriveTime()); ctcRunPlanParam.setArriveStationCode(adjacentStation.getCode()); ctcRunPlanParam.setArriveSectionCode(stationPlan.getSection().getCode()); // 停靠股道 } else { defaultRunStatus = StationDirection.ReceiveAndDeliverModel.D; - ctcRunPlanParam.setDepartTime(stationPlan.getLeaveTime()); + ctcRunPlanParam.setDepartPlanTime(stationPlan.getLeaveTime()); ctcRunPlanParam.setDepartStationCode(adjacentStation.getCode()); ctcRunPlanParam.setDepartSectionCode(stationPlan.getSection().getCode()); // 停靠股道 } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/message/SimulationUserWsListener.java b/src/main/java/club/joylink/rtss/simulation/cbtc/message/SimulationUserWsListener.java index ecf1d6380..4b9a82b98 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/message/SimulationUserWsListener.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/message/SimulationUserWsListener.java @@ -26,6 +26,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -108,14 +109,18 @@ public class SimulationUserWsListener { break; } case Ctc: { + Set userIds = Stream.of(userId).collect(Collectors.toSet()); // CTC运行日志发消息 - ctcLogicLoop.sendAllRunPlanChangeMessage(simulation, Stream.of(userId).collect(Collectors.toSet())); + ctcLogicLoop.sendAllRunPlanChangeMessage(simulation, userIds); + ctcLogicLoop.sendAllRailwayInfo(simulation, userIds); ctcLogicLoop.sendAllMessage(simulation); break; } case Ctc_Manager: { // CTC运行管理端 - // CTC管理端编辑区发送消息 - ctcLogicLoop.initCtcManageMessage(simulation, Stream.of(userId).collect(Collectors.toSet())); + Set userIds = Stream.of(userId).collect(Collectors.toSet()); + // CTC运行日志发消息 + ctcLogicLoop.sendAllRailwayInfo(simulation, userIds); + ctcLogicLoop.sendAllManageChange(simulation, userIds); break; } } diff --git a/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java b/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java index d5965a5f8..2a2b11ded 100644 --- a/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java +++ b/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java @@ -353,6 +353,12 @@ public enum WebSocketMessageType { * 大铁CTC系统的状态消息 */ Simulation_RailCtcStatus, + + /** + * CTC 铁路局、行车区段消息 + */ + SIMULATION_CTC_ZONE, + /** * 仿真CTC运行计划初始化 **/ diff --git a/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java b/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java index c256a9ca9..c7fe9390b 100644 --- a/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java +++ b/src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java @@ -105,6 +105,11 @@ public class SocketMessageFactory { topicList.add(String.format(WebSocketSubscribeTopic.Simulation, group)); break; } + case SIMULATION_CTC_ZONE: { + topicList.add(SimulationSubscribeTopic.Ctc.buildDestination(group)); + topicList.add(SimulationSubscribeTopic.Ctc_Manager.buildDestination(group)); + break; + } case SIMULATION_CTC_RUN_PLAN_INIT: case SIMULATION_CTC_RUN_PLAN_CHANGE: case SIMULATION_CTC_RUN_PLAN_REMOVE: