diff --git a/src/main/java/club/joylink/rtss/controller/runplan/RunPlanUserDataController.java b/src/main/java/club/joylink/rtss/controller/runplan/RunPlanUserDataController.java index deef52b40..5de7a70eb 100644 --- a/src/main/java/club/joylink/rtss/controller/runplan/RunPlanUserDataController.java +++ b/src/main/java/club/joylink/rtss/controller/runplan/RunPlanUserDataController.java @@ -73,6 +73,14 @@ public class RunPlanUserDataController { return iRunPlanRoutingService.getUserRoutingBy(user.getId(), mapId); } + /** + * 查询用户交路数据 + */ + @GetMapping("/{mapId}/routing/select") + public List queryRoutings(@PathVariable Long mapId, RunPlanRoutingQueryVO queryVO, @RequestAttribute AccountVO user) { + return iRunPlanRoutingService.queryRoutes(mapId, queryVO, user); + } + /** *获取用户交路详情 */ diff --git a/src/main/java/club/joylink/rtss/services/IRunPlanDraftService.java b/src/main/java/club/joylink/rtss/services/IRunPlanDraftService.java index 79ccfef19..6c050be95 100644 --- a/src/main/java/club/joylink/rtss/services/IRunPlanDraftService.java +++ b/src/main/java/club/joylink/rtss/services/IRunPlanDraftService.java @@ -6,6 +6,7 @@ import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.client.map.MapRoutingSectionVO; import club.joylink.rtss.vo.client.runplan.*; import club.joylink.rtss.vo.map.MapStationRunLevelVO; +import club.joylink.rtss.vo.map.MapVO; import club.joylink.rtss.vo.runplan.RunPlanInputData; import org.springframework.transaction.annotation.Transactional; @@ -147,6 +148,11 @@ public interface IRunPlanDraftService { */ void addRunPlanService(Long planId, RunPlanServiceConfigVO serviceConfig, AccountVO accountVO); + /** + * 构建车次计划 + */ + RunPlanTripVO buildTripPlan(RunPlanServiceConfigVO serviceConfig, MapVO mapVO, RunPlanTripConfigVO tripConfigVO); + void generateRunPlanService(Long userId, Long planId, RunPlanInputData inputData); /** diff --git a/src/main/java/club/joylink/rtss/services/RunPlanDraftService.java b/src/main/java/club/joylink/rtss/services/RunPlanDraftService.java index 5b895b632..20a6418c7 100644 --- a/src/main/java/club/joylink/rtss/services/RunPlanDraftService.java +++ b/src/main/java/club/joylink/rtss/services/RunPlanDraftService.java @@ -348,8 +348,6 @@ public class RunPlanDraftService implements IRunPlanDraftService { RunPlanVO planVO = getRunPlanById(planId); MapVO mapVO = this.iMapService.getMapDetail(planVO.getMapId()); List newTripList = new ArrayList<>(); - List userRoutings = runPlanRoutingService.getUserRoutingBy(accountVO.getId(), mapVO.getId()); - Map userRoutingMap = userRoutings.stream().collect(Collectors.toMap(RunPlanRoutingVO::getId, Function.identity(), (o, n) -> o)); for (RunPlanTripConfigVO tripConfigVO : serviceConfig.getTripConfigList()) { if (StringUtils.hasText(tripConfigVO.getTripNumber())) { RunPlanTripVO update = planVO.getTripList().stream() @@ -358,19 +356,17 @@ public class RunPlanDraftService implements IRunPlanDraftService { return true; } return false; - }).findFirst().orElseThrow(() -> BusinessExceptionAssertEnum.DATA_NOT_EXIST.exception()); + }).findFirst().orElseThrow(BusinessExceptionAssertEnum.DATA_NOT_EXIST::exception); setTripTimes(tripConfigVO, update, mapVO); newTripList.add(update); } else { - // 查询交路 - RunPlanRoutingVO routingData = userRoutingMap.get(tripConfigVO.getRoutingCode()); - RunPlanTripVO tripVO = new RunPlanTripVO(routingData); - setDirectionCode(mapVO.getConfigVO().getUpRight(), tripVO); - // 构建类车到站数据 - tripVO.setServiceNumber(serviceConfig.getServiceNumber()); - - setTripTimes(tripConfigVO, routingData, tripVO); +// List userRoutings = runPlanRoutingService.getUserRoutingBy(accountVO.getId(), mapVO.getId()); +// Map userRoutingMap = userRoutings.stream() +// .collect(Collectors.toMap(RunPlanRoutingVO::getId, Function.identity(), (o, n) -> o)); +// // 查询交路 +// RunPlanRoutingVO routingData = userRoutingMap.get(tripConfigVO.getRoutingCode()); + RunPlanTripVO tripVO = buildTripPlan(serviceConfig, mapVO, tripConfigVO); newTripList.add(tripVO); } } @@ -378,10 +374,18 @@ public class RunPlanDraftService implements IRunPlanDraftService { this.sortAndResetServiceTripNumber(newTripList); planVO.getTripList().removeAll(planVO.getTripList().stream().filter(tripVO -> tripVO.getServiceNumber().equals(serviceConfig.getServiceNumber())).collect(Collectors.toList())); planVO.getTripList().addAll(newTripList); - RunPlanDraft planDraft = planVO.convert2Draft(); - planDraft.setTrips(JsonUtils.writeValueAsString(planVO.getTripList())); - planDraft.setStatus(BusinessConsts.ReleaseReview.RELEASE_STATUS_01); - runPlanDraftDAO.updateByPrimaryKeySelective(planDraft); + } + + @Override + public RunPlanTripVO buildTripPlan(RunPlanServiceConfigVO serviceConfig, MapVO mapVO, RunPlanTripConfigVO tripConfigVO) { + RunPlanRoutingVO routingData = runPlanRoutingService.getUserRouting(tripConfigVO.getRoutingCode()); + RunPlanTripVO tripVO = new RunPlanTripVO(routingData); + setDirectionCode(mapVO.getConfigVO().getUpRight(), tripVO); + // 构建列车到站数据 + tripVO.setServiceNumber(serviceConfig.getServiceNumber()); + + setTripTimes(tripConfigVO, routingData, tripVO); + return tripVO; } private void updateRunPlanTrip(RunPlanVO runPlanVO, String SDTNumber, RunPlanTripConfigVO tripConfig, MapVO mapVO) { diff --git a/src/main/java/club/joylink/rtss/services/runplan/IRunPlanRoutingService.java b/src/main/java/club/joylink/rtss/services/runplan/IRunPlanRoutingService.java index 5b0e45527..d610729b9 100644 --- a/src/main/java/club/joylink/rtss/services/runplan/IRunPlanRoutingService.java +++ b/src/main/java/club/joylink/rtss/services/runplan/IRunPlanRoutingService.java @@ -1,5 +1,6 @@ package club.joylink.rtss.services.runplan; +import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.client.runplan.user.RunPlanRoutingQueryVO; import club.joylink.rtss.vo.client.runplan.user.RunPlanRoutingSection; @@ -40,4 +41,6 @@ public interface IRunPlanRoutingService { void syncDefaultRoutingRefData(Long userId, Long mapId); RunPlanRoutingVO generateUserRoutingData(RunPlanRoutingVO routingVO); + + List queryRoutes(Long mapId, RunPlanRoutingQueryVO queryVO, AccountVO user); } diff --git a/src/main/java/club/joylink/rtss/services/runplan/RunPlanRoutingService.java b/src/main/java/club/joylink/rtss/services/runplan/RunPlanRoutingService.java index 741a69438..ad52bcbd6 100644 --- a/src/main/java/club/joylink/rtss/services/runplan/RunPlanRoutingService.java +++ b/src/main/java/club/joylink/rtss/services/runplan/RunPlanRoutingService.java @@ -14,6 +14,7 @@ import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.client.PageVO; import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; import club.joylink.rtss.vo.client.runplan.RunPlanVO; @@ -200,6 +201,13 @@ public class RunPlanRoutingService implements IRunPlanRoutingService { return routingVO; } + @Override + public List queryRoutes(Long mapId, RunPlanRoutingQueryVO queryVO, AccountVO user) { + return getUserRoutingBy(user.getId(), mapId).stream() + .filter(routing -> Objects.equals(routing.getDestinationCode(), queryVO.getDestinationCode())) + .collect(Collectors.toList()); + } + private void generateUserRoutingSections(RunPlanRoutingVO routingVO, Map deviceMap) { Section startSection = (Section) deviceMap.get(routingVO.getStartSectionCode()); Section endSection = (Section) deviceMap.get(routingVO.getEndSectionCode()); diff --git a/src/main/java/club/joylink/rtss/services/training/generatornew/base/SectionGeneratorNew.java b/src/main/java/club/joylink/rtss/services/training/generatornew/base/SectionGeneratorNew.java index 8a03c751b..2ab87261f 100644 --- a/src/main/java/club/joylink/rtss/services/training/generatornew/base/SectionGeneratorNew.java +++ b/src/main/java/club/joylink/rtss/services/training/generatornew/base/SectionGeneratorNew.java @@ -94,9 +94,9 @@ public class SectionGeneratorNew implements GeneratorNew { case Section_Confirm_Axis_Valid: // 设置计轴失效(ARB) if (Objects.nonNull(section.getParent())) { - section.getParent().judgeAsInvalid(); + section.getParent().judgeAsNctOccupied(); } else { - section.judgeAsInvalid(); + section.judgeAsNctOccupied(); } break; case Section_Fault_Unlock: diff --git a/src/main/java/club/joylink/rtss/services/training/generatornew/base/SwitchGeneratorNew.java b/src/main/java/club/joylink/rtss/services/training/generatornew/base/SwitchGeneratorNew.java index cc68420d1..993e6822d 100644 --- a/src/main/java/club/joylink/rtss/services/training/generatornew/base/SwitchGeneratorNew.java +++ b/src/main/java/club/joylink/rtss/services/training/generatornew/base/SwitchGeneratorNew.java @@ -6,7 +6,6 @@ import club.joylink.rtss.services.training.generatornew.annotation.GeneratorSele import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsSectionService; import club.joylink.rtss.simulation.cbtc.Simulation; -import club.joylink.rtss.simulation.cbtc.data.map.Section; import club.joylink.rtss.simulation.cbtc.data.map.Switch; import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter; import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool; @@ -108,7 +107,7 @@ public class SwitchGeneratorNew implements GeneratorNew { } case Switch_Confirm_Axis_Valid:{ // 背景为道岔计轴失效 - aSwitch.getA().getParent().judgeAsInvalid(); + aSwitch.getA().getParent().judgeAsNctOccupied(); break; } default: diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java index e2220bb8a..1f15ec4e4 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/AtpSectionService.java @@ -178,13 +178,17 @@ public class AtpSectionService { * @param sectionList */ public void sectionARBCheck(Simulation simulation, Section section, List
sectionList) { - if (!section.isInvalid() && section.isNctOccupied()) { - if (!sectionList.contains(section)) { - log.debug(String.format("区段[%s(%s)]检测为ARB故障", - section.getName(), section.getCode())); - section.judgeAsInvalid(); - } + //目前ARB故障才会导致ARB判定 + if (Section.AxleFault.ARB.equals(section.getFault()) && section.getVirtualAxleCounter().isOccupy() && !sectionList.contains(section)) { + section.judgeAsARB(); + } else if (section.getVirtualAxleCounter().isOccupy() && sectionList.contains(section)){ + section.judgeAsNctOccupied(); } +// if (/*!section.isInvalid() &&*/ section.isNctOccupied()) { +// if (!sectionList.contains(section)) { +// section.judgeAsNctOccupied(); +// } +// } //ARB故障恢复判断 if (Section.AxleFault.ARB.equals(section.getFault()) && !section.getVirtualAxleCounter().isOccupy()) { Section.AxleFault.ARB.fix(section); @@ -192,7 +196,7 @@ public class AtpSectionService { } /** - * 获取列车可能存在的范围 + * 获取非通信车可能存在的范围 * * @param simulation * @param trainList @@ -201,6 +205,9 @@ public class AtpSectionService { public List
getTrainExistAxleSectionsUnderDelay(Simulation simulation, List trainList) { List
list = new ArrayList<>(); for (VirtualRealityTrain train : trainList) { + //只统计非通信车 + if (train.isCBTC()) + continue; boolean right = train.isRight(); SectionPosition headPosition = train.getHeadPosition(); float offset = 50; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java index 4be510510..e9a31f99c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/GroundAtpApiServiceImpl.java @@ -72,8 +72,8 @@ public class GroundAtpApiServiceImpl implements GroundAtpApiService { for (Section section : axleSectionList) { this.atpSectionService.sectionARBCheck(simulation, section, trainExistAxleSectionList); } - // 判断是否要将ARB设为非通信车占用 - this.atpSectionService.judgeFaultSectionAsNctOccupied(nctApproachSignalMap); +// // 判断是否要将ARB设为非通信车占用 +// this.atpSectionService.judgeFaultSectionAsNctOccupied(nctApproachSignalMap); // 根据道岔的位置修改道岔区段的占用(暂时只处理因故障导致的占用) repository.getSwitchList().stream().filter(aSwitch -> Section.AxleFault.CBTC_OCCUPIED_FAULT.equals(aSwitch.getA().getFault())) .forEach(aSwitch -> { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java index 0f28249a5..7a0c6faca 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATP/ground/ZCLogicLoop.java @@ -56,6 +56,7 @@ public class ZCLogicLoop { if (!Station.Fault.INTERLOCK_MACHINE_FAULT.equals(deviceStation.getFault())) { Float distance2NextSignal = train.calculateDistance2NextNormalOpenSignal(); if (distance2NextSignal != null && distance2NextSignal <= 5) { + train.setPositioned(true); this.calculateMAOfITC(simulation, train); } } @@ -177,7 +178,7 @@ public class ZCLogicLoop { break; } //非通信车占用区段 - if (temp.isNonCbtcOccupy() && !section.isInvalid()) { + if (temp.isNonCbtcOccupy() && !temp.isInvalid()) { endList.add(new MovementAuthority.End(temp, MovementAuthority.EndType.NCT_OCCUPIED_SECTION)); } //检查关闭的区段 diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiService.java index 19ea5d064..005b63d25 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiService.java @@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.cbtc.ATS; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; import club.joylink.rtss.simulation.cbtc.data.support.TrainStopMessage; +import club.joylink.rtss.vo.AccountVO; +import club.joylink.rtss.vo.client.runplan.RunPlanServiceConfigVO; import java.util.List; @@ -52,4 +54,14 @@ public interface AtsApiService { void handleTrainOnTransfer(Simulation simulation, String groupNumber, String sectionCode); void cancelStandSkipSetOfTrain(Simulation simulation, String groupNumber, String standCode); + + /** + * 添加车次计划(加线) + */ + void addTripPlan(Simulation simulation, RunPlanServiceConfigVO serviceConfig, AccountVO user); + + /** + * 删除车次计划(抽线) + */ + void deleteTripPlan(Simulation simulation, String serviceNumber, String tripNumber); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java index 92a31e1fc..2b0b77e00 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/AtsApiServiceImpl.java @@ -1,20 +1,34 @@ package club.joylink.rtss.simulation.cbtc.ATS; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; +import club.joylink.rtss.services.IRunPlanDraftService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsPlanService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsStandService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainMonitorService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainService; import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.build.RunPlanBuilder; +import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder; import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository; import club.joylink.rtss.simulation.cbtc.data.map.MapElement; 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.plan.TripPlan; import club.joylink.rtss.simulation.cbtc.data.support.TrainStopMessage; import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo; +import club.joylink.rtss.simulation.cbtc.event.SimulationTripPlanChangeEvent; +import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.AccountVO; +import club.joylink.rtss.vo.client.runplan.RunPlanServiceConfigVO; +import club.joylink.rtss.vo.client.runplan.RunPlanTripConfigVO; +import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; +import club.joylink.rtss.vo.client.runplan.RunPlanVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -36,6 +50,12 @@ public class AtsApiServiceImpl implements AtsApiService { @Autowired private AtsTrainMonitorService atsTrainMonitorService; + @Autowired + private IRunPlanDraftService iRunPlanDraftService; + + @Autowired + private ApplicationContext applicationContext; + @Override public void handleDeviceStatus(Simulation simulation, List deviceList) { this.atsMessageCollectAndDispatcher.collectDeviceStatusAndSend(simulation, deviceList); @@ -54,7 +74,7 @@ public class AtsApiServiceImpl implements AtsApiService { public void handleTrainStopMessage(Simulation simulation, TrainStopMessage stopMessage) { // 处理正常站台停车 SimulationDataRepository repository = simulation.getRepository(); - TrainInfo train = repository.findSupervisedTrainByGroup(stopMessage.getGroupNumber()); + TrainInfo train = repository.findSupervisedTrainByGroup(stopMessage.getTrain().getGroupNumber()); Section section = stopMessage.getSection(); Station station = section.getStation(); if (train == null || station == null) { @@ -120,7 +140,42 @@ public class AtsApiServiceImpl implements AtsApiService { if (Objects.isNull(train)) { return; } - atsStandService.cancelJumpStop(simulation, standCode,groupNumber); + atsStandService.cancelJumpStop(simulation, standCode, groupNumber); } + @Override + public void addTripPlan(Simulation simulation, RunPlanServiceConfigVO serviceConfig, AccountVO user) { + RunPlanTripConfigVO tripConfig = serviceConfig.getTripConfigList().get(0); + String serviceNumber = serviceConfig.getServiceNumber(); + String tripNumber = tripConfig.getTripNumber(); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertNull(simulation.getRepository().findTripPlan(serviceNumber, tripNumber), + String.format("车次计划[%s-%s]已存在", serviceNumber, tripNumber)); + + RunPlanTripVO tripPlanVO = iRunPlanDraftService.buildTripPlan(serviceConfig, simulation.getBuildParams().getMap(), tripConfig); + tripPlanVO.setTripNumber(tripConfig.getTripNumber()); + tripPlanVO.setAdd(true); + RunPlanVO runPlan = simulation.getBuildParams().getRunPlan(); + runPlan.getTripList().add(tripPlanVO); + try { + List errMsgList = new ArrayList<>(); + TripPlan tripPlan = RunPlanBuilder.buildTripPlan(simulation.getRepository().getDeviceMap(), errMsgList, tripPlanVO); + BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(tripPlan, JsonUtils.writeValueAsString(errMsgList)); + simulation.getRepository().addTrip(tripPlan); + } catch (RuntimeException e) { + runPlan.getTripList().remove(tripPlanVO); + throw e; + } + applicationContext.publishEvent(new SimulationTripPlanChangeEvent(this, simulation, List.of(tripPlanVO))); + } + + @Override + public void deleteTripPlan(Simulation simulation, String serviceNumber, String tripNumber) { + List invalidList = simulation.getRepository().invalidPlanFrom(serviceNumber, tripNumber); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertCollectionNotEmpty(invalidList, "车次计划不存在"); + RunPlanVO runPlan = simulation.getBuildParams().getRunPlan(); + List changeTrips = runPlan.invalidTripPlan(invalidList); + simulation.getRepository().addChangeTrips(changeTrips); + applicationContext.publishEvent(new SimulationTripPlanChangeEvent(this, simulation, changeTrips)); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/RunPlanOperateHandler.java b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/RunPlanOperateHandler.java index 68303e2b7..f45dde10e 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/RunPlanOperateHandler.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/handler/RunPlanOperateHandler.java @@ -1,24 +1,30 @@ package club.joylink.rtss.simulation.cbtc.ATS.operation.handler; +import club.joylink.rtss.simulation.cbtc.ATS.AtsApiService; 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.Simulation; +import club.joylink.rtss.vo.AccountVO; +import club.joylink.rtss.vo.client.runplan.RunPlanServiceConfigVO; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; @Slf4j @OperateHandler public class RunPlanOperateHandler { - @OperateHandlerMapping(type = Operation.Type.RunPlan_Add_Trip) - public void addTripPlan(Simulation simulation) { + @Autowired + private AtsApiService atsApiService; + @OperateHandlerMapping(type = Operation.Type.RunPlan_Add_Trip) + public void addTripPlan(Simulation simulation, RunPlanServiceConfigVO serviceConfig, AccountVO user) { + atsApiService.addTripPlan(simulation, serviceConfig, user); } @OperateHandlerMapping(type = Operation.Type.RunPlan_Delete_Trip) - public void deleteTripPlan(Simulation simulation, String serviceNumber, - String tripNumber, String stationCode) { - + public void deleteTripPlan(Simulation simulation, String serviceNumber, String tripNumber) { + atsApiService.deleteTripPlan(simulation, serviceNumber, tripNumber); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java index 495318b83..25cb6802c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/CI/service/RouteService.java @@ -1,5 +1,6 @@ package club.joylink.rtss.simulation.cbtc.CI.service; +import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; @@ -343,6 +344,8 @@ public class RouteService { if (switchElement.getASwitch().isFaultOnPosition(switchElement.isNormal()) && switchElement.getASwitch().isLoss()) { // 道岔指定位置故障且失表,不再触发 return false; + } else if (switchElement.getASwitch().isLocked() && !switchElement.getASwitch().isOnPosition(switchElement.isNormal())) { + return false; } } } @@ -726,6 +729,9 @@ public class RouteService { * @param route */ public boolean cancelNoApproachLock(Simulation simulation, Route route) { + if (route.isTransferRoute() && simulation.getRepository().getConfig().isTransferRouteCanOnlyFaultUnlock()) { + throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("转换轨进路只能通过区故解取消"); + } if (route.isLock()) { // 进路锁闭 // 取消进路逻辑 if (simulation.getRepository().getConfig().isCancelAtsControlOfAllRoutesWhenCancelRoute()) { @@ -812,6 +818,9 @@ public class RouteService { * @param route */ public boolean humanCancel(Simulation simulation, Route route) { + if (route.isTransferRoute() && simulation.getRepository().getConfig().isTransferRouteCanOnlyFaultUnlock()) { + throw BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.exception("转换轨进路只能通过区故解取消"); + } if (route.isGuideSignalOpen()) { //根据宁波一HMI教学视频添加该分支 this.cancelGuideRoute(simulation, route); } else { @@ -1463,7 +1472,7 @@ public class RouteService { List overlapList = simulation.getRepository() .getListByType(MapElement.DeviceType.OVERLAP, RouteOverlap.class); for (RouteOverlap routeOverlap : overlapList) { - if (routeOverlap.allSectionsOl() && section.isRouteLockOn(routeOverlap.isRight()) && routeOverlap.isRouteLastSection(section)) { + if (routeOverlap.allSectionsOl() && stopMessage.getTrain().isParkingAt() && section.isRouteLockOn(routeOverlap.isRight()) && routeOverlap.isRouteLastSection(section)) { // 是此延续保护的解锁区段,立即解锁 routeOverlap.releaseImmediately(); log.debug(String.format("收到列车停稳消息,[%s]延续保护[%s],触发区段[%s(%s)]立即解锁", diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java b/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java index e6eebff1a..40f955f74 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/GroupSimulationServiceImpl.java @@ -643,6 +643,7 @@ public class GroupSimulationServiceImpl implements GroupSimulationService { SchedulingPlanNewVO schedulingPlan = this.schedulingService .querySchedulingPlanUserFirst(userId, templateId, SimulationConstants.getRunPlanDate()); this.simulationLifeCycleService.reloadRunPlan(simulation, runPlan, schedulingPlan); + simulation.getRepository().clearChangeTrips(); //清除掉之前的车次计划变化信息 } @Override diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java b/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java index b9b90f3ea..26114bc08 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/Simulation.java @@ -28,6 +28,7 @@ import club.joylink.rtss.simulation.cbtc.script.ScriptBO; import club.joylink.rtss.simulation.vo.SimulationInfoVO; import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.client.fault.FaultRuleVO; +import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -39,6 +40,7 @@ import java.time.LocalTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/SimulationMainThread.java b/src/main/java/club/joylink/rtss/simulation/cbtc/SimulationMainThread.java index 2d2d59659..c780b19de 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/SimulationMainThread.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/SimulationMainThread.java @@ -13,8 +13,6 @@ import club.joylink.rtss.simulation.cbtc.communication.Joylink3DMessageService; import club.joylink.rtss.simulation.cbtc.communication.vo.fault.DeviceFaultInfo; import club.joylink.rtss.simulation.cbtc.competition.CompetitionAndScriptManager; import club.joylink.rtss.simulation.cbtc.competition.ScriptExecuteService; -import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants; -import club.joylink.rtss.simulation.cbtc.constant.SimulationModule; import club.joylink.rtss.simulation.cbtc.conversation.Conversation; import club.joylink.rtss.simulation.cbtc.conversation.ConversationMessage; import club.joylink.rtss.simulation.cbtc.data.plan.RealRun; @@ -28,8 +26,6 @@ import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.SimulationRealDev import club.joylink.rtss.simulation.cbtc.device.virtual.VRDeviceLogicLoop; import club.joylink.rtss.simulation.cbtc.device.virtual.VRTrainRunningService; import club.joylink.rtss.simulation.cbtc.event.*; -import club.joylink.rtss.simulation.cbtc.exception.SimulationException; -import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.fault.FaultGenerator; import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationUser; @@ -40,6 +36,8 @@ import club.joylink.rtss.vo.client.SocketMessageVO; import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.factory.SocketMessageFactory; import club.joylink.rtss.vo.client.psl.PslStatus; +import club.joylink.rtss.vo.client.runplan.RunPlanEChartsDataVO; +import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; import club.joylink.rtss.vo.client.script.ScriptActionVO; import club.joylink.rtss.vo.client.simulationv1.SimulationMemberMessageVO; import club.joylink.rtss.vo.client.simulationv1.SimulationUserMessageVO; @@ -497,6 +495,12 @@ public class SimulationMainThread { group, realRunRecordList); this.stompMessageService.sendToUser(String.valueOf(event.getUserId()), allTrainRealRunRecord); } + // 将车次计划变化信息同步给用户 + List changeTrips = simulation.getRepository().getChangeTrips(); + if (!CollectionUtils.isEmpty(changeTrips)) { + SocketMessageVO tripPlanChangeMessage = SocketMessageFactory.buildTripPlanChangeMessage(event.getGroup(), changeTrips); + this.stompMessageService.sendToUser(String.valueOf(event.getUserId()), tripPlanChangeMessage); + } } } @@ -849,4 +853,10 @@ public class SimulationMainThread { SocketMessageVO message = SocketMessageFactory.buildOrderPaySuccessMessage(event.getOrderCode()); this.stompMessageService.sendToUser(event.getUserId(), message); } + + @EventListener + public void handleTripPlanChangeEvent(SimulationTripPlanChangeEvent event) { + SocketMessageVO message = SocketMessageFactory.buildTripPlanChangeMessage(event.getSimulation().getId(), event.getChangeTrips()); + this.stompMessageService.sendToUser(event.getSimulation().getSimulationUserIds(), message); + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/build/RunPlanBuilder.java b/src/main/java/club/joylink/rtss/simulation/cbtc/build/RunPlanBuilder.java index 8255d1e79..4086e28ba 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/build/RunPlanBuilder.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/build/RunPlanBuilder.java @@ -112,103 +112,8 @@ public class RunPlanBuilder { List tripList = runPlan.getTripList(); if (!CollectionUtils.isEmpty(tripList)) { tripList.forEach(runPlanTripVO -> { - TripPlan.TripPlanBuilder tripBuilder = TripPlan.builder(); - tripBuilder.serviceNumber(runPlanTripVO.getServiceNumber()) - .tripNumber(runPlanTripVO.getTripNumber()) - .destinationCode(runPlanTripVO.getDestinationCode()) - .right(runPlanTripVO.getRight()) - .startTime(runPlanTripVO.getStartTime()) - .endTime(runPlanTripVO.getEndTime()); - MapElement start = deviceMap.get(runPlanTripVO.getStartSectionCode()); - if (Objects.isNull(start) || - !Objects.equals(MapElement.DeviceType.SECTION, start.getDeviceType())) { - errMsgList.add(String.format("计划车次[%s|%s|%s]起始区段[%s]数据不存在或不是区段", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode(), - runPlanTripVO.getStartSectionCode())); - } else { - tripBuilder.startSection((Section) start); - } - MapElement end = deviceMap.get(runPlanTripVO.getEndSectionCode()); - if (Objects.isNull(end) || - !Objects.equals(MapElement.DeviceType.SECTION, end.getDeviceType())) { - errMsgList.add(String.format("计划车次[%s|%s|%s]终点区段[%s]数据不存在或不是区段", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode(), - runPlanTripVO.getStartSectionCode())); - } else { - Section section = (Section) end; - tripBuilder.endSection(section); - } - boolean outbound = Objects.nonNull(runPlanTripVO.getIsOutbound()) ? runPlanTripVO.getIsOutbound() : false; - tripBuilder.outbound(outbound); - boolean inbound = Objects.nonNull(runPlanTripVO.getIsInbound()) ? runPlanTripVO.getIsInbound() : false; - tripBuilder.inbound(inbound); - boolean backup = Objects.nonNull(runPlanTripVO.getIsBackUp()) ? runPlanTripVO.getIsBackUp() : false; - tripBuilder.backup(backup); - boolean turnBack = Objects.nonNull(runPlanTripVO.getIsReentry()) ? runPlanTripVO.getIsReentry() : false; - tripBuilder.turnBack(turnBack); - // 车站到发时刻表 - List stationPlanList = new ArrayList<>(); - tripBuilder.planList(stationPlanList); - List timeList = runPlanTripVO.getTimeList(); - if (CollectionUtils.isEmpty(timeList)) { - errMsgList.add(String.format("计划车次[%s|%s|%s]没有车站到发时刻表", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode())); - } else { - timeList.forEach(runPlanTripTimeVO -> { - StationPlan.StationPlanBuilder builder = StationPlan.builder(); - MapElement station = deviceMap.get(runPlanTripTimeVO.getStationCode()); - if (Objects.isNull(station) || - !Objects.equals(MapElement.DeviceType.STATION, station.getDeviceType())) { - errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表车站[%s]数据不存在或不是车站", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode(), - runPlanTripTimeVO.getStationCode())); - } else { - builder.station((Station) station); - } - MapElement section = deviceMap.get(runPlanTripTimeVO.getSectionCode()); - if (Objects.isNull(section) || - !Objects.equals(MapElement.DeviceType.SECTION, section.getDeviceType())) { - errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表区段[%s]数据不存在或不是区段", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode(), - runPlanTripTimeVO.getSectionCode())); - } else { - builder.section((Section) section); - } - LocalTime arrivalTime = runPlanTripTimeVO.getArrivalTime(); - LocalTime departureTime = runPlanTripTimeVO.getDepartureTime(); - if (Objects.isNull(arrivalTime) || Objects.isNull(departureTime)) { - errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表计划到达时间和计划发车时间不能为空", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode())); - } else if (arrivalTime.isAfter(departureTime)) { - errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表计划到达时间不能比计划发车时间晚", - runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), - runPlanTripVO.getDestinationCode())); - } else { - builder.arriveTime(arrivalTime); - builder.leaveTime(departureTime); - int parkTime = departureTime.toSecondOfDay() - arrivalTime.toSecondOfDay(); - if (parkTime <= 0) { - builder.park(false); - builder.parkTime(0); - } else { - builder.park(true); - builder.parkTime(parkTime); - } - } - StationPlan plan = builder.build(); - stationPlanList.add(plan); - }); - if (CollectionUtils.isEmpty(errMsgList)) { - // 排序 - stationPlanList.sort(Comparator.comparing(StationPlan::getArriveTime)); - } - TripPlan tripPlan = tripBuilder.build(); + TripPlan tripPlan = buildTripPlan(deviceMap, errMsgList, runPlanTripVO); + if (tripPlan != null) { result.addTripPlan(tripPlan); } }); @@ -351,4 +256,106 @@ public class RunPlanBuilder { result.sort(); return result; } + + public static TripPlan buildTripPlan(Map deviceMap, List errMsgList, RunPlanTripVO runPlanTripVO) { + TripPlan.TripPlanBuilder tripBuilder = TripPlan.builder(); + tripBuilder.serviceNumber(runPlanTripVO.getServiceNumber()) + .tripNumber(runPlanTripVO.getTripNumber()) + .destinationCode(runPlanTripVO.getDestinationCode()) + .right(runPlanTripVO.getRight()) + .startTime(runPlanTripVO.getStartTime()) + .endTime(runPlanTripVO.getEndTime()); + MapElement start = deviceMap.get(runPlanTripVO.getStartSectionCode()); + if (Objects.isNull(start) || + !Objects.equals(MapElement.DeviceType.SECTION, start.getDeviceType())) { + errMsgList.add(String.format("计划车次[%s|%s|%s]起始区段[%s]数据不存在或不是区段", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode(), + runPlanTripVO.getStartSectionCode())); + } else { + tripBuilder.startSection((Section) start); + } + MapElement end = deviceMap.get(runPlanTripVO.getEndSectionCode()); + if (Objects.isNull(end) || + !Objects.equals(MapElement.DeviceType.SECTION, end.getDeviceType())) { + errMsgList.add(String.format("计划车次[%s|%s|%s]终点区段[%s]数据不存在或不是区段", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode(), + runPlanTripVO.getStartSectionCode())); + } else { + Section section = (Section) end; + tripBuilder.endSection(section); + } + boolean outbound = Objects.nonNull(runPlanTripVO.getIsOutbound()) ? runPlanTripVO.getIsOutbound() : false; + tripBuilder.outbound(outbound); + boolean inbound = Objects.nonNull(runPlanTripVO.getIsInbound()) ? runPlanTripVO.getIsInbound() : false; + tripBuilder.inbound(inbound); + boolean backup = Objects.nonNull(runPlanTripVO.getIsBackUp()) ? runPlanTripVO.getIsBackUp() : false; + tripBuilder.backup(backup); + boolean turnBack = Objects.nonNull(runPlanTripVO.getIsReentry()) ? runPlanTripVO.getIsReentry() : false; + tripBuilder.turnBack(turnBack); + // 车站到发时刻表 + List stationPlanList = new ArrayList<>(); + tripBuilder.planList(stationPlanList); + List timeList = runPlanTripVO.getTimeList(); + if (CollectionUtils.isEmpty(timeList)) { + errMsgList.add(String.format("计划车次[%s|%s|%s]没有车站到发时刻表", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode())); + return null; + } else { + timeList.forEach(runPlanTripTimeVO -> { + StationPlan.StationPlanBuilder builder = StationPlan.builder(); + MapElement station = deviceMap.get(runPlanTripTimeVO.getStationCode()); + if (Objects.isNull(station) || + !Objects.equals(MapElement.DeviceType.STATION, station.getDeviceType())) { + errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表车站[%s]数据不存在或不是车站", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode(), + runPlanTripTimeVO.getStationCode())); + } else { + builder.station((Station) station); + } + MapElement section = deviceMap.get(runPlanTripTimeVO.getSectionCode()); + if (Objects.isNull(section) || + !Objects.equals(MapElement.DeviceType.SECTION, section.getDeviceType())) { + errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表区段[%s]数据不存在或不是区段", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode(), + runPlanTripTimeVO.getSectionCode())); + } else { + builder.section((Section) section); + } + LocalTime arrivalTime = runPlanTripTimeVO.getArrivalTime(); + LocalTime departureTime = runPlanTripTimeVO.getDepartureTime(); + if (Objects.isNull(arrivalTime) || Objects.isNull(departureTime)) { + errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表计划到达时间和计划发车时间不能为空", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode())); + } else if (arrivalTime.isAfter(departureTime)) { + errMsgList.add(String.format("计划车次[%s|%s|%s]车站到发时刻表计划到达时间不能比计划发车时间晚", + runPlanTripVO.getServiceNumber(), runPlanTripVO.getTripNumber(), + runPlanTripVO.getDestinationCode())); + } else { + builder.arriveTime(arrivalTime); + builder.leaveTime(departureTime); + int parkTime = departureTime.toSecondOfDay() - arrivalTime.toSecondOfDay(); + if (parkTime <= 0) { + builder.park(false); + builder.parkTime(0); + } else { + builder.park(true); + builder.parkTime(parkTime); + } + } + StationPlan plan = builder.build(); + stationPlanList.add(plan); + }); + if (CollectionUtils.isEmpty(errMsgList)) { + // 排序 + stationPlanList.sort(Comparator.comparing(StationPlan::getArriveTime)); + } + return tripBuilder.build(); + } + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java index a9bb81aa8..bbd967786 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/SimulationDataRepository.java @@ -21,6 +21,7 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.util.StrUtils; import club.joylink.rtss.vo.client.psl.PslStatus; +import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -207,7 +208,7 @@ public class SimulationDataRepository { */ private final Map> catenaryMap = new ConcurrentHashMap<>(); - private Map> sectionRespondersMap = new HashMap<>(); + private Map> sectionRespondersMap = new HashMap<>(); /** * ats用户设置的列车偏离操作信息 @@ -215,6 +216,17 @@ public class SimulationDataRepository { */ private final Map deviationInfoMap = new ConcurrentHashMap<>(); + /** 加线、抽线的计划 */ + private List changeTrips = new CopyOnWriteArrayList<>(); + + public void addChangeTrips(Collection trips) { + this.changeTrips.addAll(trips); + } + + public void clearChangeTrips() { + this.changeTrips.clear(); + } + public void addDeviationInfo(DeviationInfo deviationInfo) { deviationInfoMap.put(deviationInfo.getStartStand().getCode(), deviationInfo); deviationInfoMap.put(deviationInfo.getEndStand().getCode(), deviationInfo); @@ -316,6 +328,7 @@ public class SimulationDataRepository { /** * 根据设备集中站的code获取设备集中站下的道岔 + * * @param code * @return */ @@ -460,6 +473,7 @@ public class SimulationDataRepository { /** * 查找路径 + * * @param start * @param end * @return @@ -470,6 +484,7 @@ public class SimulationDataRepository { /** * 根据终到区段查找路径 + * * @param start * @return */ @@ -485,6 +500,7 @@ public class SimulationDataRepository { /** * 根据终到区段查找路径 + * * @param end * @return */ @@ -708,6 +724,18 @@ public class SimulationDataRepository { this.deviceInfoMap.clear(); this.trainHmiMap.clear(); this.tdtStatusMap.clear(); + // 运行图 + this.changeTrips.clear(); + serviceTripsMap.forEach((k, v) -> { + for (Iterator iterator = v.iterator(); iterator.hasNext(); ) { + TripPlan tripPlan = iterator.next(); + if (tripPlan.isAdd()) { + iterator.remove(); + } else if (tripPlan.isInvalid()) { + tripPlan.setInvalid(false); + } + } + }); } /** @@ -765,7 +793,7 @@ public class SimulationDataRepository { // tripPlans.sort(Comparator.comparing(TripPlan::getStartTime)); TripPlan next = null; for (int i = 0; i < tripPlans.size(); i++) { - if (Objects.equals(tripPlans.get(i).getTripNumber(), tripNumber) && i+1 invalidPlanFrom(String serviceNumber, String tripNumber) { + List invalidList = new ArrayList<>(); + TripPlan tripPlan = findTripPlan(serviceNumber, tripNumber); + if (tripPlan != null) { + TrainInfo trainInfo = findSupervisedTrainByTrip(serviceNumber, tripNumber); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertNull(trainInfo, String.format("车次计划[%s-%s]已在运行", serviceNumber, tripNumber)); + invalidList.add(tripPlan); + List tripPlans = serviceTripsMap.get(serviceNumber); + for (TripPlan plan : tripPlans) { + if (plan.getStartTime().isAfter(tripPlan.getStartTime())) { + trainInfo = findSupervisedTrainByTrip(plan.getServiceNumber(), plan.getTripNumber()); + BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED + .assertNull(trainInfo, String.format("车次计划[%s-%s]已在运行", plan.getServiceNumber(), plan.getTripNumber())); + invalidList.add(plan); + } + } + invalidList.forEach(plan -> plan.setInvalid(true)); + } + return invalidList; + } + + public void addTrip(TripPlan tripPlan) { + List trips = this.serviceTripsMap.get(tripPlan.getServiceNumber()); + if (trips == null) { + trips = new ArrayList<>(); + serviceTripsMap.put(tripPlan.getServiceNumber(), trips); + } + trips.add(tripPlan); + } + public List getTripPlanListOfStand(Section section) { return this.standTripMap.get(section.getCode()); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java index 8cf468ce0..da810ef78 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/MapConfig.java @@ -207,6 +207,9 @@ public class MapConfig { /** 设置头码车时检查方向 */ private boolean checkDirectionWhenSetHead; + /** 转换轨进路只能通过故障解锁来取消 */ + private boolean transferRouteCanOnlyFaultUnlock; + private Set needConfirmConnectMembers = Stream.of(DISPATCHER, STATION_SUPERVISOR, MAINTAINER, ELECTRIC_DISPATCHER).collect(Collectors.toSet()); @@ -255,6 +258,7 @@ public class MapConfig { setFiguresOfTripNumber(configVO.getFiguresOfTripNumber()); setFiguresOfServiceNumber(configVO.getFiguresOfServiceNumber()); setCheckDirectionWhenSetHead(configVO.isCheckDirectionWhenSetHead()); + setTransferRouteCanOnlyFaultUnlock(configVO.isTransferRouteCanOnlyFaultUnlock()); } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java index dce0f6498..9ddcff5b2 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Route.java @@ -574,6 +574,10 @@ public class Route extends MapNamedElement { getLogicSections().forEach(section -> section.setDelayUnlock(false)); } + public boolean isTransferRoute() { + return this.sectionList.stream().anyMatch(Section::isTransferTrack); + } + /** * 进路检查失败原因 */ diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java index 9a078224a..cdc5d873a 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/RouteOverlap.java @@ -71,14 +71,14 @@ public class RouteOverlap extends MapNamedElement { } public synchronized void startSetting(LocalDateTime systemTime) { - this.lock = false; + this.setLock(false); this.settingStartTime = systemTime; this.requisition = false; this.setting = true; } public void settingFinish() { - this.lock = true; + this.setLock(true); this.setting = false; this.settingStartTime = null; this.requisition = false; @@ -113,7 +113,7 @@ public class RouteOverlap extends MapNamedElement { } } this.forbidden = true; - this.lock = false; + this.setLock(false); this.remainTime = 0; this.releasing = false; } @@ -249,4 +249,9 @@ public class RouteOverlap extends MapNamedElement { } return true; } + + public void setLock(boolean lock) { + this.signal.setOverlapLock(lock); + this.lock = lock; + } } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java index c4e068c3f..e57c86d04 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Section.java @@ -434,7 +434,8 @@ public class Section extends MayOutOfOrderDevice { public void axleCounterOccupy(boolean right) { if (!this.isInvalid()) { this.trainRight = right; - this.nctOccupied = true; + this.setNctOccupied(true); +// this.nctOccupied = true; // if (!CollectionUtils.isEmpty(logicList)) { // logicList.forEach(logic -> logic.axleCounterOccupy(right)); // } @@ -685,9 +686,17 @@ public class Section extends MayOutOfOrderDevice { this.ctOccupied = true; } + public void setNctOccupied(boolean nctOccupied) { + if (nctOccupied) { + this.invalid = false; + } + this.nctOccupied = nctOccupied; + } + public void nonCommunicateTrainOccupy(boolean right) { this.trainRight = right; - this.nctOccupied = true; + this.setNctOccupied(true); +// this.nctOccupied = true; this.ctOccupied = false; } @@ -726,10 +735,9 @@ public class Section extends MayOutOfOrderDevice { } /** - * 判定为失效(ARB)(暂时改为判定非通信车占用) + * 判定为非通信车占用 */ - public void judgeAsInvalid() { - //暂时改为判定非通信车占用(国赛用) + public void judgeAsNctOccupied() { if (!this.isAxleCounter()) { return; } @@ -758,37 +766,6 @@ public class Section extends MayOutOfOrderDevice { logic.setNctOccupied(true); } } - - -// if (!this.isAxleCounter()) { -// throw new SimulationException(SimulationExceptionType.System_Fault); -// } -// this.setInvalid(true); -// this.setNctOccupied(false); -// if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 -// List relSwitchList = this.getRelSwitchList(); -// for (Switch aSwitch : relSwitchList) { -// aSwitch.getA().setInvalid(true); -// aSwitch.getA().setNctOccupied(false); -// if (aSwitch.isNormalPosition()) { -// aSwitch.getB().setInvalid(true); -// aSwitch.getB().setNctOccupied(false); -// } else if (aSwitch.isReversePosition()) { -// aSwitch.getC().setInvalid(true); -// aSwitch.getC().setNctOccupied(false); -// } else { -// aSwitch.getB().setInvalid(true); -// aSwitch.getB().setNctOccupied(false); -// aSwitch.getC().setInvalid(true); -// aSwitch.getC().setNctOccupied(false); -// } -// } -// } else if (!CollectionUtils.isEmpty(this.logicList)) { -// for (Section logic : this.logicList) { -// logic.setInvalid(true); -// logic.setNctOccupied(false); -// } -// } } /** @@ -1033,6 +1010,40 @@ public class Section extends MayOutOfOrderDevice { return false; } + public void setInvalid(boolean invalid) { + if (invalid) { + this.setNctOccupied(false); + } + this.invalid = invalid; + } + + public void judgeAsARB() { + if (!this.isAxleCounter()) { + return; + } + this.setInvalid(true); + if (this.isSwitchAxleCounterSection()) { // 道岔计轴区段 + List relSwitchList = this.getRelSwitchList(); + for (Switch aSwitch : relSwitchList) { + aSwitch.getA().setInvalid(true); + if (aSwitch.isNormalPosition()) { + aSwitch.getB().setInvalid(true); + aSwitch.getC().setInvalid(false); + } else if (aSwitch.isReversePosition()) { + aSwitch.getC().setInvalid(true); + aSwitch.getB().setInvalid(false); + } else { + aSwitch.getB().setInvalid(true); + aSwitch.getC().setInvalid(true); + } + } + } else if (!CollectionUtils.isEmpty(this.logicList)) { + for (Section logic : this.logicList) { + logic.setInvalid(true); + } + } + } + public enum SectionRoadType { /** * 左行线 @@ -1154,10 +1165,10 @@ public class Section extends MayOutOfOrderDevice { flag = true; VirtualRealitySectionAxleCounter.Fault.FAULT.apply(axleSection.getVirtualAxleCounter()); axleSection.setFault(this); - axleSection.setInvalid(true); - if (!CollectionUtils.isEmpty(axleSection.getLogicList())) { - axleSection.getLogicList().forEach(logic -> logic.setInvalid(true)); - } +// axleSection.setInvalid(true); +// if (!CollectionUtils.isEmpty(axleSection.getLogicList())) { +// axleSection.getLogicList().forEach(logic -> logic.setInvalid(true)); +// } } } return flag; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java index 05b21a7be..f08d65ad3 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Signal.java @@ -220,6 +220,9 @@ public class Signal extends MayOutOfOrderDevice { */ private boolean approachLock; + /** 延续保护锁闭 */ + private boolean overlapLock; + @Override public void reset() { super.reset(); @@ -239,6 +242,7 @@ public class Signal extends MayOutOfOrderDevice { this.noStatus = false; this.init = false; this.approachLock = false; + this.overlapLock = false; } @Override diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java index bff904146..64f53dde1 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/map/Switch.java @@ -167,7 +167,7 @@ public class Switch extends MayOutOfOrderDevice { * 是否道岔区段被占用 */ public boolean isSectionOccupied() { - return this.a.isOccupied(); + return this.a.isOccupied() && !this.a.isInvalid(); } /** diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/plan/TripPlan.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/plan/TripPlan.java index e52ed00bc..5e6a83a82 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/plan/TripPlan.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/plan/TripPlan.java @@ -5,6 +5,7 @@ import club.joylink.rtss.simulation.cbtc.data.map.Stand; import club.joylink.rtss.simulation.cbtc.data.map.Station; import lombok.Builder; import lombok.Getter; +import lombok.Setter; import java.time.LocalTime; import java.util.ArrayList; @@ -63,6 +64,14 @@ public class TripPlan { /** 是否发车 */ private boolean departure; + /** 失效(抽线) */ + @Setter + private boolean invalid; + + /** 加线 */ + @Setter + private boolean add; + /** * 获取正线车站运行计划起始时间 * @return diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SignalStatus.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SignalStatus.java index 3f83e1c6e..413c8c3e5 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SignalStatus.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/status/SignalStatus.java @@ -69,6 +69,9 @@ public class SignalStatus extends DeviceStatus { @JsonSerialize(using = Boolean2NumSerializer.class) private boolean approachLock; + @JsonSerialize(using = Boolean2NumSerializer.class) + private boolean overlapLock; + /**故障*/ private String fault; @@ -85,6 +88,7 @@ public class SignalStatus extends DeviceStatus { this.remainTime = signal.getDelayTime(); this.noStatus = signal.isNoStatus(); this.approachLock = signal.isApproachLock(); + this.overlapLock = signal.isOverlapLock(); this.fault = Objects.nonNull(signal.getFault())?((Signal.SignalFault)signal.getFault()).name():null; } @@ -153,6 +157,11 @@ public class SignalStatus extends DeviceStatus { status.setApproachLock(approachLock); change = true; } + if (!Objects.equals(this.overlapLock, signal.isOverlapLock())) { + this.overlapLock = signal.isOverlapLock(); + status.setOverlapLock(this.overlapLock); + change = true; + } MayOutOfOrderDevice.DeviceFault fault = signal.getFault(); if (!Objects.equals(this.fault, Objects.nonNull(fault) ? ((Signal.SignalFault) fault).name():null)) { if(Objects.isNull(fault)){ @@ -179,6 +188,8 @@ public class SignalStatus extends DeviceStatus { statusVO.setReblockade(this.reblockade); statusVO.setLockedRouteCode(lockedRouteCode); statusVO.setNoStatus(noStatus); + statusVO.setApproachLock(approachLock); + statusVO.setOverlapLock(overlapLock); statusVO.setFault(fault); return statusVO; } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/TrainStopMessage.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/TrainStopMessage.java index 3fa9e2f5b..fa0f5265c 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/TrainStopMessage.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/support/TrainStopMessage.java @@ -10,12 +10,12 @@ import lombok.Getter; @Getter public class TrainStopMessage { - private String groupNumber; + private VirtualRealityTrain train; private Section section; public TrainStopMessage(VirtualRealityTrain train) { - this.groupNumber = train.getGroupNumber(); + this.train = train; this.section = train.getHeadPosition().getSection(); } diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SignalStatusVO.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SignalStatusVO.java index c6496703a..11a0be3b3 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SignalStatusVO.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/SignalStatusVO.java @@ -60,6 +60,9 @@ public class SignalStatusVO extends DeviceStatusVO{ @JsonSerialize(using = Boolean2NumSerializer.class) private Boolean approachLock; + @JsonSerialize(using = Boolean2NumSerializer.class) + private Boolean overlapLock; + /** 信号机故障 */ @JsonInclude(JsonInclude.Include.ALWAYS) private String fault; diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java index a73d4096f..1096cf879 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/data/vr/VirtualRealityTrain.java @@ -712,14 +712,20 @@ public class VirtualRealityTrain extends VirtualRealityDevice { // this.setSignalEB(false); this.setAtoOn(false); this.setDriveMode(DriveMode.RM); - this.positioned = false; //定位丢失 + this.lossPosition(); +// this.positioned = false; //定位丢失 this.setCbtcMaMiss(); //通信断开 - this.lastTwoPassedResponders.clear(); +// this.lastTwoPassedResponders.clear(); // if (RunLevel.CBTC.equals(this.runLevel)) { // this.setCbtcMaMiss(); // } } + public void lossPosition() { + this.positioned = false; + this.lastTwoPassedResponders.clear(); + } + public void useCMMode() { if (!this.isAtpOn()) { throw new SimulationException(SimulationExceptionType.Invalid_Operation, String.format("列车[%s]未打开ATP", this.getCode())); @@ -1125,13 +1131,19 @@ public class VirtualRealityTrain extends VirtualRealityDevice { * 通信异常 */ COMMUNICATION_ABNORMAL { - @Override - public void fix(MapElement device) { - VirtualRealityTrain train = (VirtualRealityTrain) device; - train.setFault(null); - train.getLastTwoPassedResponders().clear(); - } +// @Override +// public boolean apply(MapElement device) { +// VirtualRealityTrain train = (VirtualRealityTrain) device; +// if (Objects.equals(this, train.getFault())) { +// return false; +// } +// train.setFault(this); +// train.lossPosition(); +// return true; +// } }, + + /** 驾驶异常 */ DRIVE_FAULT { @Override public boolean apply(MapElement device) { diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/event/SimulationTripPlanChangeEvent.java b/src/main/java/club/joylink/rtss/simulation/cbtc/event/SimulationTripPlanChangeEvent.java new file mode 100644 index 000000000..6ef31db3a --- /dev/null +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/event/SimulationTripPlanChangeEvent.java @@ -0,0 +1,19 @@ +package club.joylink.rtss.simulation.cbtc.event; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class SimulationTripPlanChangeEvent extends AbstractSimulationEvent{ + List changeTrips; + + public SimulationTripPlanChangeEvent(Object source, Simulation simulation, List changeTrips) { + super(source, simulation); + this.changeTrips = changeTrips; + } +} diff --git a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java index b2ef3f34b..90892ab96 100644 --- a/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java +++ b/src/main/java/club/joylink/rtss/simulation/cbtc/onboard/ATP/ATPLogicLoop.java @@ -87,6 +87,7 @@ public class ATPLogicLoop { } else { //列车有定位 if (train.isCBTC() && train.isCbtcMaMiss()) { //CBTC列车的移动授权丢失 train.setRunLevel(RunLevel.IL); + train.lossPosition(); atpService.triggerSignalEB(train); train.setMa(null); } else if (!train.isCbtcMaMiss() && defaultRunLevel.equals(RunLevel.CBTC)) { 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 6f6520160..c6e32b064 100644 --- a/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java +++ b/src/main/java/club/joylink/rtss/vo/client/WebSocketMessageType.java @@ -65,6 +65,8 @@ public enum WebSocketMessageType { Simulation_Reset, /** 仿真-仿真运行计划重新加载消息 */ Simulation_Run_Plan_Reload, + /** 车次计划变化消息 */ + Simulation_Trip_Plan_Change, /** 仿真-仿真场景重新加载 */ Simulation_Scenes_Reload, /** 仿真-仿真成员改变消息 */ 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 050fdb859..26e4989f3 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 @@ -14,6 +14,8 @@ import club.joylink.rtss.vo.client.SocketMessageVO; import club.joylink.rtss.vo.client.WebSocketMessageType; import club.joylink.rtss.vo.client.passenger.PassengerFlowMessage2TD; import club.joylink.rtss.vo.client.psl.PslStatus; +import club.joylink.rtss.vo.client.runplan.RunPlanEChartsDataVO; +import club.joylink.rtss.vo.client.runplan.RunPlanTripVO; import club.joylink.rtss.vo.client.script.ScriptActionVO; import club.joylink.rtss.vo.client.simulationv1.SimulationMemberMessageVO; import club.joylink.rtss.vo.client.simulationv1.SimulationUserMessageVO; @@ -89,6 +91,7 @@ public class SocketMessageFactory { case Simulation_Control_Pause: case Simulation_Permission_Over: case Simulation_Run_Plan_Reload: + case Simulation_Trip_Plan_Change: case Simulation_Scenes_Reload: case Simulation_Quest_Finish: case Simulation_PlayBack_Finish: @@ -366,4 +369,12 @@ public class SocketMessageFactory { public static SocketMessageVO buildOrderPaySuccessMessage(String orderCode) { return build(WebSocketMessageType.Order_Pay_Result, null, orderCode); } + + /** + * 车次计划变化 + */ + public static SocketMessageVO buildTripPlanChangeMessage(String simulationId, List changeTrips) { + RunPlanEChartsDataVO eChartsDataVO = new RunPlanEChartsDataVO(changeTrips); + return build(WebSocketMessageType.Simulation_Trip_Plan_Change, simulationId, eChartsDataVO); + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanEChartsDataVO.java b/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanEChartsDataVO.java index 1382bafdb..552b95351 100644 --- a/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanEChartsDataVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanEChartsDataVO.java @@ -103,6 +103,12 @@ public class RunPlanEChartsDataVO { List stationTimeList; + Boolean add; + + Boolean firstInvalid; + + Boolean invalid; + TripNumberData(RunPlanTripVO runPlanTripVO) { this.startSectionCode = runPlanTripVO.getStartSectionCode(); this.startSecondTime = runPlanTripVO.getStartTime().toSecondOfDay(); @@ -117,6 +123,9 @@ public class RunPlanEChartsDataVO { this.outbound = runPlanTripVO.getIsOutbound(); this.backup = runPlanTripVO.getIsBackUp(); this.stationTimeList = new ArrayList<>(); + this.add = runPlanTripVO.isAdd() ? true : null; + this.firstInvalid = runPlanTripVO.isFirstInvalid() ? true : null; + this.invalid = runPlanTripVO.isInvalid() ? true : null; } } diff --git a/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanTripVO.java b/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanTripVO.java index facc2936d..67c5b5a7a 100644 --- a/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanTripVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanTripVO.java @@ -106,6 +106,12 @@ public class RunPlanTripVO { @JsonProperty(value = "n") private Boolean right; + private boolean add; + + private boolean firstInvalid; + + private boolean invalid; + public RunPlanTripVO(RunPlanImport runPlanImport) { this.serviceNumber = runPlanImport.getServiceNumber(); this.tripNumber = runPlanImport.getTripNumber(); diff --git a/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanVO.java b/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanVO.java index 898f90a51..2219104d2 100644 --- a/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/runplan/RunPlanVO.java @@ -3,6 +3,7 @@ package club.joylink.rtss.vo.client.runplan; import club.joylink.rtss.entity.RunPlanDaily; import club.joylink.rtss.entity.RunPlanDraft; import club.joylink.rtss.entity.RunPlanTemplate; +import club.joylink.rtss.simulation.cbtc.data.plan.TripPlan; import club.joylink.rtss.util.JsonUtils; import club.joylink.rtss.vo.client.validGroup.RunPlanCreateCheck; import club.joylink.rtss.vo.client.validGroup.RunPlanNameCheck; @@ -20,10 +21,9 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.time.LocalTime; +import java.util.*; +import java.util.stream.Collectors; @Getter @Setter @@ -213,28 +213,30 @@ public class RunPlanVO { return vo; } -// public void setStationDiagramList(List stationDiagramList) { -// stationDiagramList.sort(Comparator.comparing(RunPlanStationTimeVO::getArriveTime)); -// this.stationDiagramList = stationDiagramList; -// if(!CollectionUtils.isEmpty(stationDiagramList)) { -// Set serverNoList = new HashSet<>(); -// Set trainNoList = new HashSet<>(); -// Map> serverNoTrainNoRelMap = new HashMap<>(); -// Map> serverStationMap = new HashMap<>(); -// Map> trainStationMap = new HashMap<>(); -// stationDiagramList.forEach(diagram -> { -// serverNoList.add(diagram.getServiceNumber()); -// trainNoList.add(diagram.getTripNumber()); -// Set trainNoSet = serverNoTrainNoRelMap.computeIfAbsent(diagram.getServiceNumber(), k -> new HashSet<>()); -// trainNoSet.add(diagram.getTripNumber()); -// List tsList = trainStationMap.computeIfAbsent(diagram.getTripNumber(), k -> new ArrayList<>()); -// tsList.add(diagram); -// List ssList = serverStationMap.computeIfAbsent(diagram.getServiceNumber(), k -> new ArrayList<>()); -// ssList.add(diagram); -// }); -// this.serverNoList = serverNoList; -// this.trainNoList = trainNoList; -// this.serverStationMap = serverStationMap; -// } -// } + public List invalidTripPlan(List removeList) { + TripPlan first = removeList.get(0); + String serviceNumber = first.getServiceNumber(); + LocalTime startTime = first.getStartTime(); + return this.tripList.stream() + .filter(plan -> { + if (!plan.getServiceNumber().equals(serviceNumber)) + return false; + if (plan.getStartTime().isBefore(startTime)) + return false; + if (plan.isInvalid() && !plan.isFirstInvalid()) + return false; + return true; + }) + .peek(plan -> { + if (!plan.getStartTime().isBefore(startTime)) { + if (plan.isFirstInvalid()) + plan.setFirstInvalid(false); + plan.setInvalid(true); + if (plan.getTripNumber().equals(first.getTripNumber())) { + plan.setFirstInvalid(true); + } + } + }) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/club/joylink/rtss/vo/client/runplan/user/RunPlanRoutingQueryVO.java b/src/main/java/club/joylink/rtss/vo/client/runplan/user/RunPlanRoutingQueryVO.java index 50fd3ec01..780fc9e89 100644 --- a/src/main/java/club/joylink/rtss/vo/client/runplan/user/RunPlanRoutingQueryVO.java +++ b/src/main/java/club/joylink/rtss/vo/client/runplan/user/RunPlanRoutingQueryVO.java @@ -23,4 +23,8 @@ public class RunPlanRoutingQueryVO extends PageQueryVO { * 终到站台区段code */ private String endSectionCode; + /** + * 目的地码 + */ + private String destinationCode; } diff --git a/src/main/java/club/joylink/rtss/vo/map/RealLineConfigVO.java b/src/main/java/club/joylink/rtss/vo/map/RealLineConfigVO.java index 444de8494..6ba466579 100644 --- a/src/main/java/club/joylink/rtss/vo/map/RealLineConfigVO.java +++ b/src/main/java/club/joylink/rtss/vo/map/RealLineConfigVO.java @@ -196,6 +196,9 @@ public class RealLineConfigVO { /** 设置头码车时检查方向 */ private boolean checkDirectionWhenSetHead; + /** 转换轨进路只能通过故障解锁来取消 */ + private boolean transferRouteCanOnlyFaultUnlock; + public static RealLineConfigVO parseJsonStr(String configData) { if (StringUtils.hasText(configData)) { return JsonUtils.read(configData, RealLineConfigVO.class);