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

This commit is contained in:
joylink_zhangsai 2023-01-09 15:03:54 +08:00
commit b1195c02ed
8 changed files with 258 additions and 56 deletions

View File

@ -1,6 +1,8 @@
package club.joylink.rtss.controller.training2;
import club.joylink.rtss.controller.advice.AuthenticateInterceptor;
import club.joylink.rtss.services.training2.Training2RuleService;
import club.joylink.rtss.vo.LoginUserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,7 +21,6 @@ public class TrainingRuleController {
@Autowired
private Training2RuleService training2RuleService;
/**
* 根据仿真生成
*/
@ -36,9 +37,30 @@ public class TrainingRuleController {
return training2RuleService.generateTrainingByMapIdAndFunId(mapId, functionId);
}
@PostMapping("{groupId}/test")
public void test(@PathVariable String groupId){
training2RuleService.test(groupId);
/**
* 生成所有地图实训
*/
@PostMapping("generate/all")
public List<String> generateAllTraining(@RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO){
return training2RuleService.generateAllTrainingByRule(loginUserInfoVO);
}
/**
* 根据地图ID生成实训
*/
@PostMapping("generate/mapId")
public List<String> generateTrainingByMapId(@RequestBody List<Long> mapIdList
, @RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO){
return training2RuleService.generateTrainingByMapId(mapIdList, loginUserInfoVO);
}
/**
* 根据线路编号生成实训
*/
@PostMapping("generate/lineCode")
public List<String> generateTrainingByLineCode(@RequestBody List<String> lineCodeList
, @RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO) {
return training2RuleService.generateTrainingByLineCode(lineCodeList, loginUserInfoVO);
}
}

View File

@ -1,7 +1,15 @@
package club.joylink.rtss.services.training2;
import club.joylink.rtss.constants.MapStatus;
import club.joylink.rtss.controller.advice.AuthenticateInterceptor;
import club.joylink.rtss.dao.MapInfoDAO;
import club.joylink.rtss.dao.PublishedTraining2DAO;
import club.joylink.rtss.dao.RtsMapFunctionDAO;
import club.joylink.rtss.dao.training.RtsTraining2RuleMapper;
import club.joylink.rtss.entity.MapInfo;
import club.joylink.rtss.entity.MapInfoExample;
import club.joylink.rtss.entity.RtsMapFunction;
import club.joylink.rtss.entity.RtsMapFunctionExample;
import club.joylink.rtss.entity.training2.*;
import club.joylink.rtss.services.mapFunction.RtsMapFunctionService;
import club.joylink.rtss.simulation.SimulationManager;
@ -11,6 +19,7 @@ import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
import club.joylink.rtss.vo.LoginUserInfoVO;
import club.joylink.rtss.vo.training2.rule.BgSceneStatusRule;
import club.joylink.rtss.vo.training2.rule.MapLocationRule;
import club.joylink.rtss.vo.training2.rule.Training2Rule;
@ -18,8 +27,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.*;
import java.util.stream.Collectors;
/**
* 实训规则Service
@ -41,6 +53,12 @@ public class Training2RuleService {
@Autowired
private PublishedTraining2DAO publishedTraining2DAO;
@Autowired
private MapInfoDAO mapInfoDAO;
@Autowired
private RtsMapFunctionDAO rtsMapFunctionDAO;
/**
* 正在生成的地图Id
*/
@ -109,9 +127,134 @@ public class Training2RuleService {
return generateTrainingByRule(groupId);
}
public void test(String groupId) {
Simulation simulation = simulationManager.getById(groupId , Simulation.class);
Switch aSwitch = simulation.getRepository().getByCode("W32728", Switch.class);
System.out.println(aSwitch.isSingleLock());
/**
* 根据地图ID生成实训
*/
public List<String> generateTrainingByMapId(List<Long> mapIdList, LoginUserInfoVO loginUserInfoVO){
// 地图列表
MapInfoExample example = new MapInfoExample();
MapInfoExample.Criteria criteria = example.createCriteria().andStatusEqualTo(MapStatus.Online.getCode());
criteria.andIdIn(mapIdList);
List<MapInfo> mapList = mapInfoDAO.selectByExample(example);
List<String> lineCodeList = mapList.stream().map(MapInfo::getLineCode).collect(Collectors.toList());
// 规则列表
RtsTraining2RuleExample rtsTraining2RuleExample = new RtsTraining2RuleExample();
rtsTraining2RuleExample.createCriteria().andLineCodeIn(lineCodeList);
List<RtsTraining2RuleWithBLOBs> ruleList = rtsTraining2RuleMapper.selectByExampleWithBLOBs(rtsTraining2RuleExample);
Map<String, List<RtsTraining2RuleWithBLOBs>> lineCodeRuleMap = ruleList.stream().collect(Collectors.groupingBy(RtsTraining2RuleWithBLOBs::getLineCode));
List<String> errorMsgList = new ArrayList<>();
loopMapListGenerateTraining(loginUserInfoVO, mapList, lineCodeRuleMap, errorMsgList);
return errorMsgList;
}
/**
* 生成所有地图实训
*/
public List<String> generateAllTrainingByRule(LoginUserInfoVO loginUserInfoVO) {
// 规则列表
List<RtsTraining2RuleWithBLOBs> ruleList = rtsTraining2RuleMapper.selectByExampleWithBLOBs(null);
Map<String, List<RtsTraining2RuleWithBLOBs>> lineCodeRuleMap = ruleList.stream().collect(Collectors.groupingBy(RtsTraining2RuleWithBLOBs::getLineCode));
// 地图列表
MapInfoExample example = new MapInfoExample();
MapInfoExample.Criteria criteria = example.createCriteria().andStatusEqualTo(MapStatus.Online.getCode());
criteria.andLineCodeIn(lineCodeRuleMap.keySet().stream().collect(Collectors.toList()));
List<MapInfo> mapList = mapInfoDAO.selectByExample(example);
List<String> errorMsgList = new ArrayList<>();
loopMapListGenerateTraining(loginUserInfoVO, mapList, lineCodeRuleMap, errorMsgList);
return errorMsgList;
}
/**
* 根据线路类型生成实训
*/
public List<String> generateTrainingByLineCode(List<String> lineCodeList, LoginUserInfoVO loginUserInfoVO) {
// 规则列表
RtsTraining2RuleExample rtsTraining2RuleExample = new RtsTraining2RuleExample();
rtsTraining2RuleExample.createCriteria().andLineCodeIn(lineCodeList);
List<RtsTraining2RuleWithBLOBs> ruleList = rtsTraining2RuleMapper.selectByExampleWithBLOBs(rtsTraining2RuleExample);
Map<String, List<RtsTraining2RuleWithBLOBs>> lineCodeRuleMap = ruleList.stream().collect(Collectors.groupingBy(RtsTraining2RuleWithBLOBs::getLineCode));
// 地图列表
MapInfoExample example = new MapInfoExample();
MapInfoExample.Criteria criteria = example.createCriteria().andStatusEqualTo(MapStatus.Online.getCode());
criteria.andLineCodeIn(lineCodeList);
List<MapInfo> mapList = mapInfoDAO.selectByExample(example);
List<String> errorMsgList = new ArrayList<>();
loopMapListGenerateTraining(loginUserInfoVO, mapList, lineCodeRuleMap, errorMsgList);
return errorMsgList;
}
/**
* 循环地图列表生成实训信息
*/
private void loopMapListGenerateTraining(LoginUserInfoVO loginUserInfoVO, List<MapInfo> mapList
, Map<String, List<RtsTraining2RuleWithBLOBs>> lineCodeRuleMap, List<String> errorMsgList) {
mapList.forEach(mapInfo -> {
RtsMapFunctionExample rtsExample = new RtsMapFunctionExample();
RtsMapFunctionExample.Criteria rtsCriteria = rtsExample.createCriteria();
rtsCriteria.andMapIdEqualTo(mapInfo.getId());
rtsCriteria.andNameEqualTo("单操实训");
List<RtsMapFunction> entities = rtsMapFunctionDAO.selectByExampleWithBLOBs(rtsExample);
if (!CollectionUtils.isEmpty(entities) && !CollectionUtils.isEmpty(lineCodeRuleMap.get(mapInfo.getLineCode()))) {
try {
Simulation simulation = simulationService.createSimulationPojo(entities.get(0).getId(), loginUserInfoVO);
errorMsgList.addAll(generateTraining(simulation, lineCodeRuleMap.get(mapInfo.getLineCode())));
} catch (Exception e) {
errorMsgList.add(String.format("地图%d创建仿真报错原因%s", mapInfo.getId(), e.getMessage(), Locale.ENGLISH));
}
}
});
}
private List<String> generateTraining(Simulation simulation, List<RtsTraining2RuleWithBLOBs> ruleList) {
List<String> errorMsgList = new ArrayList<>(ruleList.size());
Long mapId = simulation.getBuildParams().getMap().getId();
if (runningMapIdSet.contains(mapId)) {
errorMsgList.add(String.format("地图%d正在生成", mapId, Locale.ENGLISH));
return errorMsgList;
}
synchronized (Training2RuleService.class) {
try {
if (!runningMapIdSet.contains(mapId)) {
runningMapIdSet.add(mapId);
// 清除数据库原有数据
PublishedTraining2Example publishedTraining2Example = new PublishedTraining2Example();
publishedTraining2Example.createCriteria().andMapIdEqualTo(mapId).andCreatorIdEqualTo(0L);
publishedTraining2DAO.deleteByExample(publishedTraining2Example);
// 生成新数据
for (RtsTraining2RuleWithBLOBs rule : ruleList) {
if (StringUtils.isEmpty(rule.getSteps())) {
continue;
}
Training2Rule training2Rule = new Training2Rule(rule);
try {
List<MapNamedElement> deviceList = training2Rule.getDeviceRule().filterMapDeviceList(simulation);
if (CollectionUtils.isEmpty(deviceList)) {
continue;
}
List<PublishedTraining2WithBLOBs> training2WithBLOBs = new ArrayList<>(deviceList.size());
for (MapNamedElement device : deviceList) {
simulationService.reset(simulation.getId());
training2WithBLOBs.add(training2Rule.convert2BO(simulation, device));
}
// 新数据入库
publishedTraining2DAO.insertList(training2WithBLOBs);
} catch (Exception e) {
errorMsgList.add(String.format("地图%d实训[%s]生成失败,设备信息【%s】原因%s", mapId,
training2Rule.getName(), training2Rule.getDeviceRule(),e.getMessage(),Locale.ENGLISH));
}
}
}
} finally {
runningMapIdSet.remove(mapId);
}
}
return errorMsgList;
}
}

View File

@ -58,4 +58,8 @@ public interface SimulationService {
* 监控仿真
*/
void monitor(String simulationId, AccountVO user);
Simulation createSimulationPojo(long mapId, Long mapFunctionId, SimulationWorkParamVO workParamVO, @NonNull LoginUserInfoVO loginUserInfoVO);
Simulation createSimulationPojo(Long mapFunctionId, LoginUserInfoVO loginInfo);
}

View File

@ -56,35 +56,7 @@ public class SimulationServiceImpl implements SimulationService {
@Override
public String createSimulation(long mapId, Long mapFunctionId, SimulationWorkParamVO workParamVO, @NonNull LoginUserInfoVO loginUserInfoVO) {
//获取仿真工作服务
SimulationWorkService initService = simulationWorkServiceManager.getWorkService(workParamVO.getType());
//创建仿真
String simulationId = SimulationIdGenerator.generateGroup(loginUserInfoVO.getAccountVO().getId(), mapId);
Simulation simulation = initService.create(mapId, workParamVO, loginUserInfoVO, simulationId);
simulation.setMapFunctionId(mapFunctionId);
LoginUserInfoVO loginUserInfo = simulation.getBuildParams().getLoginUserInfo();
if (Objects.nonNull(loginUserInfo)) {
simulation.setCreatorId(loginUserInfo.getAccountVO().getIdStr());
simulation.setProject(loginUserInfo.getProject());
simulation.setProjectVO(loginUserInfo.getProjectInfo());
}
// 删除旧仿真保存新仿真
simulation.setMessageSender(this.defaultMessageSender); // 设置默认的消息发布器
simulation.loadModule(); // 加载通用模块
groupSimulationService.clearSimulation(simulation.getId());
simulationManager.saveNew(simulation);
initService.loadData(simulation);
initService.addJobs(simulation);
initService.addMessagePublisher(simulation);
initService.init(simulation);
if (!CollectionUtils.isEmpty(workParamVO.getItemMap())) {
initService.addItems(simulation, workParamVO.getItemMap());
}
applicationContext.publishEvent(new SimulationCreateSuccessEvent(this, simulation));
// 仿真开始运行
simulationManager.start(simulation.getId());
return simulation.getId();
return createSimulationPojo(mapId, mapFunctionId, workParamVO, loginUserInfoVO).getId();
}
//只获取所有与该功能相关的权限信息
@ -223,4 +195,55 @@ public class SimulationServiceImpl implements SimulationService {
SimulationUser simulationUser = new SimulationUser(simulation, user, club.joylink.rtss.simulation.SimulationUser.Type.TEACHER);
simulationWorkServiceManager.addSimulationUser(simulation, simulationUser);
}
@Override
public Simulation createSimulationPojo(long mapId, Long mapFunctionId, SimulationWorkParamVO workParamVO, @NonNull LoginUserInfoVO loginUserInfoVO) {
//获取仿真工作服务
SimulationWorkService initService = simulationWorkServiceManager.getWorkService(workParamVO.getType());
//创建仿真
String simulationId = SimulationIdGenerator.generateGroup(loginUserInfoVO.getAccountVO().getId(), mapId);
Simulation simulation = initService.create(mapId, workParamVO, loginUserInfoVO, simulationId);
simulation.setMapFunctionId(mapFunctionId);
LoginUserInfoVO loginUserInfo = simulation.getBuildParams().getLoginUserInfo();
if (Objects.nonNull(loginUserInfo)) {
simulation.setCreatorId(loginUserInfo.getAccountVO().getIdStr());
simulation.setProject(loginUserInfo.getProject());
simulation.setProjectVO(loginUserInfo.getProjectInfo());
}
// 删除旧仿真保存新仿真
simulation.setMessageSender(this.defaultMessageSender); // 设置默认的消息发布器
simulation.loadModule(); // 加载通用模块
groupSimulationService.clearSimulation(simulation.getId());
simulationManager.saveNew(simulation);
initService.loadData(simulation);
initService.addJobs(simulation);
initService.addMessagePublisher(simulation);
initService.init(simulation);
if (!CollectionUtils.isEmpty(workParamVO.getItemMap())) {
initService.addItems(simulation, workParamVO.getItemMap());
}
applicationContext.publishEvent(new SimulationCreateSuccessEvent(this, simulation));
// 仿真开始运行
simulationManager.start(simulation.getId());
return simulation;
}
@Override
public Simulation createSimulationPojo(Long mapFunctionId, LoginUserInfoVO loginInfo) {
RtsMapFunctionVO rtsMapFunctionVO = rtsMapFunctionService.get(mapFunctionId);
this.checkUserPermission(rtsMapFunctionVO,loginInfo);
Long mapId = rtsMapFunctionVO.getMapId();
SimulationWorkParamVO workParamVO = rtsMapFunctionVO.getParamVO();
if (workParamVO.containsRealDeviceItem()) {
//有实体设备加载项的地图功能实训室同时只能存在一个
Stream<Simulation> stream = simulationManager.getSimulationStream();
Optional<Simulation> oldSimulationOptional = stream
.filter(sim -> Objects.equals(sim.getMapFunctionId(), mapFunctionId))
.findFirst();
oldSimulationOptional.ifPresent(simulation -> simulationManager.destroy(simulation.getId()));
}
return createSimulationPojo(mapId, mapFunctionId, workParamVO, loginInfo);
}
}

View File

@ -170,6 +170,8 @@ public abstract class Operation2 {
private String subType;
private String val;
public ClientOperation2(Operation2VO.ClientOperation2VO vo, Simulation simulation) {
super(vo.getId());
this.deviceCode = vo.getDeviceCode();
@ -179,6 +181,7 @@ public abstract class Operation2 {
this.params = vo.getParams();
this.commandId = vo.getCommandId();
this.subType = vo.getSubType();
this.val = vo.getVal();
if (vo.getTriggerCondition() != null) {
this.setTriggerCondition(vo.getTriggerCondition().convert2BO(simulation.getRepository()));
}

View File

@ -79,6 +79,8 @@ public abstract class Operation2VO {
private String subType;
private String val;
@Override
public Operation2 convert2BO(Simulation simulation) {
return new Operation2.ClientOperation2(this, simulation);

View File

@ -349,10 +349,10 @@ public enum MapDeviceRule {
@Override
public List<Stand> filterMapDeviceList(Simulation simulation) {
Station station = simulation.getRepository().getStationList().stream()
.filter(s -> s.isCentralized() && s.isInterlock() && s.isHasControlMode() && !s.isDepot())
.filter(s -> s.isCentralized() && s.isInterlock() && !s.isDepot())
.min(Comparator.comparingInt(Station::getSn)).orElse(null);
if (station == null) {
throw new SimulationException(SimulationExceptionType.Data_Not_Exist);
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "没找到第一个站站台设备");
}
List<Stand> standList = simulation.getRepository().getStandList().stream()
.filter(stand -> Objects.equals(station, stand.getStation())).collect(Collectors.toList());
@ -454,10 +454,10 @@ public enum MapDeviceRule {
@Override
public List<Section> filterMapDeviceList(Simulation simulation) {
Station station = simulation.getRepository().getStationList().stream()
.filter(s -> s.isCentralized() && s.isInterlock() && s.isHasControlMode() && !s.isDepot())
.filter(s -> s.isCentralized() && s.isInterlock() && !s.isDepot())
.min(Comparator.comparingInt(Station::getSn)).orElse(null);
if (station == null) {
throw new SimulationException(SimulationExceptionType.Data_Not_Exist);
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "没有找到第一个站物理区段设备");
}
List<Section> sectionList = simulation.getRepository().getSectionList().stream()
.filter(s -> {
@ -517,14 +517,21 @@ public enum MapDeviceRule {
? signal.getStation().isCentralized() : signal.getDeviceStation().isCentralized()), NUMBER);
}
},
SIGNAL_CONTROL_LIST("控制模式车站信号机列表") {
@Override
public List<Signal> filterMapDeviceList(Simulation simulation) {
return generateRandomElement(queryNormalSignalList(simulation, signal -> signal.getStation() != null
? signal.getStation().isInterlock() : signal.getDeviceStation().isInterlock()), NUMBER);
}
},
SIGNAL_FIRST_STATION_LIST("获取第一个站信号机列表") {
@Override
public List<Signal> filterMapDeviceList(Simulation simulation) {
Station station = simulation.getRepository().getStationList().stream()
.filter(s -> s.isCentralized() && s.isInterlock() && s.isHasControlMode() && !s.isDepot())
.filter(s -> s.isCentralized() && s.isInterlock() && !s.isDepot())
.min(Comparator.comparingInt(Station::getSn)).orElse(null);
if (station == null) {
throw new SimulationException(SimulationExceptionType.Data_Not_Exist);
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "没找到第一个站信号机数据");
}
List<Signal> signalList = simulation.getRepository().getSignalList().stream()
.filter(signal -> Objects.equals(signal.getDeviceStation(), station) && !signal.getRouteList().isEmpty())
@ -555,10 +562,10 @@ public enum MapDeviceRule {
@Override
public List<Switch> filterMapDeviceList(Simulation simulation) {
Station station = simulation.getRepository().getStationList().stream()
.filter(s -> s.isCentralized() && s.isInterlock() && s.isHasControlMode() && !s.isDepot())
.filter(s -> s.isCentralized() && s.isInterlock() && !s.isDepot())
.min(Comparator.comparingInt(Station::getSn)).orElse(null);
if (station == null) {
throw new SimulationException(SimulationExceptionType.Data_Not_Exist);
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "没找到第一个站道岔数据");
}
List<Switch> switchList = simulation.getRepository().getSwitchList().stream()
.filter(aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station))
@ -587,9 +594,7 @@ public enum MapDeviceRule {
ROUTE_ATP_LIST("ATP进路列表") {
@Override
public List<Route> filterMapDeviceList(Simulation simulation) {
return generateRandomElement(queryNormalRouteList(simulation, route ->{
return route.getInterlockStation().isCentralized() && route.isAtp() && !route.isGuide();
}), NUMBER);
return generateRandomElement(queryNormalRouteList(simulation, r -> r.getInterlockStation().isCentralized() && r.isAtp() && !r.isGuide()), NUMBER);
}
},
ROUTE_CENTRALIZED_LIST("集中站本站进路列表"){
@ -606,17 +611,13 @@ public enum MapDeviceRule {
ROUTE_CONTROL_LIST("控制模式车站进路列表") {
@Override
public List<Route> filterMapDeviceList(Simulation simulation) {
return generateRandomElement(queryNormalRouteList(simulation, route ->{
return route.getInterlockStation().isHasControlMode() && !route.isGuide() && !route.isTurnBack();
}), NUMBER);
return generateRandomElement(queryNormalRouteList(simulation, r -> r.getInterlockStation().isHasControlMode() && !r.isGuide() && !r.isTurnBack()), NUMBER);
}
},
ROUTE_GUIDE_LIST("引导进路列表") {
@Override
public List<Route> filterMapDeviceList(Simulation simulation) {
return generateRandomElement(queryNormalRouteList(simulation, route -> {
return route.getStart().isCallOn() && route.isGuide();
}), NUMBER);
return generateRandomElement(queryNormalRouteList(simulation, r -> r.getStart().isCallOn() && r.isGuide()), NUMBER);
}
},
ROUTE_DEPARTURE_LIST("发车进路列表") {
@ -642,10 +643,10 @@ public enum MapDeviceRule {
@Override
public List<Route> filterMapDeviceList(Simulation simulation) {
Station station = simulation.getRepository().getStationList().stream()
.filter(s -> s.isCentralized() && s.isInterlock() && s.isHasControlMode() && !s.isDepot())
.filter(s -> s.isCentralized() && s.isInterlock() && !s.isDepot())
.min(Comparator.comparingInt(Station::getSn)).orElse(null);
if (station == null) {
throw new SimulationException(SimulationExceptionType.Data_Not_Exist);
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "没找到第一个站进路设备");
}
List<Route> routeList = simulation.getRepository().getRouteList().stream().filter(r -> {
if (!Objects.equals(station, r.getInterlockStation())) {

View File

@ -94,6 +94,8 @@ public abstract class OperationRule {
private String subType;
private String val;
@Override
public Operation2VO.ClientOperation2VO convert2BO(Simulation simulation, Object mapElement) {
Operation2VO.ClientOperation2VO operation2 = new Operation2VO.ClientOperation2VO();
@ -113,6 +115,8 @@ public abstract class OperationRule {
operation2.setParams(new HashMap<>());
// 二级定位
operation2.setSubType(subType);
// 参数校验
operation2.setVal(val);
if (!CollectionUtils.isEmpty(params)) {
params.forEach((k, v) -> {
String vStr = String.valueOf(v);