Merge remote-tracking branch 'origin/test-training2' into test-training2

This commit is contained in:
tiger_zhou 2022-09-07 17:19:13 +08:00
commit b42794e45b
18 changed files with 561 additions and 187 deletions

View File

@ -4,6 +4,8 @@ import club.joylink.rtss.dao.DraftTraining2DAO;
import club.joylink.rtss.dao.PublishedTraining2DAO;
import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs;
import club.joylink.rtss.entity.training2.PublishedTraining2WithBLOBs;
import club.joylink.rtss.services.training2.index.IndexAlgorithmService;
import club.joylink.rtss.simulation.cbtc.ATS.ATSMessageCollectAndDispatcher;
import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher;
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
@ -19,6 +21,7 @@ import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
import club.joylink.rtss.simulation.cbtc.training2.Operation2;
import club.joylink.rtss.simulation.cbtc.training2.Step2;
import club.joylink.rtss.simulation.cbtc.training2.Training2;
import club.joylink.rtss.simulation.cbtc.training2.index.Index;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.LoginUserInfoVO;
@ -46,7 +49,7 @@ import java.util.function.Consumer;
public class Training2Service {
public static final String EXECUTE_JOB_NAME = "Training2";
public static final String SCORING_JOB_NAME = "Training2Scoring";
public static final String INDEX_JOB_NAME = "Training2Index_%d";
public static final String INDEX_JOB_NAME = "Training2Index";
public static final int RATE = 1000;
@Autowired
@ -76,15 +79,18 @@ public class Training2Service {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private ATSMessageCollectAndDispatcher atsMessageCollectAndDispatcher;
/**
* 完成步骤接口信号量
*/
private Semaphore completeStepSemaphore = new Semaphore(1);
private final Semaphore completeStepSemaphore = new Semaphore(1);
/**
* 完成操作接口信号量
*/
private Semaphore completeOperationSemaphore = new Semaphore(1);
private final Semaphore completeOperationSemaphore = new Semaphore(1);
/**
* 实训运行
@ -92,6 +98,8 @@ public class Training2Service {
public void run(Simulation simulation) {
Training2 training2 = simulation.getTraining2();
if (training2 == null || !training2.isStarted() || training2.isFinish()) {
// 结束并移除运行任务
removeTrainingJob(simulation);
return;
}
// 获取运行步骤
@ -193,18 +201,16 @@ public class Training2Service {
if (training2 == null) {
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "实训数据不存在");
}
if (training2.isNeedReloadScenes()) {
simulationLifeCycleService.pause(simulation);
if (training2.isNeedReloadScenes() && !StringUtils.isEmpty(training2.getBgSceneJson())) {
groupSimulationService.loadScenes(simulation.getId(), training2.getBgSceneJson());
} else {
// 重置仿真状态
groupSimulationService.planOver(group);
if (!StringUtils.isEmpty(training2.getBgSceneJson())) {
groupSimulationService.loadScenes(simulation.getId(), training2.getBgSceneJson());
}
simulationLifeCycleService.reset(simulation);
atsMessageCollectAndDispatcher.collectAllAndSend(simulation);
}
// 增加实训任务
training2.start(mode);
addTrainingJob(simulation, training2);
simulationLifeCycleService.resume(simulation);
}
/**
@ -223,7 +229,7 @@ public class Training2Service {
// 创建者退出则清理实训
if (simulation.getCreator().getId().equals(user.getId())) {
training2.finish();
removeTrainingJob(simulation, training2);
removeTrainingJob(simulation);
}
scoreMap = training2.mark();
} else {
@ -250,7 +256,7 @@ public class Training2Service {
if (step == null) {
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "不存在步骤");
}
if (Objects.equals(user.getId(), step.getSimulationMember().getId())) {
if (!Objects.equals(String.valueOf(user.getId()), step.getSimulationMember().getUserId())) {
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "无权限操作");
}
try {
@ -300,7 +306,7 @@ public class Training2Service {
if (step == null) {
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "不存在步骤");
}
if (Objects.equals(user.getId(), step.getSimulationMember().getId())) {
if (!Objects.equals(String.valueOf(user.getId()), step.getSimulationMember().getUserId())) {
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "无权限操作");
}
Operation2 operation = step.getOperations().stream().filter(o -> Objects.equals(o.getId(), id))
@ -364,11 +370,15 @@ public class Training2Service {
}
// 操作完成后,如果是测验模式则仿真启动
pauseOrStartSimulation(simulation, false);
// 检查是否要计算指标
if (!CollectionUtils.isEmpty(training2.getIndexList())) {
training2.getIndexList().stream()
.filter(index -> !index.getType().isContinuity()
&& Objects.equals(simOperation2.getOperationType(), index.getType().getOperationType()))
.forEach(index -> training2.getIndexAlgorithmMap().get(index.getId()).calculation(simulation, null));
.filter(index -> !index.isContinuity() && !CollectionUtils.isEmpty(index.getOperationType())
&& index.getOperationType().contains(simOperation2.getOperationType())
&& training2.getIndexAlgorithmMap().containsKey(index.name())
)
.forEach(index -> training2.getIndexAlgorithmMap().get(index.name())
.calculation(simulation, simOperation2.getParams()));
}
}
}
@ -651,7 +661,7 @@ public class Training2Service {
/**
* 移除实训任务
*/
private void removeTrainingJob(Simulation simulation, Training2 training2) {
private void removeTrainingJob(Simulation simulation) {
if (simulation.getJobMap().containsKey(SCORING_JOB_NAME)) {
simulation.removeJob(SCORING_JOB_NAME); //移除打分监视任务
}
@ -659,14 +669,8 @@ public class Training2Service {
simulation.removeJob(EXECUTE_JOB_NAME); //移除实训执行任务
}
// 去除指标计算任务
if (training2 != null && !CollectionUtils.isEmpty(training2.getIndexList())) {
training2.getIndexList().stream().filter(index -> index.getType().isContinuity())
.forEach(index -> {
String jobName = String.format(INDEX_JOB_NAME, index.getId());
if (simulation.getJobMap().containsKey(jobName)) {
simulation.removeJob(jobName); //移除指标执行任务
}
});
if (simulation.getJobMap().containsKey(INDEX_JOB_NAME)) {
simulation.removeJob(INDEX_JOB_NAME);
}
}
@ -674,18 +678,19 @@ public class Training2Service {
* 增加实训任务
*/
private void addTrainingJob(Simulation simulation, Training2 training2) {
removeTrainingJob(simulation, training2);
// 移除后再添加
removeTrainingJob(simulation);
simulation.addJobIfAbsent(EXECUTE_JOB_NAME, () -> this.run(simulation), RATE);
// 增加指标计算任务
if (training2 != null && !CollectionUtils.isEmpty(training2.getIndexList())) {
training2.getIndexList().stream().filter(index -> index.getType().isContinuity())
.forEach(index -> {
String jobName = String.format(INDEX_JOB_NAME, index.getId());
if (!simulation.getJobMap().containsKey(jobName)) {
simulation.addJobIfAbsent(jobName,
() -> training2.getIndexAlgorithmMap().get(index.getId()).calculation(simulation, null), RATE); //移除指标执行任务
}
});
Map<String, IndexAlgorithmService> trainIndexServiceMap = training2.getIndexAlgorithmMap();
simulation.addJobIfAbsent(INDEX_JOB_NAME, () ->
training2.getIndexList().stream().filter(Index::isContinuity).forEach(index -> {
if (trainIndexServiceMap.containsKey(index.name())) {
trainIndexServiceMap.get(index.name()).calculation(simulation);
}
})
, RATE);
}
}

View File

@ -1,37 +1,30 @@
package club.joylink.rtss.services.training2.index;
import club.joylink.rtss.simulation.cbtc.Simulation;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 指标计算统计接口
*/
public abstract class IndexAlgorithmService<T> {
/**
* 统计的指标结果
*/
private List<T> indexValList = new ArrayList<>();
public interface IndexAlgorithmService<R> {
/**
* 运行时计算
* 没参数计算
*/
public abstract void calculation(Simulation simulation, Map<String, Object> params);
default void calculation(Simulation simulation) {
}
/**
* 操作触发时带有参数性
*/
default void calculation(Simulation simulation, Map<String, Object> params) {
}
/**
* 结束时统计
*/
public abstract T statistics();
/**
* 清理统计数据
*/
public void reset() {
if (!CollectionUtils.isEmpty(indexValList)) {
this.indexValList.clear();
}
}
R statistics();
}

View File

@ -3,22 +3,22 @@ package club.joylink.rtss.services.training2.index.impl;
import club.joylink.rtss.services.training2.index.IndexAlgorithmService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.training2.index.IndexTestValue;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
/**
* 持续性测试指标
* 指标计算统计实现
*/
public class IndexAlgorithmTestService extends IndexAlgorithmService<IndexTestValue> {
@Slf4j
public class IndexAlgorithmTestService implements IndexAlgorithmService<IndexTestValue> {
@Override
public void calculation(Simulation simulation, Map<String, Object> params) {
System.out.println(this.hashCode() + " 计算");
public void calculation(Simulation simulation) {
log.info(this.getClass().getSimpleName() + "[" + this.hashCode() + "]任务持续 计算");
}
@Override
public IndexTestValue statistics() {
System.out.println(this.hashCode() + "统计");
log.info(this.getClass().getSimpleName() + "[" + this.hashCode() + "] 统计");
return null;
}
}

View File

@ -0,0 +1,25 @@
package club.joylink.rtss.services.training2.index.impl;
import club.joylink.rtss.services.training2.index.IndexAlgorithmService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.training2.index.IndexTestValue;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* 指标计算统计实现
*/
@Slf4j
public class IndexTriggeredTestService implements IndexAlgorithmService<IndexTestValue> {
@Override
public void calculation(Simulation simulation, Map<String, Object> params) {
log.info(this.getClass().getSimpleName() + "[" + this.hashCode() + "]操作触发 计算");
}
@Override
public IndexTestValue statistics() {
log.info(this.getClass().getSimpleName() + "[" + this.hashCode() + "] 统计");
return null;
}
}

View File

@ -64,7 +64,7 @@ public class DisCmd {
/**
* 调度命令类型
*/
private Type type;
private Type type = Type.Undefined;
/**
* 调度命令正文
*/
@ -84,10 +84,11 @@ public class DisCmd {
* 调度命令类型
*/
public enum Type {
Undefined,
/**
* 正常调度命令
*/
NORMAL,
Normal,
;
}

View File

@ -62,7 +62,7 @@ public class DisCmdRcvCompany {
/**
* 最终受令端对于调度命令的状态
*/
private Status state;
private Status state = Status.Undefined;
/**
* 最终受令端对于调度命令的接收时间
*/
@ -73,12 +73,13 @@ public class DisCmdRcvCompany {
private LocalDateTime signTime;
/**
* 最终受令端对于调度命令的实际签收人
* @see SimulationMember#getUserId()
*/
private SimulationMember signByReal;
private String signByReal;
/**
* 无线调度命令的中转站对调度命令的状态
*/
private TransStatus transStatus;
private TransStatus transStatus = TransStatus.Undefined;
/**
* 无线调度命令的中转站对调度命令的接收时间
*/
@ -111,6 +112,7 @@ public class DisCmdRcvCompany {
* 发令单位类型
*/
public enum Type {
Undefined,
Dispatcher,//调度台
Station,//车站
Train,//无线
@ -122,6 +124,7 @@ public class DisCmdRcvCompany {
* 受令单位对于调度命令的状态
*/
public enum Status {
Undefined,
Received,//接收
Signed,//签收
;
@ -131,6 +134,7 @@ public class DisCmdRcvCompany {
* 无线调度命令时中转站对于调度命令的状态
*/
public enum TransStatus {
Undefined,
Received,//接收
Sent,//发送
;

View File

@ -12,7 +12,7 @@ public class DisCmdSendCompany {
/**
* 发令单位类型
*/
private Type type;
private Type type = Type.Undefined;
/**
* 发令单位名称
*/
@ -29,7 +29,7 @@ public class DisCmdSendCompany {
/**
* 调度命令对应发令单的状态
*/
private Status state;
private Status state = Status.Undefined;
/**
* 发令时间
*/
@ -48,6 +48,7 @@ public class DisCmdSendCompany {
* 发令单位类型
*/
public enum Type {
Undefined,
Dispatcher,//调度台
Station,//车站
;
@ -57,6 +58,7 @@ public class DisCmdSendCompany {
* 发令单位对调度命令的状态
*/
public enum Status {
Undefined,
Cache,//缓存
Send,//发送
Signed,//签收完成(所有受令者签收完成)

View File

@ -4,10 +4,12 @@ import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.convertor.DisCmdConvertor;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdHolderEnum;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdRspVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdSrcVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.FindAllDisCmdForHolderRspVo;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import club.joylink.rtss.vo.client.SocketMessageVO;
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
@ -37,9 +39,14 @@ public class DisCmdService {
/**
* 保存调度命令,保存到发送方缓存箱(保存到仓库)
*/
public void save(Simulation simulation,DisCmd disCmd){
//
public void save(Simulation simulation, DisCmdSrcVo disCmdVo){
DisCmd disCmd = DisCmdConvertor.convert(disCmdVo);
CtcRepository ctcRepository = simulation.getCtcRepository();
//为受令记录生成id
disCmd.getRcvCompanies().forEach(rc->{
rc.setId(String.valueOf(ctcRepository.getDisCmdRcvCompanyIdGenerator().getAndIncrement()));
});
//
ctcRepository.getDisCmdMap().put(disCmd.getCode(),disCmd);
//
disCmd.getSendCompany().setState(DisCmdSendCompany.Status.Cache);
@ -157,7 +164,7 @@ public class DisCmdService {
//
rc.setState(DisCmdRcvCompany.Status.Signed);
rc.setSignTime(this.getNow(simulation));
rc.setSignByReal(signer);
rc.setSignByReal(signer.getUserId());
}
/**
* 监控调度命令
@ -181,8 +188,6 @@ public class DisCmdService {
}
}
//todo: 根据监控向前端推送其他通知
});
}
@ -260,7 +265,7 @@ public class DisCmdService {
}
//
if(hasCmd){
DisCmdVo cmdVo = DisCmdConvertor.convert(cmd);
DisCmdRspVo cmdVo = DisCmdConvertor.convert(cmd);
rsp.getCmdMap().put(cmdVo.getCode(),cmdVo);
}
@ -274,11 +279,12 @@ public class DisCmdService {
* 注意如果向列控服务器推送通知则系统自动处理通知签收
*/
private void sendNotifyToRcvCompany(Simulation simulation,DisCmdRcvCompany rc){
DisCmdVo disCmdVo = DisCmdConvertor.convert(this.find(simulation,rc.getDisCmdCode()));
DisCmdRspVo disCmdVo = DisCmdConvertor.convert(this.find(simulation,rc.getDisCmdCode()));
disCmdVo.setRcId(rc.getId());
//
WebSocketMessage<DisCmdVo.WsMsgType, DisCmdVo> messageBody
= new WebSocketMessage<>(DisCmdVo.WsMsgType.ADD, disCmdVo);
SocketMessageVO<WebSocketMessage<DisCmdVo.WsMsgType, DisCmdVo>> message
WebSocketMessage<DisCmdRspVo.WsMsgType, DisCmdRspVo> messageBody
= new WebSocketMessage<>(DisCmdRspVo.WsMsgType.ADD, disCmdVo);
SocketMessageVO<WebSocketMessage<DisCmdRspVo.WsMsgType, DisCmdRspVo>> message
= SocketMessageFactory.buildDispatchCommandMessage2(simulation.getId(), messageBody);
//
if(DisCmdRcvCompany.Type.Station.equals(rc.getType())){//向车站的相关成员发送通知
@ -288,6 +294,25 @@ public class DisCmdService {
.collect(Collectors.toSet());
stompMessageService.sendToUser(receiverUserIds,message);
}
}else if(DisCmdRcvCompany.Type.Dispatcher.equals(rc.getType())){
//todo: 调度台暂时没有
log.warn("==>>调度台不存在,不能推送通知!");
}else if(DisCmdRcvCompany.Type.Tsr.equals(rc.getType())){
//todo: 列控服务器暂时没有
log.warn("==>>列控服务器不存在,不能推送通知!");
}else if(DisCmdRcvCompany.Type.Train.equals(rc.getType())){
//车次号
String trainNum = rc.getTrainNum();
//机车号
String trainCode = rc.getTrainCode();
List<VirtualRealityTrain> trains = simulation.getRepository().getOnlineTrainList().stream().filter(tr->{return tr.getTripNumber().equals(trainNum);}).collect(Collectors.toList());
if(null!=trains&&!trains.isEmpty()){
VirtualRealityTrain train = trains.get(0);
//查找该次列车的司机向司机推送通知
Set<String> receiverUserIds = simulation.getSimulationMembersByDevice(train).stream().map(club.joylink.rtss.simulation.SimulationMember::getUserId)
.collect(Collectors.toSet());
stompMessageService.sendToUser(receiverUserIds,message);
}
}
}
/**
@ -299,6 +324,7 @@ public class DisCmdService {
*/
private boolean checkTrainInStation(Simulation simulation,String trainNum,String trainCode,String stationCode){
//todo
return true;
}
/**

View File

@ -5,20 +5,115 @@ import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.DisCmdRcvCompany;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.DisCmdSendCompany;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdRcvCompanyVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdSendCompanyVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdRspVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdSrcVo;
import java.util.stream.Collectors;
public class DisCmdConvertor {
public static DisCmdVo convert(DisCmd from){
return null;
public static DisCmdRspVo convert(DisCmd from){
DisCmdRspVo to = new DisCmdRspVo();
to.setAuthState(from.getAuthState());
to.setCode(from.getCode());
to.setAuthTime(from.getAuthTime());
to.setContent(from.getContent());
to.setChiefOnDuty(from.getChiefOnDuty());
to.setChiefOnDutyAuth(from.getChiefOnDutyAuth());
to.setDesigner(from.getDesigner());
to.setSender(from.getSender());
to.setDailyPlanNum(from.getDailyPlanNum());
to.setFinishedTime(from.getFinishedTime());
to.setReviewer(from.getReviewer());
to.setSendTime(from.getSendTime());
to.setTitle(from.getTitle());
to.setTransitId(from.getTransitId());
to.setType(from.getType().name());
to.setSendCompany(DisCmdConvertor.convert(from.getSendCompany()));
return to;
}
public static DisCmdSendCompanyVo convert(DisCmdSendCompany from){
return null;
DisCmdSendCompanyVo to = new DisCmdSendCompanyVo();
to.setDisCmdCode(from.getDisCmdCode());
to.setCode(from.getCode());
to.setName(from.getName());
to.setSendTime(from.getSendTime());
to.setType(from.getType().name());
to.setState(from.getState().name());
to.setSignedTime(from.getSignedTime());
return to;
}
public static DisCmdSendCompany convert(DisCmdSendCompanyVo from){
DisCmdSendCompany to = new DisCmdSendCompany();
to.setDisCmdCode(from.getDisCmdCode());
to.setCode(from.getCode());
to.setName(from.getName());
to.setSendTime(from.getSendTime());
to.setType(DisCmdSendCompany.Type.valueOf(from.getType()));
to.setState(DisCmdSendCompany.Status.valueOf(from.getState()));
to.setSignedTime(from.getSignedTime());
return to;
}
public static DisCmdRcvCompanyVo convert(DisCmdRcvCompany from){
return null;
DisCmdRcvCompanyVo to = new DisCmdRcvCompanyVo();
to.setDisCmdCode(from.getDisCmdCode());
to.setDisCode(from.getDisCode());
to.setId(from.getId());
to.setName(from.getName());
to.setState(from.getState().name());
to.setSignByReal(from.getSignByReal());
to.setReceiveTime(from.getReceiveTime());
to.setSignTime(from.getSignTime());
to.setStationCode(from.getStationCode());
to.setTrainCode(from.getTrainCode());
to.setTrainViaGsmR(from.getTrainViaGsmR());
to.setTrainNum(from.getTrainNum());
to.setTransReceiveTime(from.getTransReceiveTime());
to.setTransStationCode(from.getTransStationCode());
to.setTsrCode(from.getTsrCode());
to.setTransSendTime(from.getTransSendTime());
to.setType(from.getType().name());
to.setTransStatus(from.getTransStatus().name());
return to;
}
public static DisCmdRcvCompany convert(DisCmdRcvCompanyVo from){
DisCmdRcvCompany to = new DisCmdRcvCompany();
to.setDisCmdCode(from.getDisCmdCode());
to.setDisCode(from.getDisCode());
to.setId(from.getId());
to.setName(from.getName());
to.setState(DisCmdRcvCompany.Status.valueOf(from.getState()));
to.setSignByReal(from.getSignByReal());
to.setReceiveTime(from.getReceiveTime());
to.setSignTime(from.getSignTime());
to.setStationCode(from.getStationCode());
to.setTrainCode(from.getTrainCode());
to.setTrainViaGsmR(from.getTrainViaGsmR());
to.setTrainNum(from.getTrainNum());
to.setTransReceiveTime(from.getTransReceiveTime());
to.setTransStationCode(from.getTransStationCode());
to.setTsrCode(from.getTsrCode());
to.setTransSendTime(from.getTransSendTime());
to.setType(DisCmdRcvCompany.Type.valueOf(from.getType()));
to.setTransStatus(DisCmdRcvCompany.TransStatus.valueOf(from.getTransStatus()));
return to;
}
public static DisCmd convert(DisCmdSrcVo from){
DisCmd to = new DisCmd();
to.setAuthState(from.getAuthState());
to.setCode(from.getCode());
to.setContent(from.getContent());
to.setChiefOnDuty(from.getChiefOnDuty());
to.setChiefOnDutyAuth(from.getChiefOnDutyAuth());
to.setDesigner(from.getDesigner());
to.setSender(from.getSender());
to.setDailyPlanNum(from.getDailyPlanNum());
to.setReviewer(from.getReviewer());
to.setTitle(from.getTitle());
to.setTransitId(from.getTransitId());
to.setType(DisCmd.Type.valueOf(from.getType()));
//
to.setSendCompany(DisCmdConvertor.convert(from.getSendCompany()));
to.setRcvCompanies(from.getRcvCompanies().stream().map(rcVo->{return DisCmdConvertor.convert(rcVo);}).collect(Collectors.toList()));
return to;
}
}

View File

@ -1,14 +1,95 @@
package club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.DisCmdRcvCompany;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 受令单位
*/
@Data
public class DisCmdRcvCompanyVo {
/**
* 调度命令号(唯一)
*/
private String disCmdCode;
private String disCmdCode;
/**
* 唯一id,受令单位记录id
*/
private String id;
/**
* 受令单位类型
* @see DisCmdRcvCompany.Type
*/
private String type = "Undefined";
/**
* 受令单位名称
*/
private String name;
//////////////////受令者/////////////////////
/**
* 车站受令者code
*/
private String stationCode;
/**
* 调度台受令者code
*/
private String disCode;
/**
* 列控服务器受令者code
*/
private String tsrCode;
//////////////////受令者train////////////////////////
/**
* 无线调度命令true-通过手机移动网络直接发送false-通过车站专有网络发送
*/
private Boolean trainViaGsmR = true;
/**
* 中转车站code
* <p>
* 当trainViaGsmR=false时不为空
*/
private String transStationCode;
/**
* 车次号
*/
private String trainNum;
/**
* 机车号(train code)
*/
private String trainCode;
/////////////////////运行时数据//////////////////
/**
* 最终受令端对于调度命令的状态
* @see DisCmdRcvCompany.Status
*/
private String state = "Undefined";
/**
* 最终受令端对于调度命令的接收时间
*/
private LocalDateTime receiveTime;
/**
* 最终受令端对于调度命令的签收时间
*/
private LocalDateTime signTime;
/**
* 最终受令端对于调度命令的实际签收人id
* @see SimulationMember#getUserId()
*/
private String signByReal;
/**
* 无线调度命令的中转站对调度命令的状态
* @see DisCmdRcvCompany.TransStatus
*/
private String transStatus = "Undefined";
/**
* 无线调度命令的中转站对调度命令的接收时间
*/
private LocalDateTime transReceiveTime;
/**
* 无线调度命令的中转站对调度命令的发送时间
*/
private LocalDateTime transSendTime;
}

View File

@ -0,0 +1,101 @@
package club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.DisCmd;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* 响应给客户端调度命令记录
*/
@Data
public class DisCmdRspVo {
/**
* 标题
*/
private String title;
/**
* 调度命令号(唯一)
*/
private String code;
/**
* 中转识别号
*/
private String transitId;
/**
* 发令时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime sendTime;
/**
* 发令人
*/
private String sender;
/**
* 授权时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime authTime;
/**
* 值班主任(仿真成员)
*/
private String chiefOnDuty;
/**
* 需值班主任授权
*/
private Boolean chiefOnDutyAuth = false;
/**
* 授权状态
*/
private String authState;
/**
* 定稿时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime finishedTime;
/**
* 审核人(仿真成员)
*/
private String reviewer;
/**
* 日计划号
*/
private String dailyPlanNum;
/**
* 拟令人(起草者设计者)
*/
private String designer;
/**
* 调度命令类型
* @see DisCmd.Type
*/
private String type = "Undefined";
/**
* 调度命令正文
*/
private String content;
///////////////////////////////////////
/**
* 发令单位
*/
private DisCmdSendCompanyVo sendCompany;
///////////////////////////////////////
/**
* 受令单位记录唯一id仅在向前端推送通知时有效
*/
private String rcId;
////////////////////////////////////////
/**
* webSocket消息类型
*/
public enum WsMsgType {
ALL,
ADD,
UPDATE,
DELETE,
}
}

View File

@ -1,14 +1,50 @@
package club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.DisCmdSendCompany;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
* 发令单位
*/
@Data
public class DisCmdSendCompanyVo {
/**
* 发令单位类型
* @see DisCmdSendCompany.Type
*/
private String type = "Undefined";
/**
* 发令单位名称
*/
private String name;
/**
* 发令单位code
*/
private String code;
/**
* 调度命令号(唯一)
*/
private String disCmdCode;
private String disCmdCode;
//////////////////运行时数据////////////////
/**
* 调度命令对应发令单的状态
* @see DisCmdSendCompany.Status
*/
private String state = "Undefined";
/**
* 发令时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime sendTime;
/**
* 签收完成时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime signedTime;
}

View File

@ -0,0 +1,70 @@
package club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.DisCmd;
import lombok.Data;
import java.util.List;
/**
* 创建调度命令的源客户端(调度台或车站)发送来的调度命令原始信息
*/
@Data
public class DisCmdSrcVo {
/**
* 标题
*/
private String title;
/**
* 调度命令号(唯一)
*/
private String code;
/**
* 中转识别号
*/
private String transitId;
/**
* 发令人
*/
private String sender;
/**
* 值班主任(仿真成员)
*/
private String chiefOnDuty;
/**
* 需值班主任授权
*/
private Boolean chiefOnDutyAuth = false;
/**
* 授权状态
*/
private String authState;
/**
* 审核人(仿真成员)
*/
private String reviewer;
/**
* 日计划号
*/
private String dailyPlanNum;
/**
* 拟令人(起草者设计者)
*/
private String designer;
/**
* 调度命令类型
* @see DisCmd.Type
*/
private String type = "Undefined";
/**
* 调度命令正文
*/
private String content;
///////////////////////////////////////
/**
* 发令单位
*/
private DisCmdSendCompanyVo sendCompany;
/**
* 受令单位列表
*/
private List<DisCmdRcvCompanyVo> rcvCompanies;
}

View File

@ -1,25 +0,0 @@
package club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo;
import lombok.Data;
@Data
public class DisCmdVo {
/**
* 标题
*/
private String title;
/**
* 调度命令号(唯一)
*/
private String code;
///////////////////////////////////////
/**
* webSocket消息类型
*/
public enum WsMsgType {
ALL,
ADD,
UPDATE,
DELETE,
}
}

View File

@ -28,7 +28,7 @@ public class FindAllDisCmdForHolderRspVo {
/**
* 调度命令列表
*/
private Map<String, DisCmdVo> cmdMap = new HashMap<>();
private Map<String, DisCmdRspVo> cmdMap = new HashMap<>();
/**
* 调度命令发令单位
*/

View File

@ -14,6 +14,7 @@ import club.joylink.rtss.vo.client.training2.ScoringRuleVO;
import club.joylink.rtss.vo.client.training2.Step2VO;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
@ -95,7 +96,7 @@ public class Training2 {
/**
* 指标处理逻辑
*/
private Map<Integer, IndexAlgorithmService> indexAlgorithmMap;
private Map<String, IndexAlgorithmService> indexAlgorithmMap;
public Training2(DraftTraining2WithBLOBs draftTraining2, Simulation simulation) {
this.id = draftTraining2.getId();
@ -126,29 +127,6 @@ public class Training2 {
ExpressionVO evo = JsonUtils.read(draftTraining2.getFailureConditionJson(), ExpressionVO.class);
this.failureCondition = evo.convert2BO(simulation.getRepository());
}
Index index1 = new Index();
index1.setId(1);
index1.setName("指标1");
index1.setType(Index.Type.TRIGGERED_TEST_INDEX);
Index index2 = new Index();
index2.setId(2);
index2.setName("指标2");
index2.setType(Index.Type.CONTINUITY_TEST_INDEX);
this.indexList = (Arrays.asList(index1, index2));
if (!CollectionUtils.isEmpty(this.indexList)) {
this.indexAlgorithmMap = new HashMap<>(this.indexList.size());
this.indexList.stream().forEach(index -> {
try {
IndexAlgorithmService service =
(IndexAlgorithmService) index.getType().getAlgorithmService().getDeclaredConstructor().newInstance();
this.indexAlgorithmMap.put(index.getId(), service);
} catch (Exception e) {
}
});
} else {
this.indexAlgorithmMap = new HashMap<>();
}
}
public void start(ScriptBO.Mode mode) {
@ -237,8 +215,12 @@ public class Training2 {
this.steps.forEach(Step2::reset);
}
// 重置时清空
if (!CollectionUtils.isEmpty(this.indexAlgorithmMap)) {
this.indexAlgorithmMap.forEach((k, v) -> v.reset());
if (!CollectionUtils.isEmpty(this.indexList)) {
this.indexAlgorithmMap = new HashMap<>(this.indexList.size());
this.indexList.forEach(index -> this.indexAlgorithmMap.put(index.name(),
BeanUtils.instantiateClass(index.getAlgorithmService(), IndexAlgorithmService.class)));
} else {
this.indexAlgorithmMap = new HashMap<>();
}
}

View File

@ -1,57 +1,35 @@
package club.joylink.rtss.simulation.cbtc.training2.index;
import club.joylink.rtss.services.training2.index.impl.IndexAlgorithmTestService;
import club.joylink.rtss.services.training2.index.impl.IndexTriggeredTestService;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import lombok.Getter;
import lombok.Setter;
import java.util.Arrays;
import java.util.List;
@Getter
@Setter
public class Index {
private int id;
public enum Index {
TRIGGERED_TEST_INDEX("触发式测试指标", "", false,
IndexTriggeredTestService.class, Arrays.asList(Operation.Type.Signal_Set_Route)),
/**
* 指标名称
*/
private String name;
CONTINUITY_TEST_INDEX("连续式测试指标", "", true,
IndexAlgorithmTestService.class, null),
;
/**
* 指标描述
*/
private String description;
private final String name; // 指标名称
private final String description; // 指标说明
private final boolean continuity; // 频率 ture:连续性计算false:触发性计算
/**
* 指标类型
*/
private Type type;
private final Class<?> algorithmService; // 指标计算统计service类名
@Getter
public enum Type {
/**
* 触发式测试指标
*/
TRIGGERED_TEST_INDEX(1, IndexAlgorithmTestService.class, Operation.Type.Signal_Set_Route),
private final List<Operation.Type> operationType; // 触发式指标事件类型
/**
* 连续式测试指标
*/
CONTINUITY_TEST_INDEX(0, IndexAlgorithmTestService.class, null),
;
private int rate; // 频率 0:连续性计算1:触发性计算
private Class algorithmService; // 指标计算统计service类名
private Operation.Type operationType; // 触发式指标事件类型
Type(int rate, Class algorithmService, Operation.Type operationType) {
this.rate = rate;
this.algorithmService = algorithmService;
this.operationType = operationType;
}
public boolean isContinuity() {
return this.rate == 0;
}
Index(String name, String description, boolean continuity, Class<?> algorithmService, List<Operation.Type> operationType) {
this.name = name;
this.description = description;
this.continuity = continuity;
this.algorithmService = algorithmService;
this.operationType = operationType;
}
}

View File

@ -6,7 +6,7 @@ import club.joylink.rtss.simulation.cbtc.CTC.data.Ticket;
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.rail.cmd.vo.DisCmdVo;
import club.joylink.rtss.simulation.cbtc.CTC.rail.cmd.vo.DisCmdRspVo;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.communication.vo.TrainPosition;
import club.joylink.rtss.simulation.cbtc.conversation.Conversation;
@ -440,8 +440,8 @@ public class SocketMessageFactory {
/**
* CTC调度命令消息2
*/
public static SocketMessageVO<WebSocketMessage<DisCmdVo.WsMsgType, DisCmdVo>> buildDispatchCommandMessage2
(String simulationId, WebSocketMessage<DisCmdVo.WsMsgType, DisCmdVo> message) {
public static SocketMessageVO<WebSocketMessage<DisCmdRspVo.WsMsgType, DisCmdRspVo>> buildDispatchCommandMessage2
(String simulationId, WebSocketMessage<DisCmdRspVo.WsMsgType, DisCmdRspVo> message) {
return build(WebSocketMessageType.SIMULATION_RAIL_CTC_DISPATCH_COMMAND, simulationId, message);
}