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