diff --git a/src/main/java/com/project/exam/domain/dto/ExamRecordDTO.java b/src/main/java/com/project/exam/domain/dto/ExamRecordDTO.java index 6b9e3e2..5ea2599 100644 --- a/src/main/java/com/project/exam/domain/dto/ExamRecordDTO.java +++ b/src/main/java/com/project/exam/domain/dto/ExamRecordDTO.java @@ -80,6 +80,12 @@ public class ExamRecordDTO extends BaseDTO { private Double score; // 用户得分 private Double userScore; + // V1.1 新增:AI评分(简答题实际得分) + private Double aiScore; + // V1.1 新增:AI评语 + private String aiComment; + // V1.1 新增:命中得分点列表(简答题统计用) + private List hitPoints; } @Override diff --git a/src/main/java/com/project/exam/domain/entity/ExamRecordEntity.java b/src/main/java/com/project/exam/domain/entity/ExamRecordEntity.java index 817c6b2..4e1eaee 100644 --- a/src/main/java/com/project/exam/domain/entity/ExamRecordEntity.java +++ b/src/main/java/com/project/exam/domain/entity/ExamRecordEntity.java @@ -107,6 +107,12 @@ public class ExamRecordEntity extends BaseEntity { private String analysis; // 该题是否已发起申诉 private Boolean hasAppealed = false; + // V1.1 新增:AI评分(简答题实际得分) + private Double aiScore; + // V1.1 新增:AI评语 + private String aiComment; + // V1.1 新增:命中得分点列表(简答题统计用) + private List hitPoints; } @Override diff --git a/src/main/java/com/project/exam/domain/service/impl/SubmitPaperDomainServiceImpl.java b/src/main/java/com/project/exam/domain/service/impl/SubmitPaperDomainServiceImpl.java index 291db37..262e322 100644 --- a/src/main/java/com/project/exam/domain/service/impl/SubmitPaperDomainServiceImpl.java +++ b/src/main/java/com/project/exam/domain/service/impl/SubmitPaperDomainServiceImpl.java @@ -7,6 +7,9 @@ import com.project.exam.domain.entity.ExamRecordEntity; import com.project.exam.domain.service.BuildExamRecordDomainService; import com.project.exam.domain.service.NotifyExamRecordDomainService; import com.project.exam.domain.service.SubmitPaperDomainService; +import com.project.exam.domain.service.strategy.ScoringContext; +import com.project.exam.domain.service.strategy.ScoringStrategy; +import com.project.exam.domain.service.strategy.ScoringStrategyFactory; import com.project.exam.mapper.ExamRecordMapper; import com.project.statistics.application.StatisticsApplicationService; import com.project.task.domain.dto.TaskDTO; @@ -48,6 +51,10 @@ public class SubmitPaperDomainServiceImpl implements SubmitPaperDomainService { @Autowired private StatisticsApplicationService statisticsApplicationService; + // V1.1 新增:判分策略工厂 + @Autowired + private ScoringStrategyFactory scoringStrategyFactory; + @Override @Transactional(rollbackFor = Exception.class) public ExamRecordDTO submitPaper(Long recordId) throws Exception { @@ -59,26 +66,41 @@ public class SubmitPaperDomainServiceImpl implements SubmitPaperDomainService { TaskUserEntity taskUser = taskUserMapper.selectById(record.getTaskUserId()); TaskEntity task = taskMapper.selectById(taskUser.getTaskId()); - // 判分 + // V1.1:使用策略模式判分(客观题比对答案 + 简答题调AI) double finalScore = 0.0; List snapshotList = record.getAnswerSnapshot(); - //记录对的题目 - int rightCount = 0; + + // 构建判分上下文 + ScoringContext scoringContext = new ScoringContext(); + scoringContext.setTask(task); + for (ExamRecordEntity.QuestionSnapshot snapshot : snapshotList) { - // 比对答案 - if (StrUtil.equals(formatAnswer(snapshot.getUserAnswer()) , formatAnswer(snapshot.getRightAnswer()))) { - snapshot.setIsRight(true); - // 根据题型获取任务创建时算好的单题分值 - finalScore += getQuestionWeight(snapshot.getType(), task); - rightCount ++; - } else { - snapshot.setIsRight(false); - } + // 设置题目分值到快照(DTO转换用) + ExamRecordDTO.QuestionSnapshotDTO tempDto = new ExamRecordDTO.QuestionSnapshotDTO(); + tempDto.setQuestionId(snapshot.getQuestionId()); + tempDto.setType(snapshot.getType()); + tempDto.setQuestionContent(snapshot.getQuestionContent()); + tempDto.setUserAnswer(snapshot.getUserAnswer()); + tempDto.setRightAnswer(snapshot.getRightAnswer()); + tempDto.setScore(getQuestionWeight(snapshot.getType(), task)); + + // 根据题型获取对应策略并判分 + ScoringStrategy strategy = scoringStrategyFactory.getStrategy(snapshot.getType()); + strategy.score(tempDto, scoringContext, task.getId()); + + // 回写判分结果到快照 + snapshot.setIsRight(tempDto.getIsRight()); + snapshot.setAiScore(tempDto.getAiScore()); + snapshot.setAiComment(tempDto.getAiComment()); + snapshot.setHitPoints(tempDto.getHitPoints()); } - if (rightCount == snapshotList.size()) { - //全对,直接给满分(避免因为小数点导致的误差) + + // 汇总总分:客观题 + 简答题 + finalScore = scoringContext.getTotalScore(); + if (scoringContext.getRightCount() == scoringContext.getObjectiveTotal() && scoringContext.getSubjectiveScore() == 0) { + // 全部客观题答对且无简答题,直接给满分(避免小数点误差) finalScore = new BigDecimal("100").doubleValue(); - }else{ + } else { // 四舍五入处理(不能超过100分) finalScore = new BigDecimal(finalScore).setScale(2, RoundingMode.HALF_UP).min(new BigDecimal("100")).doubleValue(); } diff --git a/src/main/java/com/project/question/domain/dto/QuestionDTO.java b/src/main/java/com/project/question/domain/dto/QuestionDTO.java index e661e5a..dc76d75 100644 --- a/src/main/java/com/project/question/domain/dto/QuestionDTO.java +++ b/src/main/java/com/project/question/domain/dto/QuestionDTO.java @@ -38,6 +38,14 @@ public class QuestionDTO extends BaseDTO { private Map options; // 选项 private String rightAnswer; // 正确选项 private String analysis; // AI解析 + // V1.1 新增:简答题得分点(多点得分制) + private List scoringPoints; + } + + @Data + public static class ScoringPointDTO { + private Integer index; // 得分点序号 + private String content; // 得分点内容 } @Override diff --git a/src/main/java/com/project/question/domain/entity/QuestionEntity.java b/src/main/java/com/project/question/domain/entity/QuestionEntity.java index 7378b44..56ee5f6 100644 --- a/src/main/java/com/project/question/domain/entity/QuestionEntity.java +++ b/src/main/java/com/project/question/domain/entity/QuestionEntity.java @@ -73,6 +73,14 @@ public class QuestionEntity extends BaseEntity { private Map options; // 选项 private String rightAnswer; // 正确选项 private String analysis; // AI解析 + // V1.1 新增:简答题得分点(多点得分制) + private List scoringPoints; + } + + @Data + public static class ScoringPoint { + private Integer index; // 得分点序号 + private String content; // 得分点内容 } @Override public T toDTO(Supplier supplier) {