deason 2 жил өмнө
parent
commit
2284cfdf4b

+ 9 - 9
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordDataService.java

@@ -21,16 +21,16 @@ import java.util.List;
 public interface ExamRecordDataService {
 
     /**
-     * @param examingSession
-     * @param examBean
-     * @param courseBean
-     * @param basePaperId
-     * @param isFullyObjective
-     * @return
+     * 生成考试记录数据
      */
-    ExamRecordData createExamRecordData(ExamingSession examingSession, ExamSettingsCacheBean examBean,
-                                        CourseCacheBean courseBean, String basePaperId, boolean isFullyObjective,
-                                        Long examStageId, Integer examStageOrder);
+    ExamRecordData createExamRecordData(ExamingSession examingSession,
+                                        ExamSettingsCacheBean examBean,
+                                        CourseCacheBean courseBean,
+                                        String basePaperId,
+                                        boolean isFullyObjective,
+                                        Long examStageId,
+                                        Integer examStageOrder,
+                                        boolean randomPaper);
 
     /**
      * @param examRecordDataId

+ 55 - 29
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamControlServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.com.qmth.examcloud.core.oe.student.service.impl;
 
+import cn.com.qmth.examcloud.api.commons.enums.CallType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
 import cn.com.qmth.examcloud.api.commons.enums.SubmitType;
@@ -36,6 +37,9 @@ import cn.com.qmth.examcloud.core.oe.student.dao.ExamRecordDataRepo;
 import cn.com.qmth.examcloud.core.oe.student.dao.entity.ExamContinuedRecordEntity;
 import cn.com.qmth.examcloud.core.oe.student.report.ExamProcessRecordReport;
 import cn.com.qmth.examcloud.core.oe.student.service.*;
+import cn.com.qmth.examcloud.core.questions.api.ExtractConfigCloudService;
+import cn.com.qmth.examcloud.core.questions.api.request.GetRandomPaperReq;
+import cn.com.qmth.examcloud.core.questions.api.response.GetRandomPaperResp;
 import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
 import cn.com.qmth.examcloud.examwork.api.request.GetExamPropertyReq;
 import cn.com.qmth.examcloud.examwork.api.response.GetExamPropertyResp;
@@ -118,7 +122,7 @@ public class ExamControlServiceImpl implements ExamControlService {
     private ExamRecordQuestionsService examRecordQuestionsService;
 
     @Autowired
-    private ExamCaptureService examCaptureService;
+    private ExtractConfigCloudService extractConfigCloudService;
 
     @Autowired
     private ExamSyncCaptureService examSyncCaptureService;
@@ -174,6 +178,36 @@ public class ExamControlServiceImpl implements ExamControlService {
     // 又拍云签名有效时间(秒)
     private static final Integer SIGN_TIMEOUT = 60;
 
+    private DefaultPaper buildPaper(ExtractConfigCacheBean extractConfig, String paperType, boolean randomPaper) {
+        if (randomPaper) {
+            GetRandomPaperReq req = new GetRandomPaperReq();
+            req.setRandomPaperId(extractConfig.getRandomPaperId());
+            req.setPlayTime(extractConfig.getPlayTime());
+            GetRandomPaperResp resp = extractConfigCloudService.getRandomPaper(req);
+            DefaultPaper defaultPaper = resp.getDefaultPaper();
+            defaultPaper.setId(extractConfig.getRandomPaperId());
+            return defaultPaper;
+        }
+
+        // 随机生成试卷
+        Map<String, String> paperTypeMaps = getExamPaperByProbability(extractConfig.getDetails());
+        if (paperTypeMaps.isEmpty()) {
+            throw new StatusException("1006", "生成试卷失败");
+        }
+
+        String paperId = paperTypeMaps.get(paperType);
+        if (StringUtils.isEmpty(paperId)) {
+            throw new StatusException("1007", "获取试卷失败");
+        }
+
+        // 生成试卷结构
+        ExtractConfigPaperCacheBean extractConfigPaper = CacheHelper.getExtractConfigPaper(
+                extractConfig.getExamId(), extractConfig.getCourseCode(), paperType, paperId);
+        DefaultPaper defaultPaper = extractConfigPaper.getDefaultPaper();
+        defaultPaper.setId(paperId);
+        return defaultPaper;
+    }
+
     /**
      * 开始考试
      *
@@ -209,30 +243,19 @@ public class ExamControlServiceImpl implements ExamControlService {
         // 检查并获取课程信息
         CourseCacheBean courseBean = checkCourse(examingSession.getCourseId());
 
-        // 获取题库试卷结构(由于存在随机抽卷,所以不能缓存 )
-        // 获取题库调卷规则
+        // 获取题库调卷规则、题库试卷结构
         ExtractConfigCacheBean extractConfig = CacheHelper.getExtractConfig(examingSession.getExamId(),
                 courseBean.getCode());
-        // 随机生成试卷
-        Map<String, String> paperTypeMaps = getExamPaperByProbability(extractConfig.getDetails());
-        if (paperTypeMaps.isEmpty()) {
-            throw new StatusException("1006", "生成试卷失败");
-        }
 
-        String paperId = paperTypeMaps.get(examingSession.getPaperType());
-        if (StringUtils.isEmpty(paperId)) {
-            throw new StatusException("1007", "获取试卷失败");
-        }
-
-        // 生成试卷结构
-        ExtractConfigPaperCacheBean extractConfigPaper = CacheHelper.getExtractConfigPaper(examingSession.getExamId(),
-                courseBean.getCode(), examingSession.getPaperType(), paperId);
+        // 是否采用千人千卷规则
+        boolean randomPaper = CallType.RANDOM_PAPER.name().equals(examBean.getCallType());
+        DefaultPaper defaultPaper = this.buildPaper(extractConfig, examingSession.getPaperType(), randomPaper);
 
         // 生成考试记录
         ExamStudentCacheBean examStudent = CacheHelper.getExamStudent(examStudentId);
-        ExamRecordData examRecordData = examRecordDataService.createExamRecordData(examingSession, examBean, courseBean,
-                paperId, extractConfigPaper.getDefaultPaper().getFullyObjective(),
-                examStudent.getExamStageId(), examStudent.getExamStageOrder());
+        ExamRecordData examRecordData = examRecordDataService.createExamRecordData(examingSession,
+                examBean, courseBean, defaultPaper.getId(), defaultPaper.getFullyObjective(),
+                examStudent.getExamStageId(), examStudent.getExamStageOrder(), randomPaper);
 
         // 如果开启人脸比对,将同步人脸比对结果存储到抓后结果表中
         Long rootOrgId = examRecordData.getRootOrgId();
@@ -242,20 +265,21 @@ public class ExamControlServiceImpl implements ExamControlService {
         }
 
         // 小题乱序,选项乱序
-        reorderPaperStruct(extractConfig, extractConfigPaper);
+        if (!randomPaper) {
+            reorderPaperStruct(extractConfig, defaultPaper);
+        }
 
         // 保存考试试卷结构
         ExamRecordPaperStruct paperStruct = new ExamRecordPaperStruct();
         paperStruct.setId(UUID.randomUUID());
-        paperStruct.setDefaultPaper(extractConfigPaper.getDefaultPaper());
+        paperStruct.setDefaultPaper(defaultPaper);
         examRecordPaperStructService.saveExamRecordPaperStruct(examRecordData.getId(), paperStruct);
 
         // 创建考试作答记录
-        ExamRecordQuestions examRecordQuestions = examRecordQuestionsService
-                .createExamRecordQuestions(examRecordData.getId(), extractConfigPaper.getDefaultPaper());
+        ExamRecordQuestions examRecordQuestions = examRecordQuestionsService.createExamRecordQuestions(examRecordData.getId(), defaultPaper);
         // 记录试卷题目数量
         examRecordData.setQuestionCount(examRecordQuestions.getExamQuestions().size());
-        examRecordData.setIsAllObjectivePaper(extractConfigPaper.getDefaultPaper().getFullyObjective());
+        examRecordData.setIsAllObjectivePaper(defaultPaper.getFullyObjective());
         examRecordDataService.saveExamRecordDataCache(examRecordData.getId(), examRecordData);
 
         // 初始化考试会话
@@ -284,7 +308,8 @@ public class ExamControlServiceImpl implements ExamControlService {
                 new ExamProcessRecordReport(examRecordData.getId(), ExamProcess.START, examRecordData.getEnterExamTime())
         );
 
-        log.warn("startExam success! studentId:{}, examRecordDataId:{}, ip:{}", examRecordData.getStudentId(), examRecordData.getId(), ip);
+        log.warn("startExam success! studentId:{}, examRecordDataId:{}, randomPaper:{}, ip:{}",
+                examRecordData.getStudentId(), examRecordData.getId(), randomPaper, ip);
         return buildStartExamInfo(examRecordData.getId(), examingSession, examBean, courseBean);
     }
 
@@ -1472,16 +1497,17 @@ public class ExamControlServiceImpl implements ExamControlService {
      * 获取试卷结构 小题乱序、选项乱序
      *
      * @param extractConfig 调卷规则对象
-     * @param paperStruct   试卷结构对象
+     * @param defaultPaper  试卷结构对象
      */
-    private void reorderPaperStruct(ExtractConfigCacheBean extractConfig, ExtractConfigPaperCacheBean paperStruct) {
+    private void reorderPaperStruct(ExtractConfigCacheBean extractConfig, DefaultPaper defaultPaper) {
         // 小题乱序
         if (extractConfig.getSortQuestionOrder() != null && extractConfig.getSortQuestionOrder()) {
-            reorderQuestion(paperStruct.getDefaultPaper());
+            reorderQuestion(defaultPaper);
         }
+
         // 选项乱序
         if (extractConfig.getSortOptionOrder() != null && extractConfig.getSortOptionOrder()) {
-            reorderOption(paperStruct.getDefaultPaper());
+            reorderOption(defaultPaper);
         }
     }
 

+ 10 - 6
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordDataServiceImpl.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.examcloud.core.oe.student.service.impl;
 
-import cn.com.qmth.examcloud.api.commons.enums.CallType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamStageStartExamStatus;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
@@ -99,9 +98,14 @@ public class ExamRecordDataServiceImpl implements ExamRecordDataService {
 
     @Transactional
     @Override
-    public ExamRecordData createExamRecordData(ExamingSession examingSession, ExamSettingsCacheBean examBean,
-                                               CourseCacheBean courseBean, String basePaperId, boolean isFullyObjective,
-                                               Long examStageId, Integer examStageOrder) {
+    public ExamRecordData createExamRecordData(ExamingSession examingSession,
+                                               ExamSettingsCacheBean examBean,
+                                               CourseCacheBean courseBean,
+                                               String basePaperId,
+                                               boolean isFullyObjective,
+                                               Long examStageId,
+                                               Integer examStageOrder,
+                                               boolean randomPaper) {
         ExamRecordDataEntity examRecordData = new ExamRecordDataEntity();
         examRecordData.setExamId(examBean.getId());
         examRecordData.setExamType(ExamType.valueOf(examBean.getExamType()));
@@ -114,8 +118,8 @@ public class ExamRecordDataServiceImpl implements ExamRecordDataService {
         examRecordData.setCourseId(courseBean.getId());
         examRecordData.setBasePaperId(basePaperId);
         examRecordData.setPaperType(examingSession.getPaperType());
-        
-        examRecordData.setRandomPaper(CallType.RANDOM_PAPER.name().equals(examBean.getCallType()));
+
+        examRecordData.setRandomPaper(randomPaper);// 是否采用千人千卷规则
         examRecordData.setPaperScore(0d);//todo 试卷总分
 
         examRecordData.setEnterExamTime(new Date());