Browse Source

组卷逻辑

master
luoweijian 3 months ago
parent
commit
4d3370408f
  1. 16
      src/main/java/com/project/exam/application/impl/ExamRecordApplicationServiceImpl.java
  2. 5
      src/main/java/com/project/task/domain/entity/TaskPaperSnapshotEntity.java
  3. 47
      src/main/java/com/project/task/domain/service/impl/SaveOrUpdateTaskDomainServiceImpl.java

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

@ -8,6 +8,10 @@ import com.project.exam.domain.dto.ExamRecordDTO;
import com.project.exam.domain.dto.ExamRecordPictureDTO;
import com.project.exam.domain.param.ExamRecordParam;
import com.project.exam.domain.service.*;
import com.project.exam.domain.service.strategy.PaperAssemblyStrategy;
import com.project.exam.domain.service.strategy.PaperAssemblyStrategyFactory;
import com.project.task.domain.entity.TaskEntity;
import com.project.task.domain.service.TaskBaseService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -18,6 +22,13 @@ public class ExamRecordApplicationServiceImpl implements ExamRecordApplicationSe
@Autowired
private AssemblePaperDomainService assemblePaperDomainService;
// V1.1 新增:组卷策略工厂
@Autowired
private PaperAssemblyStrategyFactory paperAssemblyStrategyFactory;
@Autowired
private TaskBaseService taskBaseService;
@Autowired
private StepSaveExamRecordDomainService stepSaveExamRecordDomainService;
@ -53,7 +64,10 @@ public class ExamRecordApplicationServiceImpl implements ExamRecordApplicationSe
@Override
public Result<ExamRecordDTO> assemblePaper(Long taskId) throws Exception {
return Result.success(assemblePaperDomainService.assemblePaper(taskId , SecurityUtils.getUserId()));
// V1.1:按考试模式分发到不同组卷策略
TaskEntity task = taskBaseService.getById(taskId);
PaperAssemblyStrategy strategy = paperAssemblyStrategyFactory.getStrategy(task.getExamMode());
return Result.success(strategy.assemblePaper(taskId, SecurityUtils.getUserId()));
}
@Override

5
src/main/java/com/project/task/domain/entity/TaskPaperSnapshotEntity.java

@ -35,6 +35,11 @@ public class TaskPaperSnapshotEntity extends BaseEntity {
@Comment("原始套卷ID(追溯用)")
private Long paperId;
@Column(name = "set_index")
@TableField("set_index")
@Comment("组内序号(1~N),用于随机抽卷")
private Integer setIndex;
@Column(name = "question_id")
@TableField("question_id")
@Comment("题目ID")

47
src/main/java/com/project/task/domain/service/impl/SaveOrUpdateTaskDomainServiceImpl.java

@ -247,37 +247,62 @@ public class SaveOrUpdateTaskDomainServiceImpl implements SaveOrUpdateTaskDomain
/**
* 经典模式仅创建时冻结套卷题目快照
* 查询套卷关联的题目深拷贝题目内容题干+选项+答案+解析写入快照表
* 查询同 paperGroupId 下所有版本的题目深拷贝题目内容写入快照表
* 考生开考时从快照中随机抽一个版本
* 后续套题变更不影响已建任务的快照数据
*/
private void buildPaperSnapshot(Long taskId, Long classicPaperId) {
// 1. 查询套卷关联的题目(按 sortOrder 排序)
List<ClassicPaperQuestionEntity> paperQuestions = classicPaperQuestionBaseService.list(
// 1. 查询套卷所属的 paperGroupId
ClassicPaperEntity paper = classicPaperBaseService.getById(classicPaperId);
if (paper == null || paper.getPaperGroupId() == null) {
return;
}
Long paperGroupId = paper.getPaperGroupId();
// 2. 查询同组下所有套卷
List<ClassicPaperEntity> groupPapers = classicPaperBaseService.list(
new LambdaQueryWrapper<ClassicPaperEntity>()
.eq(ClassicPaperEntity::getPaperGroupId, paperGroupId));
if (groupPapers.isEmpty()) {
return;
}
// 3. 收集所有套卷的题目ID
List<Long> allPaperIds = groupPapers.stream()
.map(ClassicPaperEntity::getId)
.collect(Collectors.toList());
List<ClassicPaperQuestionEntity> allPaperQuestions = classicPaperQuestionBaseService.list(
new LambdaQueryWrapper<ClassicPaperQuestionEntity>()
.eq(ClassicPaperQuestionEntity::getPaperId, classicPaperId)
.orderByAsc(ClassicPaperQuestionEntity::getSortOrder));
if (paperQuestions.isEmpty()) {
.in(ClassicPaperQuestionEntity::getPaperId, allPaperIds)
.orderByAsc(ClassicPaperQuestionEntity::getPaperId, ClassicPaperQuestionEntity::getSortOrder));
if (allPaperQuestions.isEmpty()) {
return;
}
// 2. 批量查询题目详情
List<Long> questionIds = paperQuestions.stream()
// 4. 批量查询题目详情
List<Long> questionIds = allPaperQuestions.stream()
.map(ClassicPaperQuestionEntity::getQuestionId)
.distinct()
.collect(Collectors.toList());
Map<Long, QuestionEntity> questionMap = questionBaseService.listByIds(questionIds).stream()
.collect(Collectors.toMap(QuestionEntity::getId, q -> q));
// 3. 构建快照并批量保存(深拷贝 QuestionDetail 全部字段,含图片URL)
// 5. 建立 paperId → setIndex 映射
Map<Long, Integer> paperSetIndexMap = groupPapers.stream()
.collect(Collectors.toMap(ClassicPaperEntity::getId, ClassicPaperEntity::getSetIndex));
// 6. 构建快照并批量保存(深拷贝 QuestionDetail 全部字段,含图片URL)
List<TaskPaperSnapshotEntity> snapshots = new ArrayList<>();
for (ClassicPaperQuestionEntity pq : paperQuestions) {
for (ClassicPaperQuestionEntity pq : allPaperQuestions) {
QuestionEntity question = questionMap.get(pq.getQuestionId());
if (question == null) {
continue;
}
TaskPaperSnapshotEntity snapshot = new TaskPaperSnapshotEntity();
snapshot.setTaskId(taskId);
snapshot.setPaperId(classicPaperId);
snapshot.setPaperId(pq.getPaperId());
snapshot.setSetIndex(paperSetIndexMap.getOrDefault(pq.getPaperId(), 0));
snapshot.setQuestionId(pq.getQuestionId());
snapshot.setSortOrder(pq.getSortOrder());
snapshot.setQuestionType(pq.getQuestionType());

Loading…
Cancel
Save