Merge branch 'test' into test-training2-zhouyin

# Conflicts:
#	pom.xml
#	src/main/java/club/joylink/rtss/services/iscs/interactive/IscsInteractiveService.java
#	src/main/java/club/joylink/rtss/services/voice/huawei/HuaweiVoiceServiceImpl.java
#	src/main/java/club/joylink/rtss/simulation/cbtc/ATS/operation/Operation.java
#	src/main/java/club/joylink/rtss/simulation/cbtc/data/vo/TrainInfo.java
#	src/main/java/club/joylink/rtss/simulation/cbtc/message/SimulationSubscribeTopic.java
#	src/main/java/club/joylink/rtss/vo/client/factory/SocketMessageFactory.java
#	src/main/resources/application.yml
This commit is contained in:
tiger_zhou 2022-11-10 11:27:44 +08:00
commit 894ce10b40
57 changed files with 1256 additions and 566 deletions

282
pom.xml
View File

@ -1,106 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>club.joylink</groupId>
<artifactId>rtss</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rtss</name>
<description>Rail transit simulation system</description>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>club.joylink</groupId>
<artifactId>rtss</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rtss</name>
<description> Rail transit simulation system</description>
<properties>
<java.version>11</java.version>
<pagehelper.version>4.1.1</pagehelper.version>
</properties>
<properties>
<java.version>11</java.version>
<pagehelper.version>4.1.1</pagehelper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- javax.validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!-- javax.validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!--spring切面aop依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--spring切面aop依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>com.digitalpetri.modbus</groupId>
<artifactId>modbus-codec</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>com.digitalpetri.modbus</groupId>
<artifactId>modbus-codec</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 硬件检测依赖 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core-java11</artifactId>
<version>5.7.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.1</version>
</dependency>
<!-- 硬件检测依赖 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core-java11</artifactId>
<version>5.7.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.1</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.huawei.sis</groupId>-->
@ -130,49 +130,59 @@
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>com.github.shalousun</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>2.1.9</version>
<configuration>
<!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
<configFile>./src/main/resources/smart-doc.json</configFile>
<!--smart-doc实现自动分析依赖树加载第三方依赖的源码如果一些框架依赖库加载不到导致报错这时请使用excludes排除掉-->
<!-- <excludes>-->
<!-- &lt;!&ndash;格式为groupId:artifactId;参考如下&ndash;&gt;-->
<!-- <exclude>com.alibaba:fastjson</exclude>-->
<!-- </excludes>-->
<!-- &lt;!&ndash;自1.0.8版本开始插件提供includes支持,配置了includes后插件会按照用户配置加载而不是自动加载因此使用时需要注意&ndash;&gt;-->
<!-- &lt;!&ndash;smart-doc能自动分析依赖树加载所有依赖源码原则上会影响文档构建效率因此你可以使用includes来让插件加载你配置的组件&ndash;&gt;-->
<!-- <includes>-->
<!-- &lt;!&ndash;格式为groupId:artifactId;参考如下&ndash;&gt;-->
<!-- <include>com.alibaba:fastjson</include>-->
<!-- </includes>-->
</configuration>
<executions>
<execution>
<!--如果不需要在执行编译时启动smart-doc则将phase注释掉-->
<!-- <phase>compile</phase>-->
<goals>
<!--smart-doc提供了html、openapi、markdown等goal可按需配置-->
<goal>html</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<plugin>
<groupId>com.github.shalousun</groupId>
<artifactId>smart-doc-maven-plugin</artifactId>
<version>2.1.9</version>
<configuration>
<!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
<configFile>./src/main/resources/smart-doc.json</configFile>
<!--smart-doc实现自动分析依赖树加载第三方依赖的源码如果一些框架依赖库加载不到导致报错这时请使用excludes排除掉-->
<!-- <excludes>-->
<!-- &lt;!&ndash;格式为groupId:artifactId;参考如下&ndash;&gt;-->
<!-- <exclude>com.alibaba:fastjson</exclude>-->
<!-- </excludes>-->
<!-- &lt;!&ndash;自1.0.8版本开始插件提供includes支持,配置了includes后插件会按照用户配置加载而不是自动加载因此使用时需要注意&ndash;&gt;-->
<!-- &lt;!&ndash;smart-doc能自动分析依赖树加载所有依赖源码原则上会影响文档构建效率因此你可以使用includes来让插件加载你配置的组件&ndash;&gt;-->
<!-- <includes>-->
<!-- &lt;!&ndash;格式为groupId:artifactId;参考如下&ndash;&gt;-->
<!-- <include>com.alibaba:fastjson</include>-->
<!-- </includes>-->
</configuration>
<executions>
<execution>
<!--如果不需要在执行编译时启动smart-doc则将phase注释掉-->
<!-- <phase>compile</phase>-->
<goals>
<!--smart-doc提供了html、openapi、markdown等goal可按需配置-->
<goal>html</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -63,7 +63,9 @@ public enum Project {
/** 武汉8号线 */
// WH,
/** 武汉8号线 应急调度指挥系统*/
YJDDZH
YJDDZH,
/** 京津冀职业技能发展联盟 */
JJJLM,
;
public static boolean isDefault(Project project) {

View File

@ -58,7 +58,7 @@ public enum BusinessExceptionAssertEnum implements BusinessExceptionAssert {
INVALID_CLIENT(40031, "invalid client"),
INCORRECT_VERIFICATION_CODE(40051, "incorrect verification code"),
THIRD_SERVICE_CALL_EXCEPTION(40071, "the third service call exception"),
VOICE_COMMAND_PARSE_ERROR(40061,"voice command parse error"),
//支付异常
PAY_ERROR(50000, "pay error"),
WECHAT_NOTIFY_ERROR(401, "wechat notify error")

View File

@ -600,6 +600,13 @@ public class LessonService implements ILessonService {
private void generateLessonBy(AccountVO accountVO, MapVO mapVO, BusinessConsts.Lesson.PrdInfo prdLessonInfo, String prdType) {
Long mapId = mapVO.getId();
//生成课程的章节
Map<String, Map<String, List<Training>>> trainings = iTrainingV1Service.findEntities(mapId, prdType)
.stream().collect(Collectors.groupingBy(Training::getType, Collectors.groupingBy(Training::getOperateType)));
if (CollectionUtils.isEmpty(trainings)) {
log.warn(String.format("[id:%s]的地图无[%s]类型的实训,不生成课程", mapId, prdType));
return;
}
//课程
LsLesson lesson = new LsLesson();
lesson.setUpdateTime(LocalDateTime.now());
@ -626,18 +633,6 @@ public class LessonService implements ILessonService {
LsLessonChapterExample chapterExample = new LsLessonChapterExample();
chapterExample.createCriteria().andLessonIdEqualTo(lesson.getId());
lessonChapterDAO.deleteByExample(chapterExample);
// ExamDefinitionExample examDefinitionExample = new ExamDefinitionExample();
// examDefinitionExample.createCriteria().andLessonIdEqualTo(existedDefaultLesson.getId());
// List<ExamDefinition> examDefinitions = examDefinitionDAO.selectByExample(examDefinitionExample);
// if (!CollectionUtils.isEmpty(examDefinitions)) {
// List<Long> list = examDefinitions.stream().map(ExamDefinition::getId).collect(Collectors.toList());
// ExamDefinitionRulesExample rulesExample = new ExamDefinitionRulesExample();
// rulesExample.createCriteria().andExamIdIn(list);
// definitionRulesDAO.deleteByExample(rulesExample);
// examDefinitionDAO.deleteByExample(examDefinitionExample);
// }
} else {
lessonDAO.insert(lesson);
}
@ -649,12 +644,8 @@ public class LessonService implements ILessonService {
lessonVersion.setVersion(BusinessConsts.Lesson.Version.originalVersion);
lessonVersionDAO.insert(lessonVersion);
//生成课程的章节
List<Training> examTrainings = new ArrayList<>(20);
int orderNum = 1;
Random random = new Random();
Map<String, Map<String, List<Training>>> trainings = iTrainingV1Service.findEntities(mapId, prdType)
.stream().collect(Collectors.groupingBy(Training::getType, Collectors.groupingBy(Training::getOperateType)));
int orderNum = 1;
for (BusinessConsts.Training.Type type : BusinessConsts.Training.Type.values()) {
Map<String, List<Training>> collect = trainings.get(type.name());
if (CollectionUtils.isEmpty(collect)) continue;
@ -668,7 +659,6 @@ public class LessonService implements ILessonService {
lessonChapterDAO.insert(chapter);
collect.forEach((s, ts) -> {
if (ts.size() == 0) return;
examTrainings.add(ts.get(random.nextInt(ts.size())));
int i = 1;
while (i < 3) {
if (ts.size() == 0) return;
@ -687,54 +677,6 @@ public class LessonService implements ILessonService {
List<ExamDefinition> exams = iExamService.findEntities(lesson.getId());
if (CollectionUtils.isEmpty(exams)) {
iExamService.generateExam(mapId, lesson.getId(), lesson.getPrdType(), lesson.getName(), lesson.getCreatorId());
// //试卷定义
// if (CollectionUtils.isEmpty(examTrainings)) {
// return;
// }
// ExamDefinition examDefinition = new ExamDefinition();
// examDefinition.setMapId(mapId);
// examDefinition.setLessonId(lesson.getId());
// examDefinition.setType(prdType);
// examDefinition.setName(lesson.getName() + "试卷");
// examDefinition.setDuration(1800);
// examDefinition.setCreatorId(accountVO.getId());
// examDefinition.setCreateTime(LocalDateTime.now());
// examDefinition.setRemarks(examDefinition.getName() + "-默认试卷");
// examDefinition.setStatus("1");
// examDefinition.setTrial(true);
// examDefinition.setFullPoint(100);
// examDefinition.setPassingPoint(60);
// examDefinition.setAbnormal(false);
// examDefinition.setSystem(true);
// examDefinitionDAO.insert(examDefinition);
// //试卷规则 取20道题每中实训类型取一道
// if (examTrainings.size() < 20) {
// int m = examTrainings.size();
// int n = (int) Math.ceil(20f / m); //尽量平均地分配题型数量
// int num = 20 + m - m * n; //题数较多的题型的数量
// for (int i = 0; i < m; i++) {
// Training training = examTrainings.get(0);
// ExamDefinitionRules examRules = new ExamDefinitionRules();
// examRules.setExamId(examDefinition.getId());
// examRules.setNum(i < num ? n : n - 1);
// examRules.setPoint(5);
// examRules.setTrainingType(training.getType());
// examRules.setOperateType(training.getOperateType());
// definitionRulesDAO.insert(examRules);
// }
// } else {
// int i = 1;
// do {
// ExamDefinitionRules examRules = new ExamDefinitionRules();
// examRules.setExamId(examDefinition.getId());
// examRules.setNum(1);
// examRules.setPoint(5);
// Training training = examTrainings.remove(random.nextInt(examTrainings.size()));
// examRules.setTrainingType(training.getType());
// examRules.setOperateType(training.getOperateType());
// definitionRulesDAO.insert(examRules);
// } while (i++ < 20);
// }
}
}

View File

@ -9,7 +9,6 @@ import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import club.joylink.rtss.simulation.cbtc.data.info.StandPis;
import club.joylink.rtss.simulation.cbtc.data.iscs.Audio;
import club.joylink.rtss.simulation.cbtc.data.iscs.LCD;
import club.joylink.rtss.simulation.cbtc.data.iscs.LED;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityAudio;
@ -131,22 +130,15 @@ public class IscsInteractiveService {
}
SimulationDataRepository repository = simulation.getRepository();
SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository();
boolean play = false;
for (String code : param.getIscsDeviceCodes()) {
MapElement element = repository.getByCode(code);
if (element instanceof Audio) {
Audio audio = (Audio) element;
audio.updateResource(resourceVO);
VirtualRealityAudio vrAudio = audio.getVrAudio();
vrAudio.updateUrl(resourceVO.getUrl());
vrAudio.control(VirtualRealityAudio.Command.PLAY);
play = true;
} else if (element instanceof LED) {
// LED led = (LED) element;
// Station station = led.getStation();
// Stream<StandPis> standPisStream = iscsRepository.getStandPisStream(station);
// standPisStream.forEach(sp -> sp.setText(resourceVO.getDesc()));
} else if (element instanceof LCD) {
if (element instanceof LCD) {
String content;
if (!IscsSystemResourcesVO.Type.REAL_TIME.equals(param.getType())) {
content = simulation.getIscsRepository().getAudioResource(param.getResourceId()).getDesc();
} else {
content = param.getContent();
}
LCD lcd = (LCD) element;
IscsDeviceVO.Position position = lcd.getPosition();
Boolean up = null;
@ -160,14 +152,11 @@ public class IscsInteractiveService {
List<Stand> stands = lcd.getStation().getNormalStand(right);
for (Stand stand : stands) {
Optional<StandPis> standPisOptional = iscsRepository.findStandPisOptional(stand.getCode());
standPisOptional.ifPresent(sp -> sp.setText(resourceVO.getDesc()));
standPisOptional.ifPresent(sp -> sp.setText(content));
}
}
}
}
if (play) {
return resourceVO.getUrl();
}
return null;
}

View File

@ -216,12 +216,15 @@ public class PublishMapDataHandler {
// 修改地图数据
MapDataWithBLOBs mapData = getMapDataEntity(mapId);
String graphData = mapData.getGraphData();
String logicData = mapData.getLogicData();
for (Map.Entry<String, String> entry : nameMap.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
graphData = graphData.replace(k, v);
logicData = logicData.replace(k, v);
}
mapData.setGraphData(graphData);
mapData.setLogicData(logicData);
mapDataDAO.updateByPrimaryKeyWithBLOBs(mapData);
// 修改ISCS数据
IscsExample iscsExample = new IscsExample();

View File

@ -19,10 +19,10 @@ import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import club.joylink.rtss.util.JsonUtils;
import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.client.PageVO;
import club.joylink.rtss.vo.client.training.*;
import club.joylink.rtss.vo.client.trainingUsage.UserTrainingListVO;
import club.joylink.rtss.vo.client.trainingUsage.UserTrainingQueryVO;
import club.joylink.rtss.vo.client.trainingUsage.UserTrainingVO;
import club.joylink.rtss.vo.client.training.*;
import club.joylink.rtss.vo.map.MapGraphDataNewVO;
import club.joylink.rtss.vo.map.graph.MapAutomaticRouteButtonVO;
import club.joylink.rtss.vo.map.graph.MapCycleButtonVO;
@ -764,7 +764,7 @@ public class TrainingV1Service implements ITrainingV1Service {
}
}
if (deviceCode != null) {
SimulationMember member = simulation.findMemberByDeviceCode(deviceCode);
SimulationMember member = simulation.findMemberByRoleAndDeviceCode(SimulationMember.Type.STATION_SUPERVISOR, deviceCode);
if (member != null) {
memberManager.playRole(simulation, accountVO.getId(), member.getId());
}

View File

@ -42,11 +42,12 @@ public interface GeneratorNew {
* @param config
* @param mapDevice
* @param operateDefinitionVO
* @param setDeviceCode
* @return
*/
default TrainingNewVO build(GenerateConfig config, Simulation simulation, MapElement mapDevice, Object mapButton,
OperateDefinitionVO operateDefinitionVO) {
OperateDefinitionVO operateDefinitionVO, boolean setDeviceCode) {
boolean railway = simulation.getRepository().getConfig().isRailway();
// 现地设置站控
if (BusinessConsts.MapPrd.PrdType.Type01.equals(config.getPrdType())) {
switch (mapDevice.getDeviceType()) {
@ -74,73 +75,75 @@ public interface GeneratorNew {
TrainingNewVO trainingVO = new TrainingNewVO(config, operateDefinitionVO);
// 设置每一步操作的设备
List<OperateStepVO> stepList = operateDefinitionVO.getStepVOList();
if (stepList.stream().anyMatch(s -> StringUtils.hasText(s.getCodeType()))) {
stepList.forEach(s -> {
if (StringUtils.hasText(s.getCodeType())) {
//根据codeType对应类型 取当前设备相关的设备code进行设置,目前仅信号机进路操作支持
switch (TrainingConsts.CodeType.valueOf(s.getCodeType())) {
case SIGNAL:
if (MapElement.DeviceType.ROUTE.equals(mapDevice.getDeviceType())) {
s.setDeviceCode(((Route) mapDevice).getStart().getCode());
} else {
s.setDeviceCode(mapDevice.getCode());
}
break;
case START_SIGNAL:
s.setDeviceCode(((Route) mapDevice).getStart().getCode());
break;
case END_SIGNAL:
s.setDeviceCode(((Route) mapDevice).getDestination().getCode());
break;
case END_REPLACE_SIGNAL:
Route route = (Route) mapDevice;
List<Signal> replaceSignals = route.getDestination().getReplaceSignals();
if (replaceSignals != null) {
Signal signal;
if (MapPrdTypeEnum.LOCAL.equals(MapPrdTypeEnum.getMapPrdTypeEnumByCode(config.getPrdType()))) {
signal = replaceSignals.stream().filter(ss -> ss.getShowName().startsWith("F")).findFirst().orElse(null);
if (setDeviceCode) {
if (stepList.stream().anyMatch(s -> StringUtils.hasText(s.getCodeType()))) {
stepList.forEach(s -> {
if (StringUtils.hasText(s.getCodeType())) {
//根据codeType对应类型 取当前设备相关的设备code进行设置,目前仅信号机进路操作支持
switch (TrainingConsts.CodeType.valueOf(s.getCodeType())) {
case SIGNAL:
if (MapElement.DeviceType.ROUTE.equals(mapDevice.getDeviceType())) {
s.setDeviceCode(((Route) mapDevice).getStart().getCode());
} else {
signal = replaceSignals.stream().filter(ss -> ss.getShowName().startsWith("T")).findFirst().orElse(null);
s.setDeviceCode(mapDevice.getCode());
}
if (signal != null) {
s.setDeviceCode(signal.getCode());
break;
break;
case START_SIGNAL:
s.setDeviceCode(((Route) mapDevice).getStart().getCode());
break;
case END_SIGNAL:
s.setDeviceCode(((Route) mapDevice).getDestination().getCode());
break;
case END_REPLACE_SIGNAL:
Route route = (Route) mapDevice;
List<Signal> replaceSignals = route.getDestination().getReplaceSignals();
if (replaceSignals != null) {
Signal signal;
if (MapPrdTypeEnum.LOCAL.equals(MapPrdTypeEnum.getMapPrdTypeEnumByCode(config.getPrdType()))) {
signal = replaceSignals.stream().filter(ss -> ss.getShowName().startsWith("F")).findFirst().orElse(null);
} else {
signal = replaceSignals.stream().filter(ss -> ss.getShowName().startsWith("T")).findFirst().orElse(null);
}
if (signal != null) {
s.setDeviceCode(signal.getCode());
break;
}
}
}
s.setDeviceCode(route.getDestination().getCode());
break;
case END_BUTTON_SIGNAL:
s.setDeviceCode(((Route) mapDevice).getDestinationButtonSignal().getCode());
break;
case BUTTON:
if (Objects.nonNull(mapButton)) {
if (mapButton instanceof MapCycleButtonVO) {
s.setDeviceCode(((MapCycleButtonVO) mapButton).getCode());
break;
} else if (mapButton instanceof MapAutomaticRouteButtonVO) {
s.setDeviceCode(((MapAutomaticRouteButtonVO) mapButton).getCode());
break;
} else if (mapButton instanceof MapTurnBackStrategyVO) {
s.setDeviceCode(((MapTurnBackStrategyVO) mapButton).getCode());
break;
} else if (mapButton instanceof MapTotalGuideLockButtonVO) {
s.setDeviceCode(((MapTotalGuideLockButtonVO) mapButton).getCode());
break;
s.setDeviceCode(route.getDestination().getCode());
break;
case END_BUTTON_SIGNAL:
s.setDeviceCode(((Route) mapDevice).getDestinationButtonSignal().getCode());
break;
case BUTTON:
if (Objects.nonNull(mapButton)) {
if (mapButton instanceof MapCycleButtonVO) {
s.setDeviceCode(((MapCycleButtonVO) mapButton).getCode());
break;
} else if (mapButton instanceof MapAutomaticRouteButtonVO) {
s.setDeviceCode(((MapAutomaticRouteButtonVO) mapButton).getCode());
break;
} else if (mapButton instanceof MapTurnBackStrategyVO) {
s.setDeviceCode(((MapTurnBackStrategyVO) mapButton).getCode());
break;
} else if (mapButton instanceof MapTotalGuideLockButtonVO) {
s.setDeviceCode(((MapTotalGuideLockButtonVO) mapButton).getCode());
break;
}
}
}
case NULL:
break;
default:
s.setDeviceCode(mapDevice.getCode());
case NULL:
break;
default:
s.setDeviceCode(mapDevice.getCode());
}
}
}
});
} else {
if (MapElement.DeviceType.ROUTE.equals(mapDevice.getDeviceType())) {
stepList.get(0).setDeviceCode(((Route) mapDevice).getStart().getCode());
});
} else {
if (!"bar".equals(stepList.get(0).getDeviceType())) { //为处理转为站控实训操作正确但结束实训判为错误的bug
stepList.get(0).setDeviceCode(mapDevice.getCode());
if (MapElement.DeviceType.ROUTE.equals(mapDevice.getDeviceType())) {
stepList.get(0).setDeviceCode(((Route) mapDevice).getStart().getCode());
} else {
if (!"bar".equals(stepList.get(0).getDeviceType())) { //为处理转为站控实训操作正确但结束实训判为错误的bug
stepList.get(0).setDeviceCode(mapDevice.getCode());
}
}
}
}

View File

@ -52,7 +52,7 @@ public class ControlGeneratorNew implements GeneratorNew {
// 其他操作不生成
continue;
}
trainingVOList.add(build(config, simulation, station, null,operateDefinitionVO));
trainingVOList.add(build(config, simulation, station, null,operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}

View File

@ -176,7 +176,7 @@ public class SectionGeneratorNew implements GeneratorNew {
// 其他操作不生成
continue;
}
trainingVOList.add(this.build(config, simulation, section, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, section, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}

View File

@ -5,17 +5,22 @@ import club.joylink.rtss.services.training.generatornew.GeneratorNew;
import club.joylink.rtss.services.training.generatornew.annotation.GeneratorSelectorNew;
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.Cycle;
import club.joylink.rtss.simulation.cbtc.data.map.Route;
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
import club.joylink.rtss.simulation.cbtc.tool.DeviceStatusModifyTool;
import club.joylink.rtss.vo.client.training.TrainingNewVO;
import club.joylink.rtss.vo.client.training.definition.OperateDefinitionVO;
import club.joylink.rtss.vo.client.training.definition.OperateStepVO;
import club.joylink.rtss.vo.map.logic.MapRouteNewVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@GeneratorSelectorNew(operateObject = Operation.Object.Signal)
@ -28,9 +33,10 @@ public class SignalGeneratorNew implements GeneratorNew {
public List<TrainingNewVO> generate(GenerateConfig config, Simulation simulation,
OperateDefinitionVO operateDefinitionVO) {
List<TrainingNewVO> trainingVOList = new ArrayList<>();
SimulationDataRepository repository = simulation.getRepository();
switch (Operation.Type.valueOf(operateDefinitionVO.getOperateType())) {
case Signal_Set_Auto_Turn_Back: {
List<Cycle> cycleList = simulation.getRepository().getCycleList();
List<Cycle> cycleList = repository.getCycleList();
for (Cycle cycle : cycleList) {
if (cycle.getStation() != null && cycle.getStation().isDepot())
continue;
@ -38,12 +44,12 @@ public class SignalGeneratorNew implements GeneratorNew {
simulation.getBuildParams().getMap().getGraphDataNew().getCycleButtonList()
.stream().filter(mapCycleButtonVO -> mapCycleButtonVO.getCycleCode().equals(cycle.getCode()))
.forEach(button -> {
trainingVOList.add(this.build(config, simulation, cycle, button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, cycle, button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
} else {
trainingVOList.add(this.build(config, simulation, cycle, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, cycle, null, operateDefinitionVO, true));
}
// 仿真重置
this.resetSimulation(simulation);
@ -52,7 +58,7 @@ public class SignalGeneratorNew implements GeneratorNew {
}
case Signal_Cancel_Auto_Turn_Back: {
// 设置背景自动折返为已设置
List<Cycle> cycleList = simulation.getRepository().getCycleList();
List<Cycle> cycleList = repository.getCycleList();
for (Cycle cycle : cycleList) {
if (cycle.getStation() != null && cycle.getStation().isDepot())
continue;
@ -61,12 +67,12 @@ public class SignalGeneratorNew implements GeneratorNew {
simulation.getBuildParams().getMap().getGraphDataNew().getCycleButtonList()
.stream().filter(mapCycleButtonVO -> mapCycleButtonVO.getCycleCode().equals(cycle.getCode()))
.forEach(button -> {
trainingVOList.add(this.build(config, simulation, cycle, button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, cycle, button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
} else {
trainingVOList.add(this.build(config, simulation, cycle, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, cycle, null, operateDefinitionVO, true));
}
// 仿真重置
this.resetSimulation(simulation);
@ -76,31 +82,59 @@ public class SignalGeneratorNew implements GeneratorNew {
}
List<Signal> signalList = simulation.getRepository().getSignalList();
List<Signal> signalList = repository.getSignalList();
for (Signal signal : signalList) {
if (signal.isVirtual()) continue;
if (signal.getStation() != null && signal.getStation().isDepot())
continue;
List<Route> routeList = signal.getRouteList();
boolean routeLikeHa1 = simulation.getRepository().getConfig().isRouteLikeHa1();
boolean routeLikeHa1 = repository.getConfig().isRouteLikeHa1();
boolean railway = repository.getConfig().isRailway();
switch (Operation.Type.valueOf(operateDefinitionVO.getOperateType())) {
case Signal_Block:
case Signal_Find_Routes_Status:
break;
case Signal_Set_Route: {
if (!CollectionUtils.isEmpty(routeList)) {
for (Route route : routeList) {
// 类似哈尔滨一号线根据配置各类进路分别生成
if ((operateDefinitionVO.isAtp() && !route.isAtp())
|| (operateDefinitionVO.isGround() && !route.isGround())) {
continue;
if (!railway) {
for (Route route : routeList) {
// 类似哈尔滨一号线根据配置各类进路分别生成
if ((operateDefinitionVO.isAtp() && !route.isAtp())
|| (operateDefinitionVO.isGround() && !route.isGround())) {
continue;
}
if (route.isGuide()) { // 引导进路跳过
continue;
}
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
if (route.isGuide()) { // 引导进路跳过
continue;
} else {
Map<String, MapRouteNewVO> routeNewVOMap = simulation.getBuildParams().getMap().getLogicDataNew().getRouteList()
.stream().collect(Collectors.toMap(MapRouteNewVO::getCode, Function.identity()));
for (Route route : routeList) {
if (route.isGuide())
continue;
MapRouteNewVO mapRouteNewVO = routeNewVOMap.get(route.getCode());
List<String> btnCodeList = mapRouteNewVO.getBtnCodeList();
List<OperateStepVO> stepVOList = operateDefinitionVO.getStepVOList();
stepVOList.get(0).setDeviceCode(btnCodeList.get(0));
stepVOList.get(1).setDeviceCode(btnCodeList.get(1));
if (route.isTrainRoute()) {
stepVOList.get(0).setTip(String.format("鼠标左键点击【信号机%s的列车按钮】", route.getStart().getShowName()));
stepVOList.get(1).setTip(String.format("鼠标左键点击【信号机%s的列车按钮】", route.getDestination().getShowName()));
} else if (route.isPassRoute()) {
stepVOList.get(0).setTip(String.format("鼠标左键点击【信号机%s的通过按钮】", route.getStart().getShowName()));
stepVOList.get(1).setTip(String.format("鼠标左键点击【信号机%s的列车按钮】", route.getDestination().getShowName()));
} else if (route.isShutting()) {
stepVOList.get(0).setTip(String.format("鼠标左键点击【信号机%s】", route.getStart().getShowName()));
stepVOList.get(1).setTip(String.format("鼠标左键点击【信号机%s】", route.getDestination().getShowName()));
}
trainingVOList.add(this.build(config, simulation, route, mapRouteNewVO, operateDefinitionVO, false));
// 仿真重置
this.resetSimulation(simulation);
}
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO));
// 仿真重置
this.resetSimulation(simulation);
}
}
continue;
@ -111,10 +145,10 @@ public class SignalGeneratorNew implements GeneratorNew {
continue;
}
if (routeLikeHa1) {
if (simulation.getRepository().getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
routeList.forEach(route -> route.setAtsControl(false));
}
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
this.resetSimulation(simulation);
continue;
} else {
@ -127,11 +161,11 @@ public class SignalGeneratorNew implements GeneratorNew {
if (route.isGuide()) { // 引导进路跳过
continue;
}
if (simulation.getRepository().getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
route.setAtsControl(false);
}
}
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
@ -142,7 +176,7 @@ public class SignalGeneratorNew implements GeneratorNew {
case Signal_Close_Auto_Setting: {
if (!CollectionUtils.isEmpty(routeList)) {
if (routeLikeHa1 || operateDefinitionVO.onlyOperateSignal()) {
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
this.resetSimulation(simulation);
continue;
} else {
@ -155,7 +189,7 @@ public class SignalGeneratorNew implements GeneratorNew {
if (route.isGuide()) { // 引导进路跳过
continue;
}
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -166,18 +200,40 @@ public class SignalGeneratorNew implements GeneratorNew {
case Signal_Total_Cancel: // 总取消暂时只生成取消未接近锁闭的进路这一种场景的实训
case Signal_Cancel_Route: {
// 查询以信号机为始端的进路列表设置背景为进路已排列
if (!CollectionUtils.isEmpty(routeList)) {
for (Route route : routeList) {
// 类似哈尔滨一号线根据配置各类进路分别生成
if ((operateDefinitionVO.isAtp() && !route.isAtp())
|| (operateDefinitionVO.isGround() && !route.isGround())) {
continue;
if (!railway) {
if (!CollectionUtils.isEmpty(routeList)) {
for (Route route : routeList) {
// 类似哈尔滨一号线根据配置各类进路分别生成
if ((operateDefinitionVO.isAtp() && !route.isAtp())
|| (operateDefinitionVO.isGround() && !route.isGround())) {
continue;
}
if (route.isGuide()) { // 引导进路跳过
continue;
}
deviceStatusModifyTool.openRouteDirect(simulation, route);
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO, false));
// 仿真重置
this.resetSimulation(simulation);
}
if (route.isGuide()) { // 引导进路跳过
}
} else {
Map<String, MapRouteNewVO> routeNewVOMap = simulation.getBuildParams().getMap().getLogicDataNew().getRouteList()
.stream().collect(Collectors.toMap(MapRouteNewVO::getCode, Function.identity()));
for (Route route : routeList) {
if (route.isGuide() || route.isPassRoute() || route.isLongShuntingRoute())
continue;
MapRouteNewVO mapRouteNewVO = routeNewVOMap.get(route.getCode());
List<String> btnCodeList = mapRouteNewVO.getBtnCodeList();
List<OperateStepVO> stepVOList = operateDefinitionVO.getStepVOList();
stepVOList.get(1).setDeviceCode(btnCodeList.get(0));
if (route.isTrainRoute()) {
stepVOList.get(1).setTip(String.format("鼠标左键点击【信号机%s的列车按钮】", route.getStart().getShowName()));
} else if (route.isShutting()) {
stepVOList.get(1).setTip(String.format("鼠标左键点击【信号机%s】", route.getStart().getShowName()));
}
deviceStatusModifyTool.openRouteDirect(simulation, route);
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, route, mapRouteNewVO, operateDefinitionVO, false));
// 仿真重置
this.resetSimulation(simulation);
}
@ -192,7 +248,7 @@ public class SignalGeneratorNew implements GeneratorNew {
deviceStatusModifyTool.closeSignalDirectly(route.getStart());
deviceStatusModifyTool.loadManualTrainOfGroup(simulation, "001", signal.getSection(), signal.isRight());
// todo 在接近区段设置一辆列车
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -206,7 +262,7 @@ public class SignalGeneratorNew implements GeneratorNew {
continue;
}
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -223,7 +279,7 @@ public class SignalGeneratorNew implements GeneratorNew {
this.deviceStatusModifyTool.openRouteDirect(simulation, route);
this.deviceStatusModifyTool.closeSignalDirectly(route.getStart());
signal.setForbidden(true);
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -242,7 +298,7 @@ public class SignalGeneratorNew implements GeneratorNew {
for (Route route : routeList) {
route.setAtsControl(false);
}
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
} else {
@ -251,7 +307,7 @@ public class SignalGeneratorNew implements GeneratorNew {
continue;
}
route.setAtsControl(false);
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -266,19 +322,19 @@ public class SignalGeneratorNew implements GeneratorNew {
.filter(route -> route.isFlt())
.collect(Collectors.toList());
for (Route route : fltRouteList) {
if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) {
if (repository.getConfig().isSetRouteBeforeSetFlt()) {
deviceStatusModifyTool.openRouteDirect(simulation, route);
}
if (operateDefinitionVO.autoRouteButton()) {
simulation.getBuildParams().getMap().getGraphDataNew().getAutomaticRouteButtonList()
.stream().filter(automaticRouteButtonVO -> automaticRouteButtonVO.getAutomaticRouteCode().equals(route.getCode()))
.forEach(button -> {
trainingVOList.add(this.build(config, simulation, route.getStart(), button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, route.getStart(), button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
} else {
trainingVOList.add(this.build(config, simulation, route.getStart(), null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, route.getStart(), null, operateDefinitionVO, true));
}
// 仿真重置
this.resetSimulation(simulation);
@ -299,12 +355,12 @@ public class SignalGeneratorNew implements GeneratorNew {
simulation.getBuildParams().getMap().getGraphDataNew().getAutomaticRouteButtonList()
.stream().filter(automaticRouteButtonVO -> automaticRouteButtonVO.getAutomaticRouteCode().equals(route.getCode()))
.forEach(button -> {
trainingVOList.add(this.build(config, simulation, signal, button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
} else {
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
}
// 仿真重置
this.resetSimulation(simulation);
@ -322,13 +378,13 @@ public class SignalGeneratorNew implements GeneratorNew {
for (Route route : arcRouteList) {
route.setCiControl(true);
}
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
} else {
for (Route route : arcRouteList) {
route.setCiControl(true);
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -353,17 +409,17 @@ public class SignalGeneratorNew implements GeneratorNew {
.collect(Collectors.toList());
}
for (Route route : notTurnBackRouteList) {
if (simulation.getRepository().getConfig().isGuideNeedRouteSettingFirst()) {
if (repository.getConfig().isGuideNeedRouteSettingFirst()) {
deviceStatusModifyTool.openRouteDirect(simulation, route);
deviceStatusModifyTool.closeSignalDirectly(route.getStart());
}
deviceStatusModifyTool.loadManualTrainOfGroup(simulation, "001", signal.getSection(), signal.isRight());
if (operateDefinitionVO.onlyOperateSignal()) {
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
this.resetSimulation(simulation);
break;
}
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, route, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -427,7 +483,7 @@ public class SignalGeneratorNew implements GeneratorNew {
// 其他操作不生成
continue;
}
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, signal, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}

View File

@ -35,7 +35,7 @@ public class SpeedLimitGeneratorNew implements GeneratorNew {
case Cancel_All_Limit_Speed: // 取消全线临时限速
List<MapTempSpeedLimitVO> tempSpeedLimitList = simulation.getBuildParams().getMap().getGraphDataNew().getTempSpeedLimitList();
tempSpeedLimitList.forEach(mapTempSpeedLimitVO -> {
trainingVOList.add(this.build(config, simulation,null,mapTempSpeedLimitVO, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation,null,mapTempSpeedLimitVO, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
break;
@ -44,7 +44,7 @@ public class SpeedLimitGeneratorNew implements GeneratorNew {
}
@Override
public TrainingNewVO build(GenerateConfig config, Simulation simulation, MapElement nullableDevice, Object mapButton, OperateDefinitionVO operateDefinitionVO) {
public TrainingNewVO build(GenerateConfig config, Simulation simulation, MapElement nullableDevice, Object mapButton, OperateDefinitionVO operateDefinitionVO, boolean setDeviceCode) {
// 实训基本信息
TrainingNewVO trainingVO = new TrainingNewVO(config, operateDefinitionVO);

View File

@ -104,7 +104,7 @@ public class StandGeneratorNew implements GeneratorNew {
// 其他操作不生成
continue;
}
trainingVOList.add(this.build(config, simulation, stand,null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, stand,null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}

View File

@ -153,7 +153,7 @@ public class StationGeneratorNew implements GeneratorNew {
simulation.getBuildParams().getMap().getGraphDataNew().getTbStrategyList()
.stream().filter(turnBackStrategyO -> turnBackStrategyO.getStationCode().equals(station.getCode()))
.forEach(button -> {
trainingVOList.add(this.build(config, simulation, station,button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, station,button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
@ -181,7 +181,7 @@ public class StationGeneratorNew implements GeneratorNew {
List<Switch> collect = switchList.stream().filter(
aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).collect(Collectors.toList());
collect.forEach(aSwitch -> aSwitch.setFault(Switch.SwitchFault.SPLIT));
trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
@ -210,7 +210,7 @@ public class StationGeneratorNew implements GeneratorNew {
station.setControlMode(Station.ControlMode.Local);
List<Switch> switchList1 = simulation.getRepository().getSwitchList();
switchList1.stream().filter(aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).forEach(aSwitch -> aSwitch.setSingleLock(true));
trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
continue;
@ -219,7 +219,7 @@ public class StationGeneratorNew implements GeneratorNew {
station.setControlMode(Station.ControlMode.Local);
List<Switch> switchList1 = simulation.getRepository().getSwitchList();
switchList1.stream().filter(aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).forEach(aSwitch -> aSwitch.setSingleLock(true));
trainingVOList.add(this.build(config, simulation, station, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, station, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
break;
@ -235,7 +235,7 @@ public class StationGeneratorNew implements GeneratorNew {
station.setControlMode(Station.ControlMode.Local);
List<Switch> switchList1 = simulation.getRepository().getSwitchList();
switchList1.stream().filter(aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).forEach(aSwitch -> aSwitch.setSingleLock(true));
trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, station, button, operateDefinitionVO, true));
this.resetSimulation(simulation);
});
return;
@ -244,7 +244,7 @@ public class StationGeneratorNew implements GeneratorNew {
station.setControlMode(Station.ControlMode.Local);
List<Switch> switchList1 = simulation.getRepository().getSwitchList();
switchList1.stream().filter(aSwitch -> Objects.equals(aSwitch.getDeviceStation(), station)).forEach(aSwitch -> aSwitch.setSingleLock(true));
trainingVOList.add(this.build(config, simulation, station, null, operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, station, null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}
@ -304,7 +304,7 @@ public class StationGeneratorNew implements GeneratorNew {
// 其他操作不生成
continue;
}
trainingVOList.add(build(config, simulation, station,null, operateDefinitionVO));
trainingVOList.add(build(config, simulation, station,null, operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}

View File

@ -125,7 +125,7 @@ public class SwitchGeneratorNew implements GeneratorNew {
// 其他操作不生成
continue;
}
trainingVOList.add(this.build(config, simulation, aSwitch, null,operateDefinitionVO));
trainingVOList.add(this.build(config, simulation, aSwitch, null,operateDefinitionVO, true));
// 仿真重置
this.resetSimulation(simulation);
}

View File

@ -1,75 +1,74 @@
//package club.joylink.rtss.services.voice.huawei;
//
//import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
//import club.joylink.rtss.services.voice.IVoiceService;
//import club.joylink.rtss.util.VoiceFileUtils;
//import club.joylink.rtss.vo.client.VoiceRecognitionResult;
//import com.huawei.sis.bean.AuthInfo;
//import com.huawei.sis.bean.SisConfig;
//import com.huawei.sis.bean.request.AsrCustomShortRequest;
//import com.huawei.sis.bean.response.AsrCustomShortResponse;
//import com.huawei.sis.client.AsrCustomizationClient;
//import com.huawei.sis.exception.SisException;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Service;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.IOException;
//import java.util.Base64;
//
//@Slf4j
//@Service("HuaWeiVoiceService")
//public class HuaweiVoiceServiceImpl implements IVoiceService {
//
//
// @Override
// public String synthesis(String message, String per) {
// throw BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION.exception("功能暂未实现");
// }
//
// @Override
// public String synthesis(String message) {
// return this.synthesis(message, "0");
// }
//
// /**
// * 华为语音识别配置
// */
// private final String ak = "YDUXTXRYGAHGPHAIXZCU";
// private final String sk = "Kcbm3sTDCYEou8kGeAhKxfBkgWybIn6IjJyGBX3p";
// private final String region = "cn-north-4";
// private final String projectId = "0aada8176180f28c2f34c0196f5394e8";
//
// @Override
// public VoiceRecognitionResult voiceRecognition(MultipartFile file, String lang) {
// String filePath = VoiceFileUtils.saveFile(file);
// try {
// return voiceRecognition(file.getBytes(), filePath);
// } catch (IOException e) {
// throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("第三方服务调用异常");
// }
// }
//
// @Override
// public VoiceRecognitionResult voiceRecognition(byte[] bytes, String filePath) {
// AuthInfo authInfo = new AuthInfo(ak, sk, region, projectId);
// SisConfig sisConfig = new SisConfig();
// AsrCustomizationClient client = new AsrCustomizationClient(authInfo, sisConfig);
// String data = Base64.getEncoder().encodeToString(bytes);
// try {
// AsrCustomShortRequest request = new AsrCustomShortRequest(data, "pcm16k16bit", "chinese_16k_common");
// AsrCustomShortResponse response = client.getAsrShortResponse(request);
// return new VoiceRecognitionResult(filePath, response.getResult().getText());
// } catch (SisException e) {
// throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音识别失败", e);
// }
// }
//
// @Override
// public VoiceRecognitionResult voiceRecognition(String fileBase64) {
// String base64 = fileBase64.substring(fileBase64.indexOf("base64,") + "base64,".length());
// byte[] bytes = Base64.getDecoder().decode(base64.trim());
// String filePath = VoiceFileUtils.saveFile(bytes);
// return voiceRecognition(bytes, filePath);
// }
//}
package club.joylink.rtss.services.voice.huawei;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.services.voice.IVoiceService;
import club.joylink.rtss.util.VoiceFileUtils;
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
import com.huawei.sis.bean.AuthInfo;
import com.huawei.sis.bean.SisConfig;
import com.huawei.sis.bean.request.AsrCustomShortRequest;
import com.huawei.sis.bean.response.AsrCustomShortResponse;
import com.huawei.sis.client.AsrCustomizationClient;
import com.huawei.sis.exception.SisException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Base64;
@Slf4j
@Service("HuaWeiVoiceService")
public class HuaweiVoiceServiceImpl implements IVoiceService {
@Override
public String synthesis(String message, String per) {
throw BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION.exception("功能暂未实现");
}
@Override
public String synthesis(String message) {
return this.synthesis(message, "0");
}
/**
* 华为语音识别配置
*/
private final String ak = "YDUXTXRYGAHGPHAIXZCU";
private final String sk = "Kcbm3sTDCYEou8kGeAhKxfBkgWybIn6IjJyGBX3p";
private final String region = "cn-north-4";
private final String projectId = "0aada8176180f28c2f34c0196f5394e8";
@Override
public VoiceRecognitionResult voiceRecognition(MultipartFile file, String lang) {
String filePath = VoiceFileUtils.saveFile(file);
try {
return voiceRecognition(file.getBytes(), filePath);
} catch (IOException e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("第三方服务调用异常");
}
}
@Override
public VoiceRecognitionResult voiceRecognition(byte[] bytes, String filePath) {
AuthInfo authInfo = new AuthInfo(ak, sk, region, projectId);
SisConfig sisConfig = new SisConfig();
AsrCustomizationClient client = new AsrCustomizationClient(authInfo, sisConfig);
String data = Base64.getEncoder().encodeToString(bytes);
try {
AsrCustomShortRequest request = new AsrCustomShortRequest(data, "pcm16k16bit", "chinese_16k_common");
AsrCustomShortResponse response = client.getAsrShortResponse(request);
return new VoiceRecognitionResult(filePath, response.getResult().getText());
} catch (SisException e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音识别失败", e);
}
}
@Override
public VoiceRecognitionResult voiceRecognition(String fileBase64) {
String base64 = fileBase64.substring(fileBase64.indexOf("base64,") + "base64,".length());
byte[] bytes = Base64.getDecoder().decode(base64.trim());
String filePath = VoiceFileUtils.saveFile(bytes);
return voiceRecognition(bytes, filePath);
}
}

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.ATS;
import club.joylink.rtss.constants.MapPrdTypeEnum;
import club.joylink.rtss.simulation.cbtc.CI.data.StationDirection;
import club.joylink.rtss.simulation.cbtc.CI.data.vo.StationDirectionStatusVO;
import club.joylink.rtss.simulation.cbtc.CI.status.StationDirectionStatus;
@ -100,11 +101,20 @@ public class ATSMessageCollectAndDispatcher {
trainList.forEach(train -> {
TrainStatus trainStatus = repository.findStatusByCode(train.getGroupNumber(), TrainStatus.class);
if (Objects.isNull(trainStatus)) {
trainStatus = new TrainStatus(train);
if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){
trainStatus = new YJDDZHTrainStatus(train);
}else{
trainStatus = new TrainStatus(train);
}
repository.addDeviceInfo(trainStatus);
totalList.add(trainStatus.convert2VO(train));
} else {
DeviceStatusVO statusVO = new TrainStatusVO(train);
DeviceStatusVO statusVO;
if(simulation.getBuildParams().getProdType() == MapPrdTypeEnum.YJDDZH){
statusVO = new YJDDZHTrainStatusVO(train);
}else{
statusVO = new TrainStatusVO(train);
}
if (trainStatus.compareAndChange(train, statusVO)) {
totalList.add(statusVO);
}

View File

@ -1434,6 +1434,11 @@ public class Operation {
Conversation_Chat_Audio_Base64(new Label[]{Label.CLIENT}),
;
REGULAR_TRAIN_LINE_STATION_UPDATE_LOAD(new Label[]{Label.CLIENT}),
/**
* 紧急应急语音命令
*/
YJDDZH_VOICE_COMMAND(new Label[]{Label.CLIENT});
final Label[] labels;
Type(Label[] labels) {

View File

@ -6,18 +6,33 @@ import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import club.joylink.rtss.simulation.cbtc.data.iscs.Audio;
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsIbpStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsPsdStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsPslStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.IscsStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor;
import club.joylink.rtss.simulation.rt.iscs.IscsStatusPublisher;
import club.joylink.rtss.vo.client.iscs.PlayParamVO;
import club.joylink.rtss.vo.client.iscs.TimedPlayParamVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Component
public class IscsLogicLoop {
public static final String JOB_NAME = "ISCS_LOGIC_LOOP";
public static final int RATE = 1000;
public static final String MESSAGE_JOB_NAME = "ISCS_MESSAGE_SENDER";
@Autowired
private IscsInteractiveService iscsInteractiveService;
@ -65,7 +80,89 @@ public class IscsLogicLoop {
}
}
public void addJob(Simulation simulation) {
public void UpdateStatusAndSend(Simulation simulation) {
SimulationDataRepository repository = simulation.getRepository();
MapConfig config = repository.getConfig();
SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository();
Map<String, IscsStatusVO> statusVOMap = iscsRepository.getStatusVOMap();
//IBP
List<VirtualRealityIbp> vrIbpList = repository.getVrListByType(MapElement.DeviceType.IBP, VirtualRealityIbp.class);
for (VirtualRealityIbp vrIbp : vrIbpList) {
IscsStatusVO iscsStatusVO = statusVOMap.get(vrIbp.getCode());
if (iscsStatusVO == null) {
IscsIbpStatusVO iscsIbpStatusVO = new IscsIbpStatusVO(vrIbp);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(iscsIbpStatusVO, watcher);
statusVOMap.put(iscsIbpStatusVO.getCode(), iscsIbpStatusVO);
iscsIbpStatusVO.fireWatcher(null, null);
} else {
IscsIbpStatusVO iscsIbpStatusVO = (IscsIbpStatusVO) iscsStatusVO;
boolean change = iscsIbpStatusVO.compareAndChange(vrIbp);
if (change) iscsIbpStatusVO.fireWatcher(null, null);
}
}
//PSD
for (Station station : repository.getStationList()) {
boolean upRight = config.isUpRight();
List<Stand> rightStands = station.getNormalStand(true);
Stand rightStand = null;
if (!CollectionUtils.isEmpty(rightStands))
rightStand = rightStands.get(0);
List<Stand> leftStands = station.getNormalStand(false);
Stand leftStand = null;
if (!CollectionUtils.isEmpty(leftStands))
leftStand = leftStands.get(0);
Stand upStand = upRight ? rightStand : leftStand;
Stand downStand = upRight ? leftStand : rightStand;
//PSD
String iscsPsdCode = station.getCode() + "_ISCS_PSD";
VirtualRealityScreenDoor upPsd = upStand == null ? null : upStand.getPsd().getVirtualScreenDoor();
VirtualRealityScreenDoor downPsd = downStand == null ? null : downStand.getPsd().getVirtualScreenDoor();
IscsPsdStatusVO iscsPsdStatusVO = (IscsPsdStatusVO) statusVOMap.get(iscsPsdCode);
if (iscsPsdStatusVO == null) {
iscsPsdStatusVO = new IscsPsdStatusVO(iscsPsdCode, station.getCode(), upPsd, downPsd);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(iscsPsdStatusVO, watcher);
statusVOMap.put(iscsPsdStatusVO.getCode(), iscsPsdStatusVO);
iscsPsdStatusVO.fireWatcher(null, null);
} else {
boolean change = iscsPsdStatusVO.compareAndChange(upPsd, downPsd);
if (change) iscsPsdStatusVO.fireWatcher(null, null);
}
//PSL
String iscsPslCode = station.getCode() + "_ISCS_PSL";
VirtualRealityPsl upPsl = upStand == null ? null : upStand.getVrPsl();
VirtualRealityPsl downPsl = downStand == null ? null : downStand.getVrPsl();
IscsPslStatusVO iscsPslStatusVO = (IscsPslStatusVO) statusVOMap.get(iscsPslCode);
if (iscsPslStatusVO == null) {
iscsPslStatusVO = new IscsPslStatusVO(iscsPslCode, station.getCode(), upPsl, downPsl);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(iscsPslStatusVO, watcher);
statusVOMap.put(iscsPslStatusVO.getCode(), iscsPslStatusVO);
iscsPslStatusVO.fireWatcher(null, null);
} else {
boolean change = iscsPslStatusVO.compareAndChange(upPsl, downPsl);
if (change) iscsPslStatusVO.fireWatcher(null, null);
}
// //GATE 改为闸机状态由前端决定故注释这段代码
// VirtualRealityGate vrGate = station.getVrGate();
// IscsGateStatusVO iscsGateStatusVO = (IscsGateStatusVO) statusVOMap.get(vrGate.getCode());
// if (iscsGateStatusVO == null) {
// iscsGateStatusVO = new IscsGateStatusVO(vrGate.getCode(), station.getCode(), vrGate);
// IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
// simulation.watch(iscsGateStatusVO, watcher);
// statusVOMap.put(iscsGateStatusVO.getCode(), iscsGateStatusVO);
// iscsGateStatusVO.fireWatcher(null, null);
// } else {
// boolean change = iscsGateStatusVO.compareAndChange(vrGate);
// if (change) iscsGateStatusVO.fireWatcher(null, null);
// }
}
}
public void addJobs(Simulation simulation) {
simulation.addJob(JOB_NAME, () -> run(simulation), RATE);
simulation.addJob(MESSAGE_JOB_NAME, () -> UpdateStatusAndSend(simulation), RATE);
}
}

View File

@ -24,7 +24,7 @@ public class IscsMessageCollectAndDispatcher {
if (status == null) {
status = new IscsAudioStatusVO(audio);
iscsRepository.addStatus(status);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(status, watcher);
status.fireWatcher(null, null);
} else {

View File

@ -12,6 +12,7 @@ import club.joylink.rtss.services.publishData.IbpService;
import club.joylink.rtss.simulation.SimulationManager;
import club.joylink.rtss.simulation.cbtc.ATS.ATSLogicLoop;
import club.joylink.rtss.simulation.cbtc.ATS.ATSMessageCollectAndDispatcher;
import club.joylink.rtss.simulation.cbtc.ATS.service.TrainPositionTimeOverService;
import club.joylink.rtss.simulation.cbtc.CI.CiLogic;
import club.joylink.rtss.simulation.cbtc.CTC.CTCLogicLoop;
import club.joylink.rtss.simulation.cbtc.ISCS.IscsLogicLoop;
@ -49,6 +50,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
@ -143,6 +145,8 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
@Autowired
private PisLogicLoop pisLogicLoop;
@Resource
TrainPositionTimeOverService timeOverService;
@Override
public Simulation create(SimulationBuildParams params, String group) {
@ -199,6 +203,7 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
vrDeviceLogicLoop.addJobsForTrainPosition(simulation);
// ciLogic.addJobs(simulation);
ciLogic.addJobsForTrainPosition(simulation);
timeOverService.run(simulation);
return;
}
if (simulation.getRepository().getConfig().isRailway()) {
@ -210,7 +215,7 @@ public class SimulationLifeCycleServiceImpl implements SimulationLifeCycleServic
powerSupplyService.addJobs(simulation);
iVirtualRealityPslService.addJobs(simulation);
iscsMessageCollectAndDispatcher.addJob(simulation);
iscsLogicLoop.addJob(simulation);
iscsLogicLoop.addJobs(simulation);
pisLogicLoop.addJobs(simulation);
}
atpLogicLoop.addJobs(simulation);

View File

@ -1384,14 +1384,6 @@ public class MapDeviceBuilder {
elementMap.put(station.getCode(), station);
station.setCentralized(stationVO.isCentralized());
station.setDepot(stationVO.isDepot());
// if (station.isCentralized() && !station.isDepot()) {
// ZC zc = (ZC) elementMap.get(stationVO.getZcCode());
// if (Objects.isNull(zc)) {
// errMsgList.add(String.format("车站[%s(%s)]未关联ZC或ZC不存在请在ZC设备处选择管理的集中站列表", station.getName(), station.getCode()));
// } else {
// station.setZc(zc);
// }
// }
if (Objects.isNull(stationVO.getKmRange())) {
errMsgList.add(String.format("车站[%s(%s)]未设置距离", stationVO.getName(), stationVO.getCode()));
} else {
@ -1414,6 +1406,7 @@ public class MapDeviceBuilder {
if (station.isHasControlMode()) { // 有控制模式初始化为中控
station.setControlMode(Station.ControlMode.Center);
}
station.setVrGate(new VirtualRealityGate(station.getCode() + "_GATE", station.getName() + "闸机"));
});
// 设备集中站下的车站关联ZC联锁站下的车站关联联锁站
stationList.forEach(stationVO -> {
@ -1428,7 +1421,6 @@ public class MapDeviceBuilder {
station.getName(), station.getCode(), code));
} else {
normal.setDeviceStation(station);
// normal.setZc(station.getZc());
}
});
}

View File

@ -0,0 +1,26 @@
package club.joylink.rtss.simulation.cbtc.command;
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.Simulation;
import club.joylink.rtss.simulation.cbtc.command.service.VoiceCommandService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.annotation.Resource;
@OperateHandler
@Slf4j
public class VoiceCommandHandler {
@Resource
@Qualifier("voiceCommand")
private VoiceCommandService service;
@OperateHandlerMapping(type = Operation.Type.YJDDZH_VOICE_COMMAND)
public void yjddzhVoiceCommand(Simulation simulation, String base64Str) {
this.service.voiceCommand(simulation,base64Str);
}
}

View File

@ -0,0 +1,115 @@
package club.joylink.rtss.simulation.cbtc.command.service;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.services.voice.IVoiceService;
import club.joylink.rtss.simulation.cbtc.CI.device.CiSwitchControlService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.conversation.SimulationVoiceHandler;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Locale;
import java.util.Objects;
@Service(value="voiceCommand")
public class VoiceCommandService {
@Autowired
@Qualifier("baiDuVoiceService")
private IVoiceService iVoiceService;
@Autowired
private SimulationVoiceHandler voiceHandler;
@Autowired
private CiSwitchControlService ciSwitchControlService;
public void voiceCommand(Simulation simulation,String base64Str){
VoiceRecognitionResult result = this.iVoiceService.voiceRecognition(base64Str);
if(Objects.equals(false, StringUtils.hasText(result.getResult()))){
//TODO 未获取到语音识别的内容
return;
}
this.parseCommand(simulation,result.getResult());
}
private final static String SWITCH_PINYIN = "DAOCHA";
private final static String SWITCH_STATE_DINGWEI_PINGYIN = "DING";
private final static String SWITCH_STATE_FANWEI_PINGYIN = "FAN";
private void parseCommand(Simulation simulation,String result){
String changeResultStr = voiceHandler.numHandle(result);
String pinyinContent = this.toPinYin(changeResultStr);
int switchIndex = pinyinContent.indexOf(SWITCH_PINYIN);
BusinessExceptionAssertEnum.VOICE_COMMAND_PARSE_ERROR.assertTrue(switchIndex >=0,String.format("不能解析道岔的语音指令,语音识别:%s",changeResultStr));
String pinyinCommand = pinyinContent.substring(switchIndex + SWITCH_PINYIN.length());
String deviceName = pinyinContent.substring(0,switchIndex);
boolean hasDingCommand = pinyinCommand.contains(SWITCH_STATE_DINGWEI_PINGYIN);
boolean hasFanCommand = pinyinCommand.contains(SWITCH_STATE_FANWEI_PINGYIN);
BusinessExceptionAssertEnum.VOICE_COMMAND_PARSE_ERROR.assertTrue(Objects.nonNull(deviceName),String.format("不能解析道岔的名称,语音识别:%s",changeResultStr));
BusinessExceptionAssertEnum.VOICE_COMMAND_PARSE_ERROR.assertTrue(hasDingCommand || hasFanCommand,String.format("道岔的语音指令不明确,语音识别:%s",changeResultStr));
BusinessExceptionAssertEnum.VOICE_COMMAND_PARSE_ERROR.assertNotTrue(hasDingCommand && hasFanCommand,String.format("道岔的语音指令只能有一个,语音识别:%s",changeResultStr));
this.turnSwitch(simulation,deviceName,hasDingCommand,hasFanCommand);
}
private void turnSwitch(Simulation simulation,String name,boolean hasDingCommand,boolean hasFanCommand){
SimulationDataRepository repository = simulation.getRepository();
Switch aSwitch = repository.getDeviceMap().values().stream()
.filter(d->d.getDeviceType() == MapElement.DeviceType.SWITCH && Objects.equals(((Switch)d).getName().toUpperCase(),name.toUpperCase()))
.map(d->(Switch) d).findFirst().orElse(null);
BusinessExceptionAssertEnum.VOICE_COMMAND_PARSE_ERROR.assertTrue(Objects.nonNull(aSwitch),String.format("未找到对应的道岔:%s",name));
if(hasDingCommand){
this.ciSwitchControlService.turn2NormalPosition(simulation,aSwitch);
}else if(hasFanCommand){
this.ciSwitchControlService.turn2ReversePosition(simulation,aSwitch);
}
}
private final static HanyuPinyinOutputFormat PIN_YIN_FORMAT = new HanyuPinyinOutputFormat();
static{
/**
* 输出大小写设置
*
* LOWERCASE:输出小写
* UPPERCASE:输出大写
*/
PIN_YIN_FORMAT.setCaseType(HanyuPinyinCaseType.UPPERCASE);
/**
* 输出音标设置
*
* WITH_TONE_MARK:直接用音标符必须设置WITH_U_UNICODE否则会抛出异常
* WITH_TONE_NUMBER1-4数字表示音标
* WITHOUT_TONE没有音标
*/
PIN_YIN_FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
}
private String toPinYin(String content) {
StringBuilder sb = new StringBuilder();
for(char c : content.toCharArray()){
if(Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
try {
String[] ss = PinyinHelper.toHanyuPinyinStringArray(c,PIN_YIN_FORMAT);
sb.append(ss[0]);
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
}
}else{
sb.append(c);
}
}
return sb.toString();
}
}

View File

@ -231,7 +231,10 @@ public class CompetitionAndScriptManager {
case Conversation:
if (unfinishedAction.isAudioPlaying()) {
// 获取当前会话
Conversation conversation = simulation.getSimulationConversationMap().get(unfinishedAction.getConversationId());
Conversation conversation = simulation.findValidConversationBySimulationMember(unfinishedAction.getMember());
if (conversation == null) {
throw new SimulationException(SimulationExceptionType.System_Fault, "剧本会话动作执行所需会话未创建");
}
if (conversation.getMemberList().stream().allMatch(m -> m.getMember().isRobot())) { // 会话人员全部是机器人
unfinishedAction.finish();
}

View File

@ -21,20 +21,26 @@ public class SimulationVoiceHandler {
// static {
// regexReplaceMap.put("", "1");
// }
static List<Replacement> numReplacementList;
static {
replacementList = new ArrayList<>();
numReplacementList = new ArrayList<>();
//------------- 数字 --------------
// replacementList.add(new Replacement("(零|洞|栋)", "0"));
// replacementList.add(new Replacement("(一|幺)", "1"));
// replacementList.add(new Replacement("(二|两)", "2"));
// replacementList.add(new Replacement("(三)", "3"));
// replacementList.add(new Replacement("(四)", "4"));
// replacementList.add(new Replacement("(五)", "5"));
// replacementList.add(new Replacement("(六)", "6"));
// replacementList.add(new Replacement("(七|拐)", "7"));
// replacementList.add(new Replacement("(八)", "8"));
// replacementList.add(new Replacement("(九)", "9"));
numReplacementList.add(new Replacement("(零|洞|栋)", "0"));
numReplacementList.add(new Replacement("(一|幺|e|E)", "1"));
numReplacementList.add(new Replacement("(二|两|r)", "2"));
numReplacementList.add(new Replacement("(三)", "3"));
numReplacementList.add(new Replacement("(四)", "4"));
numReplacementList.add(new Replacement("(五)", "5"));
numReplacementList.add(new Replacement("(六)", "6"));
numReplacementList.add(new Replacement("(七|拐)", "7"));
numReplacementList.add(new Replacement("(八)", "8"));
numReplacementList.add(new Replacement("(九)", "9"));
numReplacementList.add(new Replacement("(|。)", ""));
numReplacementList.add(new Replacement("( )", ""));
numReplacementList.add(new Replacement("(低|地|第|敌|底|递)", "d"));
//------------- 专业词汇 --------------
replacementList.add(new Replacement("(行吊|情调|神雕|性交|心跳|香蕉|星标|平调|新调)", "行调"));
replacementList.add(new Replacement("(茼蒿)", "通号"));
@ -157,6 +163,12 @@ public class SimulationVoiceHandler {
}
}
public String numHandle(String content){
for (Replacement replacement : numReplacementList) {
content = replacement.matchAndReplace(content);
}
return regexReplace(content);
}
/**
* 对语音识别内容进行仿真用词处理
*

View File

@ -519,6 +519,8 @@ public class SimulationDataRepository {
public List<RoutePath> queryRoutePathsByStart(Section start) {
List<RoutePath> pathList = new ArrayList<>();
for (List<RoutePath> list : routePathMap.values()) {
if (CollectionUtils.isEmpty(list))
continue;
if (Objects.equals(list.get(0).getStart(), start)) {
pathList.addAll(list);
}
@ -535,6 +537,8 @@ public class SimulationDataRepository {
public List<RoutePath> queryRoutePathsByEnd(Section end) {
List<RoutePath> pathList = new ArrayList<>();
for (List<RoutePath> list : routePathMap.values()) {
if (CollectionUtils.isEmpty(list))
continue;
if (Objects.equals(list.get(0).getEnd(), end)) {
pathList.addAll(list);
}

View File

@ -91,9 +91,18 @@ public class SimulationIscsDataRepository {
}
public List<IscsStatusVO> getStatusByDeviceType(IscsStatusVO.DeviceType type) {
return getStatusStream(type).collect(Collectors.toList());
}
public Stream<IscsStatusVO> getStatusStream(IscsStatusVO.DeviceType type) {
return statusVOMap.values().stream()
.filter(vo -> Objects.equals(type, vo.getDeviceType()));
}
public Stream<IscsStatusVO> getStatusStream(IscsStatusVO.DeviceType type, String stationCode) {
return statusVOMap.values().stream()
.filter(vo -> Objects.equals(type, vo.getDeviceType()))
.collect(Collectors.toList());
.filter(vo -> Objects.equals(stationCode, vo.getStationCode()));
}
public List<IscsSystemResourcesVO> querySystemResources(String system, String type) {

View File

@ -145,6 +145,8 @@ public abstract class MapElement {
LCD,
/** iscs LED */
LED,
/** 闸机 */
GATE,
}
/**

View File

@ -821,6 +821,18 @@ public class Route extends MapNamedElement {
return Type.RECEIVING.equals(type) || Type.DEPARTURE.equals(type);
}
public boolean isPassRoute() {
return Type.PASS.equals(type);
}
public boolean isShuntingRoute() {
return Type.SHUNTING.equals(type);
}
public boolean isLongShuntingRoute() {
return Type.LONG_SHUNTING.equals(type);
}
public boolean isDepartureRoute() {
return Type.DEPARTURE.equals(type);
}

View File

@ -337,7 +337,11 @@ public class Signal extends DelayUnlockDevice {
public boolean isMainAspect() {
if (this.lockedRoute != null) {
return this.aspect.equals(this.lockedRoute.getSettedAspect());
if (this.lockedRoute.getSettedAspect() != null) {
return this.aspect.equals(this.lockedRoute.getSettedAspect());
} else { //兼容国赛场景
return this.aspect.equals(this.lockedRoute.getAspect());
}
}
return false;
}

View File

@ -6,6 +6,7 @@ import club.joylink.rtss.simulation.cbtc.CI.data.StationDirection;
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
import club.joylink.rtss.simulation.cbtc.constant.TurnBackStrategyType;
import club.joylink.rtss.simulation.cbtc.data.support.StationTurnBackStrategyOption;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityGate;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
@ -125,6 +126,11 @@ public class Station extends MayOutOfOrderDevice {
*/
private VirtualRealityIbp vrIbp;
/**
* 虚拟真实闸机
*/
private VirtualRealityGate vrGate;
//---------------------状态属性------------------------
/**

View File

@ -597,6 +597,13 @@ public class Switch extends DelayUnlockDevice {
return atpSectionList;
}
/**
* 生成实训时反射调用不要删除
*/
public boolean isNormalPosition() {
return isPosN();
}
public enum SwitchFault implements DeviceFault {
/**
* 道岔失表

View File

@ -0,0 +1,54 @@
package club.joylink.rtss.simulation.cbtc.data.status;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.vo.DeviceStatusVO;
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
import club.joylink.rtss.simulation.cbtc.data.vo.YJDDZHTrainStatusVO;
import lombok.Getter;
import lombok.Setter;
import java.util.Objects;
/**
* 应急列车状态
*/
@Getter
@Setter
public class YJDDZHTrainStatus extends TrainStatus {
/**
* 公里标
*/
private Float locationKM;
public YJDDZHTrainStatus(TrainInfo train) {
super(train);
this.setSpeed(train.getSpeed());
this.locationKM = train.getLocationKM();
}
@Override
public DeviceStatusVO convert2VO(MapElement device) {
return new YJDDZHTrainStatusVO(this);
}
@Override
public boolean compareAndChange(MapElement device, DeviceStatusVO statusVO) {
TrainInfo train = (TrainInfo) device;
YJDDZHTrainStatusVO status = (YJDDZHTrainStatusVO)statusVO;
boolean change = super.compareAndChange(device, statusVO);
if (!Objects.equals(this.locationKM, train.getLocationKM())) {
this.locationKM = train.getLocationKM();
status.setLocationKM(this.locationKM);
change = true;
}
if (!Objects.equals(this.getSpeed(), train.getSpeed())) {
this.setSpeed(train.getSpeed());
status.setSpeed(this.getSpeed());
change = true;
}
return change;
}
}

View File

@ -301,6 +301,12 @@ public class TrainInfo extends MapElement {
private boolean beAbout2Arrival;
/**
* 公里标
*/
@Setter
private Float locationKM;
public TrainInfo(String groupNumber) {
super(groupNumber, DeviceType.TRAIN);
this.groupNumber = groupNumber;
@ -322,6 +328,13 @@ public class TrainInfo extends MapElement {
info.tripNumber = StringUtils.isEmpty(train.getTripNumber()) ? "" : train.getTripNumber();
return info;
}
// public static TrainInfo constructManualTrain(VirtualRealityTrain train, TrainPosition tp) {
// TrainInfo info = constructManualTrain(train);
// info.setLocationKM(tp.getLocation());
// info.setRight(tp.isRight());
// info.setSpeed(tp.getSpeed());
// return info;
// }
private TrainInfo(VirtualRealityTrain train) {
super(train.getGroupNumber(), DeviceType.TRAIN);
@ -413,6 +426,10 @@ public class TrainInfo extends MapElement {
this.runLevel = config.getRunMode();
}
/**
* ats 数据采集
* @param train
*/
public TrainInfo tracking(VirtualRealityTrain train) {
this.runLevel = train.getRunLevel();
SectionPosition headPosition = train.getHeadPosition();
@ -428,6 +445,7 @@ public class TrainInfo extends MapElement {
}
this.right = train.isRight();
this.speed = train.getSpeed();
this.locationKM = train.getLocationKM();
this.doorOpen = !train.isAllDoorCloseAndLock();
this.driveMode = train.getDriveMode();
this.jump = train.isJump();

View File

@ -0,0 +1,43 @@
package club.joylink.rtss.simulation.cbtc.data.vo;
import club.joylink.rtss.simulation.cbtc.constant.DriveMode;
import club.joylink.rtss.simulation.cbtc.constant.PlanRoutingType;
import club.joylink.rtss.simulation.cbtc.constant.RunLevel;
import club.joylink.rtss.simulation.cbtc.constant.TrainType;
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
import club.joylink.rtss.simulation.cbtc.data.status.TrainStatus;
import club.joylink.rtss.simulation.cbtc.data.status.YJDDZHTrainStatus;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 列车状态
*/
@Getter
@Setter
@NoArgsConstructor
public class YJDDZHTrainStatusVO extends TrainStatusVO {
/**
* 公里标
*/
private Float locationKM;
public YJDDZHTrainStatusVO(TrainInfo train){
super(train);
}
public YJDDZHTrainStatusVO(TrainStatus train) {
super(train);
if(train instanceof YJDDZHTrainStatus){
YJDDZHTrainStatus yjddzhTrainStatus = (YJDDZHTrainStatus)train;
this.locationKM = yjddzhTrainStatus.getLocationKM();
}
}
}

View File

@ -0,0 +1,29 @@
package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityGate;
import lombok.Getter;
@Getter
public class IscsGateStatusVO extends IscsStatusVO{
/**
* -1未定义0故障1正常
*/
private int status;
private static final int UNDEFINED = -1;
private static final int FAULT = 0;
private static final int NORMAL = 1;
public IscsGateStatusVO(String code, String stationCode, VirtualRealityGate vrGate) {
super(code, DeviceType.GATE, stationCode);
status = vrGate.isFault() ? FAULT : NORMAL;
}
public boolean compareAndChange(VirtualRealityGate vrGate) {
int i = vrGate.isFault() ? FAULT : NORMAL;
if (status != i) {
status = i;
return true;
}
return false;
}
}

View File

@ -1,14 +1,20 @@
package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
public class IscsIbpStatusVO extends IscsStatusVO {
/** 上行状态 */
/**
* 上行状态
*/
private DirectionalStatus upStatus;
/** 下行状态 */
/**
* 下行状态
*/
private DirectionalStatus downStatus;
public IscsIbpStatusVO(String code, String stationCode,
@ -18,19 +24,83 @@ public class IscsIbpStatusVO extends IscsStatusVO {
this.downStatus = downStatus;
}
public IscsIbpStatusVO(VirtualRealityIbp vrIbp) {
super(vrIbp.getCode(), DeviceType.IBP, vrIbp.getStation().getCode());
upStatus = new DirectionalStatus();
downStatus = new DirectionalStatus();
for (VirtualRealityIbp.IbpElement element : vrIbp.getAllElements()) {
if (element.getUp() == null)
continue;
DirectionalStatus dirStatus = element.getUp() ? upStatus : downStatus;
VirtualRealityIbp.Mean mean = element.getMean();
if (mean == null)
continue;
switch (mean) {
case KM:
dirStatus.setOpenCommand(element.isOn());
break;
case PSD_SMKM:
dirStatus.setOpenSideCommand(element.isOn());
break;
case GM:
dirStatus.setCloseCommand(element.isOn());
break;
case PSD_CZYX_LIGHT:
dirStatus.setOperate(element.isOn());
break;
}
}
}
public boolean compareAndChange(VirtualRealityIbp vrIbp) {
DirectionalStatus upStatus = new DirectionalStatus();
DirectionalStatus downStatus = new DirectionalStatus();
for (VirtualRealityIbp.IbpElement element : vrIbp.getAllElements()) {
if (element.getUp() == null)
continue;
DirectionalStatus dirStatus = element.getUp() ? upStatus : downStatus;
if (element.getMean() == null)
continue;
switch (element.getMean()) {
case KM:
dirStatus.setOpenCommand(element.isOn());
break;
case PSD_SMKM:
dirStatus.setOpenSideCommand(element.isOn());
break;
case GM:
dirStatus.setCloseCommand(element.isOn());
break;
case PSD_CZYX_LIGHT:
dirStatus.setOperate(element.isOn());
break;
}
}
return this.upStatus.compareAndChange(upStatus) || this.downStatus.compareAndChange(downStatus);
}
@Getter
@Setter
@NoArgsConstructor
public static class DirectionalStatus {
/** 操作允许 */
/**
* 操作允许
*/
private boolean operate = true;
/** 开门命令 */
/**
* 开门命令
*/
private boolean openCommand = true;
/** 开边门命令 */
/**
* 开边门命令
*/
private boolean openSideCommand = true;
/** 关门命令 */
/**
* 关门命令
*/
private boolean closeCommand = true;
public DirectionalStatus(boolean operate, boolean openCommand,
@ -41,6 +111,10 @@ public class IscsIbpStatusVO extends IscsStatusVO {
this.closeCommand = closeCommand;
}
public boolean compareAndChange(DirectionalStatus dirStatus) {
return this.compareAndChange(dirStatus.isOperate(), dirStatus.isOpenCommand(), dirStatus.isOpenSideCommand(), dirStatus.isCloseCommand());
}
public boolean compareAndChange(boolean operate, boolean openCommand, boolean openSideCommand, boolean closeCommand) {
boolean change = false;
if (this.operate != operate) {

View File

@ -1,10 +1,11 @@
package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
public class IscsPsdStatusVO extends IscsStatusVO{
public class IscsPsdStatusVO extends IscsStatusVO {
private DirectionalStatus upStatus;
private DirectionalStatus downStatus;
@ -16,6 +17,23 @@ public class IscsPsdStatusVO extends IscsStatusVO{
this.downStatus = downStatus;
}
public IscsPsdStatusVO(String code, String stationCode, VirtualRealityScreenDoor upPsd, VirtualRealityScreenDoor downPsd) {
super(code, IscsStatusVO.DeviceType.SLIDING_DOOR, stationCode);
if (upPsd != null)
upStatus = new DirectionalStatus(upPsd);
if (downPsd != null)
downStatus = new DirectionalStatus(downPsd);
}
public boolean compareAndChange(VirtualRealityScreenDoor upPsd, VirtualRealityScreenDoor downPsd) {
boolean change = false;
if (upPsd != null)
change = change || upStatus.compareAndChange(upPsd);
if (downPsd != null)
change = change || downStatus.compareAndChange(downPsd);
return change;
}
public enum Status {
OPEN,
CLOSE,
@ -28,13 +46,25 @@ public class IscsPsdStatusVO extends IscsStatusVO{
public static class DirectionalStatus {
private Status status = Status.CLOSE;
private boolean isolationMode = true;
/**
* 隔离模式
*/
private boolean isolationMode = false;
public DirectionalStatus(VirtualRealityScreenDoor vrPsd) {
status = getStatus(vrPsd);
}
public DirectionalStatus(Status status, boolean isolationMode) {
this.status = status;
this.isolationMode = isolationMode;
}
public boolean compareAndChange(VirtualRealityScreenDoor vrPsd) {
Status status = getStatus(vrPsd);
return compareAndChange(status, false);
}
public boolean compareAndChange(Status status, boolean isolationMode) {
boolean change = false;
if (this.status != status) {
@ -47,5 +77,9 @@ public class IscsPsdStatusVO extends IscsStatusVO{
}
return change;
}
private Status getStatus(VirtualRealityScreenDoor vrPsd) {
return vrPsd.isLockAndClose() ? Status.CLOSE : Status.OPEN;
}
}
}

View File

@ -1,5 +1,6 @@
package club.joylink.rtss.simulation.cbtc.data.vo.iscs;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl;
import lombok.Getter;
import lombok.NoArgsConstructor;
@ -16,6 +17,23 @@ public class IscsPslStatusVO extends IscsStatusVO{
this.downStatus = downStatus;
}
public IscsPslStatusVO(String code, String stationCode, VirtualRealityPsl upPsl, VirtualRealityPsl downPsl) {
super(code, DeviceType.PSL, stationCode);
if (upPsl != null)
upStatus = new DirectionalStatus(upPsl);
if (downPsl != null)
downStatus = new DirectionalStatus(downPsl);
}
public boolean compareAndChange(VirtualRealityPsl upPsl, VirtualRealityPsl downPsl) {
boolean change = false;
if (upPsl != null)
change = change || upStatus.compareAndChange(upPsl);
if (downPsl != null)
change = change || downStatus.compareAndChange(downPsl);
return change;
}
@Getter
@NoArgsConstructor
public static class DirectionalStatus {
@ -39,6 +57,17 @@ public class IscsPslStatusVO extends IscsStatusVO{
this.interlockRelease = interlockRelease;
}
public DirectionalStatus(VirtualRealityPsl vrPsl) {
this.operate = vrPsl.isPslczLight();
this.openCommand = vrPsl.isKmButton();
this.closeCommand = vrPsl.isGmButton();
this.interlockRelease = vrPsl.isHsjcLight();
}
public boolean compareAndChange(VirtualRealityPsl vrPsl) {
return compareAndChange(vrPsl.isPslczLight(), vrPsl.isKmButton(), vrPsl.isGmButton(), vrPsl.isHsjcLight());
}
public boolean compareAndChange(boolean operate, boolean openCommand, boolean closeCommand, boolean interlockRelease) {
boolean change = false;
if (this.operate != operate) {

View File

@ -27,5 +27,6 @@ public class IscsStatusVO extends Watchable {
/** 广播 */
AUDIO,
VR_AUDIO,
GATE,
}
}

View File

@ -0,0 +1,19 @@
package club.joylink.rtss.simulation.cbtc.data.vr;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class VirtualRealityGate extends VirtualRealityDevice{
private boolean fault;
public VirtualRealityGate(String code, String name) {
super(code, name, DeviceType.GATE);
}
@Override
public void reset() {
fault = false;
}
}

View File

@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.device.real.modbustcp.hhcj;
import club.joylink.rtss.services.IVirtualRealityIbpService;
import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.map.Station;
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityIbp;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.PlcGatewayService;
import club.joylink.rtss.simulation.cbtc.device.real.modbustcp.RealDeviceService;
@ -496,6 +497,8 @@ public class HhcjIbpServiceImpl implements RealDeviceService {
} else if (r_xfsb_tzxfb2){
config.setXfsb_yxxfb2(false);
}
Station station = vrIbp.getStation();
station.getVrGate().setFault(r_zj_jjsf);
boolean w_zdft_l101 = RealDeviceConfig.getBitOf(deviceStatus, configVO.getW_zdft_l101());
boolean w_zdft_l102 = RealDeviceConfig.getBitOf(deviceStatus, configVO.getW_zdft_l102());

View File

@ -154,7 +154,7 @@ public class ZjdIbpServiceImpl implements RealDeviceService {
iscsStatus = new IscsIbpStatusVO(iscsCode,
vrIbp.getStation().getCode(), null, downStatus);
iscsRepository.addStatus(iscsStatus);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(iscsStatus, watcher);
change = true;
} else {

View File

@ -67,7 +67,7 @@ public class ZjdPsdServiceImpl implements RealDeviceService {
IscsPsdStatusVO.DirectionalStatus downStatus = new IscsPsdStatusVO.DirectionalStatus(status, r_sx_glms);
iscsStatus = new IscsPsdStatusVO(iscsCode, configVO.getStationCode(), null, downStatus);
iscsRepository.addStatus(iscsStatus);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(iscsStatus, watcher);
change = true;
} else {

View File

@ -59,7 +59,7 @@ public class ZjdPslServiceImpl implements RealDeviceService {
iscsStatus = new IscsPslStatusVO(iscsCode,
vrPsl.getStand().getStation().getCode(), null, downStatus);
iscsRepository.addStatus(iscsStatus);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.Name, IscsStatusPublisher.class);
IscsStatusPublisher watcher = simulation.getMessagePublisher(IscsStatusPublisher.NAME, IscsStatusPublisher.class);
simulation.watch(iscsStatus, watcher);
change = true;
} else {

View File

@ -26,10 +26,10 @@ public class VRDeviceLogicLoop {
@Autowired
private VirtualRealityDeviceService virtualRealityDeviceService;
public void runForTrainPosition(Simulation simulation){
// 列车占压计轴区段检查
this.updateTrainOccupySection(simulation);
}
// public void runForTrainPosition(Simulation simulation){
// // 列车占压计轴区段检查
// this.updateTrainOccupySection(simulation);
// }
public void run(Simulation simulation) {
// long start = System.currentTimeMillis();
// 虚拟真实道岔转动过程
@ -90,6 +90,8 @@ public class VRDeviceLogicLoop {
simulation.addJob(SimulationModule.VRD.name(), () -> this.run(simulation), SimulationConstants.VRD_LOOP_RATE);
}
public void addJobsForTrainPosition(Simulation simulation) {
simulation.addJob(SimulationModule.VRD.name(), () -> this.runForTrainPosition(simulation), SimulationConstants.VRD_LOOP_RATE);
//
simulation.addJob(SimulationModule.VRD.name(), () -> this.run(simulation), SimulationConstants.VRD_LOOP_RATE);
// simulation.addJob(SimulationModule.VRD.name(), () -> this.runForTrainPosition(simulation), SimulationConstants.VRD_LOOP_RATE);
}
}

View File

@ -106,6 +106,7 @@ public class MemberManager {
this.playRole(simulation, userId, supervisorList.get(0).getId());
break;
}
case YJDDZH:
case BIG_SCREEN:
case ISCS:
case CENTER:

View File

@ -19,7 +19,7 @@ public enum SimulationSubscribeTopic {
Ctc("/queue/simulation/{id}/ctc"), //大铁CTC
Room("/queue/room/{id}"),
Wgu3d("/topic/simulation/wgu3d/{id}"),
YJDDZH_TRAIN_POSITION("/topic/yjddzh/trainPosition")
YJDDZH_TRAIN_POSITION("/topic/yjddzh/trainPosition/simulation/{id}")
;
private String destPattern;

View File

@ -64,7 +64,7 @@ public class PisLogicLoop {
boolean parking = trainInfo.isParking();
String standTrackCode = parking ? trainInfo.getActualArriveStandTrack() : trainInfo.getEstimatedArriveStandTrack();
if (StringUtils.hasText(standTrackCode)) {
Section standTrack = repository.getByCode(trainInfo.getActualArriveStandTrack(), Section.class);
Section standTrack = repository.getByCode(standTrackCode, Section.class);
List<Stand> standList = standTrack.getStandList();
if (!CollectionUtils.isEmpty(standList)) {
Optional<Stand> standOptional = standList.stream().filter(stand -> !stand.isSmall()).findAny();

View File

@ -6,22 +6,28 @@ import club.joylink.rtss.simulation.SimulationTriggerMessagePublisher;
import club.joylink.rtss.simulation.Watchable;
import club.joylink.rtss.simulation.cbtc.data.SimulationIscsDataRepository;
import club.joylink.rtss.simulation.cbtc.data.vo.iscs.*;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class IscsStatusPublisher extends SimulationTriggerMessagePublisher {
public static final String Name = "iscs";
public static final String NAME = "iscs";
public static final String PSD_PATH = "psd";
public static final String PSD_PATTERN = String.format("%s/%s/%s/%s", Simulation.MESSAGE_SUB_PREFIX, "iscs", PSD_PATH, "{stationCode}");
public static final String PA_PATH = "pa";
public static final String PA_PATTERN = String.format("%s/%s/%s", Simulation.MESSAGE_SUB_PREFIX, "iscs", PA_PATH);
public static final String PIS_PATH = "pis";
public static final String PIS_PATTERN = String.format("%s/%s/%s", Simulation.MESSAGE_SUB_PREFIX, "iscs", PIS_PATH);
public static final String GATE_PATH = "gate";
public static final String GATE_PATTERN = String.format("%s/%s/%s/%s", Simulation.MESSAGE_SUB_PREFIX, "iscs", GATE_PATH, "{stationCode}");
club.joylink.rtss.simulation.cbtc.Simulation simulation;
public IscsStatusPublisher(club.joylink.rtss.simulation.cbtc.Simulation simulation) {
super(Name, Arrays.asList(PSD_PATTERN, PA_PATTERN, PIS_PATTERN));
super(NAME, Arrays.asList(PSD_PATTERN, PA_PATTERN, PIS_PATTERN, GATE_PATTERN));
this.simulation = simulation;
}
@ -36,10 +42,19 @@ public class IscsStatusPublisher extends SimulationTriggerMessagePublisher {
result = buildPaMessage();
} else if (destination.contains(PIS_PATH)) {
result = buildPisMessage();
} else if (destination.contains(GATE_PATH)) {
String s = list.get(1);
result = buildGateMessage(s);
}
return result;
}
private Object buildGateMessage(String stationCode) {
SimulationIscsDataRepository iscsRepository = simulation.getIscsRepository();
List<IscsStatusVO> collect = iscsRepository.getStatusStream(IscsStatusVO.DeviceType.GATE, stationCode).collect(Collectors.toList());
return collect;
}
private Object buildPaMessage() {
List<IscsStatusVO> audioStatus = simulation.getIscsRepository().getStatusByDeviceType(IscsStatusVO.DeviceType.AUDIO);
audioStatus = audioStatus.stream()
@ -75,26 +90,33 @@ public class IscsStatusPublisher extends SimulationTriggerMessagePublisher {
collect.add(new IscsIbpStatusVO("", stationCode, new IscsIbpStatusVO.DirectionalStatus(),
new IscsIbpStatusVO.DirectionalStatus()));
}
iscsRepository.addStatus(collect);
return collect;
}
@Override
public List<String> getNeedBuildDestination(Watchable watchable) {
public List<String> getNeedBuildDestination(@NonNull Watchable watchable) {
List<String> list = new ArrayList<>();
for (Map.Entry<String, List<String>> entry : this.getDestinationParamsMap().entrySet()) {
String destination = entry.getKey();
List<String> param = entry.getValue();
if (watchable instanceof IscsAudioStatusVO) {
IscsAudioStatusVO audioStatusVO = (IscsAudioStatusVO) watchable;
if (audioStatusVO.isPaSystem() && destination.contains(PA_PATH)) {
list.add(destination);
} else if (audioStatusVO.isPisSystem() && destination.contains(PIS_PATH)) {
list.add(destination);
if (destination.contains(PSD_PATH) || destination.contains(GATE_PATH)) {
if (CollectionUtils.isEmpty(param) || param.size() < 2) {
log.error("iscs系统屏蔽门和闸机的订阅路径中参数数量不足");
} else {
if (Objects.equals(((IscsStatusVO) watchable).getStationCode(), param.get(1))) {
list.add(destination);
}
}
} else {
if (param.get(1).equals(((IscsStatusVO) watchable).getStationCode())) {
list.add(destination);
if (watchable instanceof IscsAudioStatusVO) {
IscsAudioStatusVO audioStatusVO = (IscsAudioStatusVO) watchable;
if (audioStatusVO.isPaSystem() && destination.contains(PA_PATH)) {
list.add(destination);
} else if (audioStatusVO.isPisSystem() && destination.contains(PIS_PATH)) {
list.add(destination);
}
} else {
log.error("iscs消息出现未知情况");
}
}
}

View File

@ -8,6 +8,10 @@ import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.time.LocalDate;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class VoiceFileUtils {
@ -24,6 +28,9 @@ public class VoiceFileUtils {
private static final AtomicInteger SN = new AtomicInteger(0);
private static final String LOCAL_FILE_URI_PREFIX = File.separator + "usr" + File.separator + "local"
+ File.separator + "joylink" + File.separator + "oss" + File.separator + "joylink";
public static String saveFile(byte[] bytes) {
try {
return upload(bytes);
@ -59,6 +66,31 @@ public class VoiceFileUtils {
CommonJsonResponse response = restTemplate.postForObject(url, map, CommonJsonResponse.class);
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(200, response.getCode());
return (String) response.getData();
// return localUpload(bytes);
}
static String localUpload(byte[] bytes) {
LocalDate date = LocalDate.now();
int index = SN.getAndIncrement();
String fileName = index + ".wav";
String url = File.separator + "AUDIO" + File.separator + date + File.separator + fileName;
File file = new File(LOCAL_FILE_URI_PREFIX + url);
while (file.exists()) {
fileName = index + "-" + new Random().nextInt(10000) + ".wav";
url = File.separator + "AUDIO" + File.separator + date + File.separator + fileName;
file = new File(LOCAL_FILE_URI_PREFIX + url);
}
File parentFile = file.getAbsoluteFile().getParentFile();
if (!parentFile.exists()) {
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(parentFile.mkdirs(), "创建文件夹失败");
}
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(bytes);
} catch (Exception e) {
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("文件写入失败", e);
}
return url;
}
public static byte[] readFile(String filePath) {

View File

@ -67,8 +67,8 @@ public class SocketMessageFactory {
List<String> topicList = new ArrayList<>();
switch (messageType) {
case YJDDZH_TRAIN_POSITION: {
topicList.add(SimulationSubscribeTopic.YJDDZH_TRAIN_POSITION.getDestPattern());
break;
topicList.add(SimulationSubscribeTopic.YJDDZH_TRAIN_POSITION.buildDestination(group));
}
case BROADCAST:
case Order_Pay_Result:

View File

@ -37,9 +37,7 @@ public class WebSocketController {
}
@MessageMapping("/{mapName}/trainPosition")
// @SendTo("/topic/trainPosition")
public void mlbs( String json,@DestinationVariable String mapName) {
this.trainPositionService.initTrainOrUpdate(mapName,json);
// return json;
}
}

View File

@ -2,7 +2,6 @@ package club.joylink.rtss.websocket;
import club.joylink.rtss.services.ISysUserService;
import club.joylink.rtss.services.LoginSessionManager;
import club.joylink.rtss.services.SysUserService;
import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.LoginUserInfoVO;
import club.joylink.rtss.websocket.interceptor.PresenceChannelInterceptor;

View File

@ -53,6 +53,7 @@ public class StompClientManager {
TrainPosition tp = list.get(i);
tp.setCloseDoor(false);
tp.setStop(false);
tp.setSpeed(Float.valueOf(i));
// tp.setLocation(tp.getLocation() - 500);
String val = JsonUtils.writeValueNullableFieldAsString(tp);
Instant instant = Instant.ofEpochMilli(tp.getReceiveTime());

View File

@ -1,58 +1,56 @@
server:
port: 9000
port: 9000
modbus-tcp:
port: 19000
port: 19000
udp:
serverPort: 20002
clientPort: 20001
serverPort: 20002
clientPort: 20001
yjddzh:
receiveTimeOver: 60
spring:
profiles:
active: dev
application:
name: joylink-rtss
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
# 后续转为MINIO后删除
servlet:
multipart:
max-file-size: 10MB
profiles:
active: dev
application:
name: joylink-rtss
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
servlet:
multipart:
max-file-size: 10MB
# JavaMailSender 邮件发送的配置
mail:
host: smtp.exmail.qq.com
port: 465
username: serviceemai@joylink.club
password: Jiulian0503
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
fallback: false
# 数据库连接配置
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5 # 连接池维护的最小空闲连接数
maximum-pool-size: 10 #配置最大连接池大小
auto-commit: true #配置从池返回的连接的默认自动提交行为
idle-timeout: 30000 # 允许连接在连接池中空闲的最长时间单位ms
pool-name: HikariPool
max-lifetime: 1800000 # 池中连接关闭后的最长生命周期单位ms
connection-timeout: 30000 # 等待连接的超时时间单位ms
# mybatis 设置
mail:
host: smtp.exmail.qq.com
port: 465
username: serviceemai@joylink.club
password: Jiulian0503
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
fallback: false
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5 # 连接池维护的最小空闲连接数
maximum-pool-size: 10 #配置最大连接池大小
auto-commit: true #配置从池返回的连接的默认自动提交行为
idle-timeout: 30000 # 允许连接在连接池中空闲的最长时间单位ms
pool-name: HikariPool
max-lifetime: 1800000 # 池中连接关闭后的最长生命周期单位ms
connection-timeout: 30000 # 等待连接的超时时间单位ms
mybatis:
mapper-locations: classpath:mybatis/mapper/**/*.xml
type-aliases-package: club.joylink.rtss.entity
configuration:
map-underscore-to-camel-case: true
pagehelper:
@ -63,14 +61,22 @@ pagehelper:
# 微信配置
wechat:
domain-uri: https://api.weixin.qq.com
wm-base-url: https://joylink.club/oss/joylink/%s?state=%s
sp-app-id: wxe9150dbbcbf9440b
sp-app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
sp-app2-id: wxecb0321367be529c
sp-app2-secret: 3c31cb41588f27a78160092249123766
sp-app3-id: wxe6140d5985333338
sp-app3-secret: 6b7359860c22e3607467df421cd24eef
app-id: wx41cb66db5faf330f
app-secret: eb7199c1e73417be6a4d38b4a848effb
domain-uri: https://api.weixin.qq.com
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=http://joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
sp-app-id: wxe9150dbbcbf9440b
sp-app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
sp-app2-id: wxecb0321367be529c
sp-app2-secret: 3c31cb41588f27a78160092249123766
sp-app3-id: wxe6140d5985333338
sp-app3-secret: 6b7359860c22e3607467df421cd24eef
wm-base-url: https://joylink.club/oss/joylink/%s?state=%s
wx-module-url: http://localhost:9001
mini:
access-token-task-on: false
app-id: wxe9150dbbcbf9440b
app-secret: 4b5d453e5ec246a3f1b72360c59e4fab
# 腾讯云
tencent-cloud:
@ -82,11 +88,11 @@ tencent-cloud:
# 环境连接配置 start
---
spring:
profiles: dev
datasource:
url: jdbc:mysql://192.168.3.233:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: joylink0503
profiles: dev
datasource:
url: jdbc:mysql://localhost:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: root
tencent-cloud:
allow-send: false
@ -111,14 +117,17 @@ common:
---
spring:
profiles: local-test
datasource:
url: jdbc:mysql://192.168.53.22:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: joylink0503
profiles: test
datasource:
url: jdbc:mysql://172.16.0.128:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: Joylink@0503
wechat:
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://test.joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
wx-module-url: https://joylink.club/jlwxs
tencent-cloud:
allow-send: false
allow-send: false
logging:
file:
@ -139,12 +148,15 @@ common:
---
spring:
profiles: local
profiles: local-test
datasource:
url: jdbc:mysql://192.168.0.254:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
url: jdbc:mysql://192.168.53.22:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: localdb
password: joylink0503
wechat:
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://test.joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
wx-module-url: https://joylink.club/jlwxs
tencent-cloud:
allow-send: false
@ -163,19 +175,25 @@ minio:
common:
env: local
license-secret-key: joylink
env: test
---
spring:
profiles: test
datasource:
url: jdbc:mysql://172.16.0.128:3306/joylink?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: Joylink@0503
profiles: prd
datasource:
url: jdbc:mysql://192.168.0.169:3306/joylink?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: joylink@0503
wechat:
app-id: wx41cb66db5faf330f
app-secret: eb7199c1e73417be6a4d38b4a848effb
wx-api-url: https://open.weixin.qq.com/connect/oauth2/authorize?appid=${wechat.app-id}&redirect_uri=https://joylink.club/wx/%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect
wx-module-url: http://172.21.0.4:9001
mini:
access-token-task-on: true
tencent-cloud:
allow-send: false
file:
path: https://joylink.club/jlfile/api/upload/joylink/avatar
logging:
file:
@ -195,11 +213,11 @@ common:
---
spring:
profiles: prd
profiles: local
datasource:
url: jdbc:mysql://192.168.0.169:3306/joylink?useSSL=false&serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.0.254:3306/joylink?useSSL=false&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: joylink@0503
password: localdb
file:
path: https://joylink.club/jlfile/api/upload/joylink/avatar