泰国沙盘禁用列车自动上线逻辑

This commit is contained in:
joylink_zhangsai 2023-06-05 11:41:59 +08:00
parent 5cc2c02ccc
commit b41ea03502
2 changed files with 678 additions and 628 deletions

View File

@ -1,8 +1,17 @@
package club.joylink.rtss.simulation.cbtc.CTC; package club.joylink.rtss.simulation.cbtc.CTC;
import club.joylink.rtss.constants.ProjectCode;
import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService; import club.joylink.rtss.simulation.cbtc.ATS.service.AtsTrainLoadService;
import club.joylink.rtss.simulation.cbtc.CTC.data.*; import club.joylink.rtss.simulation.cbtc.CTC.data.CtcEffectRepository;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.*; import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence;
import club.joylink.rtss.simulation.cbtc.CTC.data.TrackView;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.BusyBoardVO;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.CtcStationRunPlanLogVO;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RailDispatchCommandVO;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RouteSequenceVO;
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.TrackViewVO;
import club.joylink.rtss.simulation.cbtc.CTC.rail.dcmd.service.DisCmdSendService; import club.joylink.rtss.simulation.cbtc.CTC.rail.dcmd.service.DisCmdSendService;
import club.joylink.rtss.simulation.cbtc.CTC.service.CTCService; import club.joylink.rtss.simulation.cbtc.CTC.service.CTCService;
import club.joylink.rtss.simulation.cbtc.CTC.service.CtcDispatchCommandService; import club.joylink.rtss.simulation.cbtc.CTC.service.CtcDispatchCommandService;
@ -21,18 +30,25 @@ import club.joylink.rtss.vo.client.WebSocketMessageType;
import club.joylink.rtss.vo.client.factory.SocketMessageFactory; import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
import club.joylink.rtss.websocket.StompMessageService; import club.joylink.rtss.websocket.StompMessageService;
import club.joylink.rtss.websocket.WebSocketMessage; import club.joylink.rtss.websocket.WebSocketMessage;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Component @Component
public class CTCLogicLoop { public class CTCLogicLoop {
public static final String LOGIC_NAME = "CTC"; //逻辑循环任务名称 public static final String LOGIC_NAME = "CTC"; //逻辑循环任务名称
public static final int LOGIC_RATE = 1000; //逻辑循环频率 public static final int LOGIC_RATE = 1000; //逻辑循环频率
public static final String MESSAGE_NAME = "CTC_MESSAGE"; //消息发送任务名称 public static final String MESSAGE_NAME = "CTC_MESSAGE"; //消息发送任务名称
@ -74,7 +90,7 @@ public class CTCLogicLoop {
//dis cmd v1 //dis cmd v1
sendUnreadDispatchCommand(simulation, userId); sendUnreadDispatchCommand(simulation, userId);
//dis cmd v2 //dis cmd v2
disCmdService.autoSendUnread(simulation,userId); disCmdService.autoSendUnread(simulation, userId);
} }
private void sendAllBusyBoardMessage(Simulation simulation, String userId) { private void sendAllBusyBoardMessage(Simulation simulation, String userId) {
@ -102,7 +118,8 @@ public class CTCLogicLoop {
private void sendUnreadDispatchCommand(Simulation simulation, String userId) { private void sendUnreadDispatchCommand(Simulation simulation, String userId) {
SimulationMember member = simulation.querySimulationMemberByUserId(userId); SimulationMember member = simulation.querySimulationMemberByUserId(userId);
if (member != null) { if (member != null) {
List<RailDispatchCommandVO> unreadCommands = ctcDispatchCommandService.queryUnreadDispatchCommand(simulation, member); List<RailDispatchCommandVO> unreadCommands = ctcDispatchCommandService.queryUnreadDispatchCommand(
simulation, member);
for (RailDispatchCommandVO unreadCommand : unreadCommands) { for (RailDispatchCommandVO unreadCommand : unreadCommands) {
WebSocketMessage<RailDispatchCommandVO.WsMsgType, RailDispatchCommandVO> messageBody WebSocketMessage<RailDispatchCommandVO.WsMsgType, RailDispatchCommandVO> messageBody
= new WebSocketMessage<>(RailDispatchCommandVO.WsMsgType.ADD, unreadCommand); = new WebSocketMessage<>(RailDispatchCommandVO.WsMsgType.ADD, unreadCommand);
@ -145,45 +162,55 @@ public class CTCLogicLoop {
private void routeSequenceUpdate(Simulation simulation) { private void routeSequenceUpdate(Simulation simulation) {
LocalDateTime correctSystemTime = simulation.getCorrectSystemTime(); LocalDateTime correctSystemTime = simulation.getCorrectSystemTime();
SimulationDataRepository repository = simulation.getRepository(); SimulationDataRepository repository = simulation.getRepository();
for (Map.Entry<String, RouteSequence> entry : simulation.getCtcRepository().getRouteSequenceMap().entrySet()) { for (Map.Entry<String, RouteSequence> entry : simulation.getCtcRepository()
.getRouteSequenceMap().entrySet()) {
String stationCode = entry.getKey(); String stationCode = entry.getKey();
Station station = repository.getByCode(stationCode, Station.class); Station station = repository.getByCode(stationCode, Station.class);
RouteSequence routeSequence = entry.getValue(); RouteSequence routeSequence = entry.getValue();
for (RouteSequence.Line line : routeSequence.getLines()) { for (RouteSequence.Line line : routeSequence.getLines()) {
//更新触发/正在触发状态 //更新触发/正在触发状态
if (line.isTriggered()) if (line.isTriggered()) {
continue; continue;
}
Route route = line.getRoute(); Route route = line.getRoute();
if (route == null) if (route == null) {
continue; continue;
}
if (Objects.equals(line.getTripNumber(), route.getTripNumber())) { if (Objects.equals(line.getTripNumber(), route.getTripNumber())) {
if (route.isLock()) { if (route.isLock()) {
line.setTriggered(true); line.setTriggered(true);
continue; continue;
} else { } else {
line.setSetting(route.isSetting()); line.setSetting(route.isSetting());
if (line.isSetting()) if (line.isSetting()) {
continue; continue;
} }
} }
}
//自动触发 //自动触发
if (station.isInterlockControl() || !line.isAutoTrigger()) //非常站控或者没有设置自触 if (station.isInterlockControl() || !line.isAutoTrigger()) //非常站控或者没有设置自触
{
continue; continue;
}
TrainInfo trainInfo = repository.findSupervisedTrainByTrip("", line.getTripNumber()); TrainInfo trainInfo = repository.findSupervisedTrainByTrip("", line.getTripNumber());
if (line.isDeparture()) { //发车进路需列车停稳并到达计划时间 if (line.isDeparture()) { //发车进路需列车停稳并到达计划时间
if (correctSystemTime.isBefore(line.getPlanDateTime())) if (correctSystemTime.isBefore(line.getPlanDateTime())) {
continue; continue;
if (trainInfo != null && trainInfo.isStop() && Objects.equals(trainInfo.getPhysicalSection(), line.getTrackCode())) }
if (trainInfo != null && trainInfo.isStop() && Objects.equals(
trainInfo.getPhysicalSection(), line.getTrackCode())) {
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
}
} else { } else {
if (!correctSystemTime.isBefore(line.getPlanDateTime())) if (!correctSystemTime.isBefore(line.getPlanDateTime())) {
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
else if (trainInfo != null && line.isTriggerSection(trainInfo.getPhysicalSection())) } else if (trainInfo != null && line.isTriggerSection(trainInfo.getPhysicalSection())) {
ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null); ctcService.setRoute(simulation, line.getRouteCode(), line.getTripNumber(), false, null);
} }
} }
} }
} }
}
/** /**
* 更新行车日志状态 * 更新行车日志状态
@ -203,8 +230,9 @@ public class CTCLogicLoop {
Station station = headSection.getDeviceStation(); Station station = headSection.getDeviceStation();
String tripNumber = trainInfo.getTripNumber(); String tripNumber = trainInfo.getTripNumber();
CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), tripNumber); CtcStationRunPlanLog runPlan = ctcRepository.findRunPlan(station.getCode(), tripNumber);
if (runPlan == null) if (runPlan == null) {
continue; continue;
}
// 接车计划到点列车占压区段与接车计划股道一致且列车是停站状态 // 接车计划到点列车占压区段与接车计划股道一致且列车是停站状态
CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan(); CtcStationRunPlanLog.RunPlanItem arriveRunPlan = runPlan.getArriveRunPlan();
if (arriveRunPlan != null) { if (arriveRunPlan != null) {
@ -215,7 +243,8 @@ public class CTCLogicLoop {
//设置上一站的<邻站到达> //设置上一站的<邻站到达>
Station previousStation = runPlan.findPreviousStation(); Station previousStation = runPlan.findPreviousStation();
if (previousStation != null) { if (previousStation != null) {
CtcStationRunPlanLog previousRunPlan = ctcRepository.findRunPlan(previousStation.getCode(), tripNumber); CtcStationRunPlanLog previousRunPlan = ctcRepository.findRunPlan(
previousStation.getCode(), tripNumber);
if (previousRunPlan != null) { if (previousRunPlan != null) {
CtcStationRunPlanLog.RunPlanItem previousDeparturePlan = previousRunPlan.getDepartRunPlan(); CtcStationRunPlanLog.RunPlanItem previousDeparturePlan = previousRunPlan.getDepartRunPlan();
if (previousDeparturePlan != null) { if (previousDeparturePlan != null) {
@ -238,7 +267,8 @@ public class CTCLogicLoop {
//设置下一站的<邻站出发> //设置下一站的<邻站出发>
Station nextStation = runPlan.findNextStation(); Station nextStation = runPlan.findNextStation();
if (nextStation != null) { if (nextStation != null) {
CtcStationRunPlanLog nextRunPlan = ctcRepository.findRunPlan(nextStation.getCode(), tripNumber); CtcStationRunPlanLog nextRunPlan = ctcRepository.findRunPlan(nextStation.getCode(),
tripNumber);
if (nextRunPlan != null) { if (nextRunPlan != null) {
CtcStationRunPlanLog.RunPlanItem nextArriveRunPlan = nextRunPlan.getArriveRunPlan(); CtcStationRunPlanLog.RunPlanItem nextArriveRunPlan = nextRunPlan.getArriveRunPlan();
if (nextArriveRunPlan != null) { if (nextArriveRunPlan != null) {
@ -293,7 +323,8 @@ public class CTCLogicLoop {
for (RouteSequence routeSequence : routeSequenceMap.values()) { for (RouteSequence routeSequence : routeSequenceMap.values()) {
RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence); RouteSequenceVO routeSequenceVO = new RouteSequenceVO(routeSequence);
routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO); routeSequenceVOMap.put(routeSequenceVO.getStationCode(), routeSequenceVO);
BusyBoardVO busyBoardVO = new BusyBoardVO(routeSequenceVO.getStationCode(), routeSequenceVO, null); BusyBoardVO busyBoardVO = new BusyBoardVO(routeSequenceVO.getStationCode(), routeSequenceVO,
null);
list.add(busyBoardVO); list.add(busyBoardVO);
} }
} else { } else {
@ -322,9 +353,11 @@ public class CTCLogicLoop {
* 行车区段运行计划下发 * 行车区段运行计划下发
*/ */
public void sendZoneRunPlanSend(Simulation simulation) { public void sendZoneRunPlanSend(Simulation simulation) {
List<CtcEffectRepository.CtcStageRunPlanRepository.CtcStageRunPlanVO> allList = simulation.getCtcRepository().getCtcEffectRepository().getChangeStageRunPlan(); List<CtcEffectRepository.CtcStageRunPlanRepository.CtcStageRunPlanVO> allList = simulation.getCtcRepository()
.getCtcEffectRepository().getChangeStageRunPlan();
if (!CollectionUtils.isEmpty(allList)) { if (!CollectionUtils.isEmpty(allList)) {
sendCtcMessage(simulation.getId(), allList, WebSocketMessageType.SIMULATION_RAILWAY_RUN_PLAN_SEND, simulation.getSimulationUserIds()); sendCtcMessage(simulation.getId(), allList,
WebSocketMessageType.SIMULATION_RAILWAY_RUN_PLAN_SEND, simulation.getSimulationUserIds());
} }
} }
@ -332,7 +365,8 @@ public class CTCLogicLoop {
* 运行计划发送变化事件 * 运行计划发送变化事件
*/ */
private void sendRunPlanChangeMessage(Simulation simulation) { private void sendRunPlanChangeMessage(Simulation simulation) {
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap(); Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository()
.getRunPlanStatusVOMap();
List<CtcStationRunPlanLog> allRunPlanList = simulation.getCtcRepository().getAllRunPlanList(); List<CtcStationRunPlanLog> allRunPlanList = simulation.getCtcRepository().getAllRunPlanList();
List<CtcStationRunPlanLogVO> messageList = new ArrayList<>(); List<CtcStationRunPlanLogVO> messageList = new ArrayList<>();
allRunPlanList.forEach(runPlan -> { allRunPlanList.forEach(runPlan -> {
@ -360,14 +394,17 @@ public class CTCLogicLoop {
* @param simulation 仿真实体 * @param simulation 仿真实体
*/ */
public void sendRunPlanRemoveMessage(Simulation simulation) { public void sendRunPlanRemoveMessage(Simulation simulation) {
Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository().getRunPlanStatusVOMap(); Map<String, CtcStationRunPlanLogVO> ctcRunPlanVOMap = simulation.getCtcRepository()
.getRunPlanStatusVOMap();
List<CtcStationRunPlanLogVO> ctcStationRunPlanLogVOList = ctcRunPlanVOMap.values().stream() List<CtcStationRunPlanLogVO> ctcStationRunPlanLogVOList = ctcRunPlanVOMap.values().stream()
.filter(vo -> simulation.getCtcRepository().getRunPlanByRunPlanCodeAndStationCode(vo.getStationCode(), vo.getCode()) == null) .filter(vo -> simulation.getCtcRepository()
.getRunPlanByRunPlanCodeAndStationCode(vo.getStationCode(), vo.getCode()) == null)
.map(vo -> new CtcStationRunPlanLogVO(vo.getStationCode(), vo.getCode())) .map(vo -> new CtcStationRunPlanLogVO(vo.getStationCode(), vo.getCode()))
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!CollectionUtils.isEmpty(ctcStationRunPlanLogVOList)) { if (!CollectionUtils.isEmpty(ctcStationRunPlanLogVOList)) {
// 移除已删除的数据 // 移除已删除的数据
ctcStationRunPlanLogVOList.forEach(vo -> ctcRunPlanVOMap.remove(vo.getStationCode() + "_" + vo.getCode())); ctcStationRunPlanLogVOList.forEach(
vo -> ctcRunPlanVOMap.remove(vo.getStationCode() + "_" + vo.getCode()));
sendCtcMessage(simulation.getId(), ctcStationRunPlanLogVOList sendCtcMessage(simulation.getId(), ctcStationRunPlanLogVOList
, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_REMOVE, simulation.getSimulationUserIds()); , WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_REMOVE, simulation.getSimulationUserIds());
} }
@ -385,9 +422,11 @@ public class CTCLogicLoop {
} }
}); });
// 为空时 // 为空时
if (!Objects.equals(simulation.getCtcRepository().getRunPlanSendOut(), changeMap.isEmpty()) || !changeMap.isEmpty()) { if (!Objects.equals(simulation.getCtcRepository().getRunPlanSendOut(), changeMap.isEmpty())
|| !changeMap.isEmpty()) {
simulation.getCtcRepository().setRunPlanSendOut(changeMap.isEmpty()); simulation.getCtcRepository().setRunPlanSendOut(changeMap.isEmpty());
sendCtcMessage(simulation.getId(), changeMap, WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CONFIRM_SEND sendCtcMessage(simulation.getId(), changeMap,
WebSocketMessageType.SIMULATION_CTC_RUN_PLAN_CONFIRM_SEND
, simulation.getSimulationUserIds()); , simulation.getSimulationUserIds());
} }
} }
@ -400,7 +439,8 @@ public class CTCLogicLoop {
* @param type 消息类型 * @param type 消息类型
* @param userIds 用户ID * @param userIds 用户ID
*/ */
public <T> void sendCtcMessage(String simulationId, T messageInfo, WebSocketMessageType type, Set<String> userIds) { public <T> void sendCtcMessage(String simulationId, T messageInfo, WebSocketMessageType type,
Set<String> userIds) {
if (messageInfo != null) { if (messageInfo != null) {
SocketMessageVO<T> messageVO = SocketMessageFactory.build(type, simulationId, messageInfo); SocketMessageVO<T> messageVO = SocketMessageFactory.build(type, simulationId, messageInfo);
stompMessageService.sendToUser(userIds, messageVO); stompMessageService.sendToUser(userIds, messageVO);
@ -414,31 +454,38 @@ public class CTCLogicLoop {
* @param simulation 仿真信息 * @param simulation 仿真信息
*/ */
private void loadSignRunPlanTrain(Simulation simulation) { private void loadSignRunPlanTrain(Simulation simulation) {
if (!simulation.isPlanRunning()) { if (!simulation.isPlanRunning() || ProjectCode.THAILAND_SANDBOX.equals(
simulation.getProject())) { //泰国沙盘项目不能随意指定列车上线所以禁用此逻辑后续考虑用地图配置
return; return;
} }
// 没有加载过计划始发计划已发送至占线板当前时间晚于计划时间提前5分钟 // 没有加载过计划始发计划已发送至占线板当前时间晚于计划时间提前5分钟
simulation.getCtcRepository().getAllRunPlanList().stream() simulation.getCtcRepository().getAllRunPlanList().stream()
.filter(r -> r.getDepartRunPlan() != null && (r.isStartRunPlan() || (r.getArriveRunPlan() == null && r.getDepartRunPlan() != null))) .filter(r -> r.getDepartRunPlan() != null && (r.isStartRunPlan() || (
r.getArriveRunPlan() == null && r.getDepartRunPlan() != null)))
.filter(r -> { .filter(r -> {
boolean valid = !r.isLoad() && r.isSign() && r.getStatus() != -1 boolean valid = !r.isLoad() && r.isSign() && r.getStatus() != -1
&& simulation.getCorrectSystemTime().isAfter(r.getDepartRunPlan().getPlanTime().minusMinutes(5)); && simulation.getCorrectSystemTime()
.isAfter(r.getDepartRunPlan().getPlanTime().minusMinutes(5));
if (valid) { if (valid) {
valid = !simulation.getRepository().getTrainInfoMap().values().stream() valid = !simulation.getRepository().getTrainInfoMap().values().stream()
.anyMatch(trainInfo -> r.getDepartRunPlan().getTripNumber().equals(trainInfo.getTripNumber())); .anyMatch(trainInfo -> r.getDepartRunPlan().getTripNumber()
.equals(trainInfo.getTripNumber()));
if (!valid) { // 如果列车已经上线则直接修改状态 if (!valid) { // 如果列车已经上线则直接修改状态
r.setLoad(true); r.setLoad(true);
} }
} }
return valid; return valid;
}) })
.sorted((r1, r2) -> r1.getDepartRunPlan().getPlanTime().isBefore(r2.getDepartRunPlan().getPlanTime()) ? -1 : 1) .sorted((r1, r2) ->
r1.getDepartRunPlan().getPlanTime().isBefore(r2.getDepartRunPlan().getPlanTime()) ? -1
: 1)
.forEach(r -> { .forEach(r -> {
Section section = r.getDepartRunPlan().getTrackSection(); Section section = r.getDepartRunPlan().getTrackSection();
if (section.isFree()) { if (section.isFree()) {
String tripNumber = r.getDepartRunPlan().getTripNumber(); String tripNumber = r.getDepartRunPlan().getTripNumber();
int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48; int lastNum = tripNumber.charAt(tripNumber.length() - 1) - 48;
atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, section.getCode(), lastNum % 2 == 0); atsTrainLoadService.loadTripNumberTrain(simulation, tripNumber, section.getCode(),
lastNum % 2 == 0);
r.setLoad(true); // 已上线 r.setLoad(true); // 已上线
} }
}); });

View File

@ -2,68 +2,44 @@ package club.joylink.rtss.simulation.cbtc.CTC.service;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum; import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.CI.CiApiService; import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
import club.joylink.rtss.simulation.cbtc.CTC.data.*; import club.joylink.rtss.simulation.cbtc.CTC.data.CascoControl;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.*; import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException; import club.joylink.rtss.simulation.cbtc.data.map.Section;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
import club.joylink.rtss.simulation.cbtc.data.map.SwitchElement;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Component @Component
public class CTCService { public class CTCService {
@Autowired @Autowired
private CiApiService ciApiService; private CiApiService ciApiService;
@Resource @Resource
private CascoControlService cascoControlService; private CascoControlService cascoControlService;
/**
* 创建了新的运行计划item
*/
public void runPlanItemCreate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) {
regenerateRouteSequenceAndTrackView(simulation, station);
// CtcRepository ctcRepository = simulation.getCtcRepository();
// //进路序列
// RouteSequence routeSequence = ctcRepository.getRouteSequence(station.getCode());
// AtomicInteger idGenerator = ctcRepository.getRouteSequenceIdGenerator();
// RouteSequence.Line line = RouteSequence.buildLine(item, departure, idGenerator);
// routeSequence.addLine(line);
// //股道视图
// TrackView trackView = ctcRepository.getTrackView(station.getCode());
// if (departure) {
// trackView.addDepartureLine(line);
// } else {
// trackView.addReceivingLine(line);
// }
}
/** /**
* 运行计划item更新了 * 重新生成进路序列和股道视图 该方法应该在车务终端发送阶段计划之后调用
*/
public void runPlanItemUpdate(Simulation simulation, Station station, CtcStationRunPlanLog.RunPlanItem item, boolean departure) {
regenerateRouteSequenceAndTrackView(simulation, station);
// CtcRepository ctcRepository = simulation.getCtcRepository();
// RouteSequence.Line routeSequenceLine = ctcRepository.getRouteSequenceLine(station.getCode(), item.getTripNumber(), departure);
//
// String oldTc = routeSequenceLine.getTrackCode();
// String oldTn = routeSequenceLine.getTripNumber();
//
// routeSequenceLine.update();
//
// ctcRepository.updateTrackView(station.getCode(), oldTc, oldTn, routeSequenceLine);
}
/**
* 重新生成进路序列和股道视图
* 该方法应该在车务终端发送阶段计划之后调用
*/ */
public void regenerateRouteSequenceAndTrackView(Simulation simulation, Station station) { public void regenerateRouteSequenceAndTrackView(Simulation simulation, Station station) {
if (simulation.getRepository().getConfig().isHasCTC()) { if (simulation.getRepository().getConfig().isHasCTC()) {
@ -79,7 +55,8 @@ public class CTCService {
public void finishReceivingNotice(Simulation simulation, String stationCode, String tripNumber) { public void finishReceivingNotice(Simulation simulation, String stationCode, String tripNumber) {
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
plan.finishReceivingNotice(); plan.finishReceivingNotice();
String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); String systemTime = simulation.getCorrectSystemTime()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
plan.getArriveRunPlan().setAdjacentMessageTime(systemTime); plan.getArriveRunPlan().setAdjacentMessageTime(systemTime);
} }
@ -96,7 +73,8 @@ public class CTCService {
public void finishDepartureNotice(Simulation simulation, String stationCode, String tripNumber) { public void finishDepartureNotice(Simulation simulation, String stationCode, String tripNumber) {
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
plan.finishDepartureNotice(); plan.finishDepartureNotice();
String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); String systemTime = simulation.getCorrectSystemTime()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
plan.getDepartRunPlan().setAdjacentMessageTime(systemTime); plan.getDepartRunPlan().setAdjacentMessageTime(systemTime);
} }
@ -104,10 +82,12 @@ public class CTCService {
} }
public void finishArrive(Simulation simulation, String stationCode, String tripNumber, LocalTime time) { public void finishArrive(Simulation simulation, String stationCode, String tripNumber,
LocalTime time) {
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
if (time == null) if (time == null) {
time = simulation.getCorrectSystemTime().toLocalTime(); time = simulation.getCorrectSystemTime().toLocalTime();
}
plan.finishArrive(time); plan.finishArrive(time);
} }
@ -116,10 +96,12 @@ public class CTCService {
plan.cancelArrive(); plan.cancelArrive();
} }
public void finishDeparture(Simulation simulation, String stationCode, String tripNumber, LocalTime time) { public void finishDeparture(Simulation simulation, String stationCode, String tripNumber,
LocalTime time) {
CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber); CtcStationRunPlanLog plan = getCtcStationRunPlan(simulation, stationCode, tripNumber);
if (time == null) if (time == null) {
time = simulation.getCorrectSystemTime().toLocalTime(); time = simulation.getCorrectSystemTime().toLocalTime();
}
plan.finishDeparture(time); plan.finishDeparture(time);
} }
@ -132,9 +114,11 @@ public class CTCService {
* 发送发车预告 * 发送发车预告
*/ */
public void sendDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) { public void sendDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, stationCode, runPlanCode); CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
stationCode, runPlanCode);
Station nextStation = currentStationPlan.getNextStation(); Station nextStation = currentStationPlan.getNextStation();
CtcStationRunPlanLog nextStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, nextStation.getCode(), runPlanCode); CtcStationRunPlanLog nextStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
nextStation.getCode(), runPlanCode);
currentStationPlan.sendDepartureNotice(); currentStationPlan.sendDepartureNotice();
nextStationPlan.receiveDepartureNotice(); nextStationPlan.receiveDepartureNotice();
} }
@ -143,12 +127,15 @@ public class CTCService {
* 同意发车预告 * 同意发车预告
*/ */
public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) { public void agreeDepartureNotice(Simulation simulation, String stationCode, String runPlanCode) {
CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, stationCode, runPlanCode); CtcStationRunPlanLog currentStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
stationCode, runPlanCode);
Station previousStation = currentStationPlan.getPreviousStation(); Station previousStation = currentStationPlan.getPreviousStation();
CtcStationRunPlanLog previousStationPlan = getCtcStationRunPlanByRunPlanCode(simulation, previousStation.getCode(), runPlanCode); CtcStationRunPlanLog previousStationPlan = getCtcStationRunPlanByRunPlanCode(simulation,
previousStation.getCode(), runPlanCode);
currentStationPlan.finishReceivingNotice(); currentStationPlan.finishReceivingNotice();
previousStationPlan.finishDepartureNotice(); previousStationPlan.finishDepartureNotice();
String systemTime = simulation.getCorrectSystemTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd")); String systemTime = simulation.getCorrectSystemTime()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd"));
currentStationPlan.getArriveRunPlan().setAdjacentMessageTime(systemTime); currentStationPlan.getArriveRunPlan().setAdjacentMessageTime(systemTime);
previousStationPlan.getDepartRunPlan().setAdjacentMessageTime(systemTime); previousStationPlan.getDepartRunPlan().setAdjacentMessageTime(systemTime);
} }
@ -156,20 +143,22 @@ public class CTCService {
/** /**
* 进路自触 * 进路自触
*/ */
public void routeAutoTrigger(Simulation simulation, String stationCode, String tripNumber, String routeCode, boolean trigger) { public void routeAutoTrigger(Simulation simulation, String stationCode, String tripNumber,
String routeCode, boolean trigger) {
CtcRepository ctcRepository = simulation.getCtcRepository(); CtcRepository ctcRepository = simulation.getCtcRepository();
RouteSequence.Line line = ctcRepository.getRouteSequenceLine(stationCode, tripNumber, routeCode); RouteSequence.Line line = ctcRepository.getRouteSequenceLine(stationCode, tripNumber,
routeCode);
line.setAutoTrigger(trigger); line.setAutoTrigger(trigger);
} }
private List<String> cascoControl(CascoControl cc,boolean force){ private List<String> cascoControl(CascoControl cc, boolean force) {
if(Objects.equals(true,force)){ if (Objects.equals(true, force)) {
return Collections.emptyList(); return Collections.emptyList();
} }
return this.cascoControlService.checkCascoControlRoute(cc); return this.cascoControlService.checkCascoControlRoute(cc);
} }
/** /**
*
* @param simulation * @param simulation
* @param routeCode * @param routeCode
* @param tripNumber * @param tripNumber
@ -177,7 +166,8 @@ public class CTCService {
* @param duration * @param duration
* @return * @return
*/ */
public List<String> setRoute(Simulation simulation, String routeCode, String tripNumber, Boolean force, Integer duration) { public List<String> setRoute(Simulation simulation, String routeCode, String tripNumber,
Boolean force, Integer duration) {
Route route = simulation.getRepository().getByCode(routeCode, Route.class); Route route = simulation.getRepository().getByCode(routeCode, Route.class);
if (force == null || !force) { // 非强制办理 if (force == null || !force) { // 非强制办理
// 存在分路不良的区段 // 存在分路不良的区段
@ -187,23 +177,29 @@ public class CTCService {
} }
} }
Station station = route.getStart().getStation(); Station station = route.getStart().getStation();
if (station == null) if (station == null) {
station = route.getStart().getDeviceStation(); station = route.getStart().getDeviceStation();
}
List<String> conflictInfo = new ArrayList<>(); List<String> conflictInfo = new ArrayList<>();
CtcRepository ctcRepository = simulation.getCtcRepository(); CtcRepository ctcRepository = simulation.getCtcRepository();
CascoControl cc = new CascoControl(simulation,station,route,tripNumber); CascoControl cc = new CascoControl(simulation, station, route, tripNumber);
List<String> errCCMsg = this.cascoControl(cc,Objects.isNull(force) ? false:force.booleanValue());//站细卡控 List<String> errCCMsg = this.cascoControl(cc,
if(Objects.equals(false,CollectionUtils.isEmpty(errCCMsg))){ Objects.isNull(force) ? false : force.booleanValue());//站细卡控
if (Objects.equals(false, CollectionUtils.isEmpty(errCCMsg))) {
//站细检测错误的信息 //站细检测错误的信息
return errCCMsg; return errCCMsg;
} }
if (StringUtils.hasText(tripNumber) && !Objects.equals(true, force)) { //列车进路防错办 if (StringUtils.hasText(tripNumber) && !Objects.equals(true, force)) { //列车进路防错办
List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLines(station.getCode(), tripNumber); List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLines(station.getCode(),
tripNumber);
if (!CollectionUtils.isEmpty(lines)) { if (!CollectionUtils.isEmpty(lines)) {
boolean b = lines.stream().noneMatch(line -> Objects.equals(line.getRouteCode(), routeCode)); boolean b = lines.stream()
if (b) .noneMatch(line -> Objects.equals(line.getRouteCode(), routeCode));
conflictInfo.add(String.format("车次[%s]的进路序列中不包含进路[name:%s]", tripNumber, route.getName())); if (b) {
conflictInfo.add(
String.format("车次[%s]的进路序列中不包含进路[name:%s]", tripNumber, route.getName()));
}
} }
} }
if (duration != null && !Objects.equals(true, force)) { //调车进路防错办 if (duration != null && !Objects.equals(true, force)) { //调车进路防错办
@ -211,15 +207,18 @@ public class CTCService {
Map<Switch, SwitchElement> switchMap = new HashMap<>(); Map<Switch, SwitchElement> switchMap = new HashMap<>();
List<SwitchElement> switchList = route.getSwitchList(); List<SwitchElement> switchList = route.getSwitchList();
if (!CollectionUtils.isEmpty(switchList)) { if (!CollectionUtils.isEmpty(switchList)) {
switchMap = switchList.stream().collect(Collectors.toMap(SwitchElement::getASwitch, Function.identity())); switchMap = switchList.stream()
.collect(Collectors.toMap(SwitchElement::getASwitch, Function.identity()));
} }
LocalTime endTime = simulation.getCorrectSystemTime().plusSeconds(duration).toLocalTime(); LocalTime endTime = simulation.getCorrectSystemTime().plusSeconds(duration).toLocalTime();
List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLineThatLessThan(station.getCode(), endTime); List<RouteSequence.Line> lines = ctcRepository.findRouteSequenceLineThatLessThan(
station.getCode(), endTime);
out: out:
for (RouteSequence.Line line : lines) { for (RouteSequence.Line line : lines) {
Route lineRoute = line.getRoute(); Route lineRoute = line.getRoute();
if (lineRoute == null) if (lineRoute == null) {
continue; continue;
}
for (Section section : lineRoute.getSectionList()) { for (Section section : lineRoute.getSectionList()) {
if (sections.contains(section)) { if (sections.contains(section)) {
conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突", conflictInfo.add(String.format("所选进路[name:%s]与车次[%s]的[name:%s]进路冲突",
@ -240,22 +239,26 @@ public class CTCService {
} }
} }
} }
if (!conflictInfo.isEmpty()) if (!conflictInfo.isEmpty()) {
return conflictInfo; return conflictInfo;
}
Route.CheckFailMessage checkFailMessage = ciApiService.settingRoute(simulation, routeCode); Route.CheckFailMessage checkFailMessage = ciApiService.settingRoute(simulation, routeCode);
if (checkFailMessage != null) if (checkFailMessage != null) {
throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception(checkFailMessage.debugStr()); throw BusinessExceptionAssertEnum.OPERATION_FAIL.exception(checkFailMessage.debugStr());
}
route.setTripNumber(tripNumber); route.setTripNumber(tripNumber);
return null; return null;
} }
private CtcStationRunPlanLog getCtcStationRunPlan(Simulation simulation, String stationCode, String tripNumber) { private CtcStationRunPlanLog getCtcStationRunPlan(Simulation simulation, String stationCode,
String tripNumber) {
CtcRepository ctcRepository = simulation.getCtcRepository(); CtcRepository ctcRepository = simulation.getCtcRepository();
return ctcRepository.getRunPlan(stationCode, tripNumber); return ctcRepository.getRunPlan(stationCode, tripNumber);
} }
private CtcStationRunPlanLog getCtcStationRunPlanByRunPlanCode(Simulation simulation, String stationCode, String runPlanCode) { private CtcStationRunPlanLog getCtcStationRunPlanByRunPlanCode(Simulation simulation,
String stationCode, String runPlanCode) {
CtcRepository ctcRepository = simulation.getCtcRepository(); CtcRepository ctcRepository = simulation.getCtcRepository();
return ctcRepository.getRunPlanByRunPlanCode(stationCode, runPlanCode); return ctcRepository.getRunPlanByRunPlanCode(stationCode, runPlanCode);
} }