Browse Source

答题相关接口

master
luoweijian 1 month ago
parent
commit
18c5a43720
  1. 4
      src/main/java/com/project/exam/application/ExamRecordApplicationService.java
  2. 20
      src/main/java/com/project/exam/application/impl/ExamRecordApplicationServiceImpl.java
  3. 12
      src/main/java/com/project/exam/controller/ExamRecordController.java
  4. 3
      src/main/java/com/project/exam/domain/dto/ExamRecordDTO.java
  5. 7
      src/main/java/com/project/exam/domain/service/SubmitPaperDomainService.java
  6. 4
      src/main/java/com/project/exam/domain/service/SummitPaperDomainService.java
  7. 7
      src/main/java/com/project/exam/domain/service/impl/BuildExamRecordDomainServiceImpl.java
  8. 2
      src/main/java/com/project/exam/domain/service/impl/StepSaveExamRecordDomainServiceImpl.java
  9. 127
      src/main/java/com/project/exam/domain/service/impl/SubmitPaperDomainServiceImpl.java

4
src/main/java/com/project/exam/application/ExamRecordApplicationService.java

@ -6,4 +6,8 @@ import com.project.exam.domain.dto.ExamRecordDTO;
public interface ExamRecordApplicationService {
Result<ExamRecordDTO> assemblePaper(Long taskId) throws Exception;
Result<ExamRecordDTO> submitPaper(Long recordId) throws Exception;
Result<String> stepSave(Long recordId, int index, String answer) throws Exception;
}

20
src/main/java/com/project/exam/application/impl/ExamRecordApplicationServiceImpl.java

@ -5,6 +5,8 @@ import com.project.ding.utils.SecurityUtils;
import com.project.exam.application.ExamRecordApplicationService;
import com.project.exam.domain.dto.ExamRecordDTO;
import com.project.exam.domain.service.AssemblePaperDomainService;
import com.project.exam.domain.service.StepSaveExamRecordDomainService;
import com.project.exam.domain.service.SubmitPaperDomainService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -12,8 +14,26 @@ import org.springframework.stereotype.Service;
public class ExamRecordApplicationServiceImpl implements ExamRecordApplicationService {
@Autowired
private AssemblePaperDomainService assemblePaperDomainService;
@Autowired
private StepSaveExamRecordDomainService stepSaveExamRecordDomainService;
@Autowired
private SubmitPaperDomainService submitPaperDomainService;
@Override
public Result<ExamRecordDTO> assemblePaper(Long taskId) throws Exception {
return Result.success(assemblePaperDomainService.assemblePaper(taskId , SecurityUtils.getUserId()));
}
@Override
public Result<ExamRecordDTO> submitPaper(Long recordId) throws Exception {
return Result.success(submitPaperDomainService.submitPaper(recordId));
}
@Override
public Result<String> stepSave(Long recordId, int index, String answer) throws Exception {
stepSaveExamRecordDomainService.stepSave(recordId , index , answer);
return Result.success("提交成功");
}
}

12
src/main/java/com/project/exam/controller/ExamRecordController.java

@ -18,4 +18,16 @@ public class ExamRecordController {
public Result<ExamRecordDTO> assemblePaper(Long taskId) throws Exception{
return examRecordApplicationService.assemblePaper(taskId);
}
@PostMapping("/submitPaper")
public Result<ExamRecordDTO> submitPaper(Long recordId) throws Exception{
return examRecordApplicationService.submitPaper(recordId);
}
@PostMapping("/stepSave")
public Result<String> stepSave(Long recordId, int index, String answer) throws Exception{
return examRecordApplicationService.stepSave(recordId , index , answer);
}
}

3
src/main/java/com/project/exam/domain/dto/ExamRecordDTO.java

@ -43,7 +43,10 @@ public class ExamRecordDTO extends BaseDTO {
private String analysis;
// 该题是否已发起申诉
private Boolean hasAppealed;
// 该题分值
private Double score;
// 用户得分
private Double userScore;
}
@Override

7
src/main/java/com/project/exam/domain/service/SubmitPaperDomainService.java

@ -0,0 +1,7 @@
package com.project.exam.domain.service;
import com.project.exam.domain.dto.ExamRecordDTO;
public interface SubmitPaperDomainService {
ExamRecordDTO submitPaper(Long recordId) throws Exception;
}

4
src/main/java/com/project/exam/domain/service/SummitPaperDomainService.java

@ -1,4 +0,0 @@
package com.project.exam.domain.service;
public interface SummitPaperDomainService {
}

7
src/main/java/com/project/exam/domain/service/impl/BuildExamRecordDomainServiceImpl.java

@ -1,5 +1,6 @@
package com.project.exam.domain.service.impl;
import cn.hutool.core.util.BooleanUtil;
import com.project.exam.domain.dto.ExamRecordDTO;
import com.project.exam.domain.service.BuildExamRecordDomainService;
import com.project.task.domain.enums.QuestionTypeEnum;
@ -21,10 +22,16 @@ public class BuildExamRecordDomainServiceImpl implements BuildExamRecordDomainSe
dto.getAnswerSnapshotDTOList().stream().map(answerSnapshotDTO -> {
if (QuestionTypeEnum.SINGLE_CHOICE.getValue().equals(answerSnapshotDTO.getType())) {
answerSnapshotDTO.setScore(dto.getTaskDTO().getSingleChoiceScore());
answerSnapshotDTO.setUserScore(BooleanUtil.isTrue(answerSnapshotDTO.getIsRight()) ?
dto.getTaskDTO().getSingleChoiceScore() : 0);
} else if (QuestionTypeEnum.TRUE_FALSE.getValue().equals(answerSnapshotDTO.getType())) {
answerSnapshotDTO.setScore(dto.getTaskDTO().getTrueFalseScore());
answerSnapshotDTO.setUserScore(BooleanUtil.isTrue(answerSnapshotDTO.getIsRight()) ?
dto.getTaskDTO().getTrueFalseScore() : 0);
} else {
answerSnapshotDTO.setScore(dto.getTaskDTO().getMultipleChoiceScore());
answerSnapshotDTO.setUserScore(BooleanUtil.isTrue(answerSnapshotDTO.getIsRight()) ?
dto.getTaskDTO().getMultipleChoiceScore() : 0);
}
return answerSnapshotDTO;
});

2
src/main/java/com/project/exam/domain/service/impl/StepSaveExamRecordDomainServiceImpl.java

@ -17,7 +17,7 @@ public class StepSaveExamRecordDomainServiceImpl implements StepSaveExamRecordDo
if (index < 1) {
throw new BusinessErrorException("非法题号");
}
if (StrUtil.isNotBlank(answer)) {
if (StrUtil.isBlank(answer)) {
throw new BusinessErrorException("答案不能为空");
}
int rows = examRecordMapper.updateAnswerIncremental(recordId, index - 1, answer);

127
src/main/java/com/project/exam/domain/service/impl/SubmitPaperDomainServiceImpl.java

@ -0,0 +1,127 @@
package com.project.exam.domain.service.impl;
import cn.hutool.core.util.StrUtil;
import com.project.base.domain.exception.BusinessErrorException;
import com.project.exam.domain.dto.ExamRecordDTO;
import com.project.exam.domain.entity.ExamRecordEntity;
import com.project.exam.domain.service.BuildExamRecordDomainService;
import com.project.exam.domain.service.SubmitPaperDomainService;
import com.project.exam.mapper.ExamRecordMapper;
import com.project.task.domain.dto.TaskDTO;
import com.project.task.domain.entity.TaskEntity;
import com.project.task.domain.entity.TaskUserEntity;
import com.project.task.domain.enums.QuestionTypeEnum;
import com.project.task.domain.enums.TaskUserStatusEnum;
import com.project.task.domain.service.TaskBaseService;
import com.project.task.mapper.TaskMapper;
import com.project.task.mapper.TaskUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class SubmitPaperDomainServiceImpl implements SubmitPaperDomainService {
@Autowired
private ExamRecordMapper examRecordMapper;
@Autowired
private TaskUserMapper taskUserMapper;
@Autowired
private TaskMapper taskMapper;
@Autowired
private TaskBaseService taskBaseService;
@Autowired
private BuildExamRecordDomainService buildExamRecordDomainService;
@Override
@Transactional(rollbackFor = Exception.class)
public ExamRecordDTO submitPaper(Long recordId) throws Exception {
ExamRecordEntity record = examRecordMapper.selectById(recordId);
if (record == null || record.getSubmitTime() != null) {
throw new BusinessErrorException("试卷已提交或记录不存在");
}
// 获取任务配置与用户进度记录
TaskUserEntity taskUser = taskUserMapper.selectById(record.getTaskUserId());
TaskEntity task = taskMapper.selectById(taskUser.getTaskId());
// 判分
double finalScore = 0.0;
List<ExamRecordEntity.QuestionSnapshot> snapshotList = record.getAnswerSnapshot();
for (ExamRecordEntity.QuestionSnapshot snapshot : snapshotList) {
// 比对答案
if (StrUtil.equals(formatAnswer(snapshot.getUserAnswer()) , formatAnswer(snapshot.getRightAnswer()))) {
snapshot.setIsRight(true);
// 根据题型获取任务创建时算好的单题分值
finalScore += getQuestionWeight(snapshot.getType(), task);
} else {
snapshot.setIsRight(false);
}
}
// 四舍五入处理
finalScore = new BigDecimal(finalScore).setScale(2, RoundingMode.HALF_UP).doubleValue();
boolean isPassed = finalScore >= task.getPassScore();
record.setScore(finalScore);
record.setPass(isPassed);
record.setSubmitTime(new Date());
record.setAnswerSnapshot(snapshotList);
examRecordMapper.updateById(record);
// 更新 TaskEntity 冗余字段
if (isPassed) {
taskBaseService.update()
.setSql("pass_num = pass_num + 1")
.eq("id", task.getId())
.update();
}
// 更新 TaskUser 冗余字段
updateTaskUserStatus(taskUser , isPassed , recordId);
// 构建dto
ExamRecordDTO dto = record.toDTO(ExamRecordDTO::new);
dto.setTaskDTO(task.toDTO(TaskDTO::new));
return buildExamRecordDomainService.buildDTO(dto);
}
/**
* 根据题型映射任务表中的动态分值
*/
private double getQuestionWeight(Integer type, TaskEntity task) {
if (QuestionTypeEnum.SINGLE_CHOICE.getValue().equals(type)) {
return task.getSingleChoiceScore();
} else if (QuestionTypeEnum.MULTIPLE_CHOICE.getValue().equals(type)) {
return task.getMultipleChoiceScore();
}
else if (QuestionTypeEnum.TRUE_FALSE.getValue().equals(type)) {
return task.getTrueFalseScore();
}
return 0.0;
}
private void updateTaskUserStatus(TaskUserEntity taskUser, boolean isPassed, Long recordId) {
taskUser.setLastRecordId(recordId);
taskUser.setAttemptNum((taskUser.getAttemptNum() == null ? 0 : taskUser.getAttemptNum()) + 1);
if (!TaskUserStatusEnum.Pass.getValue().equals(taskUser.getStatus())) {
taskUser.setStatus(isPassed ? TaskUserStatusEnum.Pass.getValue() : TaskUserStatusEnum.Fail.getValue());
}
taskUserMapper.updateById(taskUser);
}
private String formatAnswer(String ans) {
if (StrUtil.isBlank(ans)) return "";
// 去空格 -> 转大写 -> 排序(解决 B,A vs A,B 的问题)
return Arrays.stream(ans.split(","))
.map(String::trim)
.map(String::toUpperCase)
.sorted()
.collect(Collectors.joining(","));
}
}
Loading…
Cancel
Save