From 746cea77b49254395e04977f53193c57bd9ad61b Mon Sep 17 00:00:00 2001 From: weizhihong Date: Tue, 25 Oct 2022 15:17:52 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E7=94=9F=E6=88=90=E5=AE=9E=E8=AE=AD?= =?UTF-8?q?=E8=A7=84=E5=88=99=E5=AE=9E=E4=BD=93=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/training2/rule/BgSceneStatusRule.java | 149 ++++++++++++++++++ .../rtss/vo/training2/rule/ContentRule.java | 51 ++++++ .../rtss/vo/training2/rule/OperationRule.java | 112 +++++++++++++ .../vo/training2/rule/PropertyValueRule.java | 87 ++++++++++ .../rtss/vo/training2/rule/StepRule.java | 64 ++++++++ .../rtss/vo/training2/rule/Training2Rule.java | 128 +++++++++++++++ .../rtss/vo/training2/rule/ValuableRule.java | 75 +++++++++ .../services/training/Training2RuleTest.java | 59 +++++++ 8 files changed, 725 insertions(+) create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/BgSceneStatusRule.java create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/ContentRule.java create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/OperationRule.java create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/PropertyValueRule.java create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/StepRule.java create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/Training2Rule.java create mode 100644 src/main/java/club/joylink/rtss/vo/training2/rule/ValuableRule.java create mode 100644 src/test/java/club/joylink/rtss/services/training/Training2RuleTest.java diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/BgSceneStatusRule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/BgSceneStatusRule.java new file mode 100644 index 000000000..ceb59c9af --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/BgSceneStatusRule.java @@ -0,0 +1,149 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.constant.SignalAspect; +import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication; +import club.joylink.rtss.simulation.cbtc.data.map.*; +import club.joylink.rtss.simulation.cbtc.data.storage.StorageSimulation; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal; +import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch; +import club.joylink.rtss.util.JsonUtils; +import lombok.Getter; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Getter +public enum BgSceneStatusRule { + + /** + * 设置进路背景 + */ + ROUTE_BG_SCENE("进路背景") { + @Override + public String doHandle(Simulation simulation, MapElement mapElement) { + openRouteDirect(simulation, (Route) mapElement); + return getBgScene(simulation); + } + }; + + /** + * 背景说明 + */ + private final String description; + + BgSceneStatusRule(String description) { + this.description = description; + } + + /** + * 操作 + */ + public abstract String doHandle(Simulation simulation, MapElement mapElement); + + /** + * 直接开放进路 + */ + public void openRouteDirect(Simulation simulation, Route route) { + // 修改进路涉及的所有道岔元素到指定位置 + this.batchSetRouteSwitchPositionAndLock(route, route.getSwitchList(), true); + // 修改进路侧防到指定位置 + this.batchSetRouteFlsSwitchPositionAndLock(route.getFlsList()); + // 进路元素锁闭 + route.getSectionList().forEach(section -> section.routeLocking(route, route.getStart().isRight())); + if (route.isSettingOverlap()) { + SectionPath overlapPath = route.selectOverlapElement(); + if (Objects.nonNull(overlapPath)) { + this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList()); + this.batchSetRouteSwitchPositionAndLock(route, overlapPath.getSwitchList(), false); + overlapPath.getSectionList().forEach(section -> section.overlapLocking(route.getStart().isRight())); + this.batchSetRouteFlsSwitchPositionAndLock(overlapPath.getFlsList()); + route.getOverlap().setLock(true); + } + } + route.setNormalUnlock(false); + route.setLock(true); + route.setSettedAspect(route.getAspect()); + simulation.getRepository().addSettingRoute(route); + this.openSignalDirectly(route.getStart(), route.getSettedAspect()); + route.getStart().setLockedRoute(route); + } + + /** + * 直接把单个道岔转到指定位置 + */ + public void setSingleSwitchPositionDirectly(Switch aSwitch, boolean normal) { + VirtualRealitySwitch virtualSwitch = aSwitch.getVirtualSwitch(); + if (normal) { + virtualSwitch.control(VirtualRealitySwitch.Operation.NP); + virtualSwitch.finish(); + aSwitch.setPos(SwitchIndication.N); + } else { + virtualSwitch.control(VirtualRealitySwitch.Operation.RP); + virtualSwitch.finish(); + aSwitch.setPos(SwitchIndication.R); + } + } + + /** + * 获取仿真背景 + */ + public String getBgScene(Simulation simulation) { + return JsonUtils.writeValueAsString(new StorageSimulation(simulation, false)); + } + + /** + * 批量设置进路道岔位置并锁闭 + */ + private void batchSetRouteSwitchPositionAndLock(Route route, List switchList, boolean routeLock) { + if (!CollectionUtils.isEmpty(switchList)) { + for (SwitchElement switchElement : switchList) { + this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal()); + if (routeLock) { + switchElement.getASwitch().routeLock(route); + } else { // 延续保护锁闭 + switchElement.getASwitch().overlapLock(); + } + } + } + } + + private void batchSetRouteFlsSwitchPositionAndLock(List flsList) { + if (!CollectionUtils.isEmpty(flsList)) { + List switchElementList = new ArrayList<>(); + for (RouteFls routeFls : flsList) { + for (RouteFls.FlsElement flsElement : routeFls.getLevel1List()) { + SwitchElement pSwitch = flsElement.getPSwitch(); + if (pSwitch != null) { + switchElementList.add(pSwitch); + } else if (flsElement.getFpae() != null) { + switchElementList.add(flsElement.getFpae()); + } + } + } + for (SwitchElement switchElement : switchElementList) { + this.setSingleSwitchPositionDirectly(switchElement.getASwitch(), switchElement.isNormal()); + switchElement.getASwitch().fpLock(); + } + } + } + + /** + * 直接开灯(默认逻辑点灯) + */ + private void openSignalDirectly(Signal signal, SignalAspect aspect) { + VirtualRealitySignal virtualSignal = signal.getVirtualSignal(); + signal.changeLightType(true); + if (virtualSignal != null) { + if (signal.isLogicLight()) { + virtualSignal.control(SignalAspect.No); + } else { + virtualSignal.control(aspect); + } + virtualSignal.finish(); + } + signal.setAspect(aspect); + } +} diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/ContentRule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/ContentRule.java new file mode 100644 index 000000000..fe88df33e --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/ContentRule.java @@ -0,0 +1,51 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Locale; + +/** + * 内容规则 + */ +@Setter +@Getter +public class ContentRule { + /** + * 内容格式 + */ + private String contentFormat; + + /** + * 替换文本列表 + */ + private List ruleList; + + /** + * 生成文本内容 + */ + public String generateContent(Simulation simulation, MapNamedElement mapElement) { + String content = contentFormat; + if (!CollectionUtils.isEmpty(ruleList)) { + String[] params = ruleList.stream().map(rule -> rule.resolve(simulation, mapElement)).toArray(String[]::new); + content = String.format(Locale.ENGLISH, contentFormat, params); + } + return content; + } + + /** + * 生成标题内容 + */ + public String generateViewContent() { + String content = contentFormat; + if (!CollectionUtils.isEmpty(ruleList)) { + String[] params = ruleList.stream().map(PropertyValueRule::getName).toArray(String[]::new); + content = String.format(Locale.ENGLISH, contentFormat, params); + } + return content; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/OperationRule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/OperationRule.java new file mode 100644 index 000000000..12e4b93ba --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/OperationRule.java @@ -0,0 +1,112 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import club.joylink.rtss.vo.client.training2.ExpressionVO; +import club.joylink.rtss.vo.client.training2.Operation2VO; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.util.CollectionUtils; + +import java.util.Map; + +@Setter +@Getter +@NoArgsConstructor +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "t") +@JsonSubTypes({ + @JsonSubTypes.Type(value = OperationRule.SimOperationRule.class, name = "S"), + @JsonSubTypes.Type(value = OperationRule.ClientOperationRule.class, name = "C") +}) +public abstract class OperationRule { + private int id; + + private ValuableRule.ExpressionVORule triggerRule; + + private ValuableRule.ExpressionVORule completionRule; + + private ValuableRule.ExpressionVORule failureRule; + + public abstract Operation2VO convert2BO(Simulation simulation, MapNamedElement mapElement); + + protected void convertExpressionRule(Operation2VO operation2, Simulation simulation, MapNamedElement mapElement) { + if (triggerRule != null) { + operation2.setTriggerCondition((ExpressionVO) triggerRule.convert2BO(simulation, mapElement)); + } + if (completionRule != null) { + operation2.setCompletionCondition((ExpressionVO) completionRule.convert2BO(simulation, mapElement)); + } + if (failureRule != null) { + operation2.setFailureCondition((ExpressionVO) failureRule.convert2BO(simulation, mapElement)); + } + } + + @Setter + @Getter + @NoArgsConstructor + public static class SimOperationRule extends OperationRule { + private Operation.Type operationType; + + private Map paramsRule; + + @Override + public Operation2VO convert2BO(Simulation simulation, MapNamedElement mapElement) { + Operation2VO.SimOperation2VO operation2 = new Operation2VO.SimOperation2VO(); + // 操作类型 + operation2.setOperationType(operationType); + // 参数规则 + if (!CollectionUtils.isEmpty(paramsRule)) { + paramsRule.forEach((k, v) -> { + if (v instanceof PropertyValueRule) { + operation2.getParams().put(k, ((PropertyValueRule) v).resolve(simulation, mapElement)); + } + }); + } + // 校验规则 + convertExpressionRule(operation2, simulation, mapElement); + return operation2; + } + } + + @Setter + @Getter + @NoArgsConstructor + public static class ClientOperationRule extends OperationRule { + private PropertyValueRule deviceCode; + + private String userOperationType; + + private String domId; + + private String operationType; + + private Map paramsRule; + + @Override + public Operation2VO convert2BO(Simulation simulation, MapNamedElement mapElement) { + Operation2VO.ClientOperation2VO operation2 = new Operation2VO.ClientOperation2VO(); + if (deviceCode != null) { // 设备规则 + operation2.setDeviceCode(deviceCode.resolve(simulation, mapElement)); + } + // 用户操作 + operation2.setUserOperationType(userOperationType); + // 界面操作 + operation2.setDomId(domId); + // 操作类型 + operation2.setOperationType(operationType); + // 参数规则 + if (!CollectionUtils.isEmpty(paramsRule)) { + paramsRule.forEach((k, v) -> { + if (v instanceof PropertyValueRule) { + operation2.getParams().put(k, ((PropertyValueRule) v).resolve(simulation, mapElement)); + } + }); + } + return operation2; + } + } +} diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/PropertyValueRule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/PropertyValueRule.java new file mode 100644 index 000000000..56a03f0af --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/PropertyValueRule.java @@ -0,0 +1,87 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import club.joylink.rtss.simulation.cbtc.data.map.Route; +import club.joylink.rtss.simulation.cbtc.exception.SimulationException; +import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; +import club.joylink.rtss.vo.map.graph.MapSignalButtonVO; +import lombok.Getter; + +import java.util.List; +import java.util.Objects; + +@Getter +public enum PropertyValueRule { + NAME("地图设备名称") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + return mapElement.getName(); + } + }, + CODE("地图设备编码") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + return mapElement.getCode(); + } + }, + STATION_NAME("地图设备所属车站名称") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + return null; + } + }, + STATION_CODE("地图设备所属车站编码") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + return null; + } + }, + ROUTE_START_NAME("进路起始名称") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + return ((Route) mapElement).getStart().getShowName(); + } + }, + BUTTON_START_CODE("进路起始按钮编码") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + Route route = (Route) mapElement; + List signalButtonList = simulation.getBuildParams().getMap().getGraphDataNew().getSignalButtonList(); + MapSignalButtonVO buttonVO = signalButtonList.stream().filter(button -> MapSignalButtonVO.Type.PICK.equals(button.getType()) + && Objects.equals(button.getSignalCode(), route.getStart().getCode())).findFirst().orElse(null); + if (buttonVO == null) { + throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "错误数据"); + } + return buttonVO.getCode(); + } + }, + ROUTE_END_NAME("进路终端名称") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + return ((Route) mapElement).getDestination().getShowName(); + } + }, + BUTTON_END_CODE("进路终端按钮编码") { + @Override + public String resolve(Simulation simulation, MapNamedElement mapElement) { + Route route = (Route) mapElement; + List signalButtonList = simulation.getBuildParams().getMap().getGraphDataNew().getSignalButtonList(); + MapSignalButtonVO buttonVO = signalButtonList.stream().filter(button -> MapSignalButtonVO.Type.PICK.equals(button.getType()) + && Objects.equals(button.getSignalCode(), route.getDestination().getCode())).findFirst().orElse(null); + if (buttonVO == null) { + throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "错误数据"); + } + return buttonVO.getCode(); + } + }; + + private String name; + + PropertyValueRule(String name) { + this.name = name; + } + + public abstract String resolve(Simulation simulation, MapNamedElement mapElement); + +} diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/StepRule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/StepRule.java new file mode 100644 index 000000000..04b56fd8f --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/StepRule.java @@ -0,0 +1,64 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import club.joylink.rtss.vo.client.training2.ExpressionVO; +import club.joylink.rtss.vo.client.training2.Operation2VO; +import club.joylink.rtss.vo.client.training2.Step2VO; +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Setter +@Getter +public class StepRule { + + private Integer id; + + private String memberId; + + private ContentRule description; + + private List operationRules; + + private ValuableRule.ExpressionVORule triggerRule; + + private ValuableRule.ExpressionVORule completionRule; + + private ValuableRule.ExpressionVORule failureRule; + + private Map tipPositionRule; + + public Step2VO convert2BO(Simulation simulation, MapNamedElement mapElement) { + Step2VO copyStep2 = new Step2VO(); + copyStep2.setMemberId(memberId); + if (description != null) { // 描述 + copyStep2.setDescription(description.generateContent(simulation, mapElement)); + } + if (!CollectionUtils.isEmpty(operationRules)) { // 操作规则 + List operationList = operationRules.stream().map(o -> o.convert2BO(simulation, mapElement)).collect(Collectors.toList()); + copyStep2.setOperations(operationList); + } + if (triggerRule != null) { // 触发规则 + copyStep2.setTriggerCondition((ExpressionVO) triggerRule.convert2BO(simulation, mapElement)); + } + if (completionRule != null) { // 完成规则 + copyStep2.setCompletionCondition((ExpressionVO) completionRule.convert2BO(simulation, mapElement)); + } + if (failureRule != null) { // 失败规则 + copyStep2.setFailureCondition((ExpressionVO) failureRule.convert2BO(simulation, mapElement)); + } + if (!CollectionUtils.isEmpty(tipPositionRule)) { // 定位信息 + tipPositionRule.forEach((k, v) -> { + if (v instanceof PropertyValueRule) { + copyStep2.getTipPosition().put(k, ((PropertyValueRule) v).resolve(simulation, mapElement)); + } + }); + } + return copyStep2; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/Training2Rule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/Training2Rule.java new file mode 100644 index 000000000..a782bf3b6 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/Training2Rule.java @@ -0,0 +1,128 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.MapElement; +import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import club.joylink.rtss.simulation.cbtc.exception.SimulationException; +import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; +import club.joylink.rtss.simulation.cbtc.member.SimulationMemberPO; +import club.joylink.rtss.simulation.cbtc.training2.Training2; +import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.client.training2.Step2VO; +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +@Getter +@Setter +public class Training2Rule { + private Long id; + + private Long mapId; + + /** + * 操作对象类型 + */ + private MapElement.DeviceType deviceType; + + /** + * 名称格式 + */ + private ContentRule name; + + /** + * 描述 + */ + private ContentRule description; + + /** + * 实训类型 + */ + private Training2.Type type; + + /** + * 实训标签 + */ + private List labels; + + /** + * 设置状态处理方法 + */ + private BgSceneStatusRule sceneRule; + + /** + * 步骤列表 + */ + private List steps; + + /** + * 失败规则 + */ + private ValuableRule.ExpressionVORule failureRule; + + /** + * 创建者ID + */ + private Long creatorId; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; + + public DraftTraining2WithBLOBs convert2BO(Simulation simulation, MapNamedElement mapElement) { + DraftTraining2WithBLOBs copyTraining2 = new DraftTraining2WithBLOBs(); + // 地图ID + copyTraining2.setMapId(mapId); + // 名称 + if (name != null) { + copyTraining2.setName(name.generateContent(simulation, mapElement)); + } + // 描述 + if (description != null) { + copyTraining2.setDescription(description.generateContent(simulation, mapElement)); + } + // 实训类型 + copyTraining2.setType(type.name()); + // 实训标签 + copyTraining2.setLabelJson(JsonUtils.writeValueAsString(labels)); + // 背景设置 + if (sceneRule != null) { + copyTraining2.setMapLocationJson(sceneRule.doHandle(simulation, mapElement)); + } + // 步骤 + if (!CollectionUtils.isEmpty(steps)) { + List step2VOList = steps.stream().map(s -> s.convert2BO(simulation, mapElement)).collect(Collectors.toList()); + copyTraining2.setStepJson(JsonUtils.writeValueAsString(step2VOList)); + // 扮演者集合 + List playerList = step2VOList.stream().filter(s -> !StringUtils.isEmpty(s.getMemberId())).map(s -> s.getMemberId()) + .distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(playerList)) { + throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "错误数据:无扮演者"); + } + copyTraining2.setPlayerIdJson(JsonUtils.writeValueAsString(playerList)); + } + // 失败规则 + if (failureRule != null) { + copyTraining2.setFailureConditionJson(JsonUtils.writeValueAsString(failureRule.convert2BO(simulation, mapElement))); + } + // 成员ID + List simulationMemberPOList = SimulationMemberPO.convertFromBOList(simulation.getSimulationMembers()); + copyTraining2.setMemberJson(JsonUtils.writeValueAsString(simulationMemberPOList)); + copyTraining2.setCreatorId(creatorId); + copyTraining2.setCreateTime(createTime); + copyTraining2.setUpdateTime(updateTime); + return copyTraining2; + } +} diff --git a/src/main/java/club/joylink/rtss/vo/training2/rule/ValuableRule.java b/src/main/java/club/joylink/rtss/vo/training2/rule/ValuableRule.java new file mode 100644 index 000000000..d8d324745 --- /dev/null +++ b/src/main/java/club/joylink/rtss/vo/training2/rule/ValuableRule.java @@ -0,0 +1,75 @@ +package club.joylink.rtss.vo.training2.rule; + +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.data.map.MapNamedElement; +import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.client.training2.ExpressionVO; +import club.joylink.rtss.vo.client.training2.StatusValueVO; +import club.joylink.rtss.vo.client.training2.ValuableVO; +import club.joylink.rtss.vo.client.training2.ValueVO; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@Getter +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "t") +@JsonSubTypes({ + @JsonSubTypes.Type(value = ValuableRule.ExpressionVORule.class, name = "E"), + @JsonSubTypes.Type(value = ValuableRule.StatusValueVORule.class, name = "S"), + @JsonSubTypes.Type(value = ValuableRule.ValueVORule.class, name = "V"), +}) +public abstract class ValuableRule { + private ValuableVO valuableVO; + + public abstract ValuableVO convert2BO(Simulation simulation, MapNamedElement mapElement); + + @Setter + @Getter + @NoArgsConstructor + public static class StatusValueVORule extends ValuableRule { + private PropertyValueRule elementCodeRule; + + @Override + public ValuableVO convert2BO(Simulation simulation, MapNamedElement mapElement) { + StatusValueVO valuable = JsonUtils.read(JsonUtils.writeValueAsString(this.getValuableVO()), StatusValueVO.class); + if (elementCodeRule != null) { + valuable.setElementCode(elementCodeRule.resolve(simulation, mapElement)); + } + return valuable; + } + } + + @Setter + @Getter + @NoArgsConstructor + public static class ExpressionVORule extends ValuableRule { + private ValuableRule[] valueRules; + + @Override + public ValuableVO convert2BO(Simulation simulation, MapNamedElement mapElement) { + ExpressionVO valuable = JsonUtils.read(JsonUtils.writeValueAsString(this.getValuableVO()), ExpressionVO.class); + if (valueRules != null) { + ValuableVO[] valuables = valuable.getValuables(); + for (int index = 0, len = valueRules.length; index < len; index++) { + if (valueRules[index] != null) { + valuables[index] = valueRules[index].convert2BO(simulation, mapElement); + } + } + } + return valuable; + } + } + + @Setter + @Getter + @NoArgsConstructor + public static class ValueVORule extends ValuableRule { + @Override + public ValuableVO convert2BO(Simulation simulation, MapNamedElement mapElement) { + return JsonUtils.read(JsonUtils.writeValueAsString(this.getValuableVO()), ValueVO.class); + } + } +} diff --git a/src/test/java/club/joylink/rtss/services/training/Training2RuleTest.java b/src/test/java/club/joylink/rtss/services/training/Training2RuleTest.java new file mode 100644 index 000000000..53d1588f8 --- /dev/null +++ b/src/test/java/club/joylink/rtss/services/training/Training2RuleTest.java @@ -0,0 +1,59 @@ +package club.joylink.rtss.services.training; + +import club.joylink.rtss.constants.MapPrdTypeEnum; +import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs; +import club.joylink.rtss.services.IMapService; +import club.joylink.rtss.services.IRunPlanTemplateService; +import club.joylink.rtss.services.training.data.GenerateConfig; +import club.joylink.rtss.simulation.cbtc.Simulation; +import club.joylink.rtss.simulation.cbtc.build.SimulationBuildParams; +import club.joylink.rtss.simulation.cbtc.build.SimulationBuilder; +import club.joylink.rtss.simulation.cbtc.data.map.Route; +import club.joylink.rtss.util.JsonUtils; +import club.joylink.rtss.vo.client.runplan.RunPlanVO; +import club.joylink.rtss.vo.map.MapVO; +import club.joylink.rtss.vo.training2.rule.Training2Rule; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; + +@SpringBootTest +public class Training2RuleTest { + + @Autowired + private IMapService iMapService; + + @Autowired + private IRunPlanTemplateService iRunPlanTemplateService; + + @Transactional + @Test + public void entityTest() { + String trainingRuleStr = "{\"id\":1,\"mapId\":154,\"deviceType\":\"ROUTE\",\"name\":{\"contentFormat\":\"【%s】办理\",\"ruleList\":[\"NAME\"]},\"description\":{\"contentFormat\":\"【%s】办理\",\"ruleList\":[\"NAME\"]},\"type\":\"SINGLE\",\"labels\":[],\"sceneRule\":null,\"steps\":[{\"id\":1,\"memberId\":\"3\",\"description\":{\"contentFormat\":\"点击信号机【%s】按钮\",\"ruleList\":[\"ROUTE_START_NAME\"]},\"operationRules\":[{\"t\":\"C\",\"id\":0,\"deviceCode\":\"BUTTON_START_CODE\",\"userOperationType\":\"leftClick\",\"domId\":\"3010\",\"operationType\":\"\",\"params\":{}}],\"triggerRule\":null,\"completionRule\":null,\"failureRule\":null,\"tipPosition\":{\"domId\":\"3010\",\"deviceCode\":\"BUTTON_START_CODE\",\"operateIndex\":0}},{\"id\":2,\"memberId\":\"3\",\"description\":{\"contentFormat\":\"点击信号机【%s】按钮\",\"ruleList\":[\"ROUTE_END_NAME\"]},\"operationRules\":[{\"t\":\"C\",\"id\":0,\"deviceCode\":\"BUTTON_END_CODE\",\"userOperationType\":\"leftClick\",\"domId\":\"3010\",\"operationType\":\"Signal_Set_Route\",\"params\":{}}],\"tipPosition\":{\"domId\":\"3010\",\"deviceCode\":\"BUTTON_END_CODE\",\"operateIndex\":0}}],\"failureRule\":null,\"creatorId\":5710}"; + String trainingRuleStr2 = "{\"id\":1,\"mapId\":154,\"deviceType\":\"ROUTE\",\"name\":{\"contentFormat\":\"取消【%s】进路\",\"ruleList\":[\"NAME\"]},\"description\":{\"contentFormat\":\"取消【%s】进路\",\"ruleList\":[\"NAME\"]},\"type\":\"SINGLE\",\"labels\":null,\"sceneRule\": \"ROUTE_BG_SCENE\",\"steps\":[{\"id\":1,\"memberId\":\"3\",\"description\":{\"contentFormat\":\"点击总取消\",\"ruleList\":[]},\"operationRules\":[{\"t\":\"C\",\"id\":0,\"userOperationType\":\"leftClick\",\"domId\":\"2994\",\"operationType\":\"\",\"params\":{}}],\"triggerRule\":null,\"completionRule\":null,\"failureRule\":null,\"tipPosition\":{\"domId\":\"2994\",\"operateIndex\":0}},{\"id\":2,\"memberId\":\"3\",\"description\":{\"contentFormat\":\"点击信号机【%s】\",\"ruleList\":[\"ROUTE_START_NAME\"]},\"operationRules\":[{\"t\":\"C\",\"id\":0,\"deviceCode\":\"BUTTON_START_CODE\",\"userOperationType\":\"leftClick\",\"domId\":\"2994\",\"operationType\":\"Signal_Cancel_Route\",\"params\":{}}],\"tipPosition\":{\"domId\":\"2994\",\"deviceCode\":\"BUTTON_START_CODE\",\"operateIndex\":0}}],\"failureRule\":null,\"creatorId\":5710}"; + Training2Rule training2Rule = JsonUtils.read(trainingRuleStr, Training2Rule.class); + Training2Rule training2Rule2 = JsonUtils.read(trainingRuleStr2, Training2Rule.class); + // 生成实训 + MapVO mapVO = iMapService.getMapDetail(training2Rule.getMapId()); + // 仿真配置 + GenerateConfig config = new GenerateConfig(); + config.setMapId(training2Rule.getMapId()); + // 查询通用运行图 + RunPlanVO planVO = this.iRunPlanTemplateService.getFirstRunPlanByMapId(mapVO.getId()); + SimulationBuildParams params = SimulationBuildParams.builder() + .createTime(LocalDateTime.now()) + .map(mapVO) + .prodType(MapPrdTypeEnum.getMapPrdTypeEnumByCode(config.getPrdType())) + .runPlan(planVO) + .build(); + Simulation simulation = SimulationBuilder.build("", params); + Route route = simulation.getRepository().getByCode("Route94", Route.class); + DraftTraining2WithBLOBs draftTraining2WithBLOBs = training2Rule.convert2BO(simulation, route); + System.out.println(JsonUtils.writeValueAsString(draftTraining2WithBLOBs)); + DraftTraining2WithBLOBs draftTraining2WithBLOBs2 = training2Rule2.convert2BO(simulation, route); + System.out.println(JsonUtils.writeValueAsString(draftTraining2WithBLOBs2)); + } +}