Merge branch 'test-training2' of https://git.code.tencent.com/lian-cbtc/rtss-server into test-training2-zhouyin
This commit is contained in:
commit
4d991d82ab
20
pom.xml
20
pom.xml
@ -102,13 +102,13 @@
|
||||
<version>0.2.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.huawei.sis</groupId>
|
||||
<artifactId>huaweicloud-java-sdk-sis</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/libs/huaweicloud-java-sdk-sis-1.3.2.jar</systemPath>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.huawei.sis</groupId>-->
|
||||
<!-- <artifactId>huaweicloud-java-sdk-sis</artifactId>-->
|
||||
<!-- <version>1.3.2</version>-->
|
||||
<!-- <scope>system</scope>-->
|
||||
<!-- <systemPath>${project.basedir}/libs/huaweicloud-java-sdk-sis-1.3.2.jar</systemPath>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.huawei.apigateway</groupId>
|
||||
@ -129,7 +129,11 @@
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.10.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
3
sql/20220825-zhouyin.sql
Normal file
3
sql/20220825-zhouyin.sql
Normal file
@ -0,0 +1,3 @@
|
||||
-- 出入口方向添加方向属性,需要重新编辑地图中出入口方向的属性
|
||||
ALTER TABLE `draft_map_station_direction_label`
|
||||
ADD COLUMN `io_direction` varchar(20) NULL COMMENT '出入口方向';
|
48
sql/20220830-xia-draft_training2.sql
Normal file
48
sql/20220830-xia-draft_training2.sql
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : walker
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80029
|
||||
Source Host : 192.168.3.233:3306
|
||||
Source Schema : joylink
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80029
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 30/08/2022 16:02:15
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for draft_training2
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `draft_training2`;
|
||||
CREATE TABLE `draft_training2` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训名称',
|
||||
`map_id` bigint NULL DEFAULT NULL COMMENT '实训地图id',
|
||||
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
|
||||
`type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训类型(单操 single;场景scene)',
|
||||
`label_json` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标签,用于检索',
|
||||
`map_location_json` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '地图定位json',
|
||||
`bg_scene_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '初始背景',
|
||||
`final_scenes_json` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '实训编制完保存为最终场景json数据',
|
||||
`run_plan_id` bigint NULL DEFAULT NULL COMMENT '运行图id',
|
||||
`opera_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '操作列表json(List<Operation2VO>)',
|
||||
`step_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '步骤列表json(List<Step2VO>的json)',
|
||||
`scoring_rule_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '打分规则列表json(List<ScoringRuleVO>的json)',
|
||||
`member_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '仿真内所有成员',
|
||||
`player_id_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '参演的仿真成员id列表Json',
|
||||
`failure_condition_json` varchar(555) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训失败判定条件',
|
||||
`creator_id` bigint NULL DEFAULT NULL,
|
||||
`create_time` datetime NULL DEFAULT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `map_id_index`(`map_id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
48
sql/20220830-xia-published_training2.sql
Normal file
48
sql/20220830-xia-published_training2.sql
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : walker
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80029
|
||||
Source Host : 192.168.3.233:3306
|
||||
Source Schema : joylink
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80029
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 30/08/2022 16:02:51
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for published_training2
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `published_training2`;
|
||||
CREATE TABLE `published_training2` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '已发布实训的id',
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训名称',
|
||||
`map_id` bigint NULL DEFAULT NULL COMMENT '实训地图id',
|
||||
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训描述',
|
||||
`type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训类型(单操 single;场景scene)',
|
||||
`label_json` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '标签,用于检索',
|
||||
`map_location_json` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '地图定位json',
|
||||
`bg_scene_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '初始背景',
|
||||
`run_plan_id` bigint NULL DEFAULT NULL COMMENT '运行图id',
|
||||
`opera_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '操作列表json(List<Operation2VO>)',
|
||||
`step_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '步骤列表json(List<Step2VO>的json)',
|
||||
`scoring_rule_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '打分规则列表json(List<ScoringRuleVO>的json)',
|
||||
`member_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '仿真内所有成员',
|
||||
`player_id_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '参演的仿真成员id列表Json',
|
||||
`failure_condition_json` varchar(555) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '实训失败判定条件',
|
||||
`creator_id` bigint NULL DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime NULL DEFAULT NULL,
|
||||
`update_time` datetime NULL DEFAULT NULL,
|
||||
`state` int NULL DEFAULT NULL COMMENT '已发布实训的状态(0-默认未知,1-上架,2-下架)',
|
||||
`final_scenes_json` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '实训编制后的最终场景json数据',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
@ -61,4 +61,18 @@ public class TaskExecutorConfiguration {
|
||||
return taskExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新实训监控
|
||||
*/
|
||||
@Bean("trainingV2Executor")
|
||||
public TaskExecutor trainExecutor(Environment env) {
|
||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||
taskExecutor.setThreadNamePrefix("ns-training-v2-executor-");
|
||||
taskExecutor.setCorePoolSize(2);
|
||||
taskExecutor.setMaxPoolSize(2);
|
||||
taskExecutor.setQueueCapacity(100);
|
||||
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
taskExecutor.initialize();
|
||||
return taskExecutor;
|
||||
}
|
||||
}
|
||||
|
@ -4,25 +4,31 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum MapPrdTypeEnum {
|
||||
LOCAL("01", "ATS现地工作站"),
|
||||
CENTER("02", "ATS行调工作站"),
|
||||
JOINT("03", "综合演练云平台"),
|
||||
DRIVER("04", "司机模拟驾驶系统"),
|
||||
SCHEDULING("05", "派班工作站"),
|
||||
ISCS("06", "ISCS工作站"),
|
||||
BIG_SCREEN("07", "大屏工作站"),
|
||||
RUN_PLAN_MAKE("08", "运行图编制工作站"),
|
||||
DEPOT_IL("09", "车辆段联锁工作站"),
|
||||
CTC("10", "CTC工作站")
|
||||
LOCAL("01", "ATS现地工作站", "车站"),
|
||||
CENTER("02", "ATS行调工作站", "调度台"),
|
||||
JOINT("03", "综合演练云平台", "综合演练云平台"),
|
||||
DRIVER("04", "司机模拟驾驶系统", null),
|
||||
SCHEDULING("05", "派班工作站", null),
|
||||
ISCS("06", "ISCS工作站", null),
|
||||
BIG_SCREEN("07", "大屏工作站", null),
|
||||
RUN_PLAN_MAKE("08", "运行图编制工作站", null),
|
||||
DEPOT_IL("09", "车辆段联锁工作站", null),
|
||||
// CTC("10", "CTC工作站")
|
||||
;
|
||||
|
||||
private String code;
|
||||
|
||||
private String msg;
|
||||
|
||||
MapPrdTypeEnum(String code, String msg) {
|
||||
/**
|
||||
* 大铁子系统名称
|
||||
*/
|
||||
private String railName;
|
||||
|
||||
MapPrdTypeEnum(String code, String msg, String railName) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
this.railName = railName;
|
||||
}
|
||||
|
||||
public static MapPrdTypeEnum getMapPrdTypeEnumByCode(String code) {
|
||||
|
@ -60,6 +60,8 @@ public enum Project {
|
||||
RICHOR_CXJS,
|
||||
/** 哈盈达-铁路 */
|
||||
HYD_RAILWAY,
|
||||
/** 武汉8号线 */
|
||||
WH
|
||||
;
|
||||
|
||||
public static boolean isDefault(Project project) {
|
||||
|
@ -0,0 +1,97 @@
|
||||
package club.joylink.rtss.controller.simulation;
|
||||
|
||||
import club.joylink.rtss.controller.advice.AuthenticateInterceptor;
|
||||
import club.joylink.rtss.services.training2.Training2Service;
|
||||
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.LoginUserInfoVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 第二版实训应用接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/training2Simulation")
|
||||
public class SimulationTrainingV2Controller {
|
||||
|
||||
@Autowired
|
||||
private Training2Service training2Service;
|
||||
|
||||
/**
|
||||
* 在仿真中演练发布的实训
|
||||
*/
|
||||
@PostMapping("/{group}/load/{trainingId}")
|
||||
public void trainingLoad(@PathVariable String group, @PathVariable Long trainingId
|
||||
, @RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO) {
|
||||
training2Service.trainingLoad(group, trainingId, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在仿真中演练草稿实训
|
||||
*/
|
||||
@PostMapping("/{group}/load/draft/{trainingId}")
|
||||
public void trainingDraftLoad(@PathVariable String group, @PathVariable Long trainingId
|
||||
, @RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO) {
|
||||
training2Service.trainingDraftLoad(group, trainingId, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览实训信息
|
||||
*/
|
||||
@GetMapping("/preview/draft/{trainingId}")
|
||||
public String previewDraft(@PathVariable Long trainingId
|
||||
, @RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO) {
|
||||
return training2Service.previewDraft(trainingId, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览实训信息
|
||||
*/
|
||||
@GetMapping("/preview/{trainingId}")
|
||||
public String preview(@PathVariable Long trainingId
|
||||
, @RequestAttribute(name = AuthenticateInterceptor.LOGIN_INFO_KEY) LoginUserInfoVO loginUserInfoVO) {
|
||||
return training2Service.preview(trainingId, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览实训信息
|
||||
*/
|
||||
@PutMapping("/{group}/start")
|
||||
public void startTraining2(@PathVariable String group, ScriptBO.Mode mode, @RequestAttribute AccountVO user) {
|
||||
training2Service.startTraining2(group, mode, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束实训
|
||||
*/
|
||||
@PutMapping("/{group}/finish")
|
||||
public Float finishTraining2(@PathVariable String group, @RequestAttribute AccountVO user) {
|
||||
return training2Service.finishTraining2(group, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端步骤完成后操作回调
|
||||
*/
|
||||
@PutMapping("/{group}/completion/step/{stepId}")
|
||||
public Integer completionClientStep(@PathVariable String group, @PathVariable Integer stepId, @RequestAttribute AccountVO user) {
|
||||
return training2Service.completionClientStep(group, stepId, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端步骤完成后操作回调
|
||||
*/
|
||||
@PutMapping("/{group}/completion/step/{stepId}/operation/{id}")
|
||||
public Integer completionClientStepOperation(@PathVariable String group, @PathVariable Integer stepId
|
||||
, @PathVariable Integer id, @RequestAttribute AccountVO user) {
|
||||
return training2Service.completionClientStepOperation(group, stepId, id, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制剧本
|
||||
*/
|
||||
@PostMapping("/{group}/draw/{trainingId}")
|
||||
public void drawTraining(@PathVariable String group, @PathVariable Long trainingId) {
|
||||
training2Service.drawTraining(group, trainingId);
|
||||
}
|
||||
}
|
@ -0,0 +1,170 @@
|
||||
package club.joylink.rtss.controller.training2;
|
||||
|
||||
import club.joylink.rtss.services.training2.Training2DraftService;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.collector.ExpConditionMaterialCollector;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.vo.ExpConditionMaterialSrcVo;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.client.simulationv1.SimulationMemberVO;
|
||||
import club.joylink.rtss.vo.client.training2.ScoringRuleVO;
|
||||
import club.joylink.rtss.vo.client.training2.Step2VO;
|
||||
import club.joylink.rtss.vo.training2.draft.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 实训草稿管理接口
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v2/draft/training")
|
||||
public class TrainingDraftV2Controller {
|
||||
@Autowired
|
||||
private Training2DraftService training2DraftService;
|
||||
@Autowired
|
||||
private ExpConditionMaterialCollector collector;
|
||||
|
||||
/**
|
||||
* 创建实训草稿
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public CreateTraining2RspVo create(@RequestBody CreateTraining2ReqVo req, @RequestAttribute AccountVO user) {
|
||||
log.debug("==>>创建实训草稿: mapId = {} , name = {} type = {} des = {}", req.getMapId(), req.getName(), req.getType(), req.getDescription());
|
||||
return this.training2DraftService.createTraining(req, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除当前用户的实训草稿
|
||||
*/
|
||||
@DeleteMapping
|
||||
public DeleteTraining2RspVo deleteTrainings(@RequestBody DeleteTraining2ReqVo req, @RequestAttribute AccountVO user) {
|
||||
return this.training2DraftService.deleteTrainings(req, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页获取当前用户实训草稿基础信息
|
||||
*/
|
||||
@PostMapping("/info/page")
|
||||
public PageVO<DraftTraining2InfoVo> findTrainingsInfoByPage(@RequestBody DraftTraining2InfoPageReqVo req, @RequestAttribute AccountVO user) {
|
||||
return this.training2DraftService.findTrainingsInfoByPage(req, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前用户的某个实训草稿(大字段信息)
|
||||
*/
|
||||
@PostMapping("/update/content")
|
||||
public void updateTraining(@RequestBody UpdateDraftTraining2BlobReqVo req, @RequestAttribute AccountVO user) {
|
||||
this.training2DraftService.updateTrainingBlob(req, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独更新当前用户的某个实训草稿的初始背景
|
||||
* <p>
|
||||
* 背景内容由后端自己生成
|
||||
*/
|
||||
@PostMapping("/update/content/background")
|
||||
public void updateTrainingBackground(@RequestBody UpdateTraining2BackgroudReqVo req, @RequestAttribute AccountVO user) {
|
||||
this.training2DraftService.updateTrainingBackground(req, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 单独重置当前用户的某个实训草稿的初始背景
|
||||
*/
|
||||
@PostMapping("/reset/content/background")
|
||||
public void resetTrainingBackground(@RequestBody ResetTraining2BackgroudReqVo req, @RequestAttribute AccountVO user) {
|
||||
this.training2DraftService.resetTrainingBackground(req, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前用户实训草稿定位
|
||||
*/
|
||||
@PostMapping("/update/content/maplocation")
|
||||
public void updateTrainingMapLocation(@RequestBody UpdateTraining2MapLocationReqVo req, @RequestAttribute AccountVO user) {
|
||||
this.training2DraftService.updateTrainingMapLocation(req, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实训表达式条件素材
|
||||
*/
|
||||
@GetMapping("/expression/materials")
|
||||
public List<ExpConditionMaterialSrcVo> findTrainingExpressionMaterials() {
|
||||
return collector.doCollect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前用户的某个实训草稿的基础信息
|
||||
*/
|
||||
@PostMapping("/update/info")
|
||||
public void updateTrainingInfo(@RequestBody UpdateDraftTraining2InfoReqVo req, @RequestAttribute AccountVO user) {
|
||||
this.training2DraftService.updateTrainingInfo(req, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的某个实训草稿的所有信息
|
||||
*/
|
||||
@GetMapping("/all/{trainingId}")
|
||||
public DraftTraining2DetailRspVo findTrainingDetail(@NotNull(message = "实训草稿id不能为空") @PathVariable("trainingId") Long trainingDraftId, @RequestAttribute AccountVO user) {
|
||||
return this.training2DraftService.findTrainingDetail(trainingDraftId, user.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询步骤列表
|
||||
*/
|
||||
@GetMapping("/{trainingId}/step/list")
|
||||
public List<Step2VO> stepList(@PathVariable("trainingId") Long trainingId) {
|
||||
return training2DraftService.stepList(trainingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改实训所有步骤
|
||||
*/
|
||||
@PutMapping("/{group}/{trainingId}/step/update")
|
||||
public void updateSteps(@PathVariable("group") String group, @PathVariable("trainingId") Long trainingId
|
||||
, @RequestBody List<Step2VO> step2VOList) {
|
||||
training2DraftService.updateSteps(group, trainingId, step2VOList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空步骤
|
||||
*/
|
||||
@DeleteMapping("/{trainingId}/step/clear")
|
||||
public void clearStep(@PathVariable("trainingId") Long trainingId) {
|
||||
training2DraftService.clearStep(trainingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有评分规则
|
||||
*/
|
||||
@GetMapping("/{trainingId}/scoringRule/list")
|
||||
public List<ScoringRuleVO> getScoringRuleVOS(@PathVariable Long trainingId) {
|
||||
return training2DraftService.getScoringRules(trainingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有评分规则
|
||||
*/
|
||||
@PutMapping("/{trainingId}/scoringRule/list")
|
||||
public void updateScoringRules(@PathVariable Long trainingId, @RequestBody List<ScoringRuleVO> scoringRuleVOS) {
|
||||
training2DraftService.updateScoringRules(trainingId, scoringRuleVOS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实训所有成员
|
||||
*/
|
||||
@GetMapping("/{trainingId}/member/list")
|
||||
public List<SimulationMemberVO> getMembers(@PathVariable Long trainingId) {
|
||||
return training2DraftService.getMembers(trainingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实训所有参与者
|
||||
*/
|
||||
@GetMapping("/{trainingId}/player/list")
|
||||
public List<SimulationMemberVO> getPlayers(@PathVariable Long trainingId) {
|
||||
return training2DraftService.getPlayers(trainingId);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package club.joylink.rtss.controller.training2;
|
||||
|
||||
import club.joylink.rtss.services.training2.Training2DraftPublishService;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.training2.draft.TrainingDraftPublishReqVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 实训草稿发布管理接口
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v2/draft/training/publish")
|
||||
public class TrainingDraftV2PublishController {
|
||||
@Autowired
|
||||
private Training2DraftPublishService publishService;
|
||||
/**
|
||||
* 当前用户发布自己的实训草稿
|
||||
*/
|
||||
@PostMapping
|
||||
public void draftPublish(@RequestBody TrainingDraftPublishReqVo req, @RequestAttribute AccountVO user){
|
||||
this.publishService.draftPublish(req,user.getId());
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package club.joylink.rtss.controller.training2;
|
||||
|
||||
import club.joylink.rtss.services.training2.Training2PublishService;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.training2.publish.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 已发布实训管理接口
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v2/training/published")
|
||||
public class TrainingV2PublishController {
|
||||
@Autowired
|
||||
private Training2PublishService publishService;
|
||||
|
||||
/**
|
||||
* 已发布实训分页列表
|
||||
*/
|
||||
@PostMapping("/page")
|
||||
public PageVO<PublishedTraining2InfoRspVo> publishedTrainingsPage(@RequestBody PublishedTraining2InfoPageReqVo req){
|
||||
return this.publishService.publishedTrainingsPage(req);
|
||||
}
|
||||
/**
|
||||
* 已发布实训上架
|
||||
*/
|
||||
@PostMapping("/put/on")
|
||||
public PutOnPublishedTraining2RspVo putOnPublishedTrainings(@RequestBody PutOnPublishedTraining2ReqVo req){
|
||||
return this.publishService.putOnPublishedTrainings(req);
|
||||
}
|
||||
/**
|
||||
* 已发布实训下架
|
||||
*/
|
||||
@PostMapping("/pull/off")
|
||||
public PullOffPublishedTraining2RspVo pullOffPublishedTrainings(@RequestBody PullOffPublishedTraining2ReqVo req){
|
||||
return this.publishService.pullOffPublishedTrainings(req);
|
||||
}
|
||||
/**
|
||||
* 删除已发布实训
|
||||
*/
|
||||
@DeleteMapping
|
||||
public DeletePublishedTraining2RspVo deletePublishedTrainings(@RequestBody DeletePublishedTraining2ReqVo req){
|
||||
return this.publishService.deletePublishedTrainings(req);
|
||||
}
|
||||
/**
|
||||
* 根据mapId查所有的已发布单操实训的基础信息
|
||||
*/
|
||||
@GetMapping("/{mapId}/singles")
|
||||
public List<PublishedTraining2InfoRspVo> findAllSingleTrainingBasicInfo(@PathVariable("mapId") Long mapId){
|
||||
return this.publishService.findAllSingleTrainingBasicInfoByMapId(mapId);
|
||||
}
|
||||
/**
|
||||
* 根据mapId查所有的已发布场景实训的基础信息
|
||||
*/
|
||||
@GetMapping("/{mapId}/scenes")
|
||||
public List<PublishedTraining2InfoRspVo> findAllSceneTrainingBasicInfo(@PathVariable("mapId") Long mapId){
|
||||
return this.publishService.findAllSceneTrainingBasicInfoByMapId(mapId);
|
||||
}
|
||||
/**
|
||||
* 根据实训id查该已发布实训的所有信息
|
||||
*/
|
||||
@GetMapping("/{trainingId}")
|
||||
public PublishedTraining2DetailRspVo findTrainingAllInfo(@PathVariable("trainingId") Long trainingId){
|
||||
return this.publishService.findTrainingAllInfoById(trainingId);
|
||||
}
|
||||
}
|
42
src/main/java/club/joylink/rtss/dao/DraftTraining2DAO.java
Normal file
42
src/main/java/club/joylink/rtss/dao/DraftTraining2DAO.java
Normal file
@ -0,0 +1,42 @@
|
||||
package club.joylink.rtss.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2Example;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface DraftTraining2DAO {
|
||||
long countByExample(DraftTraining2Example example);
|
||||
|
||||
int deleteByExample(DraftTraining2Example example);
|
||||
|
||||
int deleteByPrimaryKey(Long id);
|
||||
|
||||
int insert(DraftTraining2WithBLOBs record);
|
||||
|
||||
int insertSelective(DraftTraining2WithBLOBs record);
|
||||
|
||||
List<DraftTraining2WithBLOBs> selectByExampleWithBLOBs(DraftTraining2Example example);
|
||||
|
||||
List<DraftTraining2> selectByExample(DraftTraining2Example example);
|
||||
|
||||
DraftTraining2WithBLOBs selectByPrimaryKey(Long id);
|
||||
|
||||
int updateByExampleSelective(@Param("record") DraftTraining2WithBLOBs record, @Param("example") DraftTraining2Example example);
|
||||
|
||||
int updateByExampleWithBLOBs(@Param("record") DraftTraining2WithBLOBs record, @Param("example") DraftTraining2Example example);
|
||||
|
||||
int updateByExample(@Param("record") DraftTraining2 record, @Param("example") DraftTraining2Example example);
|
||||
|
||||
int updateByPrimaryKeySelective(DraftTraining2WithBLOBs record);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(DraftTraining2WithBLOBs record);
|
||||
|
||||
int updateByPrimaryKey(DraftTraining2 record);
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package club.joylink.rtss.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2Example;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2WithBLOBs;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface PublishedTraining2DAO {
|
||||
long countByExample(PublishedTraining2Example example);
|
||||
|
||||
int deleteByExample(PublishedTraining2Example example);
|
||||
|
||||
int deleteByPrimaryKey(Long id);
|
||||
|
||||
int insert(PublishedTraining2WithBLOBs record);
|
||||
|
||||
int insertSelective(PublishedTraining2WithBLOBs record);
|
||||
|
||||
List<PublishedTraining2WithBLOBs> selectByExampleWithBLOBs(PublishedTraining2Example example);
|
||||
|
||||
List<PublishedTraining2> selectByExample(PublishedTraining2Example example);
|
||||
|
||||
PublishedTraining2WithBLOBs selectByPrimaryKey(Long id);
|
||||
|
||||
int updateByExampleSelective(@Param("record") PublishedTraining2WithBLOBs record, @Param("example") PublishedTraining2Example example);
|
||||
|
||||
int updateByExampleWithBLOBs(@Param("record") PublishedTraining2WithBLOBs record, @Param("example") PublishedTraining2Example example);
|
||||
|
||||
int updateByExample(@Param("record") PublishedTraining2 record, @Param("example") PublishedTraining2Example example);
|
||||
|
||||
int updateByPrimaryKeySelective(PublishedTraining2WithBLOBs record);
|
||||
|
||||
int updateByPrimaryKeyWithBLOBs(PublishedTraining2WithBLOBs record);
|
||||
|
||||
int updateByPrimaryKey(PublishedTraining2 record);
|
||||
}
|
@ -90,6 +90,11 @@ public class DraftMapStationDirection implements Serializable {
|
||||
* 相对方向
|
||||
*/
|
||||
private String relativeLabelEnum;
|
||||
/**
|
||||
* 出入口方向
|
||||
*/
|
||||
private StationDirection.IODirection ioDirection;
|
||||
|
||||
|
||||
public void generateSectionList() {
|
||||
if (StringUtils.isEmpty(sectionsCode)) {
|
||||
|
@ -0,0 +1,62 @@
|
||||
package club.joylink.rtss.entity.training2;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class DraftTraining2 implements Serializable {
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 实训名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 实训地图id
|
||||
*/
|
||||
private Long mapId;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 实训类型(单操 single;场景scene)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 标签,用于检索
|
||||
*/
|
||||
private String labelJson;
|
||||
|
||||
/**
|
||||
* 地图定位json
|
||||
*/
|
||||
private String mapLocationJson;
|
||||
|
||||
/**
|
||||
* 运行图id
|
||||
*/
|
||||
private Long runPlanId;
|
||||
|
||||
/**
|
||||
* 实训失败判定条件
|
||||
*/
|
||||
private String failureConditionJson;
|
||||
|
||||
private Long creatorId;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
package club.joylink.rtss.entity.training2;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class DraftTraining2WithBLOBs extends DraftTraining2 implements Serializable {
|
||||
/**
|
||||
* 初始背景
|
||||
*/
|
||||
private String bgSceneJson;
|
||||
|
||||
/**
|
||||
* 实训编制完保存为最终场景json数据
|
||||
*/
|
||||
private String finalScenesJson;
|
||||
|
||||
/**
|
||||
* 操作列表json(List<Operation2VO>)
|
||||
*/
|
||||
private String operaJson;
|
||||
|
||||
/**
|
||||
* 步骤列表json(List<Step2VO>的json)
|
||||
*/
|
||||
private String stepJson;
|
||||
|
||||
/**
|
||||
* 打分规则列表json(List<ScoringRuleVO>的json)
|
||||
*/
|
||||
private String scoringRuleJson;
|
||||
|
||||
/**
|
||||
* 仿真内所有成员
|
||||
*/
|
||||
private String memberJson;
|
||||
|
||||
/**
|
||||
* 参演的仿真成员id列表Json
|
||||
*/
|
||||
private String playerIdJson;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -1,24 +1,37 @@
|
||||
package club.joylink.rtss.entity.training2;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Data;
|
||||
|
||||
public class Training2 {
|
||||
/**
|
||||
* @author
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class PublishedTraining2 implements Serializable {
|
||||
/**
|
||||
* 已发布实训的id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
private Long mapId;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
* 实训名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
* 实训地图id
|
||||
*/
|
||||
private Long mapId;
|
||||
|
||||
/**
|
||||
* 实训描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 实训类型(单操、场景)
|
||||
* 实训类型(单操 single;场景scene)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
@ -33,50 +46,28 @@ public class Training2 {
|
||||
private String mapLocationJson;
|
||||
|
||||
/**
|
||||
* 初始背景
|
||||
* 运行图id
|
||||
*/
|
||||
private String bgSceneJson;
|
||||
private Long runPlanId;
|
||||
|
||||
/**
|
||||
* List<Opera> 的json
|
||||
* 实训失败判定条件
|
||||
*/
|
||||
private String operasJson;
|
||||
private String failureConditionJson;
|
||||
|
||||
/**
|
||||
* List<Step2> 的json
|
||||
* 创建者
|
||||
*/
|
||||
private String stepsJson;
|
||||
|
||||
/**
|
||||
* 评分规则json
|
||||
*/
|
||||
private String scoringRuleJson;
|
||||
|
||||
/**
|
||||
* 保存数据时的背景
|
||||
*/
|
||||
private String saveSceneJson;
|
||||
|
||||
/**
|
||||
* 仿真内所有成员
|
||||
*/
|
||||
private String memberJson;
|
||||
|
||||
/**
|
||||
* 参演的仿真成员
|
||||
*/
|
||||
private String playerJson;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private String status;
|
||||
|
||||
private Long creatorId;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private Long updaterId;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 已发布实训的状态(0-默认未知,1-上架,2-下架)
|
||||
*/
|
||||
private Integer state;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
package club.joylink.rtss.entity.training2;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class PublishedTraining2WithBLOBs extends PublishedTraining2 implements Serializable {
|
||||
/**
|
||||
* 初始背景
|
||||
*/
|
||||
private String bgSceneJson;
|
||||
|
||||
/**
|
||||
* 操作列表json(List<Operation2VO>)
|
||||
*/
|
||||
private String operaJson;
|
||||
|
||||
/**
|
||||
* 步骤列表json(List<Step2VO>的json)
|
||||
*/
|
||||
private String stepJson;
|
||||
|
||||
/**
|
||||
* 打分规则列表json(List<ScoringRuleVO>的json)
|
||||
*/
|
||||
private String scoringRuleJson;
|
||||
|
||||
/**
|
||||
* 仿真内所有成员
|
||||
*/
|
||||
private String memberJson;
|
||||
|
||||
/**
|
||||
* 参演的仿真成员id列表Json
|
||||
*/
|
||||
private String playerIdJson;
|
||||
|
||||
/**
|
||||
* 实训编制后的最终场景json数据
|
||||
*/
|
||||
private String finalScenesJson;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -35,6 +35,7 @@ public enum BusinessExceptionAssertEnum implements BusinessExceptionAssert {
|
||||
|
||||
|
||||
DATA_ERROR(11000, "data error"),
|
||||
REPEAT_RUN_PLAN_FROM_CTC_UPDATE_DATA(11200,"repeat run plan"),
|
||||
CI_GENERATE_ERROR(11001, "ci data generate error"),
|
||||
MAP_PASSENGER_FLOW_DATA_ERROR(11002, "map passenger flow data error"),
|
||||
DATA_UNIQUE_PROPERTY_REPEAT(11013, "data unique property repeat"),
|
||||
|
@ -64,20 +64,18 @@ public class MapSystemService implements IMapSystemService {
|
||||
public void generateSystem(Long mapId) {
|
||||
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(iMapService.isExist(mapId),
|
||||
String.format("id为[%s]的地图不存在", mapId));
|
||||
MapVO mapDetail = iMapService.getMapDetail(mapId);
|
||||
for (MapPrdTypeEnum value : MapPrdTypeEnum.values()) {
|
||||
if (MapPrdTypeEnum.CTC.equals(value)) {
|
||||
MapVO mapDetail = iMapService.getMapDetail(mapId);
|
||||
if (!mapDetail.getConfigVO().isRailway()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
generate(mapId, value);
|
||||
boolean railway = mapDetail.getConfigVO().isRailway();
|
||||
if (railway && value.getRailName() == null)
|
||||
continue;
|
||||
generate(mapId, value, railway);
|
||||
}
|
||||
}
|
||||
|
||||
private void generate(Long mapId, MapPrdTypeEnum value) {
|
||||
private void generate(Long mapId, MapPrdTypeEnum value, boolean railway) {
|
||||
MapSystem system = new MapSystem();
|
||||
system.setName(value.getMsg());
|
||||
system.setName(railway ? value.getRailName() : value.getMsg());
|
||||
system.setMapId(mapId);
|
||||
system.setPrdType(value.getCode());
|
||||
system.setStatus(StatusEnum.Valid.getCode());
|
||||
@ -108,7 +106,12 @@ public class MapSystemService implements IMapSystemService {
|
||||
String.format("id为[%s]的地图不存在", mapId));
|
||||
MapPrdTypeEnum prdTypeEnum = MapPrdTypeEnum.getMapPrdTypeEnumByCode(prdType);
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertNotNull(prdTypeEnum);
|
||||
generate(mapId, prdTypeEnum);
|
||||
MapVO mapDetail = iMapService.getMapDetail(mapId);
|
||||
boolean railway = mapDetail.getConfigVO().isRailway();
|
||||
if (railway && prdTypeEnum.getRailName() == null) {
|
||||
return;
|
||||
}
|
||||
generate(mapId, prdTypeEnum, railway);
|
||||
}
|
||||
|
||||
private boolean isExist(Long mapId, String prdType, String type) {
|
||||
|
@ -20,6 +20,7 @@ import club.joylink.rtss.vo.map.graph.MapSignalButtonVO;
|
||||
import club.joylink.rtss.vo.map.logic.MapRouteNewVO;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -132,6 +133,7 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
update.setOverrunList(routeNewVO.getOverrunList());
|
||||
update.setHoldStandList(routeNewVO.getHoldStandList());
|
||||
update.setType(routeNewVO.getType());
|
||||
update.setLeaveSectionWithAspectMap(routeNewVO.getLeaveSectionWithAspectMap());
|
||||
DraftMapRoute db = update.convert2Draft();
|
||||
this.draftMapRouteDAO.updateByPrimaryKeyWithBLOBs(db);
|
||||
}
|
||||
@ -258,7 +260,9 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
signalMap.values().stream()
|
||||
.filter(Signal::hasShuntingFunction)
|
||||
.forEach(signal -> {
|
||||
generateShuntingRoute(signal, new ArrayList<>(), new ArrayList<>(), routeMap, routeCodeGenerator, routeVOMap, 0);
|
||||
Assistant assistant = new Assistant(signal, routeCodeGenerator, routeMap, routeVOMap);
|
||||
assistant.btnCodes.add(signal.getCode());
|
||||
generateShuntingRoute(assistant, 0);
|
||||
});
|
||||
long passStart = System.currentTimeMillis();
|
||||
System.out.println("生成调车进路耗时:" + (passStart - dioStart));
|
||||
@ -274,6 +278,18 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
}
|
||||
}
|
||||
System.out.println("生成通过进路耗时:" + (System.currentTimeMillis() - passStart));
|
||||
/* 长调车进路 */
|
||||
Map<String, List<Route>> startSignalCode_routes_map = routeMap.values().stream()
|
||||
.filter(route -> Route.Type.SHUNTING.equals(route.getType()))
|
||||
.collect(Collectors.groupingBy(route -> route.getStart().getCode()));
|
||||
startSignalCode_routes_map.values().forEach(routes -> {
|
||||
routes.forEach(route -> {
|
||||
Assistant assistant = new Assistant(route.getStart(), routeCodeGenerator, routeMap, routeVOMap);
|
||||
assistant.startSignalCode_routes_map = startSignalCode_routes_map;
|
||||
assistant.btnCodes.add(route.getStart().getCode());
|
||||
generateLongShuntingRoute(assistant, route);
|
||||
});
|
||||
});
|
||||
|
||||
routeVOMap.values().stream().map(MapRouteNewVO::convert2Draft).forEach(draftMapRoute -> {
|
||||
draftMapRoute.setMapId(mapId);
|
||||
@ -282,46 +298,101 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
return new ArrayList<>(routeVOMap.values());
|
||||
}
|
||||
|
||||
private void generateShuntingRoute(Signal signal, List<Section> sections, List<SwitchElement> switches,
|
||||
Map<String, Route> routeMap, DraftMapCiDataGeneratorImpl.CodeGenerator routeCodeGenerator,
|
||||
Map<String, MapRouteNewVO> routeVOMap, int iter) {
|
||||
boolean right = signal.isRight();
|
||||
/**
|
||||
* 生成长调车进路
|
||||
*/
|
||||
private void generateLongShuntingRoute(Assistant assistant, Route route) {
|
||||
Signal destination = route.getDestination();
|
||||
assistant.routes.add(route);
|
||||
if (assistant.routes.size() > 1) {
|
||||
String startSignalCode = assistant.startSignal.getCode();
|
||||
String endSignalCode = destination.getCode();
|
||||
String startEndSignalCode = startSignalCode + endSignalCode;
|
||||
if (assistant.routeVOMap.containsKey(startEndSignalCode)) {
|
||||
return;
|
||||
}
|
||||
String code = assistant.routeCodeGenerator.next();
|
||||
String name = "CD_" + assistant.startSignal.getShowName() + "-" + destination.getShowName();
|
||||
List<MapRouteAspectVO> aspectVOS = assistant.routes.stream()
|
||||
.map(r -> new MapRouteAspectVO(r.getCode(), getAspectIndex(route.getAspect())))
|
||||
.collect(Collectors.toList());
|
||||
MapRouteNewVO routeNewVO = assistant.routeVOMap.get(route.getStart().getCode() + route.getDestination().getCode());
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(routeNewVO);
|
||||
String endBtnCode = routeNewVO.getBtnCodeList().get(routeNewVO.getBtnCodeList().size() - 1);
|
||||
List<String> btnCodes = Arrays.asList(startSignalCode, endBtnCode);
|
||||
MapRouteNewVO mapRouteNewVO = MapRouteNewVO.buildMultiRoute(code, name, startSignalCode, aspectVOS, Route.Type.LONG_SHUNTING, btnCodes);
|
||||
assistant.routeVOMap.put(startEndSignalCode, mapRouteNewVO);
|
||||
}
|
||||
|
||||
if (destination.isRight() != route.isRight()) { //末端信号机同向
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, List<Route>> startSignalCode_route_map = assistant.startSignalCode_routes_map;
|
||||
List<Route> routes = startSignalCode_route_map.get(destination.getCode());
|
||||
if (CollectionUtils.isEmpty(routes)) {
|
||||
return;
|
||||
}
|
||||
for (Route value : routes) {
|
||||
generateLongShuntingRoute(assistant.clone(), value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成调车进路
|
||||
*/
|
||||
private void generateShuntingRoute(Assistant assistant, int iter) {
|
||||
Signal startSignal = assistant.startSignal;
|
||||
List<Section> sections = assistant.sections;
|
||||
List<SwitchElement> switches = assistant.switches;
|
||||
List<String> btnCodes = assistant.btnCodes;
|
||||
boolean right = startSignal.isRight();
|
||||
|
||||
Section section;
|
||||
if (CollectionUtils.isEmpty(sections)) {
|
||||
section = signal.getSection();
|
||||
section = startSignal.getSection();
|
||||
section = section.getNextSection(right);
|
||||
sections.add(section);
|
||||
} else {
|
||||
section = sections.get(sections.size() - 1);
|
||||
}
|
||||
Signal oppositeDirSignal = null;
|
||||
Signal destination = null;
|
||||
|
||||
while (section != null) {
|
||||
Signal sameDirSignal = section.getSignalOf(right);
|
||||
if (sameDirSignal != null) {
|
||||
Signal odSignal = section.getSignalOf(!right);
|
||||
if (odSignal != null) { //同向和反向信号机都有
|
||||
if (odSignal.isReceivingDepartureSignal()) { //反向信号机是接发车信号机
|
||||
destination = oppositeDirSignal;
|
||||
} else {
|
||||
destination = odSignal;
|
||||
Signal sdSignal = section.getSignalOf(right); //同向信号机
|
||||
Signal tempOdSignal = section.getSignalOf(!right); //反向信号机
|
||||
if (sdSignal != null) {
|
||||
if (tempOdSignal == null) { //仅有同向信号机
|
||||
assistant.endSignal = sdSignal;
|
||||
//如果有并置信号机,选反向信号机
|
||||
Section nextSection = section.getNextSection(right);
|
||||
if (nextSection != null && nextSection.getSignalOf(!right) != null) { //并置信号机
|
||||
btnCodes.add(nextSection.getSignalOf(!right).getCode());
|
||||
}
|
||||
} else {
|
||||
if (tempOdSignal.isShunting2()) { //如果反向信号机是列车兼调车信号机
|
||||
assistant.endSignal = tempOdSignal;
|
||||
} else if (!tempOdSignal.hasShuntingFunction()) { //无调车功能
|
||||
assistant.endSignal = assistant.odSignal;
|
||||
} else {
|
||||
assistant.endSignal = sdSignal;
|
||||
btnCodes.add(tempOdSignal.getCode());
|
||||
}
|
||||
} else { //只有同向信号机
|
||||
destination = sameDirSignal;
|
||||
}
|
||||
} else {
|
||||
Signal odSignal = section.getSignalOf(!right);
|
||||
if (odSignal != null) {
|
||||
if (odSignal.isReceivingDepartureSignal()) { //反向信号机是接发车信号机
|
||||
destination = oppositeDirSignal;
|
||||
} else {
|
||||
oppositeDirSignal = odSignal;
|
||||
}
|
||||
} else if (tempOdSignal != null) {
|
||||
if (tempOdSignal.isShunting2()) { //如果反向信号机是列车兼调车信号机
|
||||
assistant.endSignal = tempOdSignal;
|
||||
} else if (!tempOdSignal.hasShuntingFunction()) { //无调车功能
|
||||
assistant.endSignal = assistant.odSignal;
|
||||
}
|
||||
}
|
||||
if (tempOdSignal != null) //记录最后一个反向信号机
|
||||
assistant.odSignal = tempOdSignal;
|
||||
|
||||
if (destination != null) {
|
||||
buildShuntingRoute(signal, sections, switches, routeMap, routeCodeGenerator, routeVOMap, right, destination);
|
||||
if (assistant.endSignal != null) {
|
||||
if (btnCodes.size() < 2) { //仅添加了始端信号机按钮
|
||||
btnCodes.add(assistant.endSignal.getCode());
|
||||
}
|
||||
buildShuntingRoute(assistant);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -331,27 +402,26 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
if (section.getNextSection(!right) != null && section.isSwitchTrack()) { //第一个条件是为了排除边缘的道岔轨道
|
||||
Switch relSwitch = section.getRelSwitch();
|
||||
if (relSwitch.isA(section)) {
|
||||
Assistant assistant2 = assistant.clone();
|
||||
//定位区段
|
||||
ArrayList<Section> sections2 = new ArrayList<>(sections);
|
||||
ArrayList<SwitchElement> switches2 = new ArrayList<>(switches);
|
||||
sections.add(relSwitch.getB());
|
||||
switches.add(new SwitchElement(relSwitch, true));
|
||||
Switch linkedSwitch = relSwitch.queryLinkedSwitch();
|
||||
if (linkedSwitch != null)
|
||||
switches.add(new SwitchElement(linkedSwitch, true));
|
||||
generateShuntingRoute(signal, sections, switches, routeMap, routeCodeGenerator, routeVOMap, iter + 1);
|
||||
generateShuntingRoute(assistant, iter + 1);
|
||||
//反位区段
|
||||
sections2.add(relSwitch.getC());
|
||||
switches2.add(new SwitchElement(relSwitch, false));
|
||||
assistant2.sections.add(relSwitch.getC());
|
||||
assistant2.switches.add(new SwitchElement(relSwitch, false));
|
||||
Switch axleRelSwitch = relSwitch.queryAxleRelatedOtherSwitch();
|
||||
if (linkedSwitch != null && axleRelSwitch != null) {
|
||||
Switch linkedAxleRelSwitch = linkedSwitch.queryAxleRelatedOtherSwitch();
|
||||
Switch axleRelLinkedSwitch = axleRelSwitch.queryLinkedSwitch();
|
||||
if (linkedAxleRelSwitch != null && linkedAxleRelSwitch.equals(axleRelLinkedSwitch)) {
|
||||
switches2.add(new SwitchElement(axleRelSwitch, true));
|
||||
assistant2.switches.add(new SwitchElement(axleRelSwitch, true));
|
||||
}
|
||||
}
|
||||
generateShuntingRoute(signal, sections2, switches2, routeMap, routeCodeGenerator, routeVOMap, iter + 1);
|
||||
generateShuntingRoute(assistant2, iter + 1);
|
||||
break;
|
||||
} else {
|
||||
next = relSwitch.getA();
|
||||
@ -379,8 +449,12 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
if (next != null) {
|
||||
sections.add(next);
|
||||
} else { //当找到轨道尽头也仅有一个反向信号机时,就以这个反向信号机作为终点
|
||||
if (oppositeDirSignal != null) {
|
||||
buildShuntingRoute(signal, sections, switches, routeMap, routeCodeGenerator, routeVOMap, right, oppositeDirSignal);
|
||||
if (assistant.odSignal != null) {
|
||||
assistant.endSignal = assistant.odSignal;
|
||||
if (btnCodes.size() < 2) { //仅添加了始端信号机按钮
|
||||
btnCodes.add(assistant.endSignal.getCode());
|
||||
}
|
||||
buildShuntingRoute(assistant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -391,33 +465,40 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
/**
|
||||
* 构建调车进路
|
||||
*/
|
||||
private void buildShuntingRoute(Signal signal, List<Section> sections, List<SwitchElement> switches,
|
||||
Map<String, Route> routeMap, DraftMapCiDataGeneratorImpl.CodeGenerator routeCodeGenerator,
|
||||
Map<String, MapRouteNewVO> routeVOMap, boolean right, Signal destination) {
|
||||
boolean sameDir = destination.isRight() == signal.isRight();
|
||||
//更正途经区段
|
||||
for (int i = sections.size() - 1; i >= 0; i--) {
|
||||
Section last = sections.get(i);
|
||||
if (sameDir) { //同向信号机
|
||||
if (destination.equals(last.getSignalOf(right))) {
|
||||
break;
|
||||
}
|
||||
} else { //反向信号机
|
||||
if (destination.equals(last.getSignalOf(!right))) {
|
||||
sections.remove(i);
|
||||
break;
|
||||
}
|
||||
private void buildShuntingRoute(Assistant assistant) {
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(assistant.startSignal);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(assistant.endSignal);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionNotEmpty(assistant.sections);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(assistant.routeCodeGenerator);
|
||||
|
||||
Signal startSignal = assistant.startSignal;
|
||||
Signal endSignal = assistant.endSignal;
|
||||
List<Section> sections = assistant.sections;
|
||||
List<SwitchElement> switches = assistant.switches;
|
||||
DraftMapCiDataGeneratorImpl.CodeGenerator routeCodeGenerator = assistant.routeCodeGenerator;
|
||||
Map<String, Route> routeMap = assistant.routeMap;
|
||||
Map<String, MapRouteNewVO> routeVOMap = assistant.routeVOMap;
|
||||
|
||||
//移除末端信号机所在区段之后的所有区段
|
||||
ListIterator<Section> iterator = sections.listIterator(sections.size());
|
||||
Section endSection = endSignal.getSection();
|
||||
while (iterator.hasPrevious()) {
|
||||
Section s = iterator.previous();
|
||||
if (endSection.equals(s)) {
|
||||
break;
|
||||
} else {
|
||||
iterator.remove();
|
||||
}
|
||||
sections.remove(i);
|
||||
}
|
||||
//添加进路
|
||||
Route route = new Route(routeCodeGenerator.next(), "D_" + signal.getShowName() + "-" + destination.getShowName());
|
||||
route.setInterlockStation(signal.getInterlockStation());
|
||||
route.setStart(signal);
|
||||
route.setDestination(destination);
|
||||
Route route = new Route(routeCodeGenerator.next(), "D_" + startSignal.getShowName() + "-" + endSignal.getShowName());
|
||||
route.setInterlockStation(startSignal.getInterlockStation());
|
||||
route.setStart(startSignal);
|
||||
route.setDestination(endSignal);
|
||||
route.setSectionList(sections);
|
||||
route.setSwitchList(switches);
|
||||
route.setAspect(SignalAspect.W);
|
||||
route.setType(Route.Type.SHUNTING);
|
||||
String startEndSignalCode = route.getStart().getCode() + route.getDestination().getCode();
|
||||
Route otherRoute = routeMap.get(startEndSignalCode); //同始、终端信号机进路
|
||||
if (otherRoute != null) { //选择反位道岔更少的/反位道岔更靠后的
|
||||
@ -450,7 +531,7 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
vo.setEndSectionCode(sections.get(sections.size() - 1).getCode());
|
||||
vo.setSignalAspect(getAspectIndex(selectedRoute.getAspect()));
|
||||
routeVOMap.put(startEndSignalCode, vo);
|
||||
vo.setBtnCodeList(Arrays.asList(route.getStart().getCode(), route.getDestination().getCode()));
|
||||
vo.setBtnCodeList(assistant.btnCodes);
|
||||
}
|
||||
|
||||
private void generatePassRoute(Signal signal, MapSignalButtonVO buttonVO, Map<String, Route> routeMap,
|
||||
@ -462,6 +543,7 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
routeVO.setStartSignalCode(signal.getCode());
|
||||
List<MapRouteAspectVO> routeAspectVOS = new ArrayList<>();
|
||||
routeVO.setRouteAspectList(routeAspectVOS);
|
||||
routeVO.setType(Route.Type.PASS);
|
||||
|
||||
Signal outboundSignal = null; //出站信号机
|
||||
boolean right = signal.isRight();
|
||||
@ -475,9 +557,9 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
routeVO.setName("T_" + signal.getShowName() + "-" + destination.getShowName());
|
||||
String startEndSignalCode = outboundSignal.getCode() + destination.getCode();
|
||||
MapRouteNewVO departureRoute = routeVOMap.get(startEndSignalCode); //发车进路
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(departureRoute.getName().startsWith("L"),
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(departureRoute.isTrainRoute(),
|
||||
String.format("信号机[%s]的通过进路的发车进路[%s]不是列车进路", signal.getCode(), departureRoute.getCode()));
|
||||
routeAspectVOS.add(new MapRouteAspectVO(departureRoute.getCode(), departureRoute.getSignalAspect()));
|
||||
routeAspectVOS.add(new MapRouteAspectVO(departureRoute.getCode(), getAspectIndex(SignalAspect.Y)));
|
||||
routeVO.setEndSectionCode(departureRoute.getEndSectionCode());
|
||||
List<MapSignalButtonVO> buttons = signalCode_button_map.get(destination.getCode());
|
||||
MapSignalButtonVO endButton = buttons.stream().filter(vo -> MapSignalButtonVO.Type.PICK.equals(vo.getType()))
|
||||
@ -493,7 +575,7 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(receivingRoute,
|
||||
String.format("[%s]接车进路不存在", startEndSignalCode));
|
||||
routeVO.setStartSectionCode(receivingRoute.getStartSectionCode());
|
||||
routeAspectVOS.add(new MapRouteAspectVO(receivingRoute.getCode(), receivingRoute.getSignalAspect()));
|
||||
routeAspectVOS.add(new MapRouteAspectVO(receivingRoute.getCode(), getAspectIndex(SignalAspect.GY)));
|
||||
outboundSignal = section.getSignalOf(right);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotNull(outboundSignal,
|
||||
String.format("股道[%s]无出站信号机", section.getCode()));
|
||||
@ -733,4 +815,82 @@ public class DraftMapRouteServiceImpl implements DraftMapRouteService {
|
||||
example.createCriteria().andMapIdEqualTo(mapId);
|
||||
draftMapRouteDAO.deleteByExample(example);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
private class Assistant implements Cloneable {
|
||||
/**
|
||||
* 始端信号机
|
||||
*/
|
||||
public Signal startSignal;
|
||||
|
||||
/**
|
||||
* 终端信号机
|
||||
*/
|
||||
public Signal endSignal;
|
||||
|
||||
/**
|
||||
* 最后一个反向信号机
|
||||
*/
|
||||
public Signal odSignal;
|
||||
|
||||
/**
|
||||
* 锁闭区段
|
||||
*/
|
||||
public List<Section> sections;
|
||||
|
||||
/**
|
||||
* 锁闭道岔
|
||||
*/
|
||||
public List<SwitchElement> switches;
|
||||
|
||||
/**
|
||||
* 按钮列表
|
||||
*/
|
||||
public List<String> btnCodes;
|
||||
|
||||
/**
|
||||
* 进路Code生成器
|
||||
*/
|
||||
public DraftMapCiDataGeneratorImpl.CodeGenerator routeCodeGenerator;
|
||||
|
||||
public Map<String, Route> routeMap;
|
||||
|
||||
public Map<String, MapRouteNewVO> routeVOMap;
|
||||
|
||||
/**
|
||||
* 组合进路包含的单元进路
|
||||
*/
|
||||
public List<Route> routes;
|
||||
|
||||
/**
|
||||
* 仅调车进路
|
||||
*/
|
||||
public Map<String, List<Route>> startSignalCode_routes_map;
|
||||
|
||||
public Assistant(Signal startSignal, DraftMapCiDataGeneratorImpl.CodeGenerator routeCodeGenerator, Map<String, Route> routeMap, Map<String, MapRouteNewVO> routeVOMap) {
|
||||
this.startSignal = startSignal;
|
||||
this.sections = new ArrayList<>();
|
||||
this.switches = new ArrayList<>();
|
||||
this.btnCodes = new ArrayList<>();
|
||||
this.routeCodeGenerator = routeCodeGenerator;
|
||||
this.routeMap = routeMap;
|
||||
this.routeVOMap = routeVOMap;
|
||||
this.routes = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Assistant clone() {
|
||||
Assistant clone;
|
||||
try {
|
||||
clone = (Assistant) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(e);
|
||||
}
|
||||
clone.sections = new ArrayList<>(this.sections);
|
||||
clone.switches = new ArrayList<>(this.switches);
|
||||
clone.btnCodes = new ArrayList<>(this.btnCodes);
|
||||
clone.routes = new ArrayList<>(this.routes);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ public class StationGeneratorNew implements GeneratorNew {
|
||||
// .filter(station -> station.isTurnBack())
|
||||
// .collect(Collectors.toList());
|
||||
// tbStationList.forEach(station -> {
|
||||
// if (Objects.equals(Operation.Type.Station_Set_Turn_Back_Strategy.name(), operateDefinitionVO.getOperateType())) {
|
||||
// if (Objects.equals(Operation2.Type.Station_Set_Turn_Back_Strategy.name(), operateDefinitionVO.getOperateType())) {
|
||||
// station.setControlMode(Station.ControlMode.Center);
|
||||
// trainingVOList.add(build(config, simulation, station,null, operateDefinitionVO));
|
||||
// // 仿真重置
|
||||
|
@ -0,0 +1,19 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
|
||||
/**
|
||||
* 已发布实训的状态(0-默认未知,1-上架,2-下架)
|
||||
*/
|
||||
public enum PublishedTraining2StateEnum {
|
||||
Default(0),//默认未知
|
||||
PutOn(1),//上架
|
||||
PullOff(2),//下架
|
||||
;
|
||||
private int state;
|
||||
private PublishedTraining2StateEnum(int state){
|
||||
this.state=state;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2WithBLOBs;
|
||||
import club.joylink.rtss.vo.training2.draft.DraftTraining2InfoVo;
|
||||
import club.joylink.rtss.vo.training2.publish.PublishedTraining2InfoRspVo;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class Training2Convertor {
|
||||
public static DraftTraining2InfoVo convertFrom(DraftTraining2 dt){
|
||||
DraftTraining2InfoVo ti=new DraftTraining2InfoVo();
|
||||
ti.setCreateTime(dt.getCreateTime());
|
||||
ti.setCreatorId(dt.getCreatorId());
|
||||
ti.setId(dt.getId());
|
||||
ti.setDescription(dt.getDescription());
|
||||
ti.setLabelJson(dt.getLabelJson());
|
||||
ti.setMapId(dt.getMapId());
|
||||
ti.setName(dt.getName());
|
||||
ti.setUpdateTime(dt.getUpdateTime());
|
||||
ti.setType(dt.getType());
|
||||
return ti;
|
||||
}
|
||||
/**
|
||||
* 实训草稿转化为已发布实训,注意已发布实训的状态为上架且已发布实训的id为空(数据库自动生成)
|
||||
*/
|
||||
public static PublishedTraining2WithBLOBs convertFrom(DraftTraining2WithBLOBs from){
|
||||
PublishedTraining2WithBLOBs pub = new PublishedTraining2WithBLOBs();
|
||||
//
|
||||
pub.setState(PublishedTraining2StateEnum.PutOn.getState());
|
||||
//
|
||||
pub.setMemberJson(from.getMemberJson());
|
||||
pub.setBgSceneJson(from.getBgSceneJson());
|
||||
pub.setFinalScenesJson(from.getFinalScenesJson());
|
||||
pub.setOperaJson(from.getOperaJson());
|
||||
pub.setDescription(from.getDescription());
|
||||
pub.setCreateTime(LocalDateTime.now());
|
||||
pub.setUpdateTime(LocalDateTime.now());
|
||||
pub.setCreatorId(from.getCreatorId());
|
||||
pub.setName(from.getName());
|
||||
pub.setPlayerIdJson(from.getPlayerIdJson());
|
||||
pub.setScoringRuleJson(from.getScoringRuleJson());
|
||||
pub.setStepJson(from.getStepJson());
|
||||
pub.setFailureConditionJson(from.getFailureConditionJson());
|
||||
pub.setLabelJson(from.getLabelJson());
|
||||
pub.setMapId(from.getMapId());
|
||||
pub.setMapLocationJson(from.getMapLocationJson());
|
||||
pub.setType(from.getType());
|
||||
pub.setRunPlanId(from.getRunPlanId());
|
||||
//
|
||||
return pub;
|
||||
}
|
||||
public static PublishedTraining2InfoRspVo convertFrom(PublishedTraining2 from){
|
||||
PublishedTraining2InfoRspVo rsp = new PublishedTraining2InfoRspVo();
|
||||
rsp.setCreateTime(from.getCreateTime());
|
||||
rsp.setDescription(from.getDescription());
|
||||
rsp.setCreatorId(from.getCreatorId());
|
||||
rsp.setId(from.getId());
|
||||
rsp.setName(from.getName());
|
||||
rsp.setLabelJson(from.getLabelJson());
|
||||
rsp.setMapId(from.getMapId());
|
||||
rsp.setType(from.getType());
|
||||
rsp.setFailureConditionJson(from.getFailureConditionJson());
|
||||
rsp.setUpdateTime(from.getUpdateTime());
|
||||
rsp.setRunPlanId(from.getRunPlanId());
|
||||
rsp.setMapLocationJson(from.getMapLocationJson());
|
||||
rsp.setState(from.getState());
|
||||
return rsp;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
|
||||
import club.joylink.rtss.dao.DraftTraining2DAO;
|
||||
import club.joylink.rtss.dao.PublishedTraining2DAO;
|
||||
import club.joylink.rtss.entity.training2.*;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.vo.training2.draft.TrainingDraftPublishReqVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 实训草稿发布业务实现
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class Training2DraftPublishService {
|
||||
@Autowired
|
||||
private DraftTraining2DAO trainingDao;
|
||||
@Autowired
|
||||
private PublishedTraining2DAO publishedDao;
|
||||
|
||||
/**
|
||||
* 草稿发布
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void draftPublish(TrainingDraftPublishReqVo req,Long userId){
|
||||
Long draftId=Long.valueOf(req.getDraftId());
|
||||
DraftTraining2Example dtExample=new DraftTraining2Example();
|
||||
dtExample.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(draftId);
|
||||
List<DraftTraining2WithBLOBs> dtFinds= this.trainingDao.selectByExampleWithBLOBs(dtExample);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null!=dtFinds&&!dtFinds.isEmpty(),"实训草稿不存在");
|
||||
DraftTraining2WithBLOBs draft = dtFinds.get(0);
|
||||
//
|
||||
PublishedTraining2WithBLOBs pub = Training2Convertor.convertFrom(draft);
|
||||
//根据要发布的草稿名称来查找已发布的实训
|
||||
//如果以有同名的则会被覆盖
|
||||
PublishedTraining2Example ptExample=new PublishedTraining2Example();
|
||||
ptExample.createCriteria().andNameEqualTo(draft.getName());
|
||||
List<PublishedTraining2> ptFinds= this.publishedDao.selectByExample(ptExample);
|
||||
//
|
||||
if(null!=ptFinds&&!ptFinds.isEmpty()){//已发布实训存在时则直接删除
|
||||
this.publishedDao.deleteByExample(ptExample);
|
||||
}
|
||||
//发布
|
||||
this.publishedDao.insertSelective(pub);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,444 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
|
||||
import club.joylink.rtss.dao.DraftTraining2DAO;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2Example;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.storage.StorageSimulation;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMemberPO;
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.client.simulationv1.SimulationMemberVO;
|
||||
import club.joylink.rtss.vo.client.training2.ScoringRuleVO;
|
||||
import club.joylink.rtss.vo.client.training2.Step2VO;
|
||||
import club.joylink.rtss.vo.training2.draft.*;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 实训草稿业务实现
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class Training2DraftService {
|
||||
|
||||
@Autowired
|
||||
private DraftTraining2DAO trainingDao;
|
||||
@Autowired
|
||||
private GroupSimulationService roupSimulationService;
|
||||
|
||||
/**
|
||||
* 根据基本信息创建实训
|
||||
*
|
||||
* @return 返回创建的实训的id
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public CreateTraining2RspVo createTraining(CreateTraining2ReqVo req, AccountVO user) {
|
||||
//校验是否已经有同名的实训
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andNameEqualTo(req.getName());
|
||||
List<DraftTraining2> check = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionEmpty(check, "实训已经存在");
|
||||
//
|
||||
DraftTraining2WithBLOBs dt = new DraftTraining2WithBLOBs();
|
||||
dt.setMapId(req.getMapId());
|
||||
dt.setName(req.getName());
|
||||
dt.setCreatorId(user.getId());
|
||||
dt.setDescription(req.getDescription());
|
||||
dt.setType(req.getType());
|
||||
dt.setLabelJson(req.getLabelJson());
|
||||
dt.setCreateTime(LocalDateTime.now());
|
||||
dt.setUpdateTime(LocalDateTime.now());
|
||||
this.trainingDao.insertSelective(dt);
|
||||
//
|
||||
List<DraftTraining2> created = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null != created && created.size() == 1, "创建实训异常");
|
||||
//
|
||||
DraftTraining2 tn = created.get(0);
|
||||
CreateTraining2RspVo rsp = new CreateTraining2RspVo();
|
||||
rsp.setId(tn.getId());
|
||||
rsp.setName(tn.getName());
|
||||
return rsp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除当前用户的实训草稿
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public DeleteTraining2RspVo deleteTrainings(DeleteTraining2ReqVo req, AccountVO user) {
|
||||
DeleteTraining2RspVo rsp = new DeleteTraining2RspVo();
|
||||
rsp.setTrainingDraftIds(new ArrayList<String>());
|
||||
for (String sId : req.getTrainingDraftIds()) {
|
||||
long draftId = Long.valueOf(sId);
|
||||
DraftTraining2Example dex = new DraftTraining2Example();
|
||||
dex.createCriteria().andIdEqualTo(draftId).andCreatorIdEqualTo(user.getId());
|
||||
int drt = this.trainingDao.deleteByExample(dex);
|
||||
if (drt > 0) {
|
||||
rsp.getTrainingDraftIds().add(sId);
|
||||
}
|
||||
}
|
||||
return rsp;
|
||||
}
|
||||
|
||||
private boolean isExistDraft(Long userId, String draftName) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andNameEqualTo(draftName);
|
||||
List<DraftTraining2> find = this.trainingDao.selectByExample(example);
|
||||
return null != find && !find.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户实训草稿的初始背景
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateTrainingBackground(UpdateTraining2BackgroudReqVo req, Long userId) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(req.getId());
|
||||
List<DraftTraining2> find = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null != find && !find.isEmpty(), "实训草稿不存在");
|
||||
//
|
||||
DraftTraining2WithBLOBs b = new DraftTraining2WithBLOBs();
|
||||
//构建背景
|
||||
String simulationId = req.getGroupId();
|
||||
Simulation simulation = this.roupSimulationService.getSimulationByGroup(simulationId);
|
||||
StorageSimulation scenesSaving = new StorageSimulation(simulation, false);
|
||||
//保存背景
|
||||
b.setBgSceneJson((JsonUtils.writeValueAsString(scenesSaving)));
|
||||
b.setMemberJson(JsonUtils.writeValueAsString(SimulationMemberVO.convert2VOList(simulation.getSimulationMembers())));
|
||||
b.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
this.trainingDao.updateByExampleSelective(b, example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户实训草稿的初始背景
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void resetTrainingBackground(ResetTraining2BackgroudReqVo req, Long userId) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(req.getId());
|
||||
List<DraftTraining2> find = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null != find && !find.isEmpty(), "实训草稿不存在");
|
||||
//
|
||||
DraftTraining2WithBLOBs b = new DraftTraining2WithBLOBs();
|
||||
b.setBgSceneJson("");
|
||||
b.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
this.trainingDao.updateByExampleSelective(b, example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户实训草稿的地图定位信息
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateTrainingMapLocation(UpdateTraining2MapLocationReqVo req, Long userId) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(req.getId());
|
||||
List<DraftTraining2> find = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null != find && !find.isEmpty(), "实训草稿不存在");
|
||||
//
|
||||
DraftTraining2WithBLOBs b = new DraftTraining2WithBLOBs();
|
||||
//
|
||||
b.setMapLocationJson(req.getMapLocationJson());
|
||||
b.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
this.trainingDao.updateByExampleSelective(b, example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前用户的实训草稿基础信息
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateTrainingInfo(UpdateDraftTraining2InfoReqVo req, Long userId) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(req.getId());
|
||||
List<DraftTraining2> find = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null != find && !find.isEmpty(), "实训草稿不存在");
|
||||
//
|
||||
if (null != req.getName()) {
|
||||
DraftTraining2 the = find.get(0);
|
||||
if (!req.getName().equals(the.getName())) {//草稿名称变了
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(this.isExistDraft(userId, req.getName()), "名称为 [" + req.getName() + "] 的草稿已经存在");
|
||||
}
|
||||
}
|
||||
//
|
||||
DraftTraining2WithBLOBs b = new DraftTraining2WithBLOBs();
|
||||
//
|
||||
b.setName(req.getName());
|
||||
b.setDescription(req.getDescription());
|
||||
b.setType(req.getType());
|
||||
b.setLabelJson(req.getLabelJson());
|
||||
//
|
||||
b.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
this.trainingDao.updateByExampleSelective(b, example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前用户的实训草稿大字段信息
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateTrainingBlob(UpdateDraftTraining2BlobReqVo req, Long userId) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(req.getId());
|
||||
List<DraftTraining2> find = this.trainingDao.selectByExample(example);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertTrue(null != find && !find.isEmpty(), "实训草稿不存在");
|
||||
//
|
||||
DraftTraining2WithBLOBs b = new DraftTraining2WithBLOBs();
|
||||
//
|
||||
b.setMapId(req.getMapId());
|
||||
b.setBgSceneJson(req.getBgSceneJson());
|
||||
b.setMapLocationJson(req.getMapLocationJson());
|
||||
b.setRunPlanId(req.getRunPlanId());
|
||||
b.setOperaJson(req.getOperaJson());
|
||||
b.setStepJson(req.getStepJson());
|
||||
b.setScoringRuleJson(req.getScoringRuleJson());
|
||||
b.setMemberJson(req.getMemberJson());
|
||||
b.setPlayerIdJson(req.getPlayerIdJson());
|
||||
b.setFailureConditionJson(req.getFailureConditionJson());
|
||||
//
|
||||
b.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
this.trainingDao.updateByExampleSelective(b, example);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实训草稿的所有信息
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public DraftTraining2DetailRspVo findTrainingDetail(Long trainingDraftId, Long userId) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andCreatorIdEqualTo(userId).andIdEqualTo(trainingDraftId);
|
||||
List<DraftTraining2WithBLOBs> bs = this.trainingDao.selectByExampleWithBLOBs(example);
|
||||
if (null != bs && !bs.isEmpty()) {
|
||||
DraftTraining2WithBLOBs b = bs.get(0);
|
||||
DraftTraining2DetailRspVo rsp = new DraftTraining2DetailRspVo();
|
||||
rsp.setDescription(b.getDescription());
|
||||
rsp.setFailureConditionJson(b.getFailureConditionJson());
|
||||
rsp.setCreateTime(b.getCreateTime());
|
||||
rsp.setCreatorId(b.getCreatorId());
|
||||
rsp.setLabelJson(b.getLabelJson());
|
||||
rsp.setMapId(b.getMapId());
|
||||
rsp.setName(b.getName());
|
||||
rsp.setId(b.getId());
|
||||
rsp.setType(b.getType());
|
||||
rsp.setBgSceneJson(b.getBgSceneJson());
|
||||
rsp.setMemberJson(b.getMemberJson());
|
||||
rsp.setOperaJson(b.getOperaJson());
|
||||
rsp.setStepJson(b.getStepJson());
|
||||
rsp.setUpdateTime(b.getUpdateTime());
|
||||
rsp.setPlayerIdJson(b.getPlayerIdJson());
|
||||
rsp.setMapLocationJson(b.getMapLocationJson());
|
||||
rsp.setRunPlanId(b.getRunPlanId());
|
||||
rsp.setScoringRuleJson(b.getScoringRuleJson());
|
||||
return rsp;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页获取当前用户草稿基础信息
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public PageVO<DraftTraining2InfoVo> findTrainingsInfoByPage(DraftTraining2InfoPageReqVo req, Long userId) {
|
||||
PageVO<DraftTraining2InfoVo> page = new PageVO<>();
|
||||
//
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
DraftTraining2Example.Criteria c = example.createCriteria().andCreatorIdEqualTo(userId);
|
||||
if (null != req.getMapId()) {
|
||||
c.andMapIdEqualTo(req.getMapId());
|
||||
}
|
||||
//
|
||||
long sum = this.trainingDao.countByExample(example);
|
||||
page.setTotal(sum);
|
||||
page.setPageNum(req.getPageNum());
|
||||
page.setPageSize(req.getPageSize());
|
||||
page.setList(new ArrayList<>());
|
||||
if (sum > 0) {
|
||||
//1--创建时间 2--更新时间 3--草稿名称;默认值为1;
|
||||
String orderBy = "create_time";
|
||||
switch (req.getOrderBy()) {
|
||||
case 1:
|
||||
orderBy = "create_time";
|
||||
break;
|
||||
case 2:
|
||||
orderBy = "update_time";
|
||||
break;
|
||||
case 3:
|
||||
orderBy = "name";
|
||||
break;
|
||||
}
|
||||
long startIndex = (req.getPageNum() - 1) * req.getPageSize();
|
||||
//
|
||||
if (req.getDesc()) {
|
||||
example.setOrderByClause(String.format("%s desc limit %s,%s", orderBy, startIndex, req.getPageSize()));
|
||||
} else {
|
||||
example.setOrderByClause(String.format("%s limit %s,%s", orderBy, startIndex, req.getPageSize()));
|
||||
}
|
||||
List<DraftTraining2> pContent = this.trainingDao.selectByExample(example);
|
||||
if (null != pContent) {
|
||||
pContent.forEach(t -> {
|
||||
page.getList().add(Training2Convertor.convertFrom(t));
|
||||
});
|
||||
}
|
||||
}
|
||||
//
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实训步骤列表
|
||||
*/
|
||||
public List<Step2VO> stepList(Long trainingId) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = trainingDao.selectByPrimaryKey(trainingId);
|
||||
if (draftTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
if (StringUtils.isEmpty(draftTraining2.getStepJson())) {
|
||||
return new ArrayList<>();
|
||||
} else {
|
||||
return JsonUtils.readCollection(draftTraining2.getStepJson(), List.class, Step2VO.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改实训所有步骤
|
||||
*/
|
||||
public void updateSteps(String group, Long trainingId, List<Step2VO> step2VOList) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = trainingDao.selectByPrimaryKey(trainingId);
|
||||
if (draftTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
// 保存当前背景
|
||||
Simulation simulation = this.roupSimulationService.getSimulationByGroup(group);
|
||||
|
||||
String stepJson;
|
||||
if (CollectionUtils.isEmpty(step2VOList)) {
|
||||
stepJson = StringUtil.EMPTY_STRING;
|
||||
} else {
|
||||
stepJson = JsonUtils.writeValueAsString(step2VOList);
|
||||
}
|
||||
// 扮演者集合
|
||||
List<String> playerList = step2VOList.stream().
|
||||
filter(s -> !StringUtils.isEmpty(s.getMemberId())).map(s -> s.getMemberId())
|
||||
.distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(playerList)) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "错误数据:无扮演者");
|
||||
}
|
||||
DraftTraining2WithBLOBs updateObj = new DraftTraining2WithBLOBs();
|
||||
updateObj.setId(trainingId);
|
||||
updateObj.setStepJson(stepJson);
|
||||
updateObj.setPlayerIdJson(JsonUtils.writeValueAsString(playerList));
|
||||
// 背景
|
||||
StorageSimulation scenesSaving = new StorageSimulation(simulation, false);
|
||||
updateObj.setFinalScenesJson(JsonUtils.writeValueAsString(scenesSaving));
|
||||
// 成员信息
|
||||
List<SimulationMemberPO> simulationMemberPOList = SimulationMemberPO.convertFromBOList(simulation.getSimulationMembers());
|
||||
updateObj.setMemberJson(JsonUtils.writeValueAsString(simulationMemberPOList));
|
||||
trainingDao.updateByPrimaryKeySelective(updateObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空步骤
|
||||
*/
|
||||
public void clearStep(Long trainingId) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = trainingDao.selectByPrimaryKey(trainingId);
|
||||
if (draftTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
DraftTraining2WithBLOBs updateObj = new DraftTraining2WithBLOBs();
|
||||
updateObj.setId(trainingId);
|
||||
updateObj.setStepJson(StringUtil.EMPTY_STRING);
|
||||
updateObj.setPlayerIdJson(StringUtil.EMPTY_STRING);
|
||||
updateObj.setFinalScenesJson(StringUtil.EMPTY_STRING);
|
||||
trainingDao.updateByPrimaryKeySelective(updateObj);
|
||||
}
|
||||
|
||||
public List<ScoringRuleVO> getScoringRules(Long trainingId) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = getEntityWithBLOBs(trainingId);
|
||||
String scoringRuleJson = draftTraining2.getScoringRuleJson();
|
||||
if (StringUtils.hasText(scoringRuleJson)) {
|
||||
return JsonUtils.readCollection(scoringRuleJson, List.class, ScoringRuleVO.class);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScoringRules(Long trainingId, List<ScoringRuleVO> scoringRuleVOS) {
|
||||
confirmExist(trainingId);
|
||||
String json = scoringRuleVOS == null ? "" : JsonUtils.writeValueAsString(scoringRuleVOS);
|
||||
DraftTraining2WithBLOBs updateEntity = new DraftTraining2WithBLOBs();
|
||||
updateEntity.setId(trainingId);
|
||||
updateEntity.setScoringRuleJson(json);
|
||||
trainingDao.updateByPrimaryKeySelective(updateEntity);
|
||||
}
|
||||
|
||||
private boolean isExist(long id) {
|
||||
DraftTraining2Example example = new DraftTraining2Example();
|
||||
example.createCriteria().andIdEqualTo(id);
|
||||
long count = trainingDao.countByExample(example);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
public void confirmExist(long id) {
|
||||
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertTrue(isExist(id),
|
||||
String.format("[id:%s]的实训不存在", id));
|
||||
}
|
||||
|
||||
private DraftTraining2WithBLOBs getEntityWithBLOBs(long id) {
|
||||
DraftTraining2WithBLOBs entityWithBLOBs = findEntityWithBLOBs(id);
|
||||
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotNull(entityWithBLOBs,
|
||||
String.format("[id:%s]的实训不存在", id));
|
||||
return entityWithBLOBs;
|
||||
}
|
||||
|
||||
private DraftTraining2WithBLOBs findEntityWithBLOBs(long id) {
|
||||
return trainingDao.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public List<SimulationMemberVO> getMembers(Long trainingId) {
|
||||
DraftTraining2WithBLOBs entity = getEntityWithBLOBs(trainingId);
|
||||
String memberJson = entity.getMemberJson();
|
||||
if (StringUtils.hasText(memberJson)) {
|
||||
return JsonUtils.readCollection(memberJson, List.class, SimulationMemberVO.class);
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public List<SimulationMemberVO> getPlayers(Long trainingId) {
|
||||
DraftTraining2WithBLOBs entity = getEntityWithBLOBs(trainingId);
|
||||
String memberJson = entity.getMemberJson();
|
||||
String playerIdJson = entity.getPlayerIdJson();
|
||||
if (!StringUtils.hasText(playerIdJson)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if (!StringUtils.hasText(memberJson)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<SimulationMemberVO> members = JsonUtils.readCollection(memberJson, List.class, SimulationMemberVO.class);
|
||||
Map<String, SimulationMemberVO> memberMap = members.stream()
|
||||
.collect(Collectors.toMap(SimulationMemberVO::getId, Function.identity()));
|
||||
List<String> playerIds = JsonUtils.readCollection(playerIdJson, List.class, String.class);
|
||||
return playerIds.stream().map(memberMap::get).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,206 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
|
||||
import club.joylink.rtss.dao.PublishedTraining2DAO;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2Example;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2WithBLOBs;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
import club.joylink.rtss.vo.training2.publish.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 已发布实训管理业务实现
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class Training2PublishService {
|
||||
@Autowired
|
||||
private PublishedTraining2DAO publishedDao;
|
||||
/**
|
||||
* 已发布实训分页列表
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public PageVO<PublishedTraining2InfoRspVo> publishedTrainingsPage(PublishedTraining2InfoPageReqVo req){
|
||||
PageVO<PublishedTraining2InfoRspVo> page = new PageVO<>();
|
||||
PublishedTraining2Example example = new PublishedTraining2Example();
|
||||
PublishedTraining2Example.Criteria c =example.createCriteria();
|
||||
if(null!=req.getState()){
|
||||
c.andStateEqualTo(req.getState());
|
||||
}
|
||||
long sum = this.publishedDao.countByExample(example);
|
||||
page.setTotal(sum);
|
||||
page.setPageNum(req.getPageNum());
|
||||
page.setPageSize(req.getPageSize());
|
||||
page.setList(new ArrayList<>());
|
||||
//
|
||||
if(sum>0){
|
||||
//1--创建时间 2--更新时间 3--草稿名称;默认值为1;
|
||||
String orderBy="create_time";
|
||||
switch(req.getOrderBy()){
|
||||
case 1:orderBy="create_time";break;
|
||||
case 2:orderBy="update_time";break;
|
||||
case 3:orderBy="name";break;
|
||||
case 4:orderBy="state";break;
|
||||
}
|
||||
long startIndex = (req.getPageNum() - 1) * req.getPageSize();
|
||||
//
|
||||
if (req.getDesc()) {
|
||||
example.setOrderByClause(String.format("%s desc limit %s,%s", orderBy,startIndex, req.getPageSize()));
|
||||
} else {
|
||||
example.setOrderByClause(String.format("%s limit %s,%s", orderBy,startIndex, req.getPageSize()));
|
||||
}
|
||||
//
|
||||
List<PublishedTraining2> pCt= this.publishedDao.selectByExample(example);
|
||||
if(null!=pCt){
|
||||
pCt.forEach(p->{
|
||||
page.getList().add(Training2Convertor.convertFrom(p));
|
||||
});
|
||||
}
|
||||
}
|
||||
//
|
||||
return page;
|
||||
}
|
||||
/**
|
||||
* 已发布实训上架
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public PutOnPublishedTraining2RspVo putOnPublishedTrainings(PutOnPublishedTraining2ReqVo req){
|
||||
final PutOnPublishedTraining2RspVo rsp =new PutOnPublishedTraining2RspVo();
|
||||
rsp.setIds(new ArrayList<>());
|
||||
req.getIds().forEach(id->{
|
||||
PublishedTraining2WithBLOBs pub =new PublishedTraining2WithBLOBs();
|
||||
pub.setId(Long.valueOf(id));
|
||||
pub.setState(PublishedTraining2StateEnum.PutOn.getState());
|
||||
pub.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
PublishedTraining2Example example=new PublishedTraining2Example();
|
||||
example.createCriteria().andIdEqualTo(pub.getId());
|
||||
//
|
||||
int urt= this.publishedDao.updateByExampleSelective(pub,example);
|
||||
if(urt>0){//记录更新成功的
|
||||
rsp.getIds().add(id);
|
||||
}
|
||||
});
|
||||
return rsp;
|
||||
}
|
||||
/**
|
||||
* 已发布实训下架
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public PullOffPublishedTraining2RspVo pullOffPublishedTrainings(PullOffPublishedTraining2ReqVo req){
|
||||
final PullOffPublishedTraining2RspVo rsp =new PullOffPublishedTraining2RspVo();
|
||||
rsp.setIds(new ArrayList<>());
|
||||
req.getIds().forEach(id->{
|
||||
PublishedTraining2WithBLOBs pub =new PublishedTraining2WithBLOBs();
|
||||
pub.setId(Long.valueOf(id));
|
||||
pub.setState(PublishedTraining2StateEnum.PullOff.getState());
|
||||
pub.setUpdateTime(LocalDateTime.now());
|
||||
//
|
||||
PublishedTraining2Example example=new PublishedTraining2Example();
|
||||
example.createCriteria().andIdEqualTo(pub.getId());
|
||||
//
|
||||
int urt= this.publishedDao.updateByExampleSelective(pub,example);
|
||||
if(urt>0){//记录更新成功的
|
||||
rsp.getIds().add(id);
|
||||
}
|
||||
});
|
||||
return rsp;
|
||||
}
|
||||
/**
|
||||
* 删除已发布实训
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public DeletePublishedTraining2RspVo deletePublishedTrainings(DeletePublishedTraining2ReqVo req){
|
||||
DeletePublishedTraining2RspVo rsp = new DeletePublishedTraining2RspVo();
|
||||
rsp.setIds(new ArrayList<>());
|
||||
//
|
||||
if(null!=req.getIds()){
|
||||
req.getIds().forEach(id->{
|
||||
int drt= this.publishedDao.deleteByPrimaryKey(Long.valueOf(id));
|
||||
if(drt>0){
|
||||
rsp.getIds().add(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
//
|
||||
return rsp;
|
||||
}
|
||||
/**
|
||||
* 根据mapId查找所有的单操实训的基础信息
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<PublishedTraining2InfoRspVo> findAllSingleTrainingBasicInfoByMapId(Long mapId){
|
||||
List<PublishedTraining2InfoRspVo> rsp =new ArrayList<>();
|
||||
//
|
||||
PublishedTraining2Example example = new PublishedTraining2Example();
|
||||
example.createCriteria().andMapIdEqualTo(mapId).andTypeEqualTo(Training2TypeEnum.single.value());
|
||||
List<PublishedTraining2> list = this.publishedDao.selectByExample(example);
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
list.forEach(p->{
|
||||
rsp.add(Training2Convertor.convertFrom(p));
|
||||
});
|
||||
}
|
||||
//
|
||||
return rsp;
|
||||
}
|
||||
/**
|
||||
* 根据mapId查找所有的场景实训的基础信息
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public List<PublishedTraining2InfoRspVo> findAllSceneTrainingBasicInfoByMapId(Long mapId){
|
||||
List<PublishedTraining2InfoRspVo> rsp =new ArrayList<>();
|
||||
//
|
||||
PublishedTraining2Example example = new PublishedTraining2Example();
|
||||
example.createCriteria().andMapIdEqualTo(mapId).andTypeEqualTo(Training2TypeEnum.scene.value());
|
||||
List<PublishedTraining2> list = this.publishedDao.selectByExample(example);
|
||||
if(!CollectionUtils.isEmpty(list)){
|
||||
list.forEach(p->{
|
||||
rsp.add(Training2Convertor.convertFrom(p));
|
||||
});
|
||||
}
|
||||
//
|
||||
return rsp;
|
||||
}
|
||||
/**
|
||||
* 根据已发布实训的id来查询实现的所有信息
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public PublishedTraining2DetailRspVo findTrainingAllInfoById(Long trainingId){
|
||||
PublishedTraining2WithBLOBs b= this.publishedDao.selectByPrimaryKey(trainingId);
|
||||
if(null!=b){
|
||||
PublishedTraining2DetailRspVo rsp = new PublishedTraining2DetailRspVo();
|
||||
//
|
||||
rsp.setDescription(b.getDescription());
|
||||
rsp.setFailureConditionJson(b.getFailureConditionJson());
|
||||
rsp.setCreateTime(b.getCreateTime());
|
||||
rsp.setCreatorId(b.getCreatorId());
|
||||
rsp.setLabelJson(b.getLabelJson());
|
||||
rsp.setMapId(b.getMapId());
|
||||
rsp.setName(b.getName());
|
||||
rsp.setId(b.getId());
|
||||
rsp.setType(b.getType());
|
||||
rsp.setBgSceneJson(b.getBgSceneJson());
|
||||
rsp.setMemberJson(b.getMemberJson());
|
||||
rsp.setOperaJson(b.getOperaJson());
|
||||
rsp.setStepJson(b.getStepJson());
|
||||
rsp.setUpdateTime(b.getUpdateTime());
|
||||
rsp.setPlayerIdJson(b.getPlayerIdJson());
|
||||
rsp.setMapLocationJson(b.getMapLocationJson());
|
||||
rsp.setRunPlanId(b.getRunPlanId());
|
||||
rsp.setScoringRuleJson(b.getScoringRuleJson());
|
||||
rsp.setState(b.getState());
|
||||
rsp.setFinalScenesJson(b.getFinalScenesJson());
|
||||
//
|
||||
return rsp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,521 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
|
||||
import club.joylink.rtss.dao.DraftTraining2DAO;
|
||||
import club.joylink.rtss.dao.PublishedTraining2DAO;
|
||||
import club.joylink.rtss.entity.training2.DraftTraining2WithBLOBs;
|
||||
import club.joylink.rtss.entity.training2.PublishedTraining2WithBLOBs;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.SimulationLifeCycleService;
|
||||
import club.joylink.rtss.simulation.cbtc.event.SimulationOperationEvent;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.MemberManager;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.Operation2;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.Step2;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.Training2;
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.LoginUserInfoVO;
|
||||
import club.joylink.rtss.vo.client.SocketMessageVO;
|
||||
import club.joylink.rtss.vo.client.WebSocketMessageType;
|
||||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||
import club.joylink.rtss.websocket.StompMessageService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Service
|
||||
public class Training2Service {
|
||||
public static final String EXECUTE_JOB_NAME = "Training2";
|
||||
public static final String SCORING_JOB_NAME = "Training2Scoring";
|
||||
public static final int RATE = 1000;
|
||||
|
||||
@Autowired
|
||||
private AtsOperationDispatcher atsOperationDispatcher;
|
||||
|
||||
@Autowired
|
||||
private PublishedTraining2DAO training2DAO;
|
||||
|
||||
@Autowired
|
||||
private DraftTraining2DAO draftTrainingDao;
|
||||
|
||||
@Autowired
|
||||
private MemberManager memberManager;
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationService groupSimulationService;
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationCache groupSimulationCache;
|
||||
|
||||
@Autowired
|
||||
private SimulationLifeCycleService simulationLifeCycleService;
|
||||
|
||||
@Autowired
|
||||
private StompMessageService stompMessageService;
|
||||
|
||||
public void run(Simulation simulation) {
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
if (training2 == null || !training2.isStarted() || training2.isFinish()) {
|
||||
return;
|
||||
}
|
||||
// 获取运行步骤
|
||||
Step2 step = training2.getCurrentRunStep();
|
||||
if (step == null) { // 步骤已经运行完毕
|
||||
training2.finish();
|
||||
// 发送实训完成消息
|
||||
sendTrainingFinish(training2, simulation);
|
||||
return;
|
||||
}
|
||||
// 步骤是否已经触发
|
||||
// 没有触发则检查触发状态,如果可以触发则继续,不能触发则返回
|
||||
if (!Step2.StepStatus.isAlreadyTrigger(step.getStepStatus()) && !step.doTriggerVail()) {
|
||||
return;
|
||||
}
|
||||
// 发送步骤提示信息
|
||||
if (!step.isPrompt()) {
|
||||
step.setPrompt(true); // 标识已发送过消息
|
||||
sendStepTips(step, simulation);
|
||||
}
|
||||
// 获取步骤中未完成的操作
|
||||
Operation2 operation2 = step.getCurrentRunOperation();
|
||||
// 操作全部完成的情况,检查步骤完成条件
|
||||
if (operation2 == null) {
|
||||
// TODO 后续判断步骤完成情况
|
||||
checkTrainStepCompletion(step, simulation);
|
||||
return;
|
||||
}
|
||||
// 操作是否已触发
|
||||
// 没有触发则检查触发状态,如果可以触发则继续,不能触发则返回(同步骤)
|
||||
if (!Step2.StepStatus.isAlreadyTrigger(operation2.getStatus()) && !operation2.doTriggerVail()) {
|
||||
return;
|
||||
}
|
||||
boolean isRobot = step.getSimulationMember().isRobot(); // 角色是否是机器人
|
||||
boolean isClient = operation2 instanceof Operation2.ClientOperation2; // 客户端操作
|
||||
// 未操作过
|
||||
if (Step2.StepStatus.isUndo(operation2.getStatus())) {
|
||||
if (isRobot) {
|
||||
if (isClient) { // 客户端操作
|
||||
operation2.doOperated();
|
||||
} else { // 仿真操
|
||||
Operation2.SimOperation2 simOperation2 = (Operation2.SimOperation2) operation2;
|
||||
atsOperationDispatcher.execute(simulation, step.getSimulationMember(),
|
||||
simOperation2.getOperationType().name(), simOperation2.getParams());
|
||||
}
|
||||
} else { // 非机器人,暂停仿真等待用户操作
|
||||
pauseOrStartSimulation(simulation, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 运行阶段,判断是否完成
|
||||
if (Step2.StepStatus.isRunning(operation2.getStatus())) {
|
||||
boolean completion = operation2.doCompletion();
|
||||
// 发送操作完成信息
|
||||
sendOperationFinish(operation2, simulation);
|
||||
// 如果是最后一步,直接检查步骤有没有完成
|
||||
if (step.getOperations().indexOf(operation2) == (step.getOperations().size() - 1) && completion) {
|
||||
checkTrainStepCompletion(step, simulation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预览实训草稿
|
||||
*/
|
||||
public String previewDraft(Long trainingId, LoginUserInfoVO loginUserInfoVO) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = draftTrainingDao.selectByPrimaryKey(trainingId);
|
||||
if (draftTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
// 校验数据
|
||||
trainingDataValid.accept(draftTraining2);
|
||||
Simulation simulation = createSimulation(draftTraining2.getMapId(), loginUserInfoVO
|
||||
, Simulation.FunctionalType.SCRIPT_PREVIEW, draftTraining2);
|
||||
return simulation.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布实训预览
|
||||
*/
|
||||
public String preview(Long trainingId, LoginUserInfoVO loginUserInfoVO) {
|
||||
PublishedTraining2WithBLOBs publishedTraining2 = training2DAO.selectByPrimaryKey(trainingId);
|
||||
if (publishedTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
DraftTraining2WithBLOBs draftTraining2 = JsonUtils.readCollection(JsonUtils.writeValueAsString(publishedTraining2)
|
||||
, DraftTraining2WithBLOBs.class);
|
||||
// 校验数据
|
||||
trainingDataValid.accept(draftTraining2);
|
||||
Simulation simulation = createSimulation(draftTraining2.getMapId(), loginUserInfoVO
|
||||
, Simulation.FunctionalType.SCRIPT_PREVIEW, draftTraining2);
|
||||
return simulation.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿真中加载发布的实训
|
||||
*/
|
||||
public void trainingLoad(String group, Long trainingId, LoginUserInfoVO loginUserInfoVO) {
|
||||
PublishedTraining2WithBLOBs publishedTraining2 = training2DAO.selectByPrimaryKey(trainingId);
|
||||
if (publishedTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
DraftTraining2WithBLOBs draftTraining2 = JsonUtils.readCollection(JsonUtils.writeValueAsString(publishedTraining2)
|
||||
, DraftTraining2WithBLOBs.class);
|
||||
// 校验数据
|
||||
trainingDataValid.accept(draftTraining2);
|
||||
// 仿真加载实训
|
||||
simulationLoadTraining(group, draftTraining2, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿真中加载草稿实训
|
||||
*/
|
||||
public void trainingDraftLoad(String group, Long trainingId, LoginUserInfoVO loginUserInfoVO) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = draftTrainingDao.selectByPrimaryKey(trainingId);
|
||||
if (draftTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
// 校验数据
|
||||
trainingDataValid.accept(draftTraining2);
|
||||
// 仿真加载实训
|
||||
simulationLoadTraining(group, draftTraining2, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启实训
|
||||
*/
|
||||
public void startTraining2(String group, ScriptBO.Mode mode, AccountVO user) {
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
if (simulation == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "仿真不存在");
|
||||
}
|
||||
if (!simulation.getCreator().getId().equals(user.getId())) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "无权限开启实训");
|
||||
}
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
if (training2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "实训数据不存在");
|
||||
}
|
||||
if (training2.isNeedReloadScenes()) {
|
||||
simulationLifeCycleService.pause(simulation);
|
||||
// 重置仿真状态
|
||||
groupSimulationService.planOver(group);
|
||||
if (!StringUtils.isEmpty(training2.getBgSceneJson())) {
|
||||
groupSimulationService.loadScenes(simulation.getId(), training2.getBgSceneJson());
|
||||
}
|
||||
}
|
||||
// 增加任务
|
||||
if (simulation.getJobMap().containsKey(EXECUTE_JOB_NAME)) {
|
||||
simulation.removeJob(EXECUTE_JOB_NAME);
|
||||
}
|
||||
simulation.addJobIfAbsent(EXECUTE_JOB_NAME, () -> this.run(simulation), RATE);
|
||||
training2.start(mode);
|
||||
simulationLifeCycleService.resume(simulation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止实训信息
|
||||
* <p>
|
||||
* 2022-08-30 完成实训后取消仿真暂停
|
||||
*/
|
||||
public Float finishTraining2(String group, AccountVO user) {
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
if (simulation == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "仿真不存在");
|
||||
}
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
Map<String, Float> scoreMap;
|
||||
if (training2 != null) {
|
||||
// 创建者退出,则清理实训
|
||||
if (simulation.getCreator().getId().equals(user.getId())) {
|
||||
training2.finish();
|
||||
simulation.removeJob(SCORING_JOB_NAME); //移除打分监视任务
|
||||
simulation.removeJob(EXECUTE_JOB_NAME); //移除实训执行任务
|
||||
}
|
||||
scoreMap = training2.mark();
|
||||
} else {
|
||||
scoreMap = new HashMap<>();
|
||||
}
|
||||
SimulationMember member = simulation.getSimulationMemberByUserId(user.getId());
|
||||
return scoreMap.get(member.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端完成步骤后回调(针对步骤中全部是客户端操作的)
|
||||
*/
|
||||
public Integer completionClientStep(String group, Integer stepId, AccountVO user) {
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
if (simulation == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "仿真不存在");
|
||||
}
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
if (training2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "实训数据不存在");
|
||||
}
|
||||
Step2 step = training2.getSteps().stream().filter(s -> Objects.equals(s.getId(), stepId))
|
||||
.findFirst().orElse(null);
|
||||
if (step == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "不存在步骤");
|
||||
}
|
||||
if (Objects.equals(user.getId(), step.getSimulationMember().getId())) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "无权限操作");
|
||||
}
|
||||
boolean result = true;
|
||||
for (Operation2 operation2 : step.getOperations()) {
|
||||
if (operation2 instanceof Operation2.ClientOperation2) { // 前端操作,直接判断结果
|
||||
operation2.doOperated();
|
||||
operation2.doCompletion();
|
||||
} else {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
checkTrainStepCompletion(step, simulation); // 直接检查步骤是否完成
|
||||
}
|
||||
// 恢复前端运行
|
||||
pauseOrStartSimulation(simulation, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成步骤中操作
|
||||
*/
|
||||
public Integer completionClientStepOperation(String group, Integer stepId
|
||||
, Integer id, AccountVO user) {
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
if (simulation == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "仿真不存在");
|
||||
}
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
if (training2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "实训数据不存在");
|
||||
}
|
||||
Step2 step = training2.getSteps().stream().filter(s -> Objects.equals(s.getId(), stepId))
|
||||
.findFirst().orElse(null);
|
||||
if (step == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "不存在步骤");
|
||||
}
|
||||
if (Objects.equals(user.getId(), step.getSimulationMember().getId())) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "无权限操作");
|
||||
}
|
||||
Operation2 operation = step.getOperations().stream().filter(o -> Objects.equals(o.getId(), id))
|
||||
.findFirst().orElse(null);
|
||||
if (operation == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "不存在操作");
|
||||
}
|
||||
operation.doOperated();
|
||||
// 恢复前端运行
|
||||
pauseOrStartSimulation(simulation, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Async("trainingV2Executor")
|
||||
@EventListener
|
||||
public void handle(SimulationOperationEvent event) {
|
||||
Simulation simulation = event.getSimulation();
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
if (training2 != null && Objects.equals(event.getSuccessful(), true)) {
|
||||
// 获取运行步骤
|
||||
Step2 step = training2.getCurrentRunStep();
|
||||
// 没找到返回
|
||||
if (step == null) {
|
||||
return;
|
||||
}
|
||||
// 角色不对
|
||||
if (!event.getMember().equals(step.getSimulationMember())) {
|
||||
return;
|
||||
}
|
||||
// 获取步骤中未完成的操作
|
||||
Operation2 operation2 = step.getCurrentRunOperation();
|
||||
if (operation2 == null) {
|
||||
return;
|
||||
}
|
||||
if (operation2 instanceof Operation2.SimOperation2) {
|
||||
Operation2.SimOperation2 simOperation2 = (Operation2.SimOperation2) operation2;
|
||||
if (simOperation2.getOperationType().name().equals(event.getOperate())
|
||||
&& Objects.equals(event.getParams(), simOperation2.getParams())) {
|
||||
operation2.doOperated(); // 标识已操作过
|
||||
} else {
|
||||
// 错误操作数增加
|
||||
operation2.getCount().incrementAndGet();
|
||||
// 错误提示
|
||||
// 发送操作完成信息
|
||||
sendOperationError(operation2, simulation);
|
||||
}
|
||||
// 操作完成后,如果是测验模式则仿真启动
|
||||
pauseOrStartSimulation(simulation, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 步骤提示
|
||||
*/
|
||||
public void sendStepTips(Step2 step, Simulation simulation) {
|
||||
SocketMessageVO<String> message =
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_Training_Step_Tip, simulation.getId(), step.getDescription());
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 步骤完成
|
||||
*/
|
||||
public void sendStepFinish(Step2 step, Simulation simulation) {
|
||||
if (Step2.StepStatus.isCompletion(step.getStepStatus())) {
|
||||
SocketMessageVO<String> message =
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_Training_Step_Finish, simulation.getId(), "步骤完成");
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作错误
|
||||
*/
|
||||
public void sendOperationError(Operation2 operation2, Simulation simulation) {
|
||||
SocketMessageVO<String> message =
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_Training_Operate_Error, simulation.getId(), "操作错误");
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作完成
|
||||
*/
|
||||
public void sendOperationFinish(Operation2 operation2, Simulation simulation) {
|
||||
if (Step2.StepStatus.isCompletion(operation2.getStatus())) {
|
||||
SocketMessageVO<String> message =
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_Training_Operate_Finish, simulation.getId(), "操作完成");
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实训完成发送消息
|
||||
*/
|
||||
public void sendTrainingFinish(Training2 training2, Simulation simulation) {
|
||||
if (training2.isFinish()) {
|
||||
SocketMessageVO<String> message =
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_Training_Finish, simulation.getId(), "实训完成");
|
||||
stompMessageService.sendToUser(simulation.getSimulationUserIds(), message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制草稿时加载实训背景
|
||||
* TODO 后续看根据需求是否加载到最后一步
|
||||
*/
|
||||
public void drawTraining(String group, Long trainingId) {
|
||||
DraftTraining2WithBLOBs draftTraining2 = draftTrainingDao.selectByPrimaryKey(trainingId);
|
||||
if (draftTraining2 == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Data_Not_Exist, "实训不存在");
|
||||
}
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
simulationLifeCycleService.pause(simulation);
|
||||
// 重置仿真状态
|
||||
groupSimulationService.planOver(group);
|
||||
// 场景的时候加载最后背景
|
||||
String bgSceneJson = draftTraining2.getBgSceneJson();
|
||||
if (Training2.Type.SCENE.name().equals(draftTraining2.getType())) {
|
||||
bgSceneJson = StringUtils.isEmpty(draftTraining2.getFinalScenesJson()) ? bgSceneJson
|
||||
: draftTraining2.getFinalScenesJson();
|
||||
}
|
||||
if (!StringUtils.isEmpty(bgSceneJson)) {
|
||||
groupSimulationService.loadScenes(simulation.getId(), bgSceneJson);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实训时创建仿真对象
|
||||
*/
|
||||
private Simulation createSimulation(Long mapId, LoginUserInfoVO loginUserInfoVO
|
||||
, Simulation.FunctionalType functionalType, DraftTraining2WithBLOBs draftTraining2) {
|
||||
// 构建仿真,加载背景,
|
||||
Simulation simulation = groupSimulationService.create(loginUserInfoVO, mapId, null, functionalType);
|
||||
// 加载实训信息
|
||||
loadTraining(simulation, draftTraining2, loginUserInfoVO);
|
||||
return simulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿真加载实训
|
||||
* 初始化仿真 -》 替换实训信息 -》 加载背景
|
||||
*/
|
||||
private void simulationLoadTraining(String group, DraftTraining2WithBLOBs draftTraining2, LoginUserInfoVO loginUserInfoVO) {
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
simulationLifeCycleService.pause(simulation);
|
||||
// 重置仿真状态
|
||||
groupSimulationService.planOver(group);
|
||||
// 加载实训信息
|
||||
loadTraining(simulation, draftTraining2, loginUserInfoVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载实训数据
|
||||
*/
|
||||
private void loadTraining(Simulation simulation, DraftTraining2WithBLOBs draftTraining2, LoginUserInfoVO loginUserInfoVO) {
|
||||
Training2 training2 = new Training2(draftTraining2, simulation);
|
||||
// 没有背景不做加载
|
||||
if (!StringUtils.isEmpty(training2.getBgSceneJson())) {
|
||||
groupSimulationService.loadScenes(simulation.getId(), training2.getBgSceneJson());
|
||||
}
|
||||
simulation.setTraining2(training2);
|
||||
// 如果是单操,设置为步骤指定角色
|
||||
if (Training2.Type.SINGLE.equals(training2.getType())) {
|
||||
String memberId = training2.getPlayerIds().stream().findFirst().orElse(null);
|
||||
if (memberId == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation
|
||||
, String.format("实训{id:[%s]}没有参训角色", training2.getId()));
|
||||
} else {
|
||||
memberManager.playRole(simulation, loginUserInfoVO.getAccountVO().getId(), memberId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断实训步骤是否完成
|
||||
*/
|
||||
private void checkTrainStepCompletion(Step2 step, Simulation simulation) {
|
||||
step.doCompletionVail();
|
||||
// 发送步骤完成信息
|
||||
sendStepFinish(step, simulation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停、恢复实训
|
||||
*/
|
||||
private void pauseOrStartSimulation(Simulation simulation, boolean isPause) {
|
||||
Training2 training2 = simulation.getTraining2();
|
||||
if (training2 == null) {
|
||||
return;
|
||||
}
|
||||
if (!ScriptBO.Mode.TEST_MODE.equals(training2.getMode())) {
|
||||
if (isPause) {
|
||||
simulation.onlyPause();
|
||||
} else {
|
||||
simulation.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验实训数据是否合规
|
||||
*/
|
||||
private Consumer<DraftTraining2WithBLOBs> trainingDataValid = (training) -> {
|
||||
if (!StringUtils.hasText(training.getPlayerIdJson())) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation
|
||||
, String.format("实训{id:[%s]}没有参训角色", training.getId()));
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package club.joylink.rtss.services.training2;
|
||||
/**
|
||||
* 实训类型(单操 single;场景scene)
|
||||
*/
|
||||
public enum Training2TypeEnum {
|
||||
single("single"),
|
||||
scene("scene"),
|
||||
;
|
||||
private String value;
|
||||
private Training2TypeEnum(String type){
|
||||
this.value=type;
|
||||
}
|
||||
public String value(){
|
||||
return this.value;
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ public interface IVoiceService {
|
||||
|
||||
VoiceRecognitionResult voiceRecognition(byte[] bytes, String filePath);
|
||||
|
||||
VoiceRecognitionResult voiceRecognition(String fileBase64);
|
||||
|
||||
/**
|
||||
* 语音合成,返回文件路径
|
||||
*
|
||||
|
@ -12,6 +12,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* 百度语音识别合成服务
|
||||
@ -58,6 +59,7 @@ public class BaiduVoiceServiceImpl implements IVoiceService {
|
||||
* 3314 用户输入错误 音频长度过短 音频长度的len参数不能小于等于4
|
||||
* 3315 服务端问题 语音服务器处理超时 请将api返回结果反馈至工单、论坛或者QQ群
|
||||
* 3316 用户输入错误 音频转为pcm失败 使用pcm格式,或者确认wav和amr的采样率16000,单声道。 wav文件需要是pcm编码,小端序,16bits
|
||||
*
|
||||
* @param errCode
|
||||
* @return
|
||||
*/
|
||||
@ -115,6 +117,18 @@ public class BaiduVoiceServiceImpl implements IVoiceService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoiceRecognitionResult voiceRecognition(String fileBase64) {
|
||||
try {
|
||||
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);
|
||||
} catch (Exception e) {
|
||||
throw BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION.exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String synthesis(String message, String per) {
|
||||
try {
|
||||
|
@ -1,68 +1,75 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//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);
|
||||
// }
|
||||
//}
|
||||
|
@ -10,6 +10,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
@Service("XunFeiVoiceService")
|
||||
public class XunFeiVoiceService implements IVoiceService {
|
||||
@ -57,6 +58,14 @@ public class XunFeiVoiceService implements IVoiceService {
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音识别失败");
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String synthesis(String message, String per) {
|
||||
return null;
|
||||
|
@ -22,7 +22,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
public abstract class Simulation<U extends SimulationUser, M extends SimulationMember> extends Watchable {
|
||||
public abstract class Simulation<U extends SimulationUser, M extends SimulationMember> extends Watchable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@ -82,8 +82,8 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
private Map<String, SimulationRepository> repositoryMap = new ConcurrentHashMap<>();
|
||||
@Setter
|
||||
private Map<String, M> simulationMemberMap = new ConcurrentHashMap<>();
|
||||
private Map<String, U> simulationUserMap = new ConcurrentHashMap<>();
|
||||
private Map<String, M> simulationMemberMap = new ConcurrentSkipListMap<>(); //2022-08-16 为前端展示成员有序
|
||||
private Map<String, U> simulationUserMap = new ConcurrentSkipListMap<>();
|
||||
private List<Operation> operationList = new ArrayList<>();
|
||||
private Map<String, Map<String, SimulationFaultVO>> deviceFaultMap = new ConcurrentHashMap<>();
|
||||
|
||||
@ -127,7 +127,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
}
|
||||
}
|
||||
long period = TimeUnit.MILLISECONDS.toNanos(BASE_RATE) / this.speed;
|
||||
ScheduledFuture<?> scheduledFuture = EXECUTOR.scheduleAtFixedRate(()->this.logic(),
|
||||
ScheduledFuture<?> scheduledFuture = EXECUTOR.scheduleAtFixedRate(() -> this.logic(),
|
||||
0, period, TimeUnit.NANOSECONDS);
|
||||
this.future = scheduledFuture;
|
||||
this.updateTimeUpdateSpeed(this.speed);
|
||||
@ -166,6 +166,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
/**
|
||||
* 仿真逻辑是否正在运行中(指代逻辑循环帧是否未完成)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isRunning() {
|
||||
@ -184,6 +185,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
this.systemTime = systemTime;
|
||||
this.jobMap.values().forEach(SimulationJob::updateRunTime);
|
||||
}
|
||||
|
||||
public LocalDateTime getSystemTime() {
|
||||
return this.systemTime;
|
||||
}
|
||||
@ -209,8 +211,9 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
/**
|
||||
* 添加定时仿真逻辑循环
|
||||
*
|
||||
* @param name 任务名称,同时也是id
|
||||
* @param job 仿真逻辑
|
||||
* @param job 仿真逻辑
|
||||
* @param rate 执行频率,单位ms
|
||||
*/
|
||||
public void addJob(String name, Runnable job, int rate) {
|
||||
@ -232,8 +235,9 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
/**
|
||||
* 添加固定频率运行的逻辑(可能主要是消息推送类逻辑)
|
||||
*
|
||||
* @param name 任务名称,同时也是id
|
||||
* @param job 仿真逻辑
|
||||
* @param job 仿真逻辑
|
||||
* @param rate 执行频率,单位ms
|
||||
*/
|
||||
public void addFixedRateJob(String name, Runnable job, int rate) {
|
||||
@ -249,6 +253,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
/**
|
||||
* 延时执行逻辑,只执行一次
|
||||
*
|
||||
* @param job
|
||||
* @param delay
|
||||
*/
|
||||
@ -259,6 +264,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
/**
|
||||
* 移除指定仿真任务逻辑循环
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void removeJob(String name) {
|
||||
@ -295,6 +301,13 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
log.debug(String.format("仿真[%s]暂停", this.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 只修改暂停状态
|
||||
*/
|
||||
public void onlyPause() {
|
||||
this.updateState(PAUSE);
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return this.state.get();
|
||||
}
|
||||
@ -313,6 +326,7 @@ public abstract class Simulation<U extends SimulationUser, M extends Simulation
|
||||
|
||||
/**
|
||||
* 更新仿真速度
|
||||
*
|
||||
* @param speed Simulation.MIN_SPEED <= speed <= Simulation.MAX_SPEED
|
||||
*/
|
||||
public void updateSpeed(int speed) {
|
||||
|
@ -0,0 +1,29 @@
|
||||
package club.joylink.rtss.simulation.cbtc.ATS;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.event.SimulationOperationEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AtsListener {
|
||||
/**
|
||||
* 计数字段名
|
||||
*/
|
||||
public static final String COUNT_PARAM_NAME = "_COUNT";
|
||||
|
||||
@EventListener
|
||||
public void handle(SimulationOperationEvent event) {
|
||||
if (event.getSuccessful() != null)
|
||||
return;
|
||||
String countName = (String) event.getParams().get(COUNT_PARAM_NAME);
|
||||
if (countName == null)
|
||||
return;
|
||||
MapElement device = event.getMember().getDevice();
|
||||
if (device instanceof Station) {
|
||||
Station station = (Station) device;
|
||||
station.count(countName);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -185,91 +185,19 @@ public class DriverOperateHandler {
|
||||
simulationRobotService.stopTrain(simulation, simulationMember, groupNumber, eb);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认运行至前方站
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Drive_Ahead)
|
||||
public void driveAhead(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.driveAhead(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路闭塞法行车
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Route_Block_Drive)
|
||||
public void routeBlockDrive(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.routeBlockDrive(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 越红灯行驶
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Drive_Through_The_Red_Light)
|
||||
public void driveThroughTheRedLight(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.driveThroughTheRedLight(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 越引导信号行驶
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Drive_Through_The_Guide_Signal)
|
||||
public void driveThroughTheGuideSignal(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.driveThroughTheGuideSignal(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开关门
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Open_Or_Close_Door)
|
||||
public void openOrCloseDoor(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
public void openOrCloseDoor(Simulation simulation, String groupNumber) {
|
||||
ATPService.openOrCloseDoor(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置限速
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Set_Speed_Limit)
|
||||
public void setSpeedLimit(Simulation simulation, SimulationMember simulationMember, String groupNumber, Float speedLimit) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.setSpeedLimit(simulation, groupNumber, speedLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 驾驶至
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Drive_To)
|
||||
public void driveTo(Simulation simulation, SimulationMember simulationMember, String groupNumber, String sectionCode) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.driveTo(simulation, groupNumber, sectionCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回库
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Inbound)
|
||||
public void inbound(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
public void inbound(Simulation simulation,String groupNumber) {
|
||||
ATPService.inbound(simulation, groupNumber);
|
||||
}
|
||||
|
||||
@ -277,11 +205,8 @@ public class DriverOperateHandler {
|
||||
* 修改预选模式
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Change_Preselection_Mode)
|
||||
public void changePreselectionMode(Simulation simulation, SimulationMember simulationMember, String groupNumber
|
||||
public void changePreselectionMode(Simulation simulation, String groupNumber
|
||||
, VirtualRealityTrain.PreselectionMode preselectionMode) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.changePreselectionMode(simulation, groupNumber, preselectionMode);
|
||||
}
|
||||
|
||||
@ -289,32 +214,7 @@ public class DriverOperateHandler {
|
||||
* 转NRM模式
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Apply_NRM)
|
||||
public void applyNRM(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
public void applyNRM(Simulation simulation, String groupNumber) {
|
||||
ATPService.applyNRM(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 大铁、发车
|
||||
**/
|
||||
@OperateHandlerMapping(type = Operation.Type.Depart_Train)
|
||||
public void departTrain(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.departTrain(simulation, groupNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 大铁、停车
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Parking_Train)
|
||||
public void parkingTrain(Simulation simulation, SimulationMember simulationMember, String groupNumber) {
|
||||
if (!SimulationMember.Type.DRIVER.equals(simulationMember.getType())) {
|
||||
throw new SimulationException(SimulationExceptionType.Member_Is_Not_Driver);
|
||||
}
|
||||
ATPService.parkingTrain(simulation, groupNumber);
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class SignalOperateHandler {
|
||||
// * @param simulation
|
||||
// * @param signalCode
|
||||
// */
|
||||
// @OperateHandlerMapping(type = Operation.Type.Signal_Force_Cancel_Route)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Signal_Force_Cancel_Route)
|
||||
// public void forceCancelRoute(Simulation simulation, String signalCode) {
|
||||
// Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode);
|
||||
// if (Objects.nonNull(route)) {
|
||||
@ -185,7 +185,7 @@ public class SignalOperateHandler {
|
||||
// * @param simulation
|
||||
// * @param routeCode
|
||||
// */
|
||||
// @OperateHandlerMapping(type = Operation.Type.Signal_Route_Guide)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Signal_Route_Guide)
|
||||
// public void settingGuideRoute(Simulation simulation, String routeCode) {
|
||||
// iciSubsystem.settingGuideRoute(simulation, routeCode);
|
||||
// }
|
||||
@ -253,7 +253,7 @@ public class SignalOperateHandler {
|
||||
// * @param simulation
|
||||
// * @param signalCode
|
||||
// */
|
||||
// @OperateHandlerMapping(type = Operation.Type.Signal_Open_Guide_Check_Switch)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Signal_Open_Guide_Check_Switch)
|
||||
// public void openGuideCheckSwitch(Simulation simulation, String signalCode) {
|
||||
// this.iciSubsystem.openGuideSignalCheckSwitch(simulation, signalCode);
|
||||
// }
|
||||
@ -263,7 +263,7 @@ public class SignalOperateHandler {
|
||||
// * @param simulation
|
||||
// * @param signalCode
|
||||
// */
|
||||
// @OperateHandlerMapping(type = Operation.Type.Signal_Open_Guide_Check_Route)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Signal_Open_Guide_Check_Route)
|
||||
// public void openGuideCheckRoute(Simulation simulation, String signalCode) {
|
||||
// this.iciSubsystem.openGuideSignalCheckRoute(simulation, signalCode);
|
||||
// }
|
||||
|
@ -96,7 +96,7 @@ public class SwitchOperateHandler {
|
||||
}
|
||||
|
||||
// /**道岔定操(联动)*/
|
||||
// @OperateHandlerMapping(type = Operation.Type.Switch_Turn_NP_Chain)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Switch_Turn_NP_Chain)
|
||||
// public void chainTurn2Normal(Simulation simulation, String switchCode) {
|
||||
// this.turn2Normal(simulation, switchCode);
|
||||
// SimulationDataRepository repository = simulation.getRepository();
|
||||
@ -108,7 +108,7 @@ public class SwitchOperateHandler {
|
||||
// }
|
||||
|
||||
// /**道岔反操(联动)*/
|
||||
// @OperateHandlerMapping(type = Operation.Type.Switch_Turn_RP_Chain)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Switch_Turn_RP_Chain)
|
||||
// public void chainTurn2Reverse(Simulation simulation, String switchCode) {
|
||||
// this.turn2Reverse(simulation, switchCode);
|
||||
// SimulationDataRepository repository = simulation.getRepository();
|
||||
@ -153,7 +153,7 @@ public class SwitchOperateHandler {
|
||||
}
|
||||
|
||||
// /**道岔单锁(联动)*/
|
||||
// @OperateHandlerMapping(type =Operation.Type.Switch_Single_Lock_Chain)
|
||||
// @OperateHandlerMapping(type =Operation2.Type.Switch_Single_Lock_Chain)
|
||||
// public void chainSingleLockSwitch(Simulation simulation, String switchCode) {
|
||||
// SimulationDataRepository repository = simulation.getRepository();
|
||||
// Switch aSwitch = repository.getByCode(switchCode, Switch.class);
|
||||
@ -165,7 +165,7 @@ public class SwitchOperateHandler {
|
||||
// }
|
||||
|
||||
// /**道岔单解(联动)*/
|
||||
// @OperateHandlerMapping(type =Operation.Type.Switch_Single_Unlock_Chain)
|
||||
// @OperateHandlerMapping(type =Operation2.Type.Switch_Single_Unlock_Chain)
|
||||
// public void chainSingleUnlockSwitch(Simulation simulation, String switchCode) {
|
||||
// SimulationDataRepository repository = simulation.getRepository();
|
||||
// Switch aSwitch = repository.getByCode(switchCode, Switch.class);
|
||||
|
@ -237,7 +237,7 @@ public class TrainOperateHandler {
|
||||
// /**
|
||||
// * 删除ID
|
||||
// */
|
||||
// @OperateHandlerMapping(type = Operation.Type.Train_Delete_Service_Number)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Train_Delete_Service_Number)
|
||||
// public void deleteServiceNumber(Simulation simulation, String groupNumber) {
|
||||
// atsTrainService.deleteServiceNumber(simulation, groupNumber);
|
||||
// }
|
||||
@ -245,7 +245,7 @@ public class TrainOperateHandler {
|
||||
// /**
|
||||
// * 修改目的地码
|
||||
// */
|
||||
// @OperateHandlerMapping(type = Operation.Type.Train_Change_Destination_Code)
|
||||
// @OperateHandlerMapping(type = Operation2.Type.Train_Change_Destination_Code)
|
||||
// public void changeDestinationCode(Simulation simulation, String groupNumber, String destinationCode) {
|
||||
// atsTrainService.changeDestinationCode(simulation, groupNumber, destinationCode);
|
||||
// }
|
||||
@ -277,6 +277,15 @@ public class TrainOperateHandler {
|
||||
/**
|
||||
* 列车托管。使用司机的驾驶指令
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Train_Drive)
|
||||
public void drive(Simulation simulation, String groupNumber, DriveParamVO param) {
|
||||
atsTrainService.trust(simulation, groupNumber, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列车托管。使用司机的驾驶指令
|
||||
* TODO 后续同Train_Trust一起删除
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Train_Trust)
|
||||
public void trust(Simulation simulation, String groupNumber, DriveParamVO param) {
|
||||
atsTrainService.trust(simulation, groupNumber, param);
|
||||
|
@ -1,318 +1,320 @@
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.service;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
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.data.status.RouteStatus;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AtsRouteService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
|
||||
@Autowired
|
||||
private CiApiService ciApiService;
|
||||
|
||||
/**
|
||||
* 进路收人工控
|
||||
*
|
||||
* @param simulation
|
||||
* @param signalCode
|
||||
* @param routeCodeList
|
||||
*/
|
||||
public void setRouteHumanControl(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
routeCodeList.forEach(routeCode -> {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
route.setAtsControl(false);
|
||||
});
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路交自动控
|
||||
*/
|
||||
public void setRouteAtsControl(Simulation simulation, String signalCode,
|
||||
List<String> routeCodeList, List<Boolean> checkConflictList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
if (!CollectionUtils.isEmpty(checkConflictList)) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(routeCodeList.size() == checkConflictList.size(),
|
||||
String.format("进路数和是否检查冲突数量不一致:[%s], [%s]",
|
||||
String.join(",", routeCodeList),
|
||||
String.join(",", checkConflictList.stream().map(String::valueOf).collect(Collectors.toList()))));
|
||||
}
|
||||
List<Route> routes = routeCodeList.stream().map(routeCode -> repository.getByCode(routeCode, Route.class)).collect(Collectors.toList());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routes.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isCiControl(),
|
||||
String.format("信号机[%s]需处于人工控状态", signal.getCode())));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(checkConflictList)) {
|
||||
routes.forEach(route -> route.setAtsControl(true));
|
||||
} else {
|
||||
for (int i = 0; i < routeCodeList.size(); i++) {
|
||||
Route route = repository.getByCode(routeCodeList.get(i), Route.class);
|
||||
boolean checkConflict = checkConflictList.get(i);
|
||||
route.setAtsControl(true);
|
||||
route.setCheckConflict(checkConflict);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode()));
|
||||
}
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询进路状态/模式
|
||||
*/
|
||||
public List<RouteStatus> findRoutesStatus(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
return routeList.stream().map(RouteStatus::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动进路
|
||||
*/
|
||||
public void setCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) {
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能设置联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFlt()) {
|
||||
throw new SimulationException(SimulationExceptionType.Unsupported_Operation,
|
||||
String.format("进路[%s]不能设置车队进路", lockedRoute.getCode()));
|
||||
}
|
||||
if (lockedRoute.isCiControl()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动追踪已开启,不能设置联锁自动进路", lockedRoute.getName(), lockedRoute.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(true);
|
||||
} else {
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, signal.debugStr() + "不是进路始端信号机");
|
||||
// 筛选最适合的进路,筛选逻辑与办理引导时筛选逻辑类似
|
||||
List<Route> fltRoutes = routeList.stream().filter(Route::isFlt).collect(Collectors.toList());
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(fltRoutes, signal.debugStr() + "下没有可设置的车队进路");
|
||||
List<Route> collect = fltRoutes.stream()
|
||||
.filter(r -> !r.isTurnBack() && CollectionUtils.isEmpty(r.getSwitchList()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes.stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes;
|
||||
}
|
||||
Route route = collect.get(0);
|
||||
Route.CheckFailMessage message = routeService.setRoute(simulation, route);
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(message, route.debugStr() + "无法办理");
|
||||
route.setFleetMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动进路
|
||||
*/
|
||||
public void cancelCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (Objects.isNull(lockedRoute)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能执行取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("信号机[%s(%s)]没有打开连锁自动进路,不能取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(false);
|
||||
if (simulation.getRepository().getConfig().isCancelRouteWhenCancelFlt()) {
|
||||
routeService.unlockRoute(simulation, lockedRoute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动触发
|
||||
*/
|
||||
public void setCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Route> routeList;
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode()));
|
||||
}
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodeList.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routeList.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isAtsControl(),
|
||||
String.format("信号机[%s]需处于人工控", signal.getCode())));
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.stream().filter(Route::isArs).forEach(route -> {
|
||||
if (route.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode()));
|
||||
}
|
||||
// if (route.isCiControl()) {
|
||||
// throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode()));
|
||||
// }
|
||||
});
|
||||
for (Route route : routeList) {
|
||||
// route.setAtsControl(false);
|
||||
if (route.isArs())
|
||||
route.setCiControl(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动触发
|
||||
*/
|
||||
public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodes) {
|
||||
List<Route> routeList;
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodes.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
for (Route route : routeList) {
|
||||
if (route.isCiControl()) {
|
||||
route.setCiControl(false);
|
||||
route.setAtsControl(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动折返进路
|
||||
*
|
||||
* @param simulation
|
||||
* @param cycleCode
|
||||
*/
|
||||
public void setAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消自动折返进路
|
||||
*/
|
||||
public void cancelAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 总取消
|
||||
*/
|
||||
public void totalCancel(Simulation simulation, String signalCode) {
|
||||
// todo 总取消操作有很多种操作方式,对应不同的按钮,此处都用信号机编号可能不妥
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,无需取消进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!signal.isApproachLock()) { //当接近区段未被占用
|
||||
this.cancelRoute(simulation, signalCode);
|
||||
} else {
|
||||
this.routeService.unlockRoute(simulation, lockedRoute);
|
||||
this.ciApiService.cancelFleetRoute(simulation, lockedRoute.getCode());
|
||||
// if (signal.isGuideAspect()) { //如果引导信号开启中
|
||||
// this.ciApiService.closeGuideSignal(simulation, signalCode);
|
||||
// } else if (signal.isClose()) { //如果信号灯关了
|
||||
// } else {
|
||||
// this.ciApiService.closeSignal(simulation, signalCode);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelRoute(Simulation simulation, String signalCode) {
|
||||
Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode);
|
||||
if (Objects.nonNull(route)) {
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.isApproachLock(), "进路接近锁闭,无法取消");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.getStart().isGuideAspect(), "引导进路,需要人解进路");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(),
|
||||
String.format("进路[%s]已开启自动通过进路,无法取消", route.debugStr()));
|
||||
this.ciApiService.unlockRoute(simulation, route.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void setOverlap(Simulation simulation, String signalCode, String overlapCode) {
|
||||
if (signalCode == null || overlapCode == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Illegal_Argument);
|
||||
}
|
||||
this.ciApiService.setOverlap(simulation, signalCode, overlapCode);
|
||||
}
|
||||
|
||||
public void conflictRouteSetConfirm(Simulation simulation, SimulationMember member, String routeCode, int way) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(
|
||||
Route.Conflict_Handle_Way_1 == way || Route.Conflict_Handle_Way_2 == way
|
||||
);
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
AtsAlarm conflictAlarm = route.getConflictAlarm();
|
||||
if (conflictAlarm != null) {
|
||||
LocalDateTime systemTime = simulation.getCorrectSystemTime();
|
||||
conflictAlarm.confirm(systemTime, member, way);
|
||||
conflictAlarm.recover(systemTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.ATS.service;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.data.AtsAlarm;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
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.data.status.RouteStatus;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AtsRouteService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService routeService;
|
||||
|
||||
@Autowired
|
||||
private CiApiService ciApiService;
|
||||
|
||||
/**
|
||||
* 进路收人工控
|
||||
*
|
||||
* @param simulation
|
||||
* @param signalCode
|
||||
* @param routeCodeList
|
||||
*/
|
||||
public void setRouteHumanControl(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
routeCodeList.forEach(routeCode -> {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
route.setAtsControl(false);
|
||||
});
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进路交自动控
|
||||
*/
|
||||
public void setRouteAtsControl(Simulation simulation, String signalCode,
|
||||
List<String> routeCodeList, List<Boolean> checkConflictList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (!CollectionUtils.isEmpty(routeCodeList)) {
|
||||
if (!CollectionUtils.isEmpty(checkConflictList)) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(routeCodeList.size() == checkConflictList.size(),
|
||||
String.format("进路数和是否检查冲突数量不一致:[%s], [%s]",
|
||||
String.join(",", routeCodeList),
|
||||
String.join(",", checkConflictList.stream().map(String::valueOf).collect(Collectors.toList()))));
|
||||
}
|
||||
List<Route> routes = routeCodeList.stream().map(routeCode -> repository.getByCode(routeCode, Route.class)).collect(Collectors.toList());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routes.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isCiControl(),
|
||||
String.format("信号机[%s]需处于人工控状态", signal.getCode())));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(checkConflictList)) {
|
||||
routes.forEach(route -> route.setAtsControl(true));
|
||||
} else {
|
||||
for (int i = 0; i < routeCodeList.size(); i++) {
|
||||
Route route = repository.getByCode(routeCodeList.get(i), Route.class);
|
||||
boolean checkConflict = checkConflictList.get(i);
|
||||
route.setAtsControl(true);
|
||||
route.setCheckConflict(checkConflict);
|
||||
}
|
||||
}
|
||||
} else if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isCiControl(), String.format("信号机[%s]需处于人工控状态", signal.getCode()));
|
||||
}
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.forEach(route -> route.setAtsControl(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询进路状态/模式
|
||||
*/
|
||||
public List<RouteStatus> findRoutesStatus(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
return routeList.stream().map(RouteStatus::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动进路
|
||||
*/
|
||||
public void setCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
if (simulation.getRepository().getConfig().isSetRouteBeforeSetFlt()) {
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能设置联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFlt()) {
|
||||
throw new SimulationException(SimulationExceptionType.Unsupported_Operation,
|
||||
String.format("进路[%s]不能设置车队进路", lockedRoute.getCode()));
|
||||
}
|
||||
if (lockedRoute.isCiControl()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动追踪已开启,不能设置联锁自动进路", lockedRoute.getName(), lockedRoute.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(true);
|
||||
} else {
|
||||
List<Route> routeList = signal.getRouteList();
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(routeList, signal.debugStr() + "不是进路始端信号机");
|
||||
// 筛选最适合的进路,筛选逻辑与办理引导时筛选逻辑类似
|
||||
List<Route> fltRoutes = routeList.stream().filter(Route::isFlt).collect(Collectors.toList());
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertCollectionNotEmpty(fltRoutes, signal.debugStr() + "下没有可设置的车队进路");
|
||||
List<Route> collect = fltRoutes.stream()
|
||||
.filter(r -> !r.isTurnBack() && CollectionUtils.isEmpty(r.getSwitchList()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes.stream().filter(r -> !r.isTurnBack()).collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(collect)) {
|
||||
collect = fltRoutes;
|
||||
}
|
||||
Route route = collect.get(0);
|
||||
Route.CheckFailMessage message = routeService.setRoute(simulation, route,route.getAspect());
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNull(message, route.debugStr() + "无法办理");
|
||||
route.setFleetMode(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动进路
|
||||
*/
|
||||
public void cancelCiAuto(Simulation simulation, String signalCode) {
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (Objects.isNull(lockedRoute)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,不能执行取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!lockedRoute.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("信号机[%s(%s)]没有打开连锁自动进路,不能取消联锁自动进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
lockedRoute.setFleetMode(false);
|
||||
if (simulation.getRepository().getConfig().isCancelRouteWhenCancelFlt()) {
|
||||
routeService.unlockRoute(simulation, lockedRoute);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置联锁自动触发
|
||||
*/
|
||||
public void setCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodeList) {
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
List<Route> routeList;
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(signal.isAtsControl(), String.format("信号机[%s]需处于人工控", signal.getCode()));
|
||||
}
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodeList.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
if (repository.getConfig().isSignalHumanControlBeforeSetAtsControlOrCIAutoTrigger()) {
|
||||
routeList.stream()
|
||||
.map(Route::getStart)
|
||||
.distinct()
|
||||
.forEach(signal ->
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED
|
||||
.assertNotTrue(signal.isAtsControl(),
|
||||
String.format("信号机[%s]需处于人工控", signal.getCode())));
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
routeList.stream().filter(Route::isArs).forEach(route -> {
|
||||
if (route.isFleetMode()) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Conflict,
|
||||
String.format("进路[%s(%s)]自动通过已开启,不能设置自动追踪", route.getName(), route.getCode()));
|
||||
}
|
||||
// if (route.isCiControl()) {
|
||||
// throw new SimulationException(SimulationExceptionType.Operation_Repetition, String.format("进路[%s(%s)]自动追踪/连锁自动触发已开启,无需重复设置", route.getName(), route.getCode()));
|
||||
// }
|
||||
});
|
||||
for (Route route : routeList) {
|
||||
// route.setAtsControl(false);
|
||||
if (route.isArs())
|
||||
route.setCiControl(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消联锁自动触发
|
||||
*/
|
||||
public void cancelCiAutoTrigger(Simulation simulation, String signalCode, List<String> routeCodes) {
|
||||
List<Route> routeList;
|
||||
SimulationDataRepository repository = simulation.getRepository();
|
||||
if (StringUtils.hasText(signalCode)) {
|
||||
Signal signal = repository.getByCode(signalCode, Signal.class);
|
||||
routeList = signal.getRouteList();
|
||||
} else {
|
||||
routeList = routeCodes.stream()
|
||||
.map(code -> repository.getByCode(code, Route.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(routeList)) {
|
||||
for (Route route : routeList) {
|
||||
if (route.isCiControl()) {
|
||||
route.setCiControl(false);
|
||||
route.setAtsControl(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动折返进路
|
||||
*
|
||||
* @param simulation
|
||||
* @param cycleCode
|
||||
*/
|
||||
public void setAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消自动折返进路
|
||||
*/
|
||||
public void cancelAutoTurnBack(Simulation simulation, String cycleCode) {
|
||||
Cycle cycle = simulation.getRepository().getByCode(cycleCode, Cycle.class);
|
||||
cycle.setSetUp(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 总取消
|
||||
*/
|
||||
public void totalCancel(Simulation simulation, String signalCode) {
|
||||
// todo 总取消操作有很多种操作方式,对应不同的按钮,此处都用信号机编号可能不妥
|
||||
Signal signal = simulation.getRepository().getByCode(signalCode, Signal.class);
|
||||
Route lockedRoute = signal.getLockedRoute();
|
||||
if (lockedRoute == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL,
|
||||
String.format("信号机[%s(%s)]没有已锁闭进路,无需取消进路", signal.getName(), signal.getCode()));
|
||||
}
|
||||
if (!signal.isApproachLock()) { //当接近区段未被占用
|
||||
this.cancelRoute(simulation, signalCode);
|
||||
} else {
|
||||
this.routeService.unlockRoute(simulation, lockedRoute);
|
||||
this.ciApiService.cancelFleetRoute(simulation, lockedRoute.getCode());
|
||||
// if (signal.isGuideAspect()) { //如果引导信号开启中
|
||||
// this.ciApiService.closeGuideSignal(simulation, signalCode);
|
||||
// } else if (signal.isClose()) { //如果信号灯关了
|
||||
// } else {
|
||||
// this.ciApiService.closeSignal(simulation, signalCode);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelRoute(Simulation simulation, String signalCode) {
|
||||
Route route = this.ciApiService.findLockedRouteByStartSignal(simulation, signalCode);
|
||||
if (Objects.nonNull(route)) {
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.isApproachLock(), "进路接近锁闭,无法取消");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
route.getStart().isGuideAspect(), "引导进路,需要人解进路");
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotTrue(route.isFleetMode(),
|
||||
String.format("进路[%s]已开启自动通过进路,无法取消", route.debugStr()));
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertNotTrue(
|
||||
Objects.nonNull(route.getDelayUnlockDevice()), String.format("进路[%s]已经开启延时取消,无法手动取消", route.debugStr()));
|
||||
this.ciApiService.unlockRoute(simulation, route.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public void setOverlap(Simulation simulation, String signalCode, String overlapCode) {
|
||||
if (signalCode == null || overlapCode == null) {
|
||||
throw new SimulationException(SimulationExceptionType.Illegal_Argument);
|
||||
}
|
||||
this.ciApiService.setOverlap(simulation, signalCode, overlapCode);
|
||||
}
|
||||
|
||||
public void conflictRouteSetConfirm(Simulation simulation, SimulationMember member, String routeCode, int way) {
|
||||
BusinessExceptionAssertEnum.ARGUMENT_ILLEGAL.assertTrue(
|
||||
Route.Conflict_Handle_Way_1 == way || Route.Conflict_Handle_Way_2 == way
|
||||
);
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
AtsAlarm conflictAlarm = route.getConflictAlarm();
|
||||
if (conflictAlarm != null) {
|
||||
LocalDateTime systemTime = simulation.getCorrectSystemTime();
|
||||
conflictAlarm.confirm(systemTime, member, way);
|
||||
conflictAlarm.recover(systemTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,19 +86,6 @@ public class AtsStationService {
|
||||
*/
|
||||
public void applyForStationControl(Simulation simulation, SimulationMember fromMember, List<String> stationCodes) {
|
||||
this.controlTransfer(simulation, fromMember, stationCodes, Station.ControlMode.Local);
|
||||
|
||||
/*//转移角色的目标成员
|
||||
List<SimulationMember> targetMembers = null;
|
||||
if(SimulationMember.Type.STATION_SUPERVISOR.equals(fromMember.getType())){
|
||||
log.debug("现地请求站控");
|
||||
targetMembers = simulation.findMemberListByRole(SimulationMember.Type.DISPATCHER);
|
||||
}
|
||||
else if(SimulationMember.Type.DISPATCHER.equals(fromMember.getType())){
|
||||
log.debug("行调请求站控");
|
||||
targetMembers = simulation.findMemberListByRole(SimulationMember.Type.STATION_SUPERVISOR);
|
||||
}
|
||||
transferControl(simulation, fromMember, stationCodes, targetMembers, Operation.Type.CM_Apply_For_Station_Control);*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,23 +93,6 @@ public class AtsStationService {
|
||||
*/
|
||||
public void applyForCenterControl(Simulation simulation, SimulationMember fromMember, List<String> stationCodes) {
|
||||
this.controlTransfer(simulation, fromMember, stationCodes, Station.ControlMode.Center);
|
||||
|
||||
/*if(CollectionUtils.isEmpty(stationCodes)){
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL, "请求中控的车站不能为空");
|
||||
}
|
||||
|
||||
//转移角色的目标成员
|
||||
List<SimulationMember> targetMembers = null;
|
||||
if(SimulationMember.Type.STATION_SUPERVISOR.equals(fromMember.getType())){
|
||||
log.debug("现地请求中控");
|
||||
targetMembers = simulation.findMemberListByRole(SimulationMember.Type.DISPATCHER);
|
||||
}
|
||||
else if(SimulationMember.Type.DISPATCHER.equals(fromMember.getType())){
|
||||
log.debug("行调请求中控");
|
||||
targetMembers = simulation.findMemberListByRole(SimulationMember.Type.STATION_SUPERVISOR);
|
||||
}
|
||||
transferControl(simulation, fromMember, stationCodes, targetMembers, Operation.Type.CM_Apply_For_Center_Control);*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,31 +460,48 @@ public class AtsTrainService {
|
||||
}
|
||||
//找要越过的信号机
|
||||
Section section = headPosition.getSection();
|
||||
if (param.isThroughRedSignal()) {
|
||||
if (param.isThroughRedSignal()) { // 越红灯行驶
|
||||
Signal signal = section.getSignalOf(right);
|
||||
boolean b = false;
|
||||
if (signal != null && signal.getPosition().isAheadOf(headPosition, right)) {
|
||||
VirtualRealitySignal vrSignal = signal.getVirtualSignal();
|
||||
b = vrSignal != null && vrSignal.getModel().getDefaultAspect().equals(vrSignal.getAspect());
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, "需要车头所在区段前方有同向信号机,且同向信号机为禁止信号");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, "需要车头所在区段前方有同向信号机,且为禁止信号");
|
||||
param.setThroughSignal(signal);
|
||||
param.setThroughSignalAspect(signal.getVirtualSignal().getModel().getDefaultAspect());
|
||||
} else if (param.isThroughGuideSignal()) {
|
||||
param.setThroughSignalAspect(signal.getDefaultAspect());
|
||||
} else if (param.isThroughGuideSignal()) { // 越引导行驶
|
||||
Signal signal = section.getSignalOf(right);
|
||||
boolean b = false;
|
||||
if (signal != null && signal.getPosition().isAheadOf(headPosition, right)) {
|
||||
VirtualRealitySignal vrSignal = signal.getVirtualSignal();
|
||||
b = vrSignal != null && vrSignal.getModel().getGuideAspect().equals(vrSignal.getAspect());
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, "需要车头所在区段前方有同向信号机,且同向信号机为引导信号");
|
||||
BusinessExceptionAssertEnum.OPERATION_FAIL.assertTrue(b, "需要车头所在区段前方有同向信号机,且为引导信号");
|
||||
param.setThroughSignal(signal);
|
||||
param.setThroughSignalAspect(signal.getVirtualSignal().getModel().getDefaultAspect());
|
||||
} else {
|
||||
param.setThroughSignalAspect(signal.getGuideAspect());
|
||||
} else if (param.isDriverNextStand()){ // 行驶至前方车站
|
||||
// 列车车头所在区段
|
||||
Section headSection = train.getHeadPosition().getSection();
|
||||
// 停车目的区段
|
||||
if (section.isStandTrack()) {
|
||||
targetPosition = new SectionPosition(headSection, headSection.getStopPointByDirection(train.isRight()));
|
||||
} else {
|
||||
targetPosition = train.calculateNextStandStopPosition();
|
||||
if (targetPosition == null && train.getTarget() != null) {
|
||||
targetPosition = new SectionPosition(train.getTarget(), train.getTarget().getStopPointByDirection(train.isRight()));
|
||||
}
|
||||
BusinessExceptionAssertEnum.OPERATION_NOT_SUPPORTED.assertNotNull(targetPosition, train.debugStr() + "找不到下一个停车点");
|
||||
}
|
||||
atpService.changePreselectionMode(train, VirtualRealityTrain.PreselectionMode.RM);
|
||||
} else if (param.isRouteBlockDriver()) { // 进路闭塞行车
|
||||
if (!train.isAMMode()) {
|
||||
atpService.changePreselectionMode(train, VirtualRealityTrain.PreselectionMode.AM_C);
|
||||
}
|
||||
}else {
|
||||
param.setThroughSignal(null);
|
||||
param.setThroughSignalAspect(null);
|
||||
}
|
||||
|
||||
param.setTargetPosition(targetPosition);
|
||||
train.setRobotDriveParam(param);
|
||||
}
|
||||
|
@ -248,6 +248,15 @@ public abstract class AtsRouteSelectService {
|
||||
Route route = null;
|
||||
for (Route temp : triggerList) {
|
||||
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
|
||||
if(null==switchList||switchList.isEmpty()){
|
||||
log.debug("==============================================================================");
|
||||
log.debug("==>>异常进路code = {} name = {}",temp.getCode(),temp.getName());
|
||||
log.debug("==>>异常相关所有进路:");
|
||||
triggerList.forEach(r->{
|
||||
log.debug("==>>进路code={} name={} , 始端信号机code={} name={}",r.getCode(),r.getName(),r.getStart().getCode(),r.getName());
|
||||
});
|
||||
log.debug("==============================================================================");
|
||||
}
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertCollectionNotEmpty(switchList,
|
||||
String.format("列车[%s]过滤进路异常:进路不是延续保护差异进路[%s]",
|
||||
trainInfo.getGroupNumber(),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,10 @@ import java.util.Objects;
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CiLogic {
|
||||
interface JobName {
|
||||
String SECTION_STOP_COUNTDOWN = "SECTION_STOP_COUNTDOWN";
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private CiDeviceStatusCollector deviceStatusCollector;
|
||||
@Autowired
|
||||
@ -78,34 +82,76 @@ public class CiLogic {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 区段停稳倒计时
|
||||
*/
|
||||
public void sectionStopCountDown(Simulation simulation) {
|
||||
for (Section section : simulation.getRepository().getHasStopCountDownSections()) {
|
||||
int stopCountDown = section.getStopCountDown();
|
||||
if (stopCountDown == 0) {
|
||||
//股道占用且股道有占用
|
||||
if (section.isOccupied()) {
|
||||
if (section.getNextRunningSectionOf(false).isOccupied() || section.getNextRunningSectionOf(true).isOccupied()) {
|
||||
section.readyStartStopCountDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stopCountDown == -1) {
|
||||
// 股道占用、股道两边没有占用、股道没有进路锁闭或该进路正在正常解锁
|
||||
if (section.isOccupied()) {
|
||||
if ((!section.getNextRunningSectionOf(false).isOccupied()
|
||||
&& !section.getNextRunningSectionOf(true).isOccupied())
|
||||
&& (section.getRoute() == null || section.getRoute().isNormalUnlock())) {
|
||||
section.startStopCountDown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
section.setStopCountDown(stopCountDown - SimulationConstants.CI_LOOP_RATE);
|
||||
if (stopCountDown <= 0) {
|
||||
section.setStopCountDown(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void signalMonitor(Simulation simulation, Signal signal) {
|
||||
signalControlService.controlLightOfSignal(simulation, signal);
|
||||
//控制通过信号机的显示:信号机前第一个区段被占用开红灯;第二个区段被占用开黄灯;否则开绿灯
|
||||
if (signal.isPassingSignal()) {
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
boolean right = signal.isRight();
|
||||
Section section = signal.getSection();
|
||||
Section one = section.getNextSection(right);
|
||||
if (one == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (one.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
|
||||
return;
|
||||
}
|
||||
Section two = one.getNextSection(right);
|
||||
if (two == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (two.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
|
||||
return;
|
||||
}
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
if (simulation.getRepository().getConfig().isRailway()) {
|
||||
railwaySignalMonitor(simulation, signal);
|
||||
}
|
||||
}
|
||||
|
||||
private void railwaySignalMonitor(Simulation simulation, Signal signal) {
|
||||
if (signal.isGuideAspect() && signal.getLockedRoute() == null) { //引导总锁后开放的引导信号
|
||||
if (signal.getRouteList().stream().noneMatch(Route::isAnySwitchMasterLock)) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, signal.getDefaultAspect());
|
||||
}
|
||||
}
|
||||
if (signal.isPassingSignal()) {
|
||||
boolean right = signal.isRight();
|
||||
Section section = signal.getSection();
|
||||
Section one = section.getNextSection(right);
|
||||
if (one == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (one.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.R);
|
||||
return;
|
||||
}
|
||||
Section two = one.getNextSection(right);
|
||||
if (two == null) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
return;
|
||||
}
|
||||
if (two.isOccupied()) {
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.Y);
|
||||
return;
|
||||
}
|
||||
signalControlService.controlSignalAspect(simulation, signal, SignalAspect.G);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,11 +164,11 @@ public class CiLogic {
|
||||
MapConfig config = simulation.getRepository().getConfig();
|
||||
if (route.isCiControl()) { // 进路联锁自动触发
|
||||
if (!route.isLock() && !route.isSetting() && ciService.isCiRouteTrigger(simulation, route)) {
|
||||
routeService.setRoute(simulation, route);
|
||||
routeService.setRoute(simulation, route, route.getAspect());
|
||||
}
|
||||
} else if (route.isFleetMode()) { // 联锁自动进路
|
||||
if (ciService.isCiRouteTrigger(simulation, route)) {
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getAspect());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation, route.getStart(), route.getSettedAspect());
|
||||
}
|
||||
}
|
||||
if (route.isSetting() || route.isLock() || route.isNormalUnlock()) { // 监控中的进路
|
||||
@ -165,7 +211,7 @@ public class CiLogic {
|
||||
} else if (start.isDefaultAspect() && !start.isForbidden() && !start.isBlockade() && start.isSupportMainAspect()) {
|
||||
CiLogic.log.info("进路[{}]联锁条件满足,开放信号", route.debugStr());
|
||||
signalControlService.tryControlSignalAspectAccordingLevel(simulation,
|
||||
start, route.getAspect());
|
||||
start, route.getSettedAspect());
|
||||
}
|
||||
} else {
|
||||
if (route.isOpenMain() && !start.isSupportMainAspect()) {//与联锁显示不同,关闭信号
|
||||
@ -234,5 +280,6 @@ public class CiLogic {
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.CI.name(), () -> run(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
simulation.addJob(JobName.SECTION_STOP_COUNTDOWN, () -> sectionStopCountDown(simulation), SimulationConstants.CI_LOOP_RATE);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class StationDirection extends MayOutOfOrderDevice {
|
||||
public class StationDirection extends MayOutOfOrderDevice implements Cloneable {
|
||||
/**
|
||||
* 发辅助默认倒计时 25s
|
||||
*/
|
||||
@ -70,6 +70,8 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
* 相对运行方向
|
||||
*/
|
||||
private StationDirection relativeStationDirection;
|
||||
|
||||
private Station relativeStation;
|
||||
/**************************************** 初始数据配置信息 **********************************************/
|
||||
|
||||
/***************************************** 联锁指示灯状态 ***********************************************/
|
||||
@ -170,6 +172,7 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
/***************************************** 半自动闭塞按钮状态 ******************************************/
|
||||
|
||||
/***************************************** 关联进路信息 ***********************************************/
|
||||
|
||||
/**
|
||||
* 当前进路列表
|
||||
*/
|
||||
@ -201,7 +204,32 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
* 默认方向
|
||||
*/
|
||||
private Boolean right;
|
||||
/***************************************** 车务终端管理出入口方向相关属性begin **********************************************/
|
||||
private IODirection ioDirection;
|
||||
/**
|
||||
* 允许超限列车
|
||||
* 选择“是/否”。
|
||||
* 1.普速铁路一般选择“是”(有明确不允许超限列
|
||||
* 车的选择“否”)。
|
||||
* 2.高速铁路一般选择“否”(200km/h 客货共线铁路
|
||||
* 根据文件确定)
|
||||
*/
|
||||
private boolean allowOverrun;
|
||||
|
||||
/**
|
||||
* 允许旅客列车
|
||||
* 选择“是/否”。两线、多线区间根据《行规》列
|
||||
* 车运行分工选择
|
||||
*/
|
||||
private boolean travelTrain;
|
||||
|
||||
/**
|
||||
* 允许货物列车
|
||||
* 选择“是/否”。两线、多线区间根据《行规》列
|
||||
* 车运行分工选择。
|
||||
*/
|
||||
private boolean goodsTrain;
|
||||
/***************************************** 车务终端管理出入口方向相关属性begin **********************************************/
|
||||
// TODO: 待数据统一之后,这个构造函数代码可删除 20220714
|
||||
public StationDirection(String code, String name, DirectionLabelEnum labelEnum) {
|
||||
this(code, name);
|
||||
@ -211,7 +239,17 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
this.defaultRunStatus = this.getDefaultReceiveAndDeliver();
|
||||
this.currentRouteList = getNowRouteList();
|
||||
}
|
||||
public StationDirection(String code, String name, DirectionLabelEnum labelEnum,IODirection ioDirection) {
|
||||
this(code, name);
|
||||
this.labelEnum = labelEnum;
|
||||
this.runModel = getDefaultDirectionRunModel();
|
||||
this.runStatus = this.getDefaultReceiveAndDeliver();
|
||||
this.defaultRunStatus = this.getDefaultReceiveAndDeliver();
|
||||
this.currentRouteList = getNowRouteList();
|
||||
this.ioDirection = ioDirection;
|
||||
|
||||
|
||||
}
|
||||
public StationDirection(DraftMapStationDirection draftMapStationDirection) {
|
||||
this(draftMapStationDirection.getCode(), draftMapStationDirection.getName());
|
||||
this.labelEnum = draftMapStationDirection.getLabelEnum();
|
||||
@ -220,6 +258,8 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
this.defaultRunStatus = draftMapStationDirection.getRunStatus();
|
||||
this.currentRouteList = getNowRouteList();
|
||||
this.isDataConfig = true;
|
||||
this.ioDirection = draftMapStationDirection.getIoDirection();
|
||||
|
||||
}
|
||||
|
||||
public StationDirection(String code, String name) {
|
||||
@ -230,7 +270,14 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
this.deliverRouteList = new ArrayList<>();
|
||||
this.routeSettingStatusMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public StationDirection clone(){
|
||||
try {
|
||||
return (StationDirection)super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public void reset() {
|
||||
this.routeSettingStatusMap.clear();
|
||||
@ -663,4 +710,16 @@ public class StationDirection extends MayOutOfOrderDevice {
|
||||
// 非自动
|
||||
N
|
||||
}
|
||||
|
||||
/**
|
||||
* 出入口方向
|
||||
*/
|
||||
public enum IODirection{
|
||||
DOWN_IN_STATION,
|
||||
UP_IN_STATION,
|
||||
DOWN_OUT_STATION,
|
||||
UP_OUT_STATION,
|
||||
BOTH_WAY_STATION;
|
||||
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -157,7 +157,7 @@ public class CiSwitchControlService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量转动道岔到指定位置
|
||||
* 确保道岔位置正确
|
||||
*/
|
||||
public boolean ensureSwitchPosCurrent(Simulation simulation, List<SwitchElement> switchElements, boolean guideSetting) {
|
||||
boolean allOn = true;
|
||||
|
@ -0,0 +1,24 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.data;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class CascoControl {
|
||||
private Simulation simulation;
|
||||
private Station station;
|
||||
private Route route;
|
||||
private List<String> errorList = new ArrayList<>();
|
||||
private String tripNum;
|
||||
|
||||
public void addErrorMsg(String msg){
|
||||
this.errorList.add(msg);
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ public class CtcEffectRepository {
|
||||
*/
|
||||
private final Map<String, CtcStageRunPlanRepository> stationApplyRunPlanMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* 阶段计划,与各车站与生效区
|
||||
* 下发至车站的运行计划,与车站原本计划进行对比,只存放不同的数据
|
||||
@ -55,6 +56,22 @@ public class CtcEffectRepository {
|
||||
* 车站为key
|
||||
*/
|
||||
private final Map<String, StationTrackSectionRepository> stationTrackSectionMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 出入口集合
|
||||
* 车站key
|
||||
*/
|
||||
private final Map<String, CtcEffectRepository.StationDoorRepository> doorRepository = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 固定径路集合
|
||||
* 车站key
|
||||
*/
|
||||
private final Map<String, CtcEffectRepository.RegularTrainLineRepository> regularTrainLineMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 列车固定经路车站更新区域(从生效区来的数据)
|
||||
*/
|
||||
private final Map<String,CtcEffectRepository.RegularTrainLineRepository> updateReguarTrainLineMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取生效区的运行计划
|
||||
@ -108,7 +125,7 @@ public class CtcEffectRepository {
|
||||
for (Map.Entry<String, CtcRunPlanParam> v : runPlanMap.entrySet()) {
|
||||
oldPlan = effectRepository.query(v.getValue().getRunPlanCode());
|
||||
if (oldPlan == null || oldPlan.getVersion().get() < v.getValue().getVersion().get()) {
|
||||
effectRepository.save(v.getValue().clone());
|
||||
effectRepository.save(v.getValue());
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
@ -414,6 +431,16 @@ public class CtcEffectRepository {
|
||||
public void remove(String code) {
|
||||
this.dataMap.remove(code);
|
||||
}
|
||||
public int version(){
|
||||
return this.version.get();
|
||||
}
|
||||
public int incrementVersionOne(){
|
||||
return this.version.incrementAndGet();
|
||||
}
|
||||
|
||||
public void resetVersion(int version){
|
||||
this.version.set(version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -448,23 +475,59 @@ public class CtcEffectRepository {
|
||||
*/
|
||||
@Data
|
||||
public static class StationDoorRepository extends AbstractWorkspaceRepository<StationDirection> {
|
||||
private final Map<String, StationDirection> trackSectionMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void save(StationDirection o) {
|
||||
|
||||
this.dataMap.put(o.getCode(),o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StationDirection query(String code) {
|
||||
return null;
|
||||
return this.dataMap.get(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 固定进路信息
|
||||
*/
|
||||
@Data
|
||||
public static class RegularTrainLineRepository extends AbstractWorkspaceRepository<RegularTrainLine> {
|
||||
/**
|
||||
* 保存运行计划
|
||||
*
|
||||
* @param runPlanParam 运行计划
|
||||
*/
|
||||
public void save(RegularTrainLine runPlanParam) {
|
||||
this.dataMap.put(runPlanParam.getCode(), runPlanParam.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取运行计划参数
|
||||
*
|
||||
* @param runPlanCode 运行计划编码
|
||||
* @return 运行计划
|
||||
*/
|
||||
public RegularTrainLine query(String runPlanCode) {
|
||||
return this.dataMap.get(runPlanCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在
|
||||
*
|
||||
* @param code 编码
|
||||
* @return 存在
|
||||
*/
|
||||
public boolean isExit(String code) {
|
||||
return this.dataMap.containsKey(code);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划固定进路信息
|
||||
*/
|
||||
@Data
|
||||
public static class StationRunPlanRepository extends AbstractWorkspaceRepository<CtcRunPlanParam> {
|
||||
/**
|
||||
* 保存运行计划
|
||||
@ -510,5 +573,8 @@ public class CtcEffectRepository {
|
||||
this.stationStageRunPlanMap.clear();
|
||||
this.stageRunPlanVersionMap.clear();
|
||||
this.stationTrackSectionMap.clear();
|
||||
this.doorRepository.clear();
|
||||
this.regularTrainLineMap.clear();
|
||||
updateReguarTrainLineMap.clear();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package club.joylink.rtss.simulation.cbtc.CTC.data;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.param.CtcRunPlanParam;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Tables;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.StringUtils;
|
||||
@ -10,6 +12,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 车务管理端数据(调度台、区段)
|
||||
@ -34,12 +37,23 @@ public class CtcManageRepository {
|
||||
* 固定径路集合
|
||||
* 车站key
|
||||
*/
|
||||
private final Map<String, CtcEffectRepository.RegularTrainLineRepository> regularTrainLineMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 计划固定径路集合
|
||||
* 车站key
|
||||
*/
|
||||
private final Map<String, CtcEffectRepository.StationRunPlanRepository> runPlanRepository = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
|
||||
public void reset() {
|
||||
|
||||
this.trackSectionRepository.clear();
|
||||
this.doorRepository.clear();
|
||||
this.runPlanRepository.clear();
|
||||
regularTrainLineMap.clear();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,7 @@ import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapConfig;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import com.google.common.base.Strings;
|
||||
import lombok.Getter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@ -54,11 +55,15 @@ public class CtcRepository {
|
||||
/******************************************* 以上为车务管理终端数据 ****************************************/
|
||||
|
||||
/******************************************* 以下为车站终端数据:车站为单位 *******************************************/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 进路序列id生成器
|
||||
*/
|
||||
private AtomicInteger routeSequenceIdGenerator = new AtomicInteger(0);
|
||||
|
||||
|
||||
/**
|
||||
* 车站-进路序列。每个车站都应该有
|
||||
* k - stationCode
|
||||
@ -487,4 +492,15 @@ public class CtcRepository {
|
||||
public boolean routeSequenceMapIsNotEmpty() {
|
||||
return this.routeSequenceMap.values().stream().anyMatch(RouteSequence::isStatusChange);
|
||||
}
|
||||
public String createCode(CtcFZKType type,String group){
|
||||
int startIndex = routeSequenceIdGenerator.decrementAndGet();
|
||||
String num = Strings.padStart(startIndex + "",4,'0');
|
||||
return String.format(group.concat(type.name().concat("%s")),num);
|
||||
}
|
||||
|
||||
public enum CtcFZKType{
|
||||
STATION_DETAIL,
|
||||
IO_GATE,
|
||||
REGULAR_TRAIN;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,173 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.data;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.CI.data.StationDirection;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RegularTrainLineVO;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Stand;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RegularTrainLine implements Cloneable {
|
||||
|
||||
public RegularTrainLine(RegularTrainLineVO vo){
|
||||
this.code = vo.getCode();
|
||||
this.arriveTipNum = vo.getArriveTipNum();
|
||||
this.leaveTipNum = vo.getLeaveTipNum();
|
||||
this.arriveTime = vo.getArriveTime();
|
||||
this.leaveTime = vo.getLeaveTime();
|
||||
this.appendData = vo.getAppendData();
|
||||
|
||||
}
|
||||
private String code;
|
||||
/**
|
||||
* 车站code
|
||||
*/
|
||||
private Station station;
|
||||
/**
|
||||
* 股道
|
||||
*/
|
||||
private Section masterStand;
|
||||
/**
|
||||
* 到达车次
|
||||
*/
|
||||
private String arriveTipNum;
|
||||
/**
|
||||
* 出发车次
|
||||
*/
|
||||
private String leaveTipNum;
|
||||
/**
|
||||
* 到达时间
|
||||
*/
|
||||
private LocalTime arriveTime;
|
||||
/**
|
||||
* 出发时间
|
||||
*/
|
||||
private LocalTime leaveTime;
|
||||
/**
|
||||
* 入口
|
||||
*/
|
||||
private StationDirection enter;
|
||||
/**
|
||||
* 后方车站
|
||||
*/
|
||||
private Station backStation;
|
||||
/**
|
||||
* 出口
|
||||
*/
|
||||
private StationDirection out;
|
||||
/**
|
||||
* 前方车站
|
||||
*/
|
||||
private Station fontStation;
|
||||
/**
|
||||
* 批量处理车次前缀
|
||||
* 参数:prefixTrain,startTipNum,endTipNum 都不为空的时候认为此次是批量处理
|
||||
*/
|
||||
private String prefixTrain;
|
||||
/**
|
||||
* 批量处理车次开始
|
||||
* 参数:prefixTrain,startTipNum,endTipNum 都不为空的时候认为此次是批量处理
|
||||
*/
|
||||
private Integer startTipNum;
|
||||
/**
|
||||
* 批量处理车次结束
|
||||
* 参数:prefixTrain,startTipNum,endTipNum 都不为空的时候认为此次是批量处理
|
||||
*/
|
||||
private Integer endTipNum;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Map<AppendDataType, Boolean> appendData;
|
||||
|
||||
|
||||
public RegularTrainLine clone(){
|
||||
try {
|
||||
return (RegularTrainLine) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum AppendDataType {
|
||||
/**
|
||||
* 技术停点
|
||||
*/
|
||||
JISHU_STOP,
|
||||
/**
|
||||
* 交令
|
||||
*/
|
||||
JIAO_LING,
|
||||
/**
|
||||
* 机车
|
||||
*/
|
||||
JICHE,
|
||||
/**
|
||||
* 货检
|
||||
*/
|
||||
HUOJIAN,
|
||||
/**
|
||||
* 乘降
|
||||
*/
|
||||
CHENGJIANG,
|
||||
/**
|
||||
* 摘挂
|
||||
*/
|
||||
ZHAIGUA,
|
||||
/**
|
||||
* 换乘
|
||||
*/
|
||||
HUANCHENG,
|
||||
/**
|
||||
* 装卸
|
||||
*/
|
||||
ZHUANGXIE,
|
||||
/**
|
||||
* 吸污
|
||||
*/
|
||||
XIWU,
|
||||
/**
|
||||
* 道口
|
||||
*/
|
||||
DAOKOU,
|
||||
/**
|
||||
* 车号
|
||||
*/
|
||||
CHEHAO,
|
||||
/**
|
||||
* 上水
|
||||
*/
|
||||
SHANGSHUI,
|
||||
/**
|
||||
* 列检
|
||||
*/
|
||||
LIEJIAN,
|
||||
/**
|
||||
* 综控
|
||||
*/
|
||||
ZONGKONG,
|
||||
/**
|
||||
* 站务
|
||||
*/
|
||||
ZHANWU,
|
||||
/**
|
||||
* 交票
|
||||
*/
|
||||
JIAOPIAO,
|
||||
/**
|
||||
* 列尾
|
||||
*/
|
||||
LIEWEI,
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.data;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.CI.data.StationDirection;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 车站出入口
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class StationIOGate {
|
||||
|
||||
public StationIOGate(StationDirection sd){
|
||||
this.code = sd.getCode();
|
||||
this.ioName = sd.getName();
|
||||
this.allowOverrun = sd.isAllowOverrun();
|
||||
this.travelTrain = sd.isTravelTrain();
|
||||
this.goodsTrain = sd.isGoodsTrain();
|
||||
this.ioDirection = sd.getIoDirection();
|
||||
// this.defaultRunStatus = sd.getRunStatus();
|
||||
// if(Objects.nonNull(sd.getRelativeStation())){
|
||||
// this.relativeStationCode = sd.getRelativeStation().getCode();
|
||||
// this.relativeStationName = sd.getRelativeStation().getName();
|
||||
// }
|
||||
}
|
||||
private String code;
|
||||
|
||||
private String ioName;
|
||||
private String relativeStationName;
|
||||
private String relativeStationCode;
|
||||
/**
|
||||
* 接发车类型
|
||||
*/
|
||||
private StationDirection.ReceiveAndDeliverModel defaultRunStatus;
|
||||
/**
|
||||
* 出入口方向
|
||||
* 1.双线自动闭塞区段,按进站信号机的行别、属性
|
||||
* 选择“下行进站/上行出站/下行出站/上行进站”。
|
||||
* 2.单线自动闭塞、半自动闭塞区段,选择“双向”
|
||||
*/
|
||||
private StationDirection.IODirection ioDirection;
|
||||
|
||||
/**
|
||||
* 允许超限列车
|
||||
* 选择“是/否”。
|
||||
* 1.普速铁路一般选择“是”(有明确不允许超限列
|
||||
* 车的选择“否”)。
|
||||
* 2.高速铁路一般选择“否”(200km/h 客货共线铁路
|
||||
* 根据文件确定)
|
||||
*/
|
||||
private boolean allowOverrun;
|
||||
|
||||
/**
|
||||
* 允许旅客列车
|
||||
* 选择“是/否”。两线、多线区间根据《行规》列
|
||||
* 车运行分工选择
|
||||
*/
|
||||
private boolean travelTrain;
|
||||
|
||||
/**
|
||||
* 允许货物列车
|
||||
* 选择“是/否”。两线、多线区间根据《行规》列
|
||||
* 车运行分工选择。
|
||||
*/
|
||||
private boolean goodsTrain;
|
||||
}
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.CTC.data;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
@ -9,6 +10,7 @@ import lombok.Setter;
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
public class TrackSection {
|
||||
/**
|
||||
* 编码
|
||||
@ -69,10 +71,24 @@ public class TrackSection {
|
||||
*/
|
||||
private boolean military;
|
||||
|
||||
|
||||
public void trainData(TrackSection ts){
|
||||
ts.name = this.name;
|
||||
ts.sectionCode = this.sectionCode;
|
||||
}
|
||||
public TrackSection(Section section) {
|
||||
this.code = section.getCode();
|
||||
this.name = section.getName();
|
||||
this.sectionCode = section.getCode();
|
||||
this.initDefault();
|
||||
}
|
||||
|
||||
private void initDefault(){
|
||||
this.trackNature =TrackNature.RIGHT_TRACK;
|
||||
this.direction =DirectionType.D;
|
||||
this.trainType = TrainType.VAN;
|
||||
this.transfinite = CtcStationRunPlanLog.TransfiniteType.NO;
|
||||
this.standType = StandType.NO;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,20 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.data.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class FZkVO<T> {
|
||||
private int version;
|
||||
private T data;
|
||||
|
||||
|
||||
public static <T> FZkVO of(int version,T d){
|
||||
FZkVO<T> vo = new FZkVO<>();
|
||||
vo.setVersion(version);
|
||||
vo.setData(d);
|
||||
return vo;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.data.vo;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.RegularTrainLine;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RegularTrainLineVO implements Cloneable {
|
||||
|
||||
public RegularTrainLineVO(RegularTrainLine rt){
|
||||
this.code = rt.getCode();
|
||||
this.stationCode = rt.getStation().getCode();
|
||||
this.stationName = rt.getStation().getName();
|
||||
this.masterCode = rt.getMasterStand().getCode();
|
||||
this.masterName = rt.getMasterStand().getName();
|
||||
this.arriveTipNum = rt.getArriveTipNum();
|
||||
this.leaveTipNum = rt.getLeaveTipNum();
|
||||
this.arriveTime = rt.getArriveTime();
|
||||
this.leaveTime = rt.getLeaveTime();
|
||||
if(Objects.nonNull(rt.getEnter())){
|
||||
this.enterDirCode = rt.getEnter().getCode();
|
||||
this.enterDirName = rt.getEnter().getName();
|
||||
}
|
||||
if(Objects.nonNull(rt.getBackStation())){
|
||||
this.backStationCode = rt.getBackStation().getCode();
|
||||
this.backStationName = rt.getBackStation().getName();
|
||||
}
|
||||
if(Objects.nonNull(rt.getOut())){
|
||||
this.outDirCode = rt.getOut().getCode();
|
||||
this.outDirName = rt.getOut().getName();
|
||||
}
|
||||
if(Objects.nonNull(rt.getFontStation())){
|
||||
this.fontStationCode = rt.getFontStation().getCode();
|
||||
this.fontStationName = rt.getFontStation().getName();
|
||||
}
|
||||
this.appendData = rt.getAppendData();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String code;
|
||||
/**
|
||||
* 车站code
|
||||
*/
|
||||
private String stationCode;
|
||||
private String stationName;
|
||||
/**
|
||||
* 股道
|
||||
*/
|
||||
private String masterCode;
|
||||
private String masterName;
|
||||
/**
|
||||
* 到达车次
|
||||
*/
|
||||
private String arriveTipNum;
|
||||
/**
|
||||
* 出发车次
|
||||
*/
|
||||
private String leaveTipNum;
|
||||
/**
|
||||
* 到达时间
|
||||
*/
|
||||
private LocalTime arriveTime;
|
||||
/**
|
||||
* 出发时间
|
||||
*/
|
||||
private LocalTime leaveTime;
|
||||
/**
|
||||
* 入口
|
||||
*/
|
||||
private String enterDirCode;
|
||||
private String enterDirName;
|
||||
|
||||
/**
|
||||
* 后方车站
|
||||
*/
|
||||
private String backStationCode;
|
||||
private String backStationName;
|
||||
|
||||
/**
|
||||
* 出口
|
||||
*/
|
||||
private String outDirCode;
|
||||
private String outDirName;
|
||||
/**
|
||||
* 前方车站
|
||||
*/
|
||||
private String fontStationCode;
|
||||
private String fontStationName;
|
||||
/**
|
||||
* 批量处理车次前缀
|
||||
* 参数:prefixTrain,startTipNum,endTipNum 都不为空的时候认为此次是批量处理
|
||||
*/
|
||||
private String prefixTrain;
|
||||
/**
|
||||
* 批量处理车次开始
|
||||
* 参数:prefixTrain,startTipNum,endTipNum 都不为空的时候认为此次是批量处理
|
||||
*/
|
||||
private Integer startTipNum;
|
||||
/**
|
||||
* 批量处理车次结束
|
||||
* 参数:prefixTrain,startTipNum,endTipNum 都不为空的时候认为此次是批量处理
|
||||
*/
|
||||
private Integer endTipNum;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Map<RegularTrainLine.AppendDataType, Boolean> appendData;
|
||||
|
||||
public RegularTrainLineVO clone() {
|
||||
try {
|
||||
return (RegularTrainLineVO) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,8 @@ package club.joylink.rtss.simulation.cbtc.CTC.operation;
|
||||
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.CTC.data.vo.FZkVO;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RegularTrainLineVO;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.param.CtcRunPlanParam;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.service.runplan.CtcManageService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
@ -40,10 +42,10 @@ public class CtcManageOperateHandler {
|
||||
* @param simulation 仿真实体
|
||||
* @param stationCode 车站编码
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION)
|
||||
/*@OperateHandlerMapping(type = Operation.Type.CTC_RELEASE_RUN_PLAN_TO_SIMULATION)
|
||||
public void releaseRunPlanToSimulation(Simulation simulation, String stationCode) {
|
||||
ctcManageService.releaseRunPlanToEffectAreaMap(simulation, stationCode);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 导入覆盖车站编辑区行车日志
|
||||
@ -90,4 +92,38 @@ public class CtcManageOperateHandler {
|
||||
public void effectRunPlanToSimulation(Simulation simulation, String stationCode) {
|
||||
ctcManageService.releaseRunPlanToStation(simulation, stationCode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 固定列车经路更新
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_STATION_UPDATE)
|
||||
public void stationUpdate(Simulation simulation, String stationCode){
|
||||
this.ctcManageService.stationUpdateFromEffect(simulation,stationCode);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_STATION_UPDATE_LIST)
|
||||
public FZkVO<List<RegularTrainLineVO>> loadUpdateTrainLineData(Simulation simulation, String stationCode){
|
||||
return this.ctcManageService.loadUpdateRegularTrainLineList(simulation,stationCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载更新区的固定列车径路到计划中
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_STATION_UPDATE_LOAD)
|
||||
public void loadRegularTrainLineToPlan(Simulation simulation, String stationCode){
|
||||
this.ctcManageService.loadRegularTrainLineToPlan(simulation,stationCode);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.operation.fck;
|
||||
|
||||
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.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.StationIOGate;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.service.runplan.CtcManageService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 车务管理终端操作--车站出入口
|
||||
*/
|
||||
@OperateHandler
|
||||
@Slf4j
|
||||
public class CtcManageIOGateOperateHandler {
|
||||
|
||||
@Resource
|
||||
private CtcManageService ctcManageService;
|
||||
/**
|
||||
* 车务管理终端车站出入口编辑
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param ts
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.STATION_IO_GATE_EDIT)
|
||||
public void stationIOGateEdit(Simulation simulation, String stationCode, StationIOGate ts){
|
||||
ctcManageService.editIOGate(simulation,stationCode,ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 车务管理终端车站出入口列表
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.STATION_IO_GATE_LIST)
|
||||
public List<StationIOGate> stationIOGateList(Simulation simulation, String stationCode){
|
||||
return ctcManageService.listIOGate(simulation,stationCode);
|
||||
}
|
||||
|
||||
|
||||
@OperateHandlerMapping(type = Operation.Type.STATION_IO_GATE_PUBLISH)
|
||||
public void publist(Simulation simulation, String stationCode){
|
||||
ctcManageService.publishData(simulation, CtcRepository.CtcFZKType.STATION_DETAIL,stationCode);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.operation.fck;
|
||||
|
||||
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.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.TrackSection;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.service.runplan.CtcManageService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 车务管理终端操作--车站股道
|
||||
*/
|
||||
@OperateHandler
|
||||
@Slf4j
|
||||
public class CtcManageMasterLineOperateHandler {
|
||||
|
||||
@Resource
|
||||
private CtcManageService ctcManageService;
|
||||
|
||||
/**
|
||||
*车务管理终端股道列表
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.STATION_DETAIL_LIST)
|
||||
public List<TrackSection> listMasterLine(Simulation simulation, String stationCode){
|
||||
return this.ctcManageService.listMasterLine(simulation,stationCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 车务管理终端股道修改
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param ts
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.STATION_DETAIL_EDIT)
|
||||
public void editMasterLine(Simulation simulation, String stationCode, TrackSection ts){
|
||||
ctcManageService.editMasterLine(simulation,stationCode,ts);
|
||||
}
|
||||
|
||||
@OperateHandlerMapping(type = Operation.Type.STATION_DETAIL_PUBLISH)
|
||||
public void publist(Simulation simulation, String stationCode){
|
||||
ctcManageService.publishData(simulation, CtcRepository.CtcFZKType.STATION_DETAIL,stationCode);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.operation.fck;
|
||||
|
||||
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.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RegularTrainLineVO;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.service.runplan.CtcManageService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 车务管理终端操作--固定列车经路
|
||||
*/
|
||||
@OperateHandler
|
||||
@Slf4j
|
||||
public class CtcManageRegularTrainLineOperateHandler {
|
||||
|
||||
@Resource
|
||||
private CtcManageService ctcManageService;
|
||||
|
||||
/**
|
||||
* 保存固定列车经路
|
||||
*
|
||||
* @param simulation 仿真实体
|
||||
* @param stationCode 车站编码
|
||||
* @param runPlanParamList 运行计划
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_SAVE)
|
||||
public void saveTrainLine(Simulation simulation, String stationCode, RegularTrainLineVO runPlanParamList) {
|
||||
this.ctcManageService.editRegularTrain(simulation,stationCode,runPlanParamList,true);
|
||||
}
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_EDIT)
|
||||
public void editTrainLine(Simulation simulation, String stationCode, RegularTrainLineVO runPlanParamList) {
|
||||
this.ctcManageService.editRegularTrain(simulation,stationCode,runPlanParamList,false);
|
||||
}
|
||||
/**
|
||||
* 保存固定列车经路批量处理
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param runPlanParamList
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_BATCH)
|
||||
public void batchSaveTrainLine(Simulation simulation, String stationCode, RegularTrainLineVO runPlanParamList) {
|
||||
this.ctcManageService.batchSaveRegularTrain(simulation,stationCode,runPlanParamList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 固定列车经路列表
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_LIST)
|
||||
public List<RegularTrainLineVO> listTrainLine(Simulation simulation, String stationCode) {
|
||||
return this.ctcManageService.regularTrainLineList(simulation,stationCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存固定列车删除
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param code
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_DELETE)
|
||||
public void delete(Simulation simulation, String stationCode,String code){
|
||||
this.ctcManageService.delete(simulation,stationCode,code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存固定列车清空
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_CLEAR)
|
||||
public void clear(Simulation simulation, String stationCode){
|
||||
this.ctcManageService.remove(simulation,stationCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑区上传到生效区
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.REGULAR_TRAIN_LINE_PUBLISH)
|
||||
public void publish(Simulation simulation, String stationCode){
|
||||
ctcManageService.publishData(simulation, CtcRepository.CtcFZKType.REGULAR_TRAIN,stationCode);
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.param;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.RegularTrainLine;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -207,6 +209,231 @@ public class CtcRunPlanParam implements Cloneable {
|
||||
*/
|
||||
private boolean receive;
|
||||
|
||||
public CtcRunPlanParam(RegularTrainLine tl){
|
||||
/**
|
||||
* 运行计划编码
|
||||
* private String runPlanCode;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 车站编码
|
||||
* private String stationCode;
|
||||
*/
|
||||
this.stationCode = tl.getStation().getCode();
|
||||
|
||||
/**
|
||||
* 班别
|
||||
* private String groupNumber;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 运行计划车次信息
|
||||
* private String tripNumber;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 运行计划的默认股道
|
||||
* private String trackSectionCode;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 到达股道
|
||||
* private String arriveSectionCode;
|
||||
*/
|
||||
|
||||
this.arriveSectionCode = tl.getMasterStand().getCode();
|
||||
|
||||
|
||||
/**
|
||||
* 到达计划时间
|
||||
* private LocalDateTime arrivePlanTime;
|
||||
*/
|
||||
|
||||
this.arrivePlanTime = tl.getArriveTime().atDate(LocalDate.now());
|
||||
|
||||
/**
|
||||
* 到达时间
|
||||
* private LocalDateTime arriveTime;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 到达车次
|
||||
* private String arriveTripNumber;
|
||||
*/
|
||||
this.arriveTripNumber = tl.getArriveTipNum();
|
||||
|
||||
/**
|
||||
* 到达车站
|
||||
* private String arriveStationCode;
|
||||
*/
|
||||
this.arriveStationCode = tl.getStation().getCode();
|
||||
|
||||
/**
|
||||
* 到达方向编码(到达口)
|
||||
* private String arriveDirectionCode;
|
||||
*/
|
||||
if(Objects.nonNull(tl.getEnter())){
|
||||
this.arriveDirectionCode = tl.getEnter().getCode();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 始发计划
|
||||
* private Boolean startRunPlan;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 发车股道
|
||||
* private String departSectionCode;
|
||||
*/
|
||||
this.departSectionCode = tl.getMasterStand().getCode();
|
||||
|
||||
/**
|
||||
* 发车计划时间
|
||||
* private LocalDateTime departPlanTime;
|
||||
*/
|
||||
this.departPlanTime = tl.getLeaveTime().atDate(LocalDate.now());
|
||||
|
||||
/**
|
||||
* 发车时间
|
||||
* private LocalDateTime departTime;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 发车车次
|
||||
* private String departTripNumber;
|
||||
*/
|
||||
this.departTripNumber = tl.getLeaveTipNum();
|
||||
|
||||
/**
|
||||
* 发车车站
|
||||
* private String departStationCode;
|
||||
*/
|
||||
this.departStationCode = tl.getBackStation().getCode();
|
||||
|
||||
/**
|
||||
* 发向方向编码(发车口)
|
||||
* private String departDirectionCode;
|
||||
*/
|
||||
if(Objects.nonNull(tl.getOut())){
|
||||
this.departDirectionCode = tl.getOut().getCode();
|
||||
}
|
||||
/**
|
||||
* 终到计划
|
||||
* private Boolean endRunPlan;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 状态:-1:删除,0:修改,1:添加
|
||||
* private int status;
|
||||
*/
|
||||
this.status = 1;
|
||||
|
||||
/**
|
||||
* 电力计划
|
||||
* private Boolean electrical;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 到达电力
|
||||
* private Boolean arriveElectrical;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 出发到达
|
||||
* private Boolean departElectrical;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 超限等级
|
||||
* private CtcStationRunPlanLog.TransfiniteType transfinite;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 到达超限
|
||||
* private CtcStationRunPlanLog.TransfiniteType arriveTransfinite;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 出发超限
|
||||
* private CtcStationRunPlanLog.TransfiniteType departTransfinite;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 办理客运
|
||||
* private Boolean passenger;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 重点列车
|
||||
* private Boolean keyTrains;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 是否军用
|
||||
* private Boolean military;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 运行股道与基本径路不一致
|
||||
* private Boolean trackDiscordant;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 出入口与基本径路不一致
|
||||
* private Boolean entryOutDiscordant;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 记事
|
||||
* private String remark;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 晚点原因
|
||||
* private String lateReason;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 列车运行计划作业
|
||||
* private Map<CtcStationRunPlanLog.RunPlanTask, Integer> runPlanTaskMap = new HashMap<>();
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 列车类型
|
||||
* private TrainType trainType;
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 运行类型
|
||||
* private RunType runType;
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除时构造实体
|
||||
*
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.CTC.service;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.CiApiService;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcEffectRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.RouteSequence;
|
||||
@ -160,6 +161,16 @@ public class CTCService {
|
||||
line.setAutoTrigger(trigger);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param simulation
|
||||
* @param routeCode
|
||||
* @param tripNumber
|
||||
* @param force
|
||||
* @param duration
|
||||
* @return
|
||||
*/
|
||||
public List<String> setRoute(Simulation simulation, String routeCode, String tripNumber, Boolean force, Integer duration) {
|
||||
Route route = simulation.getRepository().getByCode(routeCode, Route.class);
|
||||
Station station = route.getStart().getStation();
|
||||
|
@ -0,0 +1,87 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.service;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CascoControl;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcEffectRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class CascoControlService {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cc
|
||||
* @return
|
||||
*/
|
||||
public List<String> checkCascoControlRoute(CascoControl cc){
|
||||
Station station = cc.getStation();
|
||||
Simulation simulation = cc.getSimulation();
|
||||
String stationCode = station.getCode();
|
||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||
CtcEffectRepository effectRepository = ctcRepository.getCtcEffectRepository();
|
||||
Map<String, CtcStationRunPlanLog> runPlanLogMap = simulation.getCtcRepository().getSimulationRunPlanMap().get(stationCode);
|
||||
Optional<CtcStationRunPlanLog> runPlanLogOptional = null;
|
||||
if(Objects.nonNull(runPlanLogMap) && !runPlanLogMap.isEmpty()){
|
||||
runPlanLogOptional = this.checkForRunPlan(cc);
|
||||
}
|
||||
// List<CtcStationRunPlanLog> allRunPlanLogList = runPlanLogMap.values().stream().filter(d->d.getChangeType() == null && d.isSign()).collect(Collectors.toList());
|
||||
|
||||
CtcEffectRepository.StationDoorRepository doorRepository = effectRepository.getDoorRepository().get(stationCode);
|
||||
if(Objects.nonNull(doorRepository)){
|
||||
if(runPlanLogOptional.isPresent()){
|
||||
|
||||
}
|
||||
return cc.getErrorList();
|
||||
}
|
||||
|
||||
|
||||
CtcEffectRepository.StationTrackSectionRepository stationTrackRepository = effectRepository.getStationTrackSectionMap().get(stationCode);
|
||||
if(Objects.nonNull(stationTrackRepository)){
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<CtcStationRunPlanLog> checkForRunPlan(/*List<CtcStationRunPlanLog> allRunPlanLogList,*/CascoControl cc){
|
||||
CtcStationRunPlanLog runPlanLog = cc.getSimulation().getCtcRepository().getRunPlan(cc.getStation().getCode(),cc.getTripNum());
|
||||
if(Objects.isNull(runPlanLog)){
|
||||
cc.addErrorMsg(String.format("未在计划中找到对应的车次[%s]",cc.getTripNum()));
|
||||
}
|
||||
if(!Objects.isNull(runPlanLog.getChangeType()) && !runPlanLog.isSign()){
|
||||
cc.addErrorMsg(String.format("未在计划中找到对应的车次[%s]",cc.getTripNum()));
|
||||
}
|
||||
return Optional.of(runPlanLog);
|
||||
/*Map<String,CtcStationRunPlanLog> tripNumMap = allRunPlanLogList.stream().collect(Collectors.toMap(CtcStationRunPlanLog::getTripNumber, Function.identity(),(v1,v2)->v1));
|
||||
CtcStationRunPlanLog runPlanLog = tripNumMap.get(cc.getTripNum());
|
||||
if(Objects.isNull(runPlanLog)){
|
||||
cc.addErrorMsg(String.format("未在计划中找到对应的车次[%s]",cc.getTripNum()));
|
||||
}*/
|
||||
}
|
||||
private void checkCascoForStationTrack(CtcEffectRepository.StationTrackSectionRepository stationTrackRepository){
|
||||
|
||||
}
|
||||
|
||||
private void checkCascoForDoor(CtcEffectRepository.StationDoorRepository doorRepository,CtcStationRunPlanLog runPlanLog){
|
||||
CtcStationRunPlanLog.RunPlanItem departPlan = runPlanLog.getDepartRunPlan();
|
||||
CtcStationRunPlanLog.RunPlanItem arrivePlan = runPlanLog.getArriveRunPlan();
|
||||
if(Objects.nonNull(departPlan)){
|
||||
|
||||
}
|
||||
if(Objects.nonNull(arrivePlan)){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +1,34 @@
|
||||
package club.joylink.rtss.simulation.cbtc.CTC.service.runplan;
|
||||
|
||||
import club.joylink.rtss.exception.BaseException;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcManageRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.data.StationDirection;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.*;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.FZkVO;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.vo.RegularTrainLineVO;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.param.CtcRunPlanParam;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CtcManageService {
|
||||
|
||||
@Autowired
|
||||
@Resource
|
||||
private CtcStationRunPlanLogService ctcStationRunPlanLogService;
|
||||
|
||||
/**
|
||||
@ -107,7 +120,7 @@ public class CtcManageService {
|
||||
* @param stationCode 车站编码
|
||||
*/
|
||||
public void releaseRunPlanToEffectAreaMap(Simulation simulation, String stationCode) {
|
||||
|
||||
// simulation.getCtcRepository().getCtcEffectRepository()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,4 +132,349 @@ public class CtcManageService {
|
||||
public List<CtcRunPlanParam> pullCtcManageRunPlan(Simulation simulation) {
|
||||
return simulation.getCtcRepository().getCtcManageRepository().getEditAllRunPlan();
|
||||
}
|
||||
|
||||
/**
|
||||
* 车务管理终端股道修改
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param ts
|
||||
*/
|
||||
public void editMasterLine(Simulation simulation,String stationCode, TrackSection ts){
|
||||
BusinessExceptionAssertEnum.DATA_NOT_EXIST
|
||||
.assertNotTrue(Strings.isNullOrEmpty(ts.getCode()), String.format("未找到对应的站细"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.StationTrackSectionRepository trackSectionRepository = repository.getTrackSectionRepository().get(stationCode);
|
||||
TrackSection obj = trackSectionRepository.query(ts.getCode());
|
||||
BusinessExceptionAssertEnum.DATA_NOT_EXIST
|
||||
.assertNotTrue(Objects.isNull(obj), String.format("未找到对应的站细"));
|
||||
obj.trainData(ts);
|
||||
trackSectionRepository.save(ts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 车务管理终端股道列表
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
public List<TrackSection> listMasterLine(Simulation simulation,String stationCode){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.StationTrackSectionRepository trackSectionRepository = repository.getTrackSectionRepository().get(stationCode);
|
||||
if(Objects.isNull(trackSectionRepository) || trackSectionRepository.getDataMap().isEmpty()){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Lists.newArrayList(trackSectionRepository.getDataMap().values());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改出入口
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param ts
|
||||
*/
|
||||
public void editIOGate(Simulation simulation,String stationCode, StationIOGate ts){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.StationDoorRepository trackSectionRepository = repository.getDoorRepository().get(stationCode);
|
||||
StationDirection obj = trackSectionRepository.query(ts.getCode());
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(obj), String.format("出入口%s未找到,无法修改",stationCode));
|
||||
obj.setAllowOverrun(ts.isAllowOverrun());
|
||||
obj.setTravelTrain(ts.isTravelTrain());
|
||||
obj.setGoodsTrain(ts.isGoodsTrain());
|
||||
trackSectionRepository.save(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 出入口列表
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
public List<StationIOGate> listIOGate(Simulation simulation,String stationCode){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.StationDoorRepository doorRepository = repository.getDoorRepository().get(stationCode);
|
||||
if(Objects.isNull(doorRepository) || doorRepository.getDataMap().isEmpty()){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<StationIOGate> gateList = new ArrayList<>();
|
||||
for (StationDirection value : doorRepository.getDataMap().values()) {
|
||||
gateList.add(new StationIOGate(value));
|
||||
}
|
||||
return gateList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 固定列车经路添加修改
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param rt
|
||||
*/
|
||||
public void editRegularTrain(Simulation simulation, String stationCode, RegularTrainLineVO rt,boolean isSave){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
if(!isSave && Strings.isNullOrEmpty(rt.getCode())){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("固定列车径路code 不能为空"));
|
||||
}
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository tLRepository = repository.getRegularTrainLineMap().get(stationCode);
|
||||
if(tLRepository == null){
|
||||
tLRepository = new CtcEffectRepository.RegularTrainLineRepository();
|
||||
repository.getRegularTrainLineMap().put(stationCode,tLRepository);
|
||||
}
|
||||
|
||||
if(Strings.isNullOrEmpty(rt.getCode())){
|
||||
rt.setCode(simulation.getCtcRepository().createCode(CtcRepository.CtcFZKType.REGULAR_TRAIN,simulation.getId()));
|
||||
}else{
|
||||
RegularTrainLine tl = tLRepository.query(rt.getCode());
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(tl), String.format("车站%s未找到,不能修改",stationCode));
|
||||
tLRepository.remove(rt.getCode());
|
||||
}
|
||||
SimulationDataRepository dataRepository = simulation.getRepository();
|
||||
RegularTrainLine rtObj = this.regularTrainLineChangeObj(dataRepository,stationCode,rt);
|
||||
|
||||
tLRepository.save(rtObj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private RegularTrainLine regularTrainLineChangeObj(SimulationDataRepository dataRepository,String stationCode,RegularTrainLineVO rtvo){
|
||||
RegularTrainLine rt = new RegularTrainLine(rtvo);
|
||||
Station station = dataRepository.getByCode(stationCode, Station.class);
|
||||
Section stand = dataRepository.getByCode(rtvo.getMasterCode(), Section.class);
|
||||
|
||||
rt.setStation(station);
|
||||
rt.setMasterStand(stand);
|
||||
if(Objects.nonNull(rtvo.getBackStationCode())){
|
||||
Station backStation = dataRepository.getByCode(rtvo.getBackStationCode(),Station.class);
|
||||
rt.setBackStation(backStation);
|
||||
}
|
||||
if(Objects.nonNull(rtvo.getFontStationCode())){
|
||||
Station fontStation = dataRepository.getByCode(rtvo.getFontStationCode(),Station.class);
|
||||
rt.setFontStation(fontStation);
|
||||
}
|
||||
if(Objects.nonNull(rtvo.getEnterDirCode())){
|
||||
StationDirection enter = dataRepository.getByCode(rtvo.getEnterDirCode(),StationDirection.class);
|
||||
rt.setEnter(enter);
|
||||
}
|
||||
if(Objects.nonNull(rtvo.getOutDirCode())){
|
||||
StationDirection outer = dataRepository.getByCode(rtvo.getOutDirCode(),StationDirection.class);
|
||||
rt.setOut(outer);
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
/**
|
||||
* 固定列车经路批量添加
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param rt
|
||||
*/
|
||||
public void batchSaveRegularTrain(Simulation simulation, String stationCode, RegularTrainLineVO rt){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Strings.isNullOrEmpty(rt.getPrefixTrain()), String.format("批量添加车次前缀不能为空"));
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue((Objects.isNull(rt.getStartTipNum()) || Objects.isNull(rt.getEndTipNum())), String.format("批量添加车次号开始或结束不能为空"));
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(rt.getEndTipNum() < rt.getStartTipNum(), String.format("批量添加车次号结束不能小于车次号开始"));
|
||||
int min = 0;
|
||||
for(var start = rt.getStartTipNum() ; start <= rt.getEndTipNum();start++){
|
||||
RegularTrainLineVO newRt = rt.clone();
|
||||
String tipNum = rt.getPrefixTrain().concat(start.toString());
|
||||
newRt.setArriveTipNum(tipNum);
|
||||
newRt.setLeaveTipNum(tipNum);
|
||||
//批量处理默认到达离开时间
|
||||
if(min > 0){
|
||||
//除了第一次剩下的到达时间晚3分钟;
|
||||
min += 3 * 60;
|
||||
}
|
||||
newRt.setArriveTime(LocalTime.ofSecondOfDay(min));
|
||||
//离开时间加5分钟
|
||||
min += 5 * 60;
|
||||
newRt.setLeaveTime(LocalTime.ofSecondOfDay(min));
|
||||
this.editRegularTrain(simulation,stationCode,newRt,true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 编辑区的列车经路列表
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
public List<RegularTrainLineVO> regularTrainLineList(Simulation simulation, String stationCode){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository tLRepository = repository.getRegularTrainLineMap().get(stationCode);
|
||||
return this.loadRegularTrainLineData(tLRepository);
|
||||
}
|
||||
|
||||
|
||||
private List<RegularTrainLineVO> loadRegularTrainLineData(CtcEffectRepository.RegularTrainLineRepository tLRepository){
|
||||
if(Objects.isNull(tLRepository) || tLRepository.getDataMap().isEmpty()){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<RegularTrainLineVO> voList = new ArrayList<>(tLRepository.getDataMap().values().size());
|
||||
for (RegularTrainLine value : tLRepository.getDataMap().values()) {
|
||||
voList.add(new RegularTrainLineVO(value));
|
||||
}
|
||||
return voList;
|
||||
}
|
||||
/**
|
||||
* 删除编辑区的列车经路的数据
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @param code
|
||||
*/
|
||||
public void delete(Simulation simulation, String stationCode,String code){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository tLRepository = repository.getRegularTrainLineMap().get(stationCode);
|
||||
tLRepository.remove(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除编辑区的列车经路的数据
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
public void remove(Simulation simulation, String stationCode){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository repository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository tLRepository = repository.getRegularTrainLineMap().get(stationCode);
|
||||
tLRepository.getDataMap().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑区发布到生效区
|
||||
* @param simulation
|
||||
* @param fzkType
|
||||
* @param stationCode
|
||||
*/
|
||||
public void publishData(Simulation simulation, CtcRepository.CtcFZKType fzkType, String stationCode){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcManageRepository ctcManageRepository = simulation.getCtcRepository().getCtcManageRepository();
|
||||
CtcEffectRepository effectRepository = simulation.getCtcRepository().getCtcEffectRepository();
|
||||
CtcEffectRepository.AbstractWorkspaceRepository source = null;
|
||||
CtcEffectRepository.AbstractWorkspaceRepository target = null;
|
||||
|
||||
switch (fzkType){
|
||||
case STATION_DETAIL:
|
||||
source = ctcManageRepository.getTrackSectionRepository().get(stationCode);
|
||||
target = effectRepository.getStationTrackSectionMap().get(stationCode);
|
||||
if(Objects.isNull(source)){
|
||||
source = new CtcEffectRepository.StationTrackSectionRepository();
|
||||
ctcManageRepository.getTrackSectionRepository().put(stationCode, (CtcEffectRepository.StationTrackSectionRepository) source);
|
||||
}
|
||||
if(Objects.isNull(target)){
|
||||
target = new CtcEffectRepository.StationTrackSectionRepository();
|
||||
effectRepository.getStationTrackSectionMap().put(stationCode, (CtcEffectRepository.StationTrackSectionRepository) target);
|
||||
}
|
||||
break;
|
||||
case IO_GATE:
|
||||
source = ctcManageRepository.getDoorRepository().get(stationCode);
|
||||
target = effectRepository.getDoorRepository().get(stationCode);
|
||||
if(Objects.isNull(source)){
|
||||
source = new CtcEffectRepository.StationDoorRepository();
|
||||
ctcManageRepository.getDoorRepository().put(stationCode, (CtcEffectRepository.StationDoorRepository) source);
|
||||
}
|
||||
if(Objects.isNull(target)){
|
||||
target = new CtcEffectRepository.StationDoorRepository();
|
||||
effectRepository.getDoorRepository().put(stationCode, (CtcEffectRepository.StationDoorRepository) target);
|
||||
}
|
||||
break;
|
||||
case REGULAR_TRAIN:
|
||||
source = ctcManageRepository.getRegularTrainLineMap().get(stationCode);
|
||||
target = effectRepository.getRegularTrainLineMap().get(stationCode);
|
||||
if(Objects.isNull(source)){
|
||||
source = new CtcEffectRepository.RegularTrainLineRepository();
|
||||
ctcManageRepository.getRegularTrainLineMap().put(stationCode, (CtcEffectRepository.RegularTrainLineRepository) source);
|
||||
}
|
||||
if(Objects.isNull(target)){
|
||||
target = new CtcEffectRepository.RegularTrainLineRepository();
|
||||
effectRepository.getRegularTrainLineMap().put(stationCode, (CtcEffectRepository.RegularTrainLineRepository) target);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BusinessExceptionAssertEnum.DATA_NOT_EXIST.assertNotTrue(true, String.format("未找到要发布的类型type[%s],stationCode[%s]",fzkType,stationCode));
|
||||
}
|
||||
this.dataTranFromDraft2Effect(source,target);
|
||||
}
|
||||
|
||||
private void dataTranFromDraft2Effect(CtcEffectRepository.AbstractWorkspaceRepository source,CtcEffectRepository.AbstractWorkspaceRepository target){
|
||||
int targetVersion = target.incrementVersionOne();
|
||||
source.resetVersion(targetVersion);
|
||||
for (Object value : source.getDataMap().values()) {
|
||||
target.save(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 固定列车经路更新到车站的更新区
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
public void stationUpdateFromEffect(Simulation simulation, String stationCode){
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcEffectRepository effectRepository = simulation.getCtcRepository().getCtcEffectRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository regularTrainLineRepository = effectRepository.getRegularTrainLineMap().get(stationCode);
|
||||
boolean isEmptyData = Objects.isNull(regularTrainLineRepository) || regularTrainLineRepository.getDataMap().isEmpty();
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(isEmptyData, String.format("当前生效区没有数据,无法更新"));
|
||||
CtcEffectRepository.RegularTrainLineRepository updateRepository = simulation.getCtcRepository().getCtcEffectRepository().getUpdateReguarTrainLineMap().get(stationCode);
|
||||
if(Objects.isNull(updateRepository)){
|
||||
updateRepository = new CtcEffectRepository.RegularTrainLineRepository();
|
||||
simulation.getCtcRepository().getCtcEffectRepository().getUpdateReguarTrainLineMap().put(stationCode,updateRepository);
|
||||
}
|
||||
if(updateRepository.version() != regularTrainLineRepository.version()){
|
||||
updateRepository.resetVersion(regularTrainLineRepository.version());
|
||||
for (RegularTrainLine val : regularTrainLineRepository.getDataMap().values()) {
|
||||
updateRepository.save(val);
|
||||
}
|
||||
}else{
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(true, String.format("当前生效区与更新区的版本一致,无法更新"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载更新区固定列车经路的数据
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
* @return
|
||||
*/
|
||||
public FZkVO<List<RegularTrainLineVO>> loadUpdateRegularTrainLineList(Simulation simulation, String stationCode){
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcEffectRepository repository = simulation.getCtcRepository().getCtcEffectRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository tLRepository = repository.getUpdateReguarTrainLineMap().get(stationCode);
|
||||
|
||||
List<RegularTrainLineVO> list = this.loadRegularTrainLineData(tLRepository);
|
||||
return FZkVO.of(CollectionUtils.isEmpty(list)?0:tLRepository.version(),list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载更新区的固定列车径路数据到计划中
|
||||
* @param simulation
|
||||
* @param stationCode
|
||||
*/
|
||||
public void loadRegularTrainLineToPlan(Simulation simulation, String stationCode){
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(Objects.isNull(stationCode), String.format("车站号不能为空"));
|
||||
CtcEffectRepository repository = simulation.getCtcRepository().getCtcEffectRepository();
|
||||
CtcEffectRepository.RegularTrainLineRepository tLRepository = repository.getUpdateReguarTrainLineMap().get(stationCode);
|
||||
boolean isEmptyData = Objects.isNull(tLRepository) || tLRepository.getDataMap().isEmpty();
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertNotTrue(isEmptyData, String.format("当前更新区没有数据,无法加载"));
|
||||
for (RegularTrainLine val : tLRepository.getDataMap().values()) {
|
||||
CtcRunPlanParam param = new CtcRunPlanParam(val);
|
||||
try{
|
||||
ctcStationRunPlanLogService.saveInfo(simulation,stationCode,param,1);
|
||||
}catch (BaseException e){
|
||||
if(e.getCode() == BusinessExceptionAssertEnum.REPEAT_RUN_PLAN_FROM_CTC_UPDATE_DATA.getCode()){
|
||||
log.error("车站:[{}],入口车次:[{}],出口车次:[{}],固定径路code:[{}] 发布计划发现重复的车次",stationCode,val.getArriveTipNum(),val.getLeaveTipNum(),val.getCode());
|
||||
}else{
|
||||
log.error("车站:[{}],入口车次:[{}],出口车次:[{}],固定径路code:[{}] 发布计划发现重复的车次失败 msg:{} ",stationCode,val.getArriveTipNum(),val.getLeaveTipNum(),val.getCode(),e.getVoMessage(),e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -446,7 +446,7 @@ public class CtcStationRunPlanLogService {
|
||||
long time = simulation.getCtcRepository().getAllRunPlanList().stream()
|
||||
.filter(r -> tripNumber.equals(r.getTripNumber()) && stationCode.equals(r.getStation().getCode()))
|
||||
.count();
|
||||
BusinessExceptionAssertEnum.DATA_ERROR.assertNotTrue(time > 0, "本站存在相同车次运行记录");
|
||||
BusinessExceptionAssertEnum.REPEAT_RUN_PLAN_FROM_CTC_UPDATE_DATA.assertNotTrue(time > 0, "本站存在相同车次运行记录");
|
||||
runPlanParam.generateGroupNumber(time + 1);
|
||||
runPlanParam.generateRunPlanCode();
|
||||
// 设置默认的实际时间
|
||||
|
@ -49,10 +49,14 @@ public interface GroupSimulationService {
|
||||
*/
|
||||
String simulation(Long mapId, String prodCode, LoginUserInfoVO loginUserInfoVO);
|
||||
|
||||
/**实训仿真*/
|
||||
/**
|
||||
* 实训仿真
|
||||
*/
|
||||
String trainingSimulation(Long trainingId, LoginUserInfoVO loginUserInfoVO);
|
||||
|
||||
/**考试仿真*/
|
||||
/**
|
||||
* 考试仿真
|
||||
*/
|
||||
String examSimulation(Long examId, LoginUserInfoVO loginUserInfoVO);
|
||||
|
||||
/**
|
||||
@ -185,10 +189,14 @@ public interface GroupSimulationService {
|
||||
*/
|
||||
PlanTripNumberVO planTripInfoByServiceAndTripNumber(String group, String serviceNumber, String tripNumber);
|
||||
|
||||
/**故障模式设置*/
|
||||
/**
|
||||
* 故障模式设置
|
||||
*/
|
||||
Integer setFaultMode(String group, FaultRuleVO ruleVO);
|
||||
|
||||
/**获取已设置且自动故障*/
|
||||
/**
|
||||
* 获取已设置且自动故障
|
||||
*/
|
||||
Set<FaultRuleVO> getTriggerAutoFaults(String group);
|
||||
|
||||
/**
|
||||
@ -255,6 +263,7 @@ public interface GroupSimulationService {
|
||||
|
||||
/**
|
||||
* 获取所有目的地码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DestinationCodeVO> getAllDestinationCode(String group);
|
||||
@ -276,6 +285,7 @@ public interface GroupSimulationService {
|
||||
|
||||
/**
|
||||
* 获取仿真日志
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
PageVO<SimulationLog> getLog(String group, SimulationLogPagedQueryVO queryVO);
|
||||
|
@ -27,6 +27,7 @@ import club.joylink.rtss.simulation.cbtc.command.CommandExecuteService;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
|
||||
import club.joylink.rtss.simulation.cbtc.communication.vo.fault.DeviceFaultInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.conversation.ConversationManagerService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DestinationCodeDefinition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
@ -148,6 +149,8 @@ public class GroupSimulationServiceImpl implements GroupSimulationService {
|
||||
private CommandExecuteService commandExecuteService;
|
||||
@Autowired
|
||||
private QRCodeManager qrCodeManager;
|
||||
@Autowired
|
||||
private ConversationManagerService conversationManagerService;
|
||||
// /**
|
||||
// * 创建仿真并进行缓存
|
||||
// *
|
||||
|
@ -27,6 +27,7 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationUser;
|
||||
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.Training2;
|
||||
import club.joylink.rtss.simulation.vo.SimulationInfoVO;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.client.fault.FaultRuleVO;
|
||||
@ -87,6 +88,11 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
|
||||
*/
|
||||
private ScriptBO script;
|
||||
|
||||
/**
|
||||
* 实训信息
|
||||
*/
|
||||
private Training2 training2;
|
||||
|
||||
// /**
|
||||
// * 仿真成员map
|
||||
// * key-仿真成员id
|
||||
@ -585,6 +591,9 @@ public class Simulation extends club.joylink.rtss.simulation.Simulation<Simulati
|
||||
simulationConversationMap.clear();
|
||||
}
|
||||
this.logs = null;
|
||||
if (this.training2 != null) {
|
||||
training2.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1672,7 +1672,8 @@ public class InterlockBuilder2 {
|
||||
model = new StationDirection(stationDirection);
|
||||
} else {
|
||||
// TODO: 待数据统一之后,下方构建代码可删除 20220714
|
||||
model = new StationDirection(stationDirection.getCode(), stationDirection.getName(), stationDirection.getLabelEnum());
|
||||
// model = new StationDirection(stationDirection.getCode(), stationDirection.getName(), stationDirection.getLabelEnum());
|
||||
model = new StationDirection(stationDirection.getCode(), stationDirection.getName(), stationDirection.getLabelEnum(),stationDirection.getIoDirection());
|
||||
}
|
||||
// 注入信号灯数据
|
||||
if (!StringUtils.isEmpty(stationDirection.getSignalCode())) {
|
||||
@ -1700,6 +1701,12 @@ public class InterlockBuilder2 {
|
||||
}
|
||||
Station station = (Station) elementMap.get(stationDirection.getStationCode());
|
||||
model.setStation(station);
|
||||
if(Objects.nonNull(stationDirection.getRelativeStationCode())){
|
||||
MapElement relativeStation = elementMap.get(stationDirection.getRelativeStationCode());
|
||||
if(Objects.nonNull(relativeStation)){
|
||||
model.setRelativeStation((Station) relativeStation);
|
||||
}
|
||||
}
|
||||
station.getStationDirectionMap().put(model.getLabelEnum(), model);
|
||||
elementMap.put(model.getCode(), model);
|
||||
}
|
||||
|
@ -1116,6 +1116,7 @@ public class MapDeviceBuilder {
|
||||
section.setVirtualAxleCounter(axleCounter);
|
||||
deviceMap.put(axleCounter.getCode(), axleCounter);
|
||||
}
|
||||
section.setHasStopCountDown(sectionVO.isHasStopCD());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
package club.joylink.rtss.simulation.cbtc.build;
|
||||
|
||||
import club.joylink.rtss.entity.Ibp;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcEffectRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcStationRunPlanLog;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.CtcZoneRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.data.StationDirection;
|
||||
import club.joylink.rtss.simulation.cbtc.CTC.data.*;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.CalculateService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
@ -330,10 +329,12 @@ public class SimulationBuilder {
|
||||
*/
|
||||
public static void buildCtcStationRunPlanLog(Simulation simulation) {
|
||||
List<Station> stationList = simulation.getRepository().getStationList();
|
||||
|
||||
// 调度台
|
||||
CtcZoneRepository ctcZoneRepository = simulation.getCtcRepository().getCtcZoneRepository();
|
||||
CtcRepository ctcRepository = simulation.getCtcRepository();
|
||||
// 生效区
|
||||
CtcEffectRepository ctcEffectRepository = simulation.getCtcRepository().getCtcEffectRepository();
|
||||
CtcEffectRepository ctcEffectRepository = ctcRepository.getCtcEffectRepository();
|
||||
ctcEffectRepository.getStationRunPlanMap().forEach((k, v) -> {
|
||||
v.getDataMap().forEach((c, r) -> {
|
||||
// 调度台放入
|
||||
@ -344,6 +345,38 @@ public class SimulationBuilder {
|
||||
simulation.getCtcRepository().addRunPlanToSimulationMap(runPlanLog);
|
||||
});
|
||||
});
|
||||
//加载车站股道到编辑区
|
||||
Map<String, CtcEffectRepository.StationTrackSectionRepository> stationTrackRepositoryMap = ctcRepository.getCtcManageRepository().getTrackSectionRepository();
|
||||
Map<String, CtcEffectRepository.StationDoorRepository> doorRepository = ctcRepository.getCtcManageRepository().getDoorRepository();
|
||||
|
||||
for (Station station : stationList) {
|
||||
String stationCode = station.getCode();
|
||||
CtcEffectRepository.StationTrackSectionRepository rep = stationTrackRepositoryMap.get(stationCode);
|
||||
CtcEffectRepository.StationDoorRepository doorRep = doorRepository.get(stationCode);
|
||||
if(rep == null){
|
||||
rep = new CtcEffectRepository.StationTrackSectionRepository();
|
||||
stationTrackRepositoryMap.put(stationCode,rep);
|
||||
}
|
||||
if(doorRep == null){
|
||||
doorRep = new CtcEffectRepository.StationDoorRepository();
|
||||
doorRepository.put(stationCode,doorRep);
|
||||
}
|
||||
for (StationDirection sd : station.getStationDirectionMap().values()) {
|
||||
// StationIOGate ioGate = new StationIOGate();
|
||||
// ioGate.setCode(sd.getCode());
|
||||
// ioGate.setIoName(sd.getName());
|
||||
// ioGate.setDirection(sd.getLabelEnum());
|
||||
|
||||
doorRep.save(sd.clone());
|
||||
}
|
||||
for (Stand stand : station.getAllStandList()) {
|
||||
TrackSection ts = new TrackSection(stand.getSection());
|
||||
|
||||
rep.save(ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static List<String> checkRunPlanAndBuildLostRoutePaths(Map<String, List<TripPlan>> serverTripMap,
|
||||
|
@ -234,7 +234,7 @@ public class Joylink3DMessageService {
|
||||
// vrSwitchList.forEach(vrSwitch -> {
|
||||
// boolean normal;
|
||||
// if (vrSwitch.isTurning()) {
|
||||
// normal = vrSwitch.getCommand().equals(VirtualRealitySwitch.Operation.NP);
|
||||
// normal = vrSwitch.getCommand().equals(VirtualRealitySwitch.Operation2.NP);
|
||||
// } else if (vrSwitch.isPosN()) {
|
||||
// normal = true;
|
||||
// } else {
|
||||
@ -247,7 +247,7 @@ public class Joylink3DMessageService {
|
||||
// vrPsdList.forEach(vrPsd -> {
|
||||
// boolean open;
|
||||
// if (vrPsd.isTurning()) {
|
||||
// open = vrPsd.getCommand().equals(VirtualRealityScreenDoor.Operation.K);
|
||||
// open = vrPsd.getCommand().equals(VirtualRealityScreenDoor.Operation2.K);
|
||||
// } else if (vrPsd.isClose()) {
|
||||
// open = false;
|
||||
// } else {
|
||||
|
@ -107,7 +107,7 @@ public class CompetitionAndScriptManager {
|
||||
}
|
||||
// //本地测试用
|
||||
// if (Objects.equals(unfinishedAction.getType(), ScriptActionBO.ActionType.Conversation)
|
||||
// || Objects.equals(unfinishedAction.getType(), ScriptActionBO.ActionType.Operation)) {
|
||||
// || Objects.equals(unfinishedAction.getType(), ScriptActionBO.ActionType.Operation2)) {
|
||||
// scriptExecuteService.executeAction(simulation, unfinishedAction, correctSystemTime);
|
||||
// }
|
||||
return;
|
||||
|
@ -4,6 +4,7 @@ import club.joylink.rtss.services.voice.IVoiceService;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.competition.ScriptExecuteService;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.ConversationMessageVO;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.ConversationVO;
|
||||
import club.joylink.rtss.simulation.cbtc.event.*;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
@ -11,13 +12,18 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationUser;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.client.SocketMessageVO;
|
||||
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
|
||||
import club.joylink.rtss.vo.client.WebSocketMessageType;
|
||||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||
import club.joylink.rtss.websocket.StompMessageService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -44,15 +50,18 @@ public class ConversationManagerService {
|
||||
@Autowired
|
||||
private ScriptExecuteService scriptExecuteService;
|
||||
|
||||
@Autowired
|
||||
private StompMessageService stompMessageService;
|
||||
|
||||
public ConversationVO getConversationById(String group, String conversationId) {
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
Conversation conversation = simulation.getSimulationConversationById(conversationId);
|
||||
ConversationVO conversationVO = new ConversationVO(conversation);
|
||||
return conversationVO;
|
||||
}
|
||||
|
||||
public List<ConversationVO> getAllConversations(String group) {
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
List<Conversation> allConversations = simulation.queryAllConversations();
|
||||
return ConversationVO.convert2VOList(allConversations);
|
||||
}
|
||||
@ -64,13 +73,13 @@ public class ConversationManagerService {
|
||||
if (CollectionUtils.isEmpty(memberIdList)) {
|
||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "一个人不能开启会话");
|
||||
}
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
SimulationUser simulationUser = simulation.getSimulationUserById(accountVO.getId());
|
||||
SimulationMember creator = simulationUser.getPlayedMember();
|
||||
if (Objects.isNull(creator)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL);
|
||||
}
|
||||
return this.createConversation(simulation, creator, memberIdList);
|
||||
return createConversation(simulation, creator, memberIdList);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,7 +91,7 @@ public class ConversationManagerService {
|
||||
List<SimulationMember> invitedList = new ArrayList<>();
|
||||
for (String memberId : memberIdList) {
|
||||
SimulationMember member = simulation.getSimulationMemberById(memberId);
|
||||
if (this.isMemberConnect2Conversation(simulation, member)) {
|
||||
if (isMemberConnect2Conversation(simulation, member)) {
|
||||
throw new SimulationException(SimulationExceptionType.Simulation_Conversation_Member_Busy,
|
||||
memberId);
|
||||
}
|
||||
@ -105,19 +114,19 @@ public class ConversationManagerService {
|
||||
simulation.addConversation(conversation);
|
||||
// 会话创建成功事件
|
||||
SimulationConversationCreateEvent createEvent = new SimulationConversationCreateEvent(this, simulation, conversation);
|
||||
this.applicationEventPublisher.publishEvent(createEvent);
|
||||
applicationEventPublisher.publishEvent(createEvent);
|
||||
return new ConversationVO(conversation);
|
||||
}
|
||||
|
||||
/*---------------------------------- (创建会话)需要被邀请者同意 ----------------------------------*/
|
||||
public ConversationVO createConversation(String group, AccountVO user, CommunicationObject object, List<String> memberIds) {
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
SimulationUser simulationUser = simulation.getSimulationUserById(user.getId());
|
||||
SimulationMember creator = simulationUser.getPlayedMember();
|
||||
if (Objects.isNull(creator)) {
|
||||
throw new SimulationException(SimulationExceptionType.Operation_Handle_FAIL);
|
||||
}
|
||||
return this.createConversation(simulation, creator, object, memberIds);
|
||||
return createConversation(simulation, creator, object, memberIds);
|
||||
}
|
||||
|
||||
public ConversationVO createConversation(Simulation simulation, SimulationMember creator, CommunicationObject object, List<String> memberIds) {
|
||||
@ -178,7 +187,7 @@ public class ConversationManagerService {
|
||||
simulation.addConversation(conversation);
|
||||
// 会话创建成功事件
|
||||
SimulationConversationCreateEvent createEvent = new SimulationConversationCreateEvent(this, simulation, conversation);
|
||||
this.applicationEventPublisher.publishEvent(createEvent);
|
||||
applicationEventPublisher.publishEvent(createEvent);
|
||||
// 用户发送会话邀请事件;机器人直接连接
|
||||
List<ConversationMember> memberList = conversation.getMemberList();
|
||||
for (ConversationMember conversationMember : memberList) {
|
||||
@ -189,9 +198,9 @@ public class ConversationManagerService {
|
||||
if (!member.isRobot()) {
|
||||
log.info(String.format("仿真[%s]会话[%s]邀请成员[%s]事件发布",
|
||||
simulation.getId(), conversation.getId(), member.toString()));
|
||||
this.applicationEventPublisher.publishEvent(new SimulationConversationInviteEvent(this, simulation, conversation, member));
|
||||
applicationEventPublisher.publishEvent(new SimulationConversationInviteEvent(this, simulation, conversation, member));
|
||||
} else {
|
||||
this.connect2Conversation(simulation, conversation, member);
|
||||
connect2Conversation(simulation, conversation, member);
|
||||
}
|
||||
}
|
||||
return new ConversationVO(conversation);
|
||||
@ -209,10 +218,10 @@ public class ConversationManagerService {
|
||||
}
|
||||
|
||||
public ConversationVO connect2Conversation(String group, AccountVO accountVO, String conversationId) {
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
Conversation conversation = simulation.getSimulationConversationById(conversationId);
|
||||
SimulationMember member = simulation.getSimulationMemberByUserId(accountVO.getId());
|
||||
return this.connect2Conversation(simulation, conversation, member);
|
||||
return connect2Conversation(simulation, conversation, member);
|
||||
}
|
||||
|
||||
public ConversationVO connect2Conversation(Simulation simulation, Conversation conversation, SimulationMember member) {
|
||||
@ -224,7 +233,7 @@ public class ConversationManagerService {
|
||||
// 发布用户连接会话事件
|
||||
SimulationConversationMemberConnectEvent connectEvent =
|
||||
new SimulationConversationMemberConnectEvent(this, simulation, conversation, member);
|
||||
this.applicationEventPublisher.publishEvent(connectEvent);
|
||||
applicationEventPublisher.publishEvent(connectEvent);
|
||||
return new ConversationVO(conversation);
|
||||
}
|
||||
|
||||
@ -232,10 +241,10 @@ public class ConversationManagerService {
|
||||
* 结束会话
|
||||
*/
|
||||
public void exitConversation(String group, String conversationId, AccountVO accountVO) {
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
Conversation conversation = simulation.getSimulationConversationById(conversationId);
|
||||
SimulationMember member = simulation.getSimulationMemberByUserId(accountVO.getId());
|
||||
this.exitConversation(simulation, conversation, member);
|
||||
exitConversation(simulation, conversation, member);
|
||||
}
|
||||
|
||||
public void exitConversation(Simulation simulation, Conversation conversation, SimulationMember member) {
|
||||
@ -245,20 +254,20 @@ public class ConversationManagerService {
|
||||
}
|
||||
// 发布会话成员退出事件
|
||||
SimulationConversationExitEvent overEvent = new SimulationConversationExitEvent(this, simulation, conversation, member);
|
||||
this.applicationEventPublisher.publishEvent(overEvent);
|
||||
applicationEventPublisher.publishEvent(overEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仿真用户会话chat
|
||||
*/
|
||||
public void chat(String group, String conversationId, AccountVO accountVO, MultipartFile file) {
|
||||
Simulation simulation = this.groupSimulationCache.getSimulationByGroup(group);
|
||||
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||
Conversation conversation = simulation.getSimulationConversationById(conversationId);
|
||||
SimulationMember member = simulation.getSimulationMemberByUserId(accountVO.getId());
|
||||
VoiceRecognitionResult recognitionResult = this.iVoiceService.voiceRecognition(file, "");
|
||||
VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(file, "");
|
||||
String upperCaseResult = recognitionResult.getResult().toUpperCase();
|
||||
String handledContent = this.simulationVoiceHandler.handle(upperCaseResult);
|
||||
this.chat(simulation, conversation, member, handledContent, recognitionResult.getFilePath());
|
||||
String handledContent = simulationVoiceHandler.handle(upperCaseResult);
|
||||
chat(simulation, conversation, member, handledContent, recognitionResult.getFilePath());
|
||||
}
|
||||
|
||||
public String chat(Simulation simulation, Conversation conversation,
|
||||
@ -269,7 +278,7 @@ public class ConversationManagerService {
|
||||
conversation.addMessage(conversationMessage);
|
||||
// scriptExecuteService.replaceContent4ConversationAction(simulation, conversation, conversationMessage);
|
||||
SimulationConversationChatEvent chatEvent = new SimulationConversationChatEvent(this, simulation, conversation, conversationMessage);
|
||||
this.applicationEventPublisher.publishEvent(chatEvent);
|
||||
applicationEventPublisher.publishEvent(chatEvent);
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -293,4 +302,118 @@ public class ConversationManagerService {
|
||||
String path = iVoiceService.synthesis(content, "0");
|
||||
chat(simulation, conversation, member, content, path);
|
||||
}
|
||||
|
||||
//----------------------------------- 电话会话操作 -------------------------------------
|
||||
|
||||
/**
|
||||
* 打电话
|
||||
*/
|
||||
public ConversationVO phoneStart(Simulation simulation, SimulationMember member, CommunicationObject object, List<String> memberIds) {
|
||||
Set<SimulationMember> members = new LinkedHashSet<>();
|
||||
if (!CollectionUtils.isEmpty(memberIds)) {
|
||||
members.addAll(memberIds.stream().map(simulation::getSimulationMemberById).filter(simulationMember -> {
|
||||
if (Objects.nonNull(simulationMember.getUserId())) {
|
||||
SimulationUser simulationUser = simulation.querySimulationUserById(simulationMember.getUserId());
|
||||
return simulationUser.isOnline();
|
||||
}
|
||||
return true;
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
if (object != null) {
|
||||
switch (object) {
|
||||
case ALL_TRAIN:
|
||||
members.addAll(simulation.getMemberListByType(SimulationMember.Type.DRIVER));
|
||||
break;
|
||||
case ALL_STATION:
|
||||
members.addAll(simulation.getMemberListByType(SimulationMember.Type.STATION_SUPERVISOR));
|
||||
break;
|
||||
default:
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, String.format("未知的通讯对象[%s]", object));
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isEmpty(members)) {
|
||||
throw new SimulationException(SimulationExceptionType.Illegal_Argument, "会话成员列表为空/成员都不在线");
|
||||
}
|
||||
if (members.stream().anyMatch(simulation::isInValidConversation)) {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, "有被邀请的成员正在进行其它通话");
|
||||
}
|
||||
Conversation conversation = new Conversation(simulation.getIdGenerator().nextConversationId(),
|
||||
member, simulation.getSystemTime(), new ArrayList<>(members), object);
|
||||
simulation.addConversation(conversation);
|
||||
// 会话创建成功事件
|
||||
SimulationConversationCreateEvent createEvent = new SimulationConversationCreateEvent(this, simulation, conversation);
|
||||
applicationEventPublisher.publishEvent(createEvent);
|
||||
return new ConversationVO(conversation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接听电话
|
||||
*/
|
||||
public ConversationVO phoneConnect(Simulation simulation, SimulationMember member, String conversationId) {
|
||||
Conversation conversation = simulation.getSimulationConversationById(conversationId);
|
||||
return connect2Conversation(simulation, conversation, member);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接听电话,聊天输入
|
||||
*/
|
||||
public void phoneChat(Simulation simulation, SimulationMember member, String id, String content, String audioPath) {
|
||||
Conversation conversation = simulation.getSimulationConversationById(id);
|
||||
if (conversation.isOver()) {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, String.format("会话[%s]已经结束", id));
|
||||
}
|
||||
if (!conversation.contains(member)) {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, String.format("会话[%s]不包含该成员[%s]", id, member.getId()));
|
||||
}
|
||||
String path = audioPath;
|
||||
if (StringUtils.isEmpty(audioPath)) {
|
||||
path = iVoiceService.synthesis(content, "0");
|
||||
}
|
||||
chat(simulation, conversation, member, content, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话:挂电话
|
||||
*/
|
||||
public void phoneExit(Simulation simulation, SimulationMember member, String id) {
|
||||
Conversation conversation = simulation.getSimulationConversationById(id);
|
||||
if (conversation.isOver()) {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, String.format("会话[%s]已经结束", id));
|
||||
}
|
||||
if (!conversation.contains(member)) {
|
||||
throw new SimulationException(SimulationExceptionType.System_Fault, String.format("会话[%s]不包含该成员[%s]", id, member.getId()));
|
||||
}
|
||||
exitConversation(simulation, conversation, member);
|
||||
}
|
||||
|
||||
//----------------------------------- 消息会话 -------------------------------------
|
||||
|
||||
/**
|
||||
* 文件BASE64编码
|
||||
*/
|
||||
public ConversationMessageVO conversationChat(Simulation simulation, SimulationMember member, String fileBase64Str) {
|
||||
VoiceRecognitionResult recognitionResult = iVoiceService.voiceRecognition(fileBase64Str);
|
||||
String upperCaseResult = recognitionResult.getResult().toUpperCase();
|
||||
String handledContent = simulationVoiceHandler.handle(upperCaseResult);
|
||||
ConversationMessage conversationMessage = new ConversationMessage(simulation.getIdGenerator().nextConversationMessageId(),
|
||||
member, simulation.getCorrectSystemTime(), handledContent, recognitionResult.getFilePath());
|
||||
return sendChatMessage(simulation.getId(), simulation.getSimulationUserIds(), conversationMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 会话操作
|
||||
*/
|
||||
public ConversationMessageVO conversationChat(Simulation simulation, SimulationMember member, String content, String audioPath) {
|
||||
ConversationMessage conversationMessage = new ConversationMessage(simulation.getIdGenerator().nextConversationMessageId(),
|
||||
member, simulation.getCorrectSystemTime(), content, audioPath);
|
||||
return sendChatMessage(simulation.getId(), simulation.getSimulationUserIds(), conversationMessage);
|
||||
}
|
||||
|
||||
private ConversationMessageVO sendChatMessage(String simulationId, Set<String> userIds, ConversationMessage conversationMessage) {
|
||||
ConversationMessageVO conversationMessageVO = new ConversationMessageVO(conversationMessage);
|
||||
SocketMessageVO<ConversationMessageVO> chatMessage =
|
||||
SocketMessageFactory.build(WebSocketMessageType.Simulation_Conversation_Operation, simulationId, conversationMessageVO);
|
||||
stompMessageService.sendToUser(userIds, chatMessage);
|
||||
return conversationMessageVO;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.simulation.cbtc.conversation;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import lombok.Getter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -18,6 +19,8 @@ public class ConversationMessage {
|
||||
|
||||
private String audioPath;
|
||||
|
||||
private MessageType type;
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
@ -28,5 +31,10 @@ public class ConversationMessage {
|
||||
this.time = systemTime;
|
||||
this.content = content;
|
||||
this.audioPath = filePath;
|
||||
this.type = StringUtils.isEmpty(filePath) ? MessageType.Text : MessageType.Voice;
|
||||
}
|
||||
|
||||
public enum MessageType {
|
||||
Voice, Text;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
package club.joylink.rtss.simulation.cbtc.conversation;
|
||||
|
||||
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.data.vo.ConversationMessageVO;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.ConversationVO;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会话操作
|
||||
*/
|
||||
@OperateHandler
|
||||
@Slf4j
|
||||
public class ConversationOperateHandler {
|
||||
@Autowired
|
||||
private ConversationManagerService conversationManagerService;
|
||||
|
||||
//-------------------------------- 电话消息操作 ---------------------------------------
|
||||
|
||||
/**
|
||||
* 电话:创建电话消息
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Phone_Start)
|
||||
public ConversationVO phoneStart(Simulation simulation, SimulationMember member, CommunicationObject object, List<String> memberIds) {
|
||||
return conversationManagerService.phoneStart(simulation, member, object, memberIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话:接听电话
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Phone_Connect)
|
||||
public ConversationVO phoneConnect(Simulation simulation, SimulationMember member, String id) {
|
||||
return conversationManagerService.phoneConnect(simulation, member, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话:语音消息
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Phone_Audio)
|
||||
public void phoneAudio(Simulation simulation, SimulationMember member, String id, String audioPath, String content) {
|
||||
conversationManagerService.phoneChat(simulation, member, id, content, audioPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话:文字消息
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Phone_Text)
|
||||
public void phonePhoneText(Simulation simulation, SimulationMember member, String id, String content) {
|
||||
conversationManagerService.phoneChat(simulation, member, id, content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话:挂电话
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Phone_Exit)
|
||||
public void phoneExit(Simulation simulation, SimulationMember member, String id) {
|
||||
conversationManagerService.phoneExit(simulation, member, id);
|
||||
}
|
||||
|
||||
//-------------------------------- 消息操作 ---------------------------------------
|
||||
|
||||
/**
|
||||
* 发送会话消息(语音输入)
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Chat_Audio)
|
||||
public ConversationMessageVO audioChat(Simulation simulation, SimulationMember member, String audioPath, String content) {
|
||||
return conversationManagerService.conversationChat(simulation, member, content, audioPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送会话消息(文字输入)
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Chat_Text)
|
||||
public ConversationMessageVO textChat(Simulation simulation, SimulationMember member, String content) {
|
||||
return conversationManagerService.conversationChat(simulation, member, content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送会话消息(语音输入)Base64格式
|
||||
*/
|
||||
@OperateHandlerMapping(type = Operation.Type.Conversation_Chat_Audio_Base64)
|
||||
public ConversationMessageVO audioBase64(Simulation simulation, SimulationMember member, String fileBase64Str) {
|
||||
return conversationManagerService.conversationChat(simulation, member, fileBase64Str);
|
||||
}
|
||||
}
|
@ -1248,4 +1248,10 @@ public class SimulationDataRepository {
|
||||
}
|
||||
return stream.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Section> getHasStopCountDownSections() {
|
||||
return getListByType(MapElement.DeviceType.SECTION, Section.class).stream()
|
||||
.filter(Section::isHasStopCountDown)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,21 @@ public abstract class DelayUnlockDevice extends MayOutOfOrderDevice {
|
||||
super(code, name, deviceType);
|
||||
}
|
||||
|
||||
public void delayUnlockStart(Route route,MapConfig mc) {
|
||||
// route.getType() == Type
|
||||
int baseDelayTime = route.getDelayReleaseTime();
|
||||
if(mc.isRailway()){
|
||||
switch (route.getType()){
|
||||
case DEPARTURE:
|
||||
case RECEIVING:
|
||||
baseDelayTime = 180;
|
||||
break;
|
||||
case SHUNTING:
|
||||
baseDelayTime = 30;
|
||||
}
|
||||
}
|
||||
this.remain = baseDelayTime * 1000;
|
||||
}
|
||||
public void delayUnlockStart(Route route) {
|
||||
this.remain = route.getDelayReleaseTime() * 1000;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,8 @@ import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySectionAxleCounter;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@ -19,6 +21,7 @@ import java.util.*;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ExpConditionMaterialSrcAnno(name = "Section")
|
||||
public class Section extends DelayUnlockDevice {
|
||||
|
||||
public Section(String code, String name) {
|
||||
@ -164,16 +167,23 @@ public class Section extends DelayUnlockDevice {
|
||||
*/
|
||||
private Set<ZC> zcs = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 有停稳计时?
|
||||
*/
|
||||
private boolean hasStopCountDown;
|
||||
|
||||
// ------------------状态属性---------------------
|
||||
|
||||
/**
|
||||
* 是否封锁(封锁后,包含区段的进路不能排列)
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "blockade",type = "boolean",desc = "是否封锁(封锁后,包含区段的进路不能排列)")
|
||||
private boolean blockade;
|
||||
|
||||
/**
|
||||
* 是否进路锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "routeLock",type = "boolean",desc = "是否进路锁闭")
|
||||
private boolean routeLock;
|
||||
|
||||
/**
|
||||
@ -189,36 +199,43 @@ public class Section extends DelayUnlockDevice {
|
||||
/**
|
||||
* 进路延续保护锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "overlapLock",type = "boolean",desc = "进路延续保护锁闭")
|
||||
private boolean overlapLock;
|
||||
|
||||
/**
|
||||
* 通信车占用
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "ctOccupied",type = "boolean",desc = "通信车占用")
|
||||
private boolean ctOccupied;
|
||||
|
||||
/**
|
||||
* 计轴占用-非通信车占用
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "nctOccupied",type = "boolean",desc = "计轴占用-非通信车占用")
|
||||
private boolean nctOccupied;
|
||||
|
||||
/**
|
||||
* 占用列车方向
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "trainRight",type = "boolean",desc = "占用列车方向")
|
||||
private boolean trainRight;
|
||||
|
||||
/**
|
||||
* 是否切除
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "cutOff",type = "boolean",desc = "是否切除")
|
||||
private boolean cutOff;
|
||||
|
||||
/**
|
||||
* 计轴是否被报失效(ARB故障)
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "invalid",type = "boolean",desc = "计轴是否被报失效(ARB故障)")
|
||||
private boolean invalid;
|
||||
|
||||
/**
|
||||
* 故障锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "faultLock",type = "boolean",desc = "故障锁闭")
|
||||
private boolean faultLock;
|
||||
|
||||
/**
|
||||
@ -261,6 +278,14 @@ public class Section extends DelayUnlockDevice {
|
||||
*/
|
||||
private List<ShuntingType> shuntingTypeList;
|
||||
|
||||
/**
|
||||
* 停稳倒计时
|
||||
* 0 表示初始状态
|
||||
* -1 表示准备开始计时;
|
||||
* 非负数表示当前计时;
|
||||
*/
|
||||
private int stopCountDown;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
@ -280,13 +305,31 @@ public class Section extends DelayUnlockDevice {
|
||||
this.closeInit = false;
|
||||
this.openInit = false;
|
||||
this.closed = false;
|
||||
this.badShunt = false;
|
||||
this.shuntingTypeList = new ArrayList<>();
|
||||
this.stopCountDown = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始停稳倒计时
|
||||
*/
|
||||
public void startStopCountDown() {
|
||||
stopCountDown = 40 * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 准备开始停稳倒计时
|
||||
*/
|
||||
public void readyStartStopCountDown() {
|
||||
stopCountDown = -1;
|
||||
}
|
||||
|
||||
public int getStopCountDownInSeconds() {
|
||||
return stopCountDown / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 区段是否被列车占用
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOccupied() {
|
||||
return this.nctOccupied || this.ctOccupied || this.isLogicOccupied();
|
||||
|
@ -4,6 +4,8 @@ import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalModel;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySignal;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@ -20,6 +22,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ExpConditionMaterialSrcAnno(name = "Signal")
|
||||
public class Signal extends DelayUnlockDevice {
|
||||
public static int GUIDE_DELAY = 15 * 1000; //大铁首区段占用的引导进路的延时关闭时长
|
||||
|
||||
@ -111,7 +114,9 @@ public class Signal extends DelayUnlockDevice {
|
||||
*/
|
||||
private boolean ctc;
|
||||
|
||||
/** CTC级别是否办理延续保护 */
|
||||
/**
|
||||
* CTC级别是否办理延续保护
|
||||
*/
|
||||
private boolean ctcSetOverlap;
|
||||
|
||||
/**
|
||||
@ -176,15 +181,18 @@ public class Signal extends DelayUnlockDevice {
|
||||
/**
|
||||
* 是否封锁
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "blockade", type = "boolean", desc = "是否封锁")
|
||||
private boolean blockade;
|
||||
/**
|
||||
* 是否钮封
|
||||
* 是否钮封
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "buttonBlockade", type = "boolean", desc = "是否钮封")
|
||||
private boolean buttonBlockade;
|
||||
|
||||
/**
|
||||
* 重复封锁(*后期去掉*)
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "reblockade", type = "boolean", desc = "重复封锁")
|
||||
private boolean reblockade;
|
||||
/**
|
||||
* 侧防锁闭(侧防锁闭后,不能排列此信号机为始端的任何进路)
|
||||
@ -199,14 +207,18 @@ public class Signal extends DelayUnlockDevice {
|
||||
/**
|
||||
* 当前信号显示
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "aspect", type = "SignalAspect", desc = "信号显示")
|
||||
private SignalAspect aspect;
|
||||
/**
|
||||
* 是否禁止联锁自动开信号
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "forbidden", type = "boolean", desc = "是否禁止联锁自动开信号")
|
||||
private boolean forbidden;
|
||||
|
||||
/**
|
||||
* 引导信号开放剩余时间,单位ms
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "guideRemain", type = "int", desc = "引导信号开放剩余时间,单位ms")
|
||||
private int guideRemain;
|
||||
|
||||
/**
|
||||
@ -222,9 +234,13 @@ public class Signal extends DelayUnlockDevice {
|
||||
/**
|
||||
* 是否接近锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "approachLock", type = "boolean", desc = "是否接近锁闭")
|
||||
private boolean approachLock;
|
||||
|
||||
/** 延续保护锁闭 */
|
||||
/**
|
||||
* 延续保护锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "overlapLock", type = "boolean", desc = "延续保护锁闭")
|
||||
private boolean overlapLock;
|
||||
|
||||
/**
|
||||
@ -244,7 +260,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
this.lockedRoute = null;
|
||||
this.level = LEVEL_Close;
|
||||
this.blockade = false;
|
||||
this.buttonBlockade=false;
|
||||
this.buttonBlockade = false;
|
||||
this.reblockade = false;
|
||||
this.fpl = false;
|
||||
this.logicLight = this.isCtc();
|
||||
@ -267,6 +283,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 切换为CBTC模式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean changeToCbtcMode() {
|
||||
@ -287,6 +304,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 切换为后备模式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean changeToBackupMode() {
|
||||
@ -318,7 +336,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
public boolean isMainAspect() {
|
||||
if (this.lockedRoute != null) {
|
||||
return this.aspect.equals(this.lockedRoute.getAspect());
|
||||
return this.aspect.equals(this.lockedRoute.getSettedAspect());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -566,6 +584,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 引导信号控制级别
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isGuideLevel() {
|
||||
@ -574,6 +593,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* ATP 移动闭塞信号控制级别
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAtpLevel() {
|
||||
@ -582,6 +602,7 @@ public class Signal extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 主信号控制级别
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isMainLevel() {
|
||||
@ -736,9 +757,13 @@ public class Signal extends DelayUnlockDevice {
|
||||
* 出段信号机
|
||||
*/
|
||||
OUTBOUND,
|
||||
/** 接车信号机(大铁,X/S) */
|
||||
/**
|
||||
* 接车信号机(大铁,X/S)
|
||||
*/
|
||||
RECEIVING,
|
||||
/** 发车信号机(大铁,XF/SF) */
|
||||
/**
|
||||
* 发车信号机(大铁,XF/SF)
|
||||
*/
|
||||
DEPARTURE,
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@ import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityPsl;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityScreenDoor;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@ -18,6 +20,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ExpConditionMaterialSrcAnno(name = "Stand")
|
||||
public class Stand extends MayOutOfOrderDevice {
|
||||
|
||||
public Stand(String code, String name) {
|
||||
@ -62,7 +65,9 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
|
||||
private VirtualRealityPsl vrPsl;
|
||||
|
||||
/** 默认折返策略 */
|
||||
/**
|
||||
* 默认折返策略
|
||||
*/
|
||||
private TurnBackType defaultTypeStrategy;
|
||||
|
||||
// -------------------------------状态属性---------------------------------
|
||||
@ -75,12 +80,14 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
/**
|
||||
* 列车停站倒计时,单位ms
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "remainTime", type = "int", desc = "列车停站倒计时,单位ms")
|
||||
private int remainTime;
|
||||
|
||||
/*扣车相关*/
|
||||
/**
|
||||
* 车站是否扣车
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "stationHoldTrain", type = "boolean", desc = "车站是否扣车")
|
||||
private volatile boolean stationHoldTrain;
|
||||
|
||||
/**
|
||||
@ -88,10 +95,14 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
*/
|
||||
private volatile boolean centerHoldTrain;
|
||||
|
||||
/**系统扣车*/
|
||||
/**
|
||||
* 系统扣车
|
||||
*/
|
||||
private volatile boolean sysHoldTrain;
|
||||
|
||||
/** IBP盘扣车 */
|
||||
/**
|
||||
* IBP盘扣车
|
||||
*/
|
||||
private boolean ibpHoldTrain;
|
||||
|
||||
/**
|
||||
@ -103,6 +114,7 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
/**
|
||||
* 是否全部跳停
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "allSkip", type = "boolean", desc = "是否全部跳停")
|
||||
private volatile boolean allSkip;
|
||||
|
||||
/**
|
||||
@ -113,6 +125,7 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
/**
|
||||
* 跳停一直有效?
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "skipAlwaysValid", type = "boolean", desc = "跳停持续有效")
|
||||
private boolean skipAlwaysValid;
|
||||
|
||||
/*运行等级(时间)相关*/
|
||||
@ -121,7 +134,9 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
*/
|
||||
private int runLevelTime;
|
||||
|
||||
/** 列车-停站时间map */
|
||||
/**
|
||||
* 列车-停站时间map
|
||||
*/
|
||||
private final Map<String, Integer> runTimeMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
@ -140,7 +155,9 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
*/
|
||||
private int parkingTime;
|
||||
|
||||
/** 列车-停站时间map */
|
||||
/**
|
||||
* 列车-停站时间map
|
||||
*/
|
||||
private final Map<String, Integer> parkingTimeMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
@ -157,7 +174,9 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
|
||||
private boolean closed;
|
||||
|
||||
/** 最后一辆列车的发车时间 */
|
||||
/**
|
||||
* 最后一辆列车的发车时间
|
||||
*/
|
||||
private LocalDateTime lastTrainDepartTime;
|
||||
|
||||
// ---------------------------- method -------------------------------------
|
||||
@ -298,7 +317,7 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
|
||||
public String debugStr() {
|
||||
return String.format("%s-%s-%s(%s)", this.station.getName(),
|
||||
this.isRight()?"右行":"左行", this.getName(), this.getCode());
|
||||
this.isRight() ? "右行" : "左行", this.getName(), this.getCode());
|
||||
}
|
||||
|
||||
public String showStr() {
|
||||
@ -407,7 +426,9 @@ public class Stand extends MayOutOfOrderDevice {
|
||||
}
|
||||
},
|
||||
|
||||
/** 无关闭锁紧信号 */
|
||||
/**
|
||||
* 无关闭锁紧信号
|
||||
*/
|
||||
NO_CLOSE_AND_LOCK {
|
||||
@Override
|
||||
public boolean apply(MayOutOfOrderDevice device) {
|
||||
|
@ -10,6 +10,8 @@ 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;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
@ -22,6 +24,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ExpConditionMaterialSrcAnno(name = "Station")
|
||||
public class Station extends MayOutOfOrderDevice {
|
||||
public Station(String code, String name) {
|
||||
super(code, name, DeviceType.STATION);
|
||||
@ -126,11 +129,13 @@ public class Station extends MayOutOfOrderDevice {
|
||||
/**
|
||||
* 是否引导总锁
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "totalGuideLock", type = "boolean", desc = "是否引导总锁")
|
||||
private boolean totalGuideLock;
|
||||
|
||||
/**
|
||||
* 控制模式
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "controlMode", type = "ControlMode", desc = "控制模式")
|
||||
private ControlMode controlMode;
|
||||
|
||||
/**
|
||||
@ -171,6 +176,7 @@ public class Station extends MayOutOfOrderDevice {
|
||||
/**
|
||||
* 是否紧急控制
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "emergencyController", type = "boolean", desc = "是否紧急控制")
|
||||
private boolean emergencyController;
|
||||
|
||||
/**
|
||||
@ -188,8 +194,10 @@ public class Station extends MayOutOfOrderDevice {
|
||||
*/
|
||||
private Map<DirectionLabelEnum, StationDirection> stationDirectionMap;
|
||||
|
||||
@ExpConditionMaterialAnno(name = "sGuideMasterLock", type = "boolean", desc = "S引导总锁")
|
||||
private boolean sGuideMasterLock;
|
||||
|
||||
@ExpConditionMaterialAnno(name = "xGuideMasterLock", type = "boolean", desc = "X引导总锁")
|
||||
private boolean xGuideMasterLock;
|
||||
|
||||
/**
|
||||
@ -197,8 +205,12 @@ public class Station extends MayOutOfOrderDevice {
|
||||
*/
|
||||
private boolean allowAutonomy;
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 操作计数器
|
||||
*/
|
||||
private Map<String, Integer> counter;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
if (vrIbp != null) {
|
||||
@ -223,6 +235,7 @@ public class Station extends MayOutOfOrderDevice {
|
||||
preResetValidDuration = new AtomicInteger(0);
|
||||
sGuideMasterLock = false;
|
||||
xGuideMasterLock = false;
|
||||
counter = null;
|
||||
}
|
||||
|
||||
public List<Stand> getStandOf(boolean right) {
|
||||
@ -459,6 +472,13 @@ public class Station extends MayOutOfOrderDevice {
|
||||
return Fault.ATS_ROUTE_TRIGGER_FAULT.equals(getFault());
|
||||
}
|
||||
|
||||
public void count(String countName) {
|
||||
if (this.counter == null) {
|
||||
this.counter = new HashMap<>();
|
||||
}
|
||||
this.counter.merge(countName, 1, Integer::sum);
|
||||
}
|
||||
|
||||
public enum ControlMode {
|
||||
/**
|
||||
* 交出未被接收
|
||||
|
@ -2,6 +2,8 @@ package club.joylink.rtss.simulation.cbtc.data.map;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SwitchIndication;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealitySwitch;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@ -13,6 +15,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ExpConditionMaterialSrcAnno(name = "Switch")
|
||||
public class Switch extends DelayUnlockDevice {
|
||||
public Switch(String code, String name) {
|
||||
super(code, name, DeviceType.SWITCH);
|
||||
@ -53,11 +56,13 @@ public class Switch extends DelayUnlockDevice {
|
||||
/**
|
||||
* 是否单锁
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "singleLock", type = "boolean", desc = "是否单锁")
|
||||
private boolean singleLock;
|
||||
|
||||
/**
|
||||
* 是否封锁
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "blockade", type = "boolean", desc = "是否封锁")
|
||||
private boolean blockade;
|
||||
|
||||
/**
|
||||
@ -71,6 +76,7 @@ public class Switch extends DelayUnlockDevice {
|
||||
/**
|
||||
* 是否进路锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "routeLock", type = "boolean", desc = "是否进路锁闭")
|
||||
private boolean routeLock;
|
||||
|
||||
/**
|
||||
@ -81,25 +87,30 @@ public class Switch extends DelayUnlockDevice {
|
||||
/**
|
||||
* 是否进路侧防锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "fpLock", type = "boolean", desc = "是否进路侧防锁闭")
|
||||
private boolean fpLock;
|
||||
|
||||
/**
|
||||
* 是否进路延续保护锁闭
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "overlapLock", type = "boolean", desc = "是否进路延续保护锁闭")
|
||||
private boolean overlapLock;
|
||||
|
||||
/**
|
||||
* 是否引导总锁
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "guideMasterLock", type = "boolean", desc = "是否引导总锁")
|
||||
private boolean guideMasterLock;
|
||||
/**
|
||||
* 道岔位置表示
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "pos", type = "SwitchIndication", desc = "道岔位置表示")
|
||||
private SwitchIndication pos;
|
||||
|
||||
/**
|
||||
* 预复位
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "preReset", type = "boolean", desc = "预复位")
|
||||
private boolean preReset;
|
||||
|
||||
/**
|
||||
@ -404,6 +415,7 @@ public class Switch extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 联锁征用(进路/延续保护/侧防等)
|
||||
*
|
||||
* @param normal
|
||||
*/
|
||||
public boolean ciUse(boolean normal) {
|
||||
@ -423,6 +435,7 @@ public class Switch extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 是否被征用至相反位置
|
||||
*
|
||||
* @param normal
|
||||
* @return
|
||||
*/
|
||||
@ -436,6 +449,7 @@ public class Switch extends DelayUnlockDevice {
|
||||
|
||||
/**
|
||||
* 是否被征用至所需位置
|
||||
*
|
||||
* @param normal
|
||||
* @return
|
||||
*/
|
||||
|
@ -126,6 +126,8 @@ public class SectionStatus extends DeviceStatus {
|
||||
*/
|
||||
private boolean badShunt;
|
||||
|
||||
private Integer stopCountDown;
|
||||
|
||||
public SectionStatus(Section section) {
|
||||
super(section.getCode(), section.getDeviceType());
|
||||
this.blockade = section.isBlockade();
|
||||
@ -147,6 +149,7 @@ public class SectionStatus extends DeviceStatus {
|
||||
this.fault = section.getFault() == null ? null : section.getFault().toString();
|
||||
this.shuntingTypeList = section.getShuntingTypeList();
|
||||
this.badShunt = section.isBadShunt();
|
||||
this.stopCountDown = section.getStopCountDownInSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -250,6 +253,13 @@ public class SectionStatus extends DeviceStatus {
|
||||
this.badShunt = section.isBadShunt();
|
||||
status.setBadShunt(this.badShunt);
|
||||
}
|
||||
int stopCountDownInSeconds = section.getStopCountDownInSeconds();
|
||||
if (!Objects.equals(this.stopCountDown, stopCountDownInSeconds)) {
|
||||
change = true;
|
||||
this.stopCountDown = stopCountDownInSeconds;
|
||||
}
|
||||
status.setStopCountDown(stopCountDown == 0 ? null : stopCountDown);
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
@ -272,6 +282,7 @@ public class SectionStatus extends DeviceStatus {
|
||||
statusVO.setDelayUnlock(delayUnlock);
|
||||
statusVO.setClosed(closed);
|
||||
statusVO.setFault(fault);
|
||||
statusVO.setBadShunt(badShunt);
|
||||
statusVO.setShuntingTypeList(this.shuntingTypeList);
|
||||
return statusVO;
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -90,6 +92,11 @@ public class StationStatus extends DeviceStatus {
|
||||
*/
|
||||
private boolean allowAutonomy;
|
||||
|
||||
/**
|
||||
* 计数器
|
||||
*/
|
||||
private Map<String, Integer> counter;
|
||||
|
||||
public StationStatus(Station station) {
|
||||
super(station.getCode(), station.getDeviceType());
|
||||
controlMode = station.getControlMode();
|
||||
@ -107,6 +114,9 @@ public class StationStatus extends DeviceStatus {
|
||||
sGuideMasterLock = station.isSGuideMasterLock();
|
||||
xGuideMasterLock = station.isXGuideMasterLock();
|
||||
allowAutonomy = station.isAllowAutonomy();
|
||||
if (station.getCounter() != null) {
|
||||
counter = new HashMap<>(station.getCounter());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -190,6 +200,15 @@ public class StationStatus extends DeviceStatus {
|
||||
allowAutonomy = station.isAllowAutonomy();
|
||||
status.setAllowAutonomy(allowAutonomy);
|
||||
}
|
||||
if (!Objects.equals(counter, station.getCounter())) {
|
||||
change = true;
|
||||
if (counter == null) {
|
||||
counter = new HashMap<>(station.getCounter());
|
||||
} else {
|
||||
counter.putAll(station.getCounter());
|
||||
}
|
||||
status.setCounter(counter);
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
|
@ -1,177 +1,191 @@
|
||||
package club.joylink.rtss.simulation.cbtc.data.storage.device;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class StorageRoute extends StorageDevice {
|
||||
|
||||
/**
|
||||
* 是否CBTC模式
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean cbtcMode;
|
||||
|
||||
/**
|
||||
* ats自动控制
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean atsControl;
|
||||
|
||||
/**
|
||||
* 连续通过进路模式(联锁自动进路)开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean fleetMode;
|
||||
|
||||
/**
|
||||
* 自动追踪/联锁自动触发模式开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean ciControl;
|
||||
|
||||
/**
|
||||
* 进路是否排列中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean setting;
|
||||
|
||||
private LocalDateTime settingStartTime;
|
||||
|
||||
/**
|
||||
* 是否引导进路排列
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean settingGuide;
|
||||
|
||||
/**
|
||||
* 进路是否锁闭
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean lock;
|
||||
|
||||
/** 进路延时解锁设备 */
|
||||
private String delayUnlockDevice;
|
||||
|
||||
/**
|
||||
* 是否正常解锁中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean normalUnlock;
|
||||
|
||||
private String unlockedSection;
|
||||
|
||||
// public StorageRoute(Route route) {
|
||||
// super(route.getCode());
|
||||
// cbtcMode = route.isCbtcMode();
|
||||
// turnBackMode = route.isTurnBackMode();
|
||||
// atsControl = route.isAtsControl();
|
||||
// fleetMode = route.isFleetMode();
|
||||
// ciControl = route.isCiControl();
|
||||
// setting = route.isSetting();
|
||||
// settingGuide = route.isSettingGuide();
|
||||
// lock = route.isLock();
|
||||
// canceling = route.isCanceling();
|
||||
// normalUnlock = route.isNormalUnlock();
|
||||
// }
|
||||
|
||||
public StorageRoute(String code) {
|
||||
super(code);
|
||||
}
|
||||
|
||||
public static StorageRoute convert2Storage(Route route) {
|
||||
StorageRoute storageRoute = new StorageRoute(route.getCode());
|
||||
if (storageRoute.convert(route)) {
|
||||
return storageRoute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean convert(MapElement element) {
|
||||
boolean change = false;
|
||||
Route route = (Route) element;
|
||||
if (!route.isAtsControl()) {
|
||||
change = true;
|
||||
this.setAtsControl(route.isAtsControl());
|
||||
}
|
||||
if (route.isFleetMode()) {
|
||||
change = true;
|
||||
this.setFleetMode(route.isFleetMode());
|
||||
}
|
||||
if (route.isCiControl()) {
|
||||
change = true;
|
||||
this.setCiControl(route.isCiControl());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
change = true;
|
||||
this.setSetting(route.isSetting());
|
||||
this.setSettingStartTime(route.getSettingStartTime());
|
||||
}
|
||||
if (route.isGuideSetting()) {
|
||||
change = true;
|
||||
this.setSettingGuide(route.isGuideSetting());
|
||||
}
|
||||
if (route.isLock()) {
|
||||
change = true;
|
||||
this.setLock(route.isLock());
|
||||
}
|
||||
if (route.getDelayUnlockDevice() != null) {
|
||||
change = true;
|
||||
this.setDelayUnlockDevice(route.getDelayUnlockDevice().getCode());
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
change = true;
|
||||
this.setNormalUnlock(route.isNormalUnlock());
|
||||
}
|
||||
if (Objects.nonNull(route.getUnlockedSection())) {
|
||||
change = true;
|
||||
this.setUnlockedSection(route.getUnlockedSection().getCode());
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recover2Simulation(MapElement element, Simulation simulation, SimulationDataRepository repository) {
|
||||
Route route = (Route) element;
|
||||
route.setAtsControl(atsControl != null ? atsControl : true);
|
||||
route.setFleetMode(fleetMode != null ? fleetMode : false);
|
||||
route.setCiControl(ciControl != null ? ciControl : false);
|
||||
route.setSetting(setting != null? setting : false);
|
||||
route.setSettingStartTime(this.settingStartTime);
|
||||
route.setGuideSetting(settingGuide != null? settingGuide : false);
|
||||
route.setLock(lock != null ? lock : false);
|
||||
if (this.delayUnlockDevice != null) {
|
||||
route.setDelayUnlockDevice((DelayUnlockDevice) repository.getByCode(this.delayUnlockDevice));
|
||||
}
|
||||
route.setNormalUnlock(normalUnlock != null ? normalUnlock : false);
|
||||
if (Objects.nonNull(this.unlockedSection)) {
|
||||
route.setUnlockedSection(repository.getByCode(this.unlockedSection, Section.class));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.data.storage.device;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SignalAspect;
|
||||
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.DelayUnlockDevice;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.MapElement;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumDeserializer;
|
||||
import club.joylink.rtss.util.jsonSerialize.Boolean2NumSerializer;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class StorageRoute extends StorageDevice {
|
||||
|
||||
/**
|
||||
* 是否CBTC模式
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean cbtcMode;
|
||||
|
||||
/**
|
||||
* ats自动控制
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean atsControl;
|
||||
|
||||
/**
|
||||
* 连续通过进路模式(联锁自动进路)开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean fleetMode;
|
||||
|
||||
/**
|
||||
* 自动追踪/联锁自动触发模式开启
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean ciControl;
|
||||
|
||||
/**
|
||||
* 进路是否排列中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean setting;
|
||||
|
||||
private LocalDateTime settingStartTime;
|
||||
|
||||
/**
|
||||
* 是否引导进路排列
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean settingGuide;
|
||||
|
||||
/**
|
||||
* 进路是否锁闭
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean lock;
|
||||
|
||||
/** 进路延时解锁设备 */
|
||||
private String delayUnlockDevice;
|
||||
|
||||
/**
|
||||
* 是否正常解锁中
|
||||
*/
|
||||
@JsonSerialize(using = Boolean2NumSerializer.class)
|
||||
@JsonDeserialize(using = Boolean2NumDeserializer.class)
|
||||
private Boolean normalUnlock;
|
||||
|
||||
private String unlockedSection;
|
||||
|
||||
/**
|
||||
* 该进路办理成功后要开放的信号
|
||||
* <p>
|
||||
* 注意:每次开始触发办理进路时设置
|
||||
*/
|
||||
private SignalAspect settedAspect;
|
||||
|
||||
// public StorageRoute(Route route) {
|
||||
// super(route.getCode());
|
||||
// cbtcMode = route.isCbtcMode();
|
||||
// turnBackMode = route.isTurnBackMode();
|
||||
// atsControl = route.isAtsControl();
|
||||
// fleetMode = route.isFleetMode();
|
||||
// ciControl = route.isCiControl();
|
||||
// setting = route.isSetting();
|
||||
// settingGuide = route.isSettingGuide();
|
||||
// lock = route.isLock();
|
||||
// canceling = route.isCanceling();
|
||||
// normalUnlock = route.isNormalUnlock();
|
||||
// }
|
||||
|
||||
public StorageRoute(String code) {
|
||||
super(code);
|
||||
}
|
||||
|
||||
public static StorageRoute convert2Storage(Route route) {
|
||||
StorageRoute storageRoute = new StorageRoute(route.getCode());
|
||||
if (storageRoute.convert(route)) {
|
||||
return storageRoute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean convert(MapElement element) {
|
||||
boolean change = false;
|
||||
Route route = (Route) element;
|
||||
if (!route.isAtsControl()) {
|
||||
change = true;
|
||||
this.setAtsControl(route.isAtsControl());
|
||||
}
|
||||
if (route.isFleetMode()) {
|
||||
change = true;
|
||||
this.setFleetMode(route.isFleetMode());
|
||||
}
|
||||
if (route.isCiControl()) {
|
||||
change = true;
|
||||
this.setCiControl(route.isCiControl());
|
||||
}
|
||||
if (route.isSetting()) {
|
||||
change = true;
|
||||
this.setSetting(route.isSetting());
|
||||
this.setSettingStartTime(route.getSettingStartTime());
|
||||
}
|
||||
if (route.isGuideSetting()) {
|
||||
change = true;
|
||||
this.setSettingGuide(route.isGuideSetting());
|
||||
}
|
||||
if (route.isLock()) {
|
||||
change = true;
|
||||
this.setLock(route.isLock());
|
||||
}
|
||||
if (route.getDelayUnlockDevice() != null) {
|
||||
change = true;
|
||||
this.setDelayUnlockDevice(route.getDelayUnlockDevice().getCode());
|
||||
}
|
||||
if (route.isNormalUnlock()) {
|
||||
change = true;
|
||||
this.setNormalUnlock(route.isNormalUnlock());
|
||||
}
|
||||
if (Objects.nonNull(route.getUnlockedSection())) {
|
||||
change = true;
|
||||
this.setUnlockedSection(route.getUnlockedSection().getCode());
|
||||
}
|
||||
if (Objects.nonNull(route.getSettedAspect())) {
|
||||
change = true;
|
||||
this.setSettedAspect(route.getSettedAspect());
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recover2Simulation(MapElement element, Simulation simulation, SimulationDataRepository repository) {
|
||||
Route route = (Route) element;
|
||||
route.setAtsControl(atsControl != null ? atsControl : true);
|
||||
route.setFleetMode(fleetMode != null ? fleetMode : false);
|
||||
route.setCiControl(ciControl != null ? ciControl : false);
|
||||
route.setSetting(setting != null? setting : false);
|
||||
route.setSettingStartTime(this.settingStartTime);
|
||||
route.setGuideSetting(settingGuide != null? settingGuide : false);
|
||||
route.setLock(lock != null ? lock : false);
|
||||
if (this.delayUnlockDevice != null) {
|
||||
route.setDelayUnlockDevice((DelayUnlockDevice) repository.getByCode(this.delayUnlockDevice));
|
||||
}
|
||||
route.setNormalUnlock(normalUnlock != null ? normalUnlock : false);
|
||||
if (Objects.nonNull(this.unlockedSection)) {
|
||||
route.setUnlockedSection(repository.getByCode(this.unlockedSection, Section.class));
|
||||
}
|
||||
route.setSettedAspect(settedAspect);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -106,6 +106,11 @@ public class StorageSection extends StorageDelayUnlockDevice {
|
||||
*/
|
||||
private Boolean badShunt;
|
||||
|
||||
/**
|
||||
* 停稳倒计时
|
||||
*/
|
||||
private Integer stopCountDown;
|
||||
|
||||
public StorageSection(Section section) {
|
||||
super(section);
|
||||
}
|
||||
@ -176,6 +181,10 @@ public class StorageSection extends StorageDelayUnlockDevice {
|
||||
this.shuntingTypeList = section.getShuntingTypeList();
|
||||
this.badShunt = section.isBadShunt();
|
||||
}
|
||||
if (section.getStopCountDown() != 0) {
|
||||
change = true;
|
||||
this.stopCountDown = section.getStopCountDown();
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
@ -197,5 +206,6 @@ public class StorageSection extends StorageDelayUnlockDevice {
|
||||
section.setSpeedLimitBeforeFault(speedLimitBeforeFault);
|
||||
section.setShuntingTypeList(shuntingTypeList != null ? shuntingTypeList : new ArrayList<>());
|
||||
section.setBadShunt(badShunt != null ? badShunt : false);
|
||||
section.setStopCountDown(stopCountDown == null ? 0 : stopCountDown);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@ -65,6 +66,8 @@ public class StorageStation extends StorageStatusDevice {
|
||||
|
||||
private Integer preResetValidDuration;
|
||||
|
||||
private Map<String, Integer> counter;
|
||||
|
||||
public StorageStation(Station station) {
|
||||
super(station);
|
||||
}
|
||||
@ -111,6 +114,7 @@ public class StorageStation extends StorageStatusDevice {
|
||||
if (station.getPreResetValidDuration() != null && station.getPreResetValidDuration().get() != 0) {
|
||||
this.setPreResetValidDuration(station.getPreResetValidDuration().get());
|
||||
}
|
||||
this.counter = station.getCounter();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -133,5 +137,6 @@ public class StorageStation extends StorageStatusDevice {
|
||||
station.setEmergencyController(emergencyController != null ? emergencyController : false);
|
||||
station.setControlApplicant(controlApplicant != null ? simulation.getSimulationMemberById(controlApplicant) : null);
|
||||
station.setPreResetValidDuration(new AtomicInteger(Objects.requireNonNullElse(preResetValidDuration, 0)));
|
||||
station.setCounter(counter);
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,12 @@ package club.joylink.rtss.simulation.cbtc.data.support;
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.*;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
public class RoutePath {
|
||||
|
||||
@ -470,6 +471,15 @@ public class RoutePath {
|
||||
// 取第一个延续保护道岔定位的
|
||||
for (Route temp : triggerList) {
|
||||
List<SwitchElement> switchList = temp.getOverlap().getFirstPath().getSwitchList();
|
||||
if(null==switchList||switchList.isEmpty()){
|
||||
log.debug("==============================================================================");
|
||||
log.debug("==>>异常进路code = {} name = {}",temp.getCode(),temp.getName());
|
||||
log.debug("==>>异常相关所有进路:");
|
||||
triggerList.forEach(r->{
|
||||
log.debug("==>>进路code={} name={} , 始端信号机code={} name={}",r.getCode(),r.getName(),r.getStart().getCode(),r.getName());
|
||||
});
|
||||
log.debug("==============================================================================");
|
||||
}
|
||||
if (switchList.get(0).isNormal()) {
|
||||
route = temp;
|
||||
break;
|
||||
|
@ -23,12 +23,15 @@ public class ConversationMessageVO {
|
||||
|
||||
private String audioPath;
|
||||
|
||||
private ConversationMessage.MessageType type;
|
||||
|
||||
public ConversationMessageVO(ConversationMessage message) {
|
||||
this.id = message.getId();
|
||||
this.memberId = message.getMember().getId();
|
||||
this.time = message.getTime();
|
||||
this.content = message.getContent();
|
||||
this.audioPath = message.getAudioPath();
|
||||
this.type = message.getType();
|
||||
}
|
||||
|
||||
public static List<ConversationMessageVO> convert2VOList(List<ConversationMessage> list) {
|
||||
|
@ -99,6 +99,9 @@ public class SectionStatusVO extends DeviceStatusVO {
|
||||
|
||||
private Boolean badShunt;
|
||||
|
||||
@JsonInclude
|
||||
private Integer stopCountDown;
|
||||
|
||||
public SectionStatusVO(Section section) {
|
||||
super(section.getCode(), section.getDeviceType());
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 车站状态
|
||||
@ -87,6 +88,8 @@ public class StationStatusVO extends DeviceStatusVO {
|
||||
|
||||
private Boolean allowAutonomy;
|
||||
|
||||
private Map<String, Integer> counter;
|
||||
|
||||
public StationStatusVO(Station station) {
|
||||
super(station.getCode(), station.getDeviceType());
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import club.joylink.rtss.simulation.cbtc.data.support.MovementAuthority;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialAnno;
|
||||
import club.joylink.rtss.simulation.cbtc.training2.ecm.anno.ExpConditionMaterialSrcAnno;
|
||||
import club.joylink.rtss.vo.client.operation.DriveParamVO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@ -27,6 +29,7 @@ import java.util.*;
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
@ExpConditionMaterialSrcAnno(name = "Train")
|
||||
public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
|
||||
// -----------列车公共属性-----------
|
||||
@ -118,15 +121,17 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 车载服务通讯是否正常在线
|
||||
*/
|
||||
private boolean communication;
|
||||
private boolean communication;
|
||||
/**
|
||||
* 列车运行级别
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "runLevel", type = "RunLevel", desc = "列车运行级别")
|
||||
private RunLevel runLevel;
|
||||
|
||||
/**
|
||||
* 驾驶模式
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "driveMode", type = "DriveMode", desc = "驾驶模式")
|
||||
private DriveMode driveMode;
|
||||
|
||||
/**
|
||||
@ -260,12 +265,14 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 是否紧急停车(信号)
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "signalEB", type = "boolean", desc = "是否紧急停车(信号)")
|
||||
private boolean signalEB;
|
||||
|
||||
/**
|
||||
* 是否紧急停车(电路)
|
||||
*/
|
||||
private boolean circuitEB;
|
||||
@ExpConditionMaterialAnno(name = "circuitEB", type = "boolean", desc = "是否紧急停车(电路)")
|
||||
private boolean circuitEB;
|
||||
|
||||
/**
|
||||
* 站台停靠列车动作
|
||||
@ -275,6 +282,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 下一计划是否停站
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "nextParking", type = "boolean", desc = "下一计划是否停站")
|
||||
private boolean nextParking;
|
||||
|
||||
/**
|
||||
@ -285,6 +293,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 是否扣车
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "hold", type = "boolean", desc = "是否扣车")
|
||||
private boolean hold;
|
||||
|
||||
/**
|
||||
@ -295,11 +304,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 是否自动折返中
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "dtro", type = "boolean", desc = "是否自动折返中")
|
||||
private boolean dtro;
|
||||
|
||||
/**
|
||||
* 是否换端中
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "changeEnds", type = "boolean", desc = "是否换端中")
|
||||
private boolean changeEnds;
|
||||
|
||||
/**
|
||||
@ -310,16 +321,19 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* ATO是否开启
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "atoOn", type = "boolean", desc = "ATO是否开启")
|
||||
private boolean atoOn;
|
||||
|
||||
/**
|
||||
* ATP是否可用
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "atpOn", type = "boolean", desc = "ATP是否可用")
|
||||
private boolean atpOn;
|
||||
|
||||
/**
|
||||
* 进路优先排列
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "priorityRouteSet", type = "boolean", desc = "进路优先排列")
|
||||
private boolean priorityRouteSet;
|
||||
|
||||
/**
|
||||
@ -335,6 +349,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 门模式
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "doorMode", type = "DoorMode", desc = "门模式")
|
||||
private DoorMode doorMode;
|
||||
|
||||
/**
|
||||
@ -409,6 +424,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* 运行类型
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "runType", type = "RunType", desc = "运行类型")
|
||||
private RunType runType;
|
||||
|
||||
/**
|
||||
@ -445,6 +461,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
/**
|
||||
* ato可以开启
|
||||
*/
|
||||
@ExpConditionMaterialAnno(name = "atoCanOpen", type = "boolean", desc = "ato可以开启")
|
||||
private boolean atoCanOpen;
|
||||
|
||||
private VirtualRealityAudio vrAudio;
|
||||
@ -507,7 +524,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
super(code, groupNumber, DeviceType.TRAIN);
|
||||
this.groupNumber = groupNumber;
|
||||
this.gear = Handwheel.ATO;
|
||||
this.communication = true;
|
||||
this.communication = true;
|
||||
this.atpOn = true;
|
||||
this.door1 = new Door(this, "1");
|
||||
this.door2 = new Door(this, "2");
|
||||
@ -523,7 +540,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
@Override
|
||||
public void reset() {
|
||||
this.noCommunicateDevice = false;
|
||||
this.communication = true;
|
||||
this.communication = true;
|
||||
this.runLevel = null;
|
||||
this.driveMode = null;
|
||||
this.tempPreselectionMode = PreselectionMode.AM_C;
|
||||
@ -653,7 +670,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.communication = true;
|
||||
this.communication = true;
|
||||
this.jump = false;
|
||||
this.hold = false;
|
||||
this.standParkedTrainActivity = null;
|
||||
@ -1024,7 +1041,7 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
* 在空挡?
|
||||
*/
|
||||
public boolean isInNeutralGear() {
|
||||
return Handwheel.WASH.equals(gear) || Handwheel.DISCONNECT.equals(gear);
|
||||
return Handwheel.WASH.equals(gear) || Handwheel.DISCONNECT.equals(gear);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1078,12 +1095,16 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
return getAtoSpeed() * 3.6 < 20;
|
||||
}
|
||||
|
||||
/** 操纵杆是否在惰行位 */
|
||||
/**
|
||||
* 操纵杆是否在惰行位
|
||||
*/
|
||||
public boolean isLeverInCoastingGear() {
|
||||
return leverPosition == 0;
|
||||
}
|
||||
|
||||
/** 是否不在牵引位 */
|
||||
/**
|
||||
* 是否不在牵引位
|
||||
*/
|
||||
public boolean isLeverNotInTractionGear() {
|
||||
return leverPosition <= 0;
|
||||
}
|
||||
@ -1155,9 +1176,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
* 道岔支持的操作
|
||||
*/
|
||||
public enum Operation {
|
||||
/** 开门 */
|
||||
/**
|
||||
* 开门
|
||||
*/
|
||||
K,
|
||||
/** 关门 */
|
||||
/**
|
||||
* 关门
|
||||
*/
|
||||
G,
|
||||
}
|
||||
|
||||
@ -1273,7 +1298,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
},
|
||||
|
||||
/** 驾驶异常 */
|
||||
/**
|
||||
* 驾驶异常
|
||||
*/
|
||||
DRIVE_FAULT {
|
||||
@Override
|
||||
public boolean apply(MapElement device) {
|
||||
@ -1285,10 +1312,15 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
/** 列车脱线 */
|
||||
/**
|
||||
* 列车脱线
|
||||
*/
|
||||
OFF_LINE {},
|
||||
/** 突然EB */
|
||||
SUDDEN_EB{},;
|
||||
/**
|
||||
* 突然EB
|
||||
*/
|
||||
SUDDEN_EB {},
|
||||
;
|
||||
|
||||
public boolean apply(MapElement device) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
@ -1298,8 +1330,9 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
train.setFault(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消故障
|
||||
* 取消故障
|
||||
*/
|
||||
public void fix(MapElement device) {
|
||||
VirtualRealityTrain train = (VirtualRealityTrain) device;
|
||||
@ -1416,9 +1449,13 @@ public class VirtualRealityTrain extends VirtualRealityDevice {
|
||||
}
|
||||
},
|
||||
;
|
||||
/** 所允许的最高驾驶模式 */
|
||||
/**
|
||||
* 所允许的最高驾驶模式
|
||||
*/
|
||||
private DriveMode driveMode;
|
||||
/** 所允许的最高运行级别 */
|
||||
/**
|
||||
* 所允许的最高运行级别
|
||||
*/
|
||||
private RunLevel runLevel;
|
||||
|
||||
PreselectionMode(DriveMode driveMode, RunLevel runLevel) {
|
||||
|
@ -1,236 +1,236 @@
|
||||
package club.joylink.rtss.simulation.cbtc.depot;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class DepotService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService ciRouteService;
|
||||
|
||||
@Autowired
|
||||
private TrainOutboundLoadTool trainOutboundLoadTool;
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationService groupSimulationService;
|
||||
|
||||
@Autowired
|
||||
private ATPService atpService;
|
||||
|
||||
public void loadDepotTrain(Simulation simulation) {
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
return;
|
||||
}
|
||||
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
|
||||
simulation.getRepository().getAllVrTrain().stream()
|
||||
.collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation))
|
||||
.forEach((station, trainList) -> {
|
||||
List<Section> sections = parkingTracksMap.get(station);
|
||||
// 先加载内侧的停车轨
|
||||
sections.sort(Comparator.comparing(section ->
|
||||
Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection())));
|
||||
boolean right = sections.get(sections.size() - 1).getLeftSection() == null;
|
||||
for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) {
|
||||
VirtualRealityTrain train = trainList.get(i);
|
||||
Section section = sections.get(i);
|
||||
train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right);
|
||||
train.parkingAt(section);
|
||||
train.initAsRM();
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
simulation.getRepository().addOnlineTrain(train);
|
||||
simulation.getRepository().addTrainInfo(trainInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE);
|
||||
}
|
||||
|
||||
private void run(Simulation simulation) {
|
||||
if (!simulation.isPlanRunning()) {
|
||||
return;
|
||||
}
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
trainOutboundLoadTool.loadOutboundTrain(simulation);
|
||||
} else {
|
||||
timeToDeparture(simulation);
|
||||
backToParking(simulation);
|
||||
settingRouteAndMoving(simulation);
|
||||
arriveDestination(simulation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间筛选,从停车轨自动发车
|
||||
*/
|
||||
private void timeToDeparture(Simulation simulation) {
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
|
||||
if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) {
|
||||
continue;
|
||||
}
|
||||
if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) {
|
||||
schedulingTrainPlan.getOutDepotTrip().dispatched();
|
||||
// 保存信息
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(schedulingTrainPlan.getGroupNumber(), VirtualRealityTrain.class);
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = schedulingTrainPlan.getOutDepotTrip().getStartSection();
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, false);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选入库
|
||||
*/
|
||||
private void backToParking(Simulation simulation) {
|
||||
for (TrainInfo trainInfo : simulation.getRepository().getTrainInfoMap().values()) {
|
||||
if (trainInfo.isInbound() && trainInfo.isParking()) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(trainInfo.getGroupNumber(), VirtualRealityTrain.class);
|
||||
if (train.getHeadPosition().getSection().isTransferTrack()
|
||||
&& train.getTailPosition().getSection().isTransferTrack()) {
|
||||
if (simulation.getRepository().getDepotRunningInfoList().stream()
|
||||
.anyMatch(depotRunningInfo -> depotRunningInfo.getTrain().equals(train))) {
|
||||
continue;
|
||||
}
|
||||
train.initAsRM();
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = null;
|
||||
for (Section section : simulation.getRepository().getParkingTracksMap().get(startSection.getStation())) {
|
||||
if (section.isOccupied()) {
|
||||
continue;
|
||||
}
|
||||
if (section.getLeftSection() == null || section.getRightSection() == null) {
|
||||
endSection = section;
|
||||
} else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) {
|
||||
endSection = section.getLeftSection();
|
||||
} else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) {
|
||||
endSection = section.getRightSection();
|
||||
} else {
|
||||
endSection = section;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// train.setTarget(endSection);
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
if (routePaths == null || routePaths.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, true);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列车排进路并运行
|
||||
*/
|
||||
private void settingRouteAndMoving(Simulation simulation) {
|
||||
for (DepotRunningInfo depotRunningInfo : simulation.getRepository().getDepotRunningInfoList()) {
|
||||
Section endSection = depotRunningInfo.getEndSection();
|
||||
SectionPosition position = new SectionPosition(endSection, endSection.getStopPointByDirection(depotRunningInfo.getRight()));
|
||||
depotRunningInfo.getTrain().setRobotTargetPosition(position);
|
||||
if (!depotRunningInfo.getRouteList().isEmpty()) {
|
||||
Route route = depotRunningInfo.getRouteList().get(0);
|
||||
if (route.isLock()) {
|
||||
depotRunningInfo.getRouteList().remove(0);
|
||||
}
|
||||
if (!route.isSetting()) {
|
||||
ciRouteService.setRoute(simulation, route);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断运行列车是否到达转换轨并升级
|
||||
*/
|
||||
private void arriveDestination(Simulation simulation) {
|
||||
for (Iterator<DepotRunningInfo> iterator = simulation.getRepository().getDepotRunningInfoList().iterator(); iterator.hasNext(); ) {
|
||||
DepotRunningInfo depotRunningInfo = iterator.next();
|
||||
VirtualRealityTrain train = depotRunningInfo.getTrain();
|
||||
if (depotRunningInfo.isArrival()) {
|
||||
// 到达
|
||||
iterator.remove();
|
||||
if (depotRunningInfo.in) {
|
||||
atpService.turnDirectionImmediately(train);
|
||||
} else {
|
||||
// 升级
|
||||
SimulationMember member = simulation.getSimulationMember(train, SimulationMember.Type.DRIVER);
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("preselectionMode", "AM_C");
|
||||
CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode,
|
||||
member.getId(), param);
|
||||
groupSimulationService.command(simulation, commandInitiateVO, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DepotRunningInfo {
|
||||
|
||||
private final List<Route> routeList = new ArrayList<>();
|
||||
|
||||
private final Section endSection;
|
||||
|
||||
private final VirtualRealityTrain train;
|
||||
|
||||
private final Boolean right;
|
||||
|
||||
private final Boolean in;
|
||||
|
||||
public DepotRunningInfo(Section endSection, VirtualRealityTrain train, RoutePath routePath, boolean in) {
|
||||
this.endSection = endSection;
|
||||
this.train = train;
|
||||
for (Signal signal : routePath.getSignalList()) {
|
||||
for (Route route : signal.getRouteList()) {
|
||||
if (routePath.getRouteList().contains(route)) {
|
||||
routeList.add(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.right = routePath.isRight();
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
// 列车是否到达终点
|
||||
public boolean isArrival() {
|
||||
return train.getSpeed() == 0 && train.getHeadPosition().getSection().equals(endSection)
|
||||
&& train.getTailPosition().getSection().equals(endSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
package club.joylink.rtss.simulation.cbtc.depot;
|
||||
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.tools.TrainOutboundLoadTool;
|
||||
import club.joylink.rtss.simulation.cbtc.CI.device.CiRouteService;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationService;
|
||||
import club.joylink.rtss.simulation.cbtc.Simulation;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandBO;
|
||||
import club.joylink.rtss.simulation.cbtc.command.CommandInitiateVO;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationConstants;
|
||||
import club.joylink.rtss.simulation.cbtc.constant.SimulationModule;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Route;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Section;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Signal;
|
||||
import club.joylink.rtss.simulation.cbtc.data.map.Station;
|
||||
import club.joylink.rtss.simulation.cbtc.data.plan.SchedulingTrainPlan;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.RoutePath;
|
||||
import club.joylink.rtss.simulation.cbtc.data.support.SectionPosition;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vo.TrainInfo;
|
||||
import club.joylink.rtss.simulation.cbtc.data.vr.VirtualRealityTrain;
|
||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||
import club.joylink.rtss.simulation.cbtc.onboard.ATP.ATPService;
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class DepotService {
|
||||
|
||||
@Autowired
|
||||
private CiRouteService ciRouteService;
|
||||
|
||||
@Autowired
|
||||
private TrainOutboundLoadTool trainOutboundLoadTool;
|
||||
|
||||
@Autowired
|
||||
private GroupSimulationService groupSimulationService;
|
||||
|
||||
@Autowired
|
||||
private ATPService atpService;
|
||||
|
||||
public void loadDepotTrain(Simulation simulation) {
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
return;
|
||||
}
|
||||
Map<Station, List<Section>> parkingTracksMap = simulation.getRepository().getParkingTracksMap();
|
||||
simulation.getRepository().getAllVrTrain().stream()
|
||||
.collect(Collectors.groupingBy(VirtualRealityTrain::getDepotStation))
|
||||
.forEach((station, trainList) -> {
|
||||
List<Section> sections = parkingTracksMap.get(station);
|
||||
// 先加载内侧的停车轨
|
||||
sections.sort(Comparator.comparing(section ->
|
||||
Objects.isNull(section.getLeftSection()) || Objects.isNull(section.getRightSection())));
|
||||
boolean right = sections.get(sections.size() - 1).getLeftSection() == null;
|
||||
for (int i = 0, trainListSize = trainList.size(); i < trainListSize; i++) {
|
||||
VirtualRealityTrain train = trainList.get(i);
|
||||
Section section = sections.get(i);
|
||||
train.initManualTrain(new SectionPosition(section, section.getStopPointByDirection(right)), right);
|
||||
train.parkingAt(section);
|
||||
train.initAsRM();
|
||||
TrainInfo trainInfo = TrainInfo.constructManualTrain(train);
|
||||
trainInfo.tracking(train);
|
||||
simulation.getRepository().addOnlineTrain(train);
|
||||
simulation.getRepository().addTrainInfo(trainInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addJobs(Simulation simulation) {
|
||||
simulation.addJob(SimulationModule.DEPOT.name(), () -> this.run(simulation), SimulationConstants.DEPOT_LOOP_RATE);
|
||||
}
|
||||
|
||||
private void run(Simulation simulation) {
|
||||
if (!simulation.isPlanRunning()) {
|
||||
return;
|
||||
}
|
||||
if (!simulation.getRepository().getConfig().isHandleDepot()) {
|
||||
trainOutboundLoadTool.loadOutboundTrain(simulation);
|
||||
} else {
|
||||
timeToDeparture(simulation);
|
||||
backToParking(simulation);
|
||||
settingRouteAndMoving(simulation);
|
||||
arriveDestination(simulation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间筛选,从停车轨自动发车
|
||||
*/
|
||||
private void timeToDeparture(Simulation simulation) {
|
||||
LocalDateTime systemTime = simulation.getSystemTime();
|
||||
for (SchedulingTrainPlan schedulingTrainPlan : simulation.getRepository().getSchedulingTrainPlanList()) {
|
||||
if (schedulingTrainPlan.getOutDepotTrip().isDispatched()) {
|
||||
continue;
|
||||
}
|
||||
if (schedulingTrainPlan.getOutDepotTrip().getStartTime().minusMinutes(10).isBefore(systemTime.toLocalTime())) {
|
||||
schedulingTrainPlan.getOutDepotTrip().dispatched();
|
||||
// 保存信息
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(schedulingTrainPlan.getGroupNumber(), VirtualRealityTrain.class);
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = schedulingTrainPlan.getOutDepotTrip().getStartSection();
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, false);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 筛选入库
|
||||
*/
|
||||
private void backToParking(Simulation simulation) {
|
||||
for (TrainInfo trainInfo : simulation.getRepository().getTrainInfoMap().values()) {
|
||||
if (trainInfo.isInbound() && trainInfo.isParking()) {
|
||||
VirtualRealityTrain train = simulation.getRepository().getVRByCode(trainInfo.getGroupNumber(), VirtualRealityTrain.class);
|
||||
if (train.getHeadPosition().getSection().isTransferTrack()
|
||||
&& train.getTailPosition().getSection().isTransferTrack()) {
|
||||
if (simulation.getRepository().getDepotRunningInfoList().stream()
|
||||
.anyMatch(depotRunningInfo -> depotRunningInfo.getTrain().equals(train))) {
|
||||
continue;
|
||||
}
|
||||
train.initAsRM();
|
||||
Section startSection = train.getHeadPosition().getSection();
|
||||
Section endSection = null;
|
||||
for (Section section : simulation.getRepository().getParkingTracksMap().get(startSection.getStation())) {
|
||||
if (section.isOccupied()) {
|
||||
continue;
|
||||
}
|
||||
if (section.getLeftSection() == null || section.getRightSection() == null) {
|
||||
endSection = section;
|
||||
} else if (section.getLeftSection().isParkingTrack() && !section.getLeftSection().isOccupied()) {
|
||||
endSection = section.getLeftSection();
|
||||
} else if (section.getRightSection().isParkingTrack() && !section.getRightSection().isOccupied()) {
|
||||
endSection = section.getRightSection();
|
||||
} else {
|
||||
endSection = section;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// train.setTarget(endSection);
|
||||
List<RoutePath> routePaths = simulation.getRepository().queryRoutePaths(startSection, endSection);
|
||||
if (routePaths == null || routePaths.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RoutePath routePath = routePaths.get(0);
|
||||
DepotRunningInfo depotRunningInfo = new DepotRunningInfo(endSection, train, routePath, true);
|
||||
simulation.getRepository().getDepotRunningInfoList().add(depotRunningInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列车排进路并运行
|
||||
*/
|
||||
private void settingRouteAndMoving(Simulation simulation) {
|
||||
for (DepotRunningInfo depotRunningInfo : simulation.getRepository().getDepotRunningInfoList()) {
|
||||
Section endSection = depotRunningInfo.getEndSection();
|
||||
SectionPosition position = new SectionPosition(endSection, endSection.getStopPointByDirection(depotRunningInfo.getRight()));
|
||||
depotRunningInfo.getTrain().setRobotTargetPosition(position);
|
||||
if (!depotRunningInfo.getRouteList().isEmpty()) {
|
||||
Route route = depotRunningInfo.getRouteList().get(0);
|
||||
if (route.isLock()) {
|
||||
depotRunningInfo.getRouteList().remove(0);
|
||||
}
|
||||
if (!route.isSetting()) {
|
||||
ciRouteService.setRoute(simulation, route,route.getAspect());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断运行列车是否到达转换轨并升级
|
||||
*/
|
||||
private void arriveDestination(Simulation simulation) {
|
||||
for (Iterator<DepotRunningInfo> iterator = simulation.getRepository().getDepotRunningInfoList().iterator(); iterator.hasNext(); ) {
|
||||
DepotRunningInfo depotRunningInfo = iterator.next();
|
||||
VirtualRealityTrain train = depotRunningInfo.getTrain();
|
||||
if (depotRunningInfo.isArrival()) {
|
||||
// 到达
|
||||
iterator.remove();
|
||||
if (depotRunningInfo.in) {
|
||||
atpService.turnDirectionImmediately(train);
|
||||
} else {
|
||||
// 升级
|
||||
SimulationMember member = simulation.getSimulationMember(train, SimulationMember.Type.DRIVER);
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("preselectionMode", "AM_C");
|
||||
CommandInitiateVO commandInitiateVO = new CommandInitiateVO(CommandBO.CommandType.Change_Preselection_Mode,
|
||||
member.getId(), param);
|
||||
groupSimulationService.command(simulation, commandInitiateVO, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
public static class DepotRunningInfo {
|
||||
|
||||
private final List<Route> routeList = new ArrayList<>();
|
||||
|
||||
private final Section endSection;
|
||||
|
||||
private final VirtualRealityTrain train;
|
||||
|
||||
private final Boolean right;
|
||||
|
||||
private final Boolean in;
|
||||
|
||||
public DepotRunningInfo(Section endSection, VirtualRealityTrain train, RoutePath routePath, boolean in) {
|
||||
this.endSection = endSection;
|
||||
this.train = train;
|
||||
for (Signal signal : routePath.getSignalList()) {
|
||||
for (Route route : signal.getRouteList()) {
|
||||
if (routePath.getRouteList().contains(route)) {
|
||||
routeList.add(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.right = routePath.isRight();
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
// 列车是否到达终点
|
||||
public boolean isArrival() {
|
||||
return train.getSpeed() == 0 && train.getHeadPosition().getSection().equals(endSection)
|
||||
&& train.getTailPosition().getSection().equals(endSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,11 +106,11 @@ public class MemberManager {
|
||||
this.playRole(simulation, userId, ddList.get(0).getId());
|
||||
break;
|
||||
}
|
||||
case CTC: {
|
||||
List<SimulationMember> list = simulation.querySimulationMembersOfRole(SimulationMember.Type.RAIL_CTC);
|
||||
this.playRole(simulation, userId, list.get(0).getId());
|
||||
break;
|
||||
}
|
||||
// case CTC: {
|
||||
// List<SimulationMember> list = simulation.querySimulationMembersOfRole(SimulationMember.Type.RAIL_CTC);
|
||||
// this.playRole(simulation, userId, list.get(0).getId());
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user