【实训跳转至目标步骤功能】
This commit is contained in:
parent
aace990217
commit
5073f9f788
@ -99,4 +99,14 @@ public class SimulationTrainingV2Controller {
|
|||||||
public void drawTraining(@PathVariable String group, @PathVariable Long trainingId) {
|
public void drawTraining(@PathVariable String group, @PathVariable Long trainingId) {
|
||||||
training2Service.drawTraining(group, trainingId);
|
training2Service.drawTraining(group, trainingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载实训到第{stepId}步
|
||||||
|
* @param group 仿真ID
|
||||||
|
* @param stepId 步数ID
|
||||||
|
*/
|
||||||
|
@PutMapping("/{group}/jumpTo/{stepId}")
|
||||||
|
public void jumpToStep(@PathVariable String group, @PathVariable Long stepId){
|
||||||
|
training2Service.jumpToStep(group, stepId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,6 @@ import club.joylink.rtss.simulation.cbtc.ATS.ATSMessageCollectAndDispatcher;
|
|||||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher;
|
import club.joylink.rtss.simulation.cbtc.ATS.operation.AtsOperationDispatcher;
|
||||||
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
|
import club.joylink.rtss.simulation.cbtc.ATS.operation.Operation;
|
||||||
import club.joylink.rtss.simulation.cbtc.*;
|
import club.joylink.rtss.simulation.cbtc.*;
|
||||||
import club.joylink.rtss.simulation.cbtc.conversation.Conversation;
|
|
||||||
import club.joylink.rtss.simulation.cbtc.conversation.ConversationManagerService;
|
|
||||||
import club.joylink.rtss.simulation.cbtc.conversation.ConversationMessage;
|
|
||||||
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
import club.joylink.rtss.simulation.cbtc.data.map.Switch;
|
||||||
import club.joylink.rtss.simulation.cbtc.data.vo.ConversationMessageVO;
|
import club.joylink.rtss.simulation.cbtc.data.vo.ConversationMessageVO;
|
||||||
import club.joylink.rtss.simulation.cbtc.data.vo.Training2MessageVO;
|
import club.joylink.rtss.simulation.cbtc.data.vo.Training2MessageVO;
|
||||||
@ -26,7 +23,6 @@ import club.joylink.rtss.simulation.cbtc.member.MemberManager;
|
|||||||
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
|
||||||
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
|
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
|
||||||
import club.joylink.rtss.simulation.cbtc.training2.Operation2;
|
import club.joylink.rtss.simulation.cbtc.training2.Operation2;
|
||||||
import club.joylink.rtss.simulation.cbtc.training2.ScoringRule2;
|
|
||||||
import club.joylink.rtss.simulation.cbtc.training2.Step2;
|
import club.joylink.rtss.simulation.cbtc.training2.Step2;
|
||||||
import club.joylink.rtss.simulation.cbtc.training2.Training2;
|
import club.joylink.rtss.simulation.cbtc.training2.Training2;
|
||||||
import club.joylink.rtss.simulation.cbtc.training2.index.Index;
|
import club.joylink.rtss.simulation.cbtc.training2.index.Index;
|
||||||
@ -37,7 +33,6 @@ import club.joylink.rtss.vo.LoginUserInfoVO;
|
|||||||
import club.joylink.rtss.vo.client.SocketMessageVO;
|
import club.joylink.rtss.vo.client.SocketMessageVO;
|
||||||
import club.joylink.rtss.vo.client.WebSocketMessageType;
|
import club.joylink.rtss.vo.client.WebSocketMessageType;
|
||||||
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
import club.joylink.rtss.vo.client.factory.SocketMessageFactory;
|
||||||
import club.joylink.rtss.vo.client.training2.ScoringRuleVO;
|
|
||||||
import club.joylink.rtss.vo.paper.PaperTrainAnswerDetail;
|
import club.joylink.rtss.vo.paper.PaperTrainAnswerDetail;
|
||||||
import club.joylink.rtss.websocket.StompMessageService;
|
import club.joylink.rtss.websocket.StompMessageService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -48,6 +43,8 @@ import org.springframework.scheduling.annotation.Async;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
@ -151,6 +148,18 @@ public class Training2Service {
|
|||||||
Step2 step = getNextStepAndCheckTrainingStatus(training2, simulation);
|
Step2 step = getNextStepAndCheckTrainingStatus(training2, simulation);
|
||||||
// 如果步骤执行完毕 或者 步骤内操作全部是前端操作则直接返回交于前端操作 || step.allClientOperation()
|
// 如果步骤执行完毕 或者 步骤内操作全部是前端操作则直接返回交于前端操作 || step.allClientOperation()
|
||||||
if (step == null) {
|
if (step == null) {
|
||||||
|
if (training2.haveJumpStep()) { // 当跳转步骤是最后一步时,结束需要做额外清空
|
||||||
|
clearJumpStep(simulation);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 因为是跳转,前端不需要操作,直接置成成功
|
||||||
|
if (training2.isJumpStep(step)) {
|
||||||
|
step.getOperations().forEach(Operation2::doSuccessVail);
|
||||||
|
}
|
||||||
|
// 如果跳转到目标步骤,停止加速并置空跳转步骤
|
||||||
|
if (training2.haveJumpStep() && !training2.isJumpStep(step)) {
|
||||||
|
clearJumpStep(simulation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 尝试触发步骤
|
// 尝试触发步骤
|
||||||
@ -247,20 +256,7 @@ public class Training2Service {
|
|||||||
if (training2 == null) {
|
if (training2 == null) {
|
||||||
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "实训数据不存在");
|
throw new SimulationException(SimulationExceptionType.Invalid_Operation, "实训数据不存在");
|
||||||
}
|
}
|
||||||
if (!StringUtils.isEmpty(training2.getBgSceneJson())) {
|
doStartTraining(mode, simulation, training2);
|
||||||
if (training2.isNeedReloadScenes()) {
|
|
||||||
groupSimulationService.loadScenes(simulation.getId(), training2.getBgSceneJson());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 重置仿真状态
|
|
||||||
simulationService.reset(simulation.getId());
|
|
||||||
}
|
|
||||||
atsMessageCollectAndDispatcher.collectAllAndSend(simulation);
|
|
||||||
// 增加实训任务
|
|
||||||
training2.start(mode);
|
|
||||||
addTrainingJob(simulation, training2);
|
|
||||||
// 启动仿真
|
|
||||||
simulationLifeCycleService.resume(simulation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -437,6 +433,9 @@ public class Training2Service {
|
|||||||
simCommand2.doCompletion();
|
simCommand2.doCompletion();
|
||||||
startFlag = Boolean.TRUE;
|
startFlag = Boolean.TRUE;
|
||||||
}
|
}
|
||||||
|
if (training2.getJumpToStep() != null) { // 处于跳转状态下,下边步骤不执行
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 指令执行后启动仿真
|
// 指令执行后启动仿真
|
||||||
if (simulation.isPause() && startFlag) {
|
if (simulation.isPause() && startFlag) {
|
||||||
simulation.start();
|
simulation.start();
|
||||||
@ -538,6 +537,26 @@ public class Training2Service {
|
|||||||
sendSimulationConversation(simulation);
|
sendSimulationConversation(simulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载实训到第几步
|
||||||
|
* @param group 仿真
|
||||||
|
* @param stepId 实训步数ID
|
||||||
|
*/
|
||||||
|
public void jumpToStep(String group, Long stepId) {
|
||||||
|
Simulation simulation = groupSimulationCache.getSimulationByGroup(group);
|
||||||
|
Training2 training2 = simulation.getTraining2();
|
||||||
|
try {
|
||||||
|
Step2 step2 = training2.getStep(stepId.intValue()); // 跳转目标步骤
|
||||||
|
training2.setJumpToStep(step2);
|
||||||
|
doStartTraining(null, simulation, training2); // 开始执行
|
||||||
|
simulation.updateSpeed(Simulation.MAX_SPEED);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("loadTrainingToStep is error", e);
|
||||||
|
training2.finish();
|
||||||
|
removeTrainingJob(simulation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实训时创建仿真对象
|
* 实训时创建仿真对象
|
||||||
*/
|
*/
|
||||||
@ -591,7 +610,8 @@ public class Training2Service {
|
|||||||
*/
|
*/
|
||||||
private boolean checkTrainStepCompletion(Step2 step, Simulation simulation) {
|
private boolean checkTrainStepCompletion(Step2 step, Simulation simulation) {
|
||||||
boolean result = step.doCompletionVail();
|
boolean result = step.doCompletionVail();
|
||||||
if (result) {
|
// 如果实在跳过过程中,不需要发消息信息
|
||||||
|
if (result && !simulation.getTraining2().isJumpStep(step)) {
|
||||||
// 发送步骤完成信息
|
// 发送步骤完成信息
|
||||||
applicationContext.publishEvent(new SimulationStepFinishEvent(this, simulation, step));
|
applicationContext.publishEvent(new SimulationStepFinishEvent(this, simulation, step));
|
||||||
}
|
}
|
||||||
@ -635,8 +655,8 @@ public class Training2Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 发送步骤提示信息
|
// 发送步骤提示信息,需要跳过步骤不发消息
|
||||||
if (!step.isPrompt()) {
|
if (!step.isPrompt() && !simulation.getTraining2().isJumpStep(step)) {
|
||||||
step.setPrompt(true); // 标识已发送过消息
|
step.setPrompt(true); // 标识已发送过消息
|
||||||
applicationContext.publishEvent(new SimulationStepTipEvent(this, simulation, step));
|
applicationContext.publishEvent(new SimulationStepTipEvent(this, simulation, step));
|
||||||
}
|
}
|
||||||
@ -676,7 +696,7 @@ public class Training2Service {
|
|||||||
isExec = (simCurTime == operation2.getSimTime() || operation2.getSimTime() < simCurTime);
|
isExec = (simCurTime == operation2.getSimTime() || operation2.getSimTime() < simCurTime);
|
||||||
}
|
}
|
||||||
if (isExec) {
|
if (isExec) {
|
||||||
if (isRobot || operation2.isSpecial()) { // 特殊操作直接执行
|
if (isRobot || operation2.isSpecial() || simulation.getTraining2().isJumpStep(step)) { // 特殊操作直接执行
|
||||||
atsOperationDispatcher.execute(simulation, step.getSimulationMember(), operation2.getOperationType().name()
|
atsOperationDispatcher.execute(simulation, step.getSimulationMember(), operation2.getOperationType().name()
|
||||||
, operation2.getParams());
|
, operation2.getParams());
|
||||||
return true;
|
return true;
|
||||||
@ -782,17 +802,19 @@ public class Training2Service {
|
|||||||
ConversationMessageVO message = (ConversationMessageVO) event.getResult();
|
ConversationMessageVO message = (ConversationMessageVO) event.getResult();
|
||||||
String source = String.valueOf(simOperation2.getParams().get("content"));
|
String source = String.valueOf(simOperation2.getParams().get("content"));
|
||||||
String target = message.getContent();
|
String target = message.getContent();
|
||||||
|
boolean doCompletion = false;
|
||||||
if (CONVERSATION_TEXT_LIST.contains(event.getOperate())) {
|
if (CONVERSATION_TEXT_LIST.contains(event.getOperate())) {
|
||||||
if (Objects.equals(source,target)) {
|
doCompletion = Objects.equals(source,target);
|
||||||
simOperation2.doOperated();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
boolean result = StrUtils.isMatch(source, target, 20);
|
doCompletion = StrUtils.isMatch(source, target, 20);
|
||||||
if (result) {
|
}
|
||||||
|
if (doCompletion) {
|
||||||
simOperation2.doOperated();
|
simOperation2.doOperated();
|
||||||
|
simOperation2.doCompletion();
|
||||||
}
|
}
|
||||||
// 发送步骤完成信息
|
// 发送步骤完成信息
|
||||||
applicationContext.publishEvent(new SimulationTrainingAudioEvent(this, simulation, step, simOperation2, result));
|
if (!simulation.getTraining2().isJumpStep(step)) {
|
||||||
|
applicationContext.publishEvent(new SimulationTrainingAudioEvent(this, simulation, step, simOperation2, doCompletion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,4 +888,39 @@ public class Training2Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始执行实训
|
||||||
|
*
|
||||||
|
* @param mode 模式
|
||||||
|
* @param simulation 仿真
|
||||||
|
* @param training2 实训
|
||||||
|
*/
|
||||||
|
private void doStartTraining(ScriptBO.Mode mode, Simulation simulation, Training2 training2) {
|
||||||
|
if (!StringUtils.isEmpty(training2.getBgSceneJson())) {
|
||||||
|
if (training2.isNeedReloadScenes() && training2.getJumpToStep() != null) {
|
||||||
|
groupSimulationService.loadScenes(simulation.getId(), training2.getBgSceneJson());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 重置仿真状态
|
||||||
|
simulationService.reset(simulation.getId());
|
||||||
|
}
|
||||||
|
if (training2.getJumpToStep() == null) { // 跳转步骤时不需要发送初始状态,减小交互
|
||||||
|
atsMessageCollectAndDispatcher.collectAllAndSend(simulation);
|
||||||
|
}
|
||||||
|
// 增加实训任务
|
||||||
|
training2.start(mode);
|
||||||
|
addTrainingJob(simulation, training2);
|
||||||
|
// 启动仿真
|
||||||
|
simulationLifeCycleService.resume(simulation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除当前实训跳转步骤信息
|
||||||
|
*/
|
||||||
|
private void clearJumpStep(Simulation simulation) {
|
||||||
|
simulation.updateSpeed(Simulation.MIN_SPEED);
|
||||||
|
simulation.getTraining2().setJumpToStep(null);
|
||||||
|
simulation.getTraining2().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public class AtsAlarmService {
|
|||||||
Simulation simulation = event.getSimulation();
|
Simulation simulation = event.getSimulation();
|
||||||
DeviceFaultInfo deviceFaultInfo = event.getDeviceFaultInfo();
|
DeviceFaultInfo deviceFaultInfo = event.getDeviceFaultInfo();
|
||||||
List<AtsAlarm> list = simulation.getRepository().getAlarmList().stream()
|
List<AtsAlarm> list = simulation.getRepository().getAlarmList().stream()
|
||||||
.filter(atsAlarm -> !atsAlarm.getRecovered() && atsAlarm.getDeviceCode().equals(deviceFaultInfo.getCode()))
|
.filter(atsAlarm -> (atsAlarm.getRecovered() == null || !atsAlarm.getRecovered()) && atsAlarm.getDeviceCode().equals(deviceFaultInfo.getCode()))
|
||||||
.peek(atsAlarm -> atsAlarm.recover(simulation.getCorrectSystemTime()))
|
.peek(atsAlarm -> atsAlarm.recover(simulation.getCorrectSystemTime()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
SocketMessageVO<Collection<AtsAlarm>> messageVO = SocketMessageFactory
|
SocketMessageVO<Collection<AtsAlarm>> messageVO = SocketMessageFactory
|
||||||
|
@ -122,6 +122,10 @@ public abstract class Operation2 {
|
|||||||
this.operatedTime = LocalDateTime.now();
|
this.operatedTime = LocalDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return Step2.StepStatus.isSuccess(this.status);
|
||||||
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
this.startTime = null;
|
this.startTime = null;
|
||||||
this.operatedTime = null;
|
this.operatedTime = null;
|
||||||
|
@ -104,6 +104,10 @@ public class Training2 {
|
|||||||
*/
|
*/
|
||||||
private Map<String, IndexAlgorithmService> indexAlgorithmMap;
|
private Map<String, IndexAlgorithmService> indexAlgorithmMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转至第几步
|
||||||
|
*/
|
||||||
|
private Step2 jumpToStep;
|
||||||
|
|
||||||
public Training2(DraftTraining2WithBLOBs draftTraining2, Simulation simulation) {
|
public Training2(DraftTraining2WithBLOBs draftTraining2, Simulation simulation) {
|
||||||
this.id = draftTraining2.getId();
|
this.id = draftTraining2.getId();
|
||||||
@ -232,6 +236,22 @@ public class Training2 {
|
|||||||
return Type.SCENE.equals(this.type);
|
return Type.SCENE.equals(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是跳转步骤
|
||||||
|
*
|
||||||
|
* @return true | false
|
||||||
|
*/
|
||||||
|
public boolean isJumpStep(Step2 step) {
|
||||||
|
if (jumpToStep == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return steps.indexOf(step) <= steps.indexOf(jumpToStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean haveJumpStep() {
|
||||||
|
return jumpToStep != null;
|
||||||
|
}
|
||||||
|
|
||||||
private void resetStepAndIndex() {
|
private void resetStepAndIndex() {
|
||||||
if (this.steps != null) {
|
if (this.steps != null) {
|
||||||
this.steps.forEach(Step2::reset);
|
this.steps.forEach(Step2::reset);
|
||||||
|
Loading…
Reference in New Issue
Block a user