Merge branch 'test-training2' of https://git.code.tencent.com/lian-cbtc/rtss-server into test-training2

This commit is contained in:
weizhihong 2022-08-29 10:37:21 +08:00
commit 90d4acbdb5
3 changed files with 42 additions and 101 deletions

View File

@ -14,7 +14,9 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType; import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
import club.joylink.rtss.simulation.cbtc.member.MemberManager; import club.joylink.rtss.simulation.cbtc.member.MemberManager;
import club.joylink.rtss.simulation.cbtc.script.ScriptBO; import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
import club.joylink.rtss.simulation.cbtc.training2.*; 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.util.JsonUtils;
import club.joylink.rtss.vo.AccountVO; import club.joylink.rtss.vo.AccountVO;
import club.joylink.rtss.vo.LoginUserInfoVO; import club.joylink.rtss.vo.LoginUserInfoVO;
@ -31,7 +33,6 @@ import org.springframework.util.StringUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -136,28 +137,6 @@ public class Training2Service {
atsOperationDispatcher.execute(simulation, step.getSimulationMember(), simOperation2.getOperationType().name(), simOperation2.getParams()); atsOperationDispatcher.execute(simulation, step.getSimulationMember(), simOperation2.getOperationType().name(), simOperation2.getParams());
} }
/**
* 评分监视
*/
public void scoringMonitor(Simulation simulation) {
Training2 training2 = simulation.getTraining2();
List<ScoringRule2> scoringRules = training2.getScoringRules();
if (CollectionUtils.isEmpty(scoringRules))
return;
for (ScoringRule2 scoringRule : scoringRules) {
for (ScoringRule2.Detail durativeDetail : scoringRule.getDurativeDetails()) {
if (durativeDetail.getDeduct() != null) //已经被判定的不用再监视
continue;
Expression condition = durativeDetail.getCondition();
if (condition != null) {
if (condition.getValue(boolean.class)) {
durativeDetail.setDeduct(true);
}
}
}
}
}
/** /**
* 预览实训草稿 * 预览实训草稿
*/ */
@ -245,7 +224,6 @@ public class Training2Service {
simulation.removeJob(EXECUTE_JOB_NAME); simulation.removeJob(EXECUTE_JOB_NAME);
} }
simulation.addJobIfAbsent(EXECUTE_JOB_NAME, () -> this.run(simulation), RATE); simulation.addJobIfAbsent(EXECUTE_JOB_NAME, () -> this.run(simulation), RATE);
simulation.addJobIfAbsent(SCORING_JOB_NAME, () -> this.scoringMonitor(simulation), RATE);
training2.start(mode); training2.start(mode);
simulationLifeCycleService.resume(simulation); simulationLifeCycleService.resume(simulation);
} }

View File

@ -1,9 +1,8 @@
package club.joylink.rtss.simulation.cbtc.training2; package club.joylink.rtss.simulation.cbtc.training2;
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -30,11 +29,6 @@ public class ScoringRule2 {
*/ */
private List<Detail> details; private List<Detail> details;
/**
* 最终得分
*/
private Float finalScore;
public ScoringRule2(SimulationMember member, Float fullMarks, List<Detail> details) { public ScoringRule2(SimulationMember member, Float fullMarks, List<Detail> details) {
this.member = member; this.member = member;
this.fullMarks = fullMarks; this.fullMarks = fullMarks;
@ -52,75 +46,45 @@ public class ScoringRule2 {
} }
public float mark(boolean allStepCompletion) { public float mark(boolean allStepCompletion) {
if (finalScore != null)
return finalScore;
if (CollectionUtils.isEmpty(details)) { //没有打分细则则实训完成给满分否则0分 if (CollectionUtils.isEmpty(details)) { //没有打分细则则实训完成给满分否则0分
return allStepCompletion ? fullMarks : 0f; return allStepCompletion ? fullMarks : 0f;
} else { } else {
double deductedPoints = details.stream() double deductedPoints = details.stream()
.peek(detail -> { .mapToDouble(detail -> {
if (detail.getDeduct() == null) { //未作出判定
if (detail.isDurative()) { if (detail.isDurative()) {
detail.setDeduct(false); throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("暂不支持该类型评分规则");
} else { } else {
if (detail.getCondition() != null) { return !detail.isCompletion() ? detail.getScore() : 0;
detail.setDeduct(detail.getCondition().getValue(boolean.class));
} else {
detail.setDeduct(!detail.isCompletion());
}
}
} }
}) })
.mapToDouble(detail -> Boolean.TRUE.equals(detail.getDeduct()) ? detail.getScore() : 0) .sum(); //统计扣分分值
.sum();
float finalScore = (float) (fullMarks - deductedPoints); float finalScore = (float) (fullMarks - deductedPoints);
this.finalScore = finalScore < 0 ? 0 : finalScore; return finalScore < 0 ? 0 : finalScore;
return finalScore;
} }
} }
@Getter @Getter
@AllArgsConstructor public static abstract class Detail {
public static class Detail {
private Type type; private Type type;
private ElementType elementType; private ElementType elementType;
/** /**
* 扣分分值 * 分值
*/ */
private float score; private float score;
/** public Detail(Type type, ElementType elementType, float score) {
* 满足该条件则扣分
*/
private Expression condition;
/**
* null 未判定true 扣分false 不扣分
*/
@Setter
private Boolean deduct;
public Detail(Type type, ElementType elementType, float score, Expression condition) {
this.type = type; this.type = type;
this.elementType = elementType; this.elementType = elementType;
this.score = score; this.score = score;
this.condition = condition;
}
public Object getElement() {
return null;
} }
public boolean isDurative() { public boolean isDurative() {
return Type.DURATIVE.equals(type); return Type.DURATIVE.equals(type);
} }
public boolean isCompletion() { public abstract boolean isCompletion();
return true;
}
public enum Type { public enum Type {
/** /**
@ -150,40 +114,44 @@ public class ScoringRule2 {
} }
public static class Operation2Detail extends Detail { public static class Operation2Detail extends Detail {
private Operation2 element; private Operation2 operation2;
public Operation2Detail(Type type, ElementType elementType, Operation2 element, float score, Expression condition) { public Operation2Detail(Type type, ElementType elementType, float score, Operation2 operation2) {
super(type, elementType, score, condition); super(type, elementType, score);
this.element = element; this.operation2 = operation2;
}
@Override
public Object getElement() {
return element;
} }
@Override @Override
public boolean isCompletion() { public boolean isCompletion() {
return element.isCompletion(); return operation2.isCompletion();
} }
} }
public static class Step2Detail extends Detail { public static class Step2Detail extends Detail {
private Step2 step; private Step2 step;
public Step2Detail(Type type, ElementType elementType, Step2 step, float score, Expression condition) { public Step2Detail(Type type, ElementType elementType, float score, Step2 step) {
super(type, elementType, score, condition); super(type, elementType, score);
this.step = step; this.step = step;
} }
@Override
public Object getElement() {
return step;
}
@Override @Override
public boolean isCompletion() { public boolean isCompletion() {
return step.isCompletion(); return step.isCompletion();
} }
} }
public static class Training2Detail extends Detail {
private List<Step2> steps;
public Training2Detail(Type type, ElementType elementType, float score, List<Step2> steps) {
super(type, elementType, score);
this.steps = steps;
}
@Override
public boolean isCompletion() {
return steps.stream().allMatch(Step2::isCompletion);
}
}
} }

View File

@ -1,7 +1,6 @@
package club.joylink.rtss.vo.client.training2; package club.joylink.rtss.vo.client.training2;
import club.joylink.rtss.simulation.cbtc.Simulation; import club.joylink.rtss.simulation.cbtc.Simulation;
import club.joylink.rtss.simulation.cbtc.data.SimulationDataRepository;
import club.joylink.rtss.simulation.cbtc.member.SimulationMember; import club.joylink.rtss.simulation.cbtc.member.SimulationMember;
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.ScoringRule2;
@ -44,8 +43,9 @@ public class ScoringRuleVO {
simulationMember = simulation.getSimulationMemberById(memberId); simulationMember = simulation.getSimulationMemberById(memberId);
} }
if (!CollectionUtils.isEmpty(this.details)) { if (!CollectionUtils.isEmpty(this.details)) {
SimulationMember finalSimulationMember = simulationMember;
details = this.details.stream() details = this.details.stream()
.map(vo -> vo.convert2BO(training2, simulation.getRepository())) .map(vo -> vo.convert2BO(training2, finalSimulationMember))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
return new ScoringRule2(simulationMember, fullMarks, details); return new ScoringRule2(simulationMember, fullMarks, details);
@ -69,21 +69,16 @@ public class ScoringRuleVO {
*/ */
private float score; private float score;
/** public ScoringRule2.Detail convert2BO(Training2 training2, SimulationMember simulationMember) {
* 扣分条件
*/
private ExpressionVO condition;
public ScoringRule2.Detail convert2BO(Training2 training2, SimulationDataRepository repository) {
switch (elementType) { switch (elementType) {
case O: case O:
Operation2 operation2 = training2.getOperation(Integer.parseInt(elementId)); Operation2 operation2 = training2.getOperation(Integer.parseInt(elementId));
return new ScoringRule2.Operation2Detail(type, elementType, operation2, score, ExpressionVO.convert2BO(condition, repository)); return new ScoringRule2.Operation2Detail(type, elementType, score, operation2);
case S: case S:
Step2 step2 = training2.getStep(Integer.parseInt(elementId)); Step2 step2 = training2.getStep(Integer.parseInt(elementId));
return new ScoringRule2.Step2Detail(type, elementType, step2, score, ExpressionVO.convert2BO(condition, repository)); return new ScoringRule2.Step2Detail(type, elementType, score, step2);
case T: case T:
return new ScoringRule2.Detail(type, elementType, score, ExpressionVO.convert2BO(condition, repository)); return new ScoringRule2.Training2Detail(type, elementType, score, training2.getSteps(simulationMember));
default: default:
throw new IllegalStateException("Unexpected value: " + elementType); throw new IllegalStateException("Unexpected value: " + elementType);
} }