Przeglądaj źródła

优化交卷逻辑和开考逻辑

lideyin 5 lat temu
rodzic
commit
cfdfab0200

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

@@ -15,102 +15,119 @@ import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
  * @description 考试记录数据服务接口
  */
 public interface ExamRecordDataService {
-	
-	/**
-	 * 创建ExamRecordDataEntity
-	 * @param examRecordEntity
-	 * @return
-	 */
-	ExamRecordDataEntity createExamRecordData(ExamRecordEntity examRecordEntity, ExamStudentEntity examStudentEntity, ExamBean examBean, boolean isFullyObjetive);
+
+    /**
+     * 创建ExamRecordDataEntity
+     * @param examRecord 考试记录实体
+     * @param examedTimes 已考次数
+     * @param canExamTimes 可考次数
+     * @param isReExamine 本次考试是否为重考
+     * @param isFullyObjetive 是否全客观题
+     * @return
+     */
+    ExamRecordDataEntity createExamRecordData(ExamRecordEntity examRecord, Integer examedTimes, Long canExamTimes,
+                                              Boolean isReExamine, Boolean isFullyObjetive);
 
     List<ExamRecordDataEntity> findByStatusAndExamTypeIn(ExamRecordStatus examRecordStatus, List<String> examTypeList);
-    
+
     /**
      * 根据考生ID查询所有有效考试记录
+     *
      * @param examStudentId
      * @return
      */
-	List<ExamRecordDataEntity> findValidExamRecordDataByExamStudentId(Long examStudentId);
-    
+    List<ExamRecordDataEntity> findValidExamRecordDataByExamStudentId(Long examStudentId);
+
     /**
      * 计算人脸检测结果
+     *
      * @param examRecordDataEntity
      * @return
      */
-	CalculateFaceCheckResultInfo calculateFaceCheckResult(ExamRecordDataEntity examRecordDataEntity);
-
-	/**
-	 * 创建进行中的考试记录
-	 * @param examRecordId
-	 * @param examRecordDataId
-	 * @param studentId
-	 */
+    CalculateFaceCheckResultInfo calculateFaceCheckResult(ExamRecordDataEntity examRecordDataEntity);
+
+    /**
+     * 创建进行中的考试记录
+     *
+     * @param examRecordId
+     * @param examRecordDataId
+     * @param studentId
+     */
     void createExamingRecord(Long examRecordId, Long examRecordDataId, Long studentId, ExamType examType);
 
-	/**
-	 * 创建已交卷的考试记录
-	 * @param examRecordId
-	 * @param examRecordDataId
-	 * @param studentId
-	 */
-	void createHandInExamRecord(Long examRecordId, Long examRecordDataId, Long studentId);
+    /**
+     * 创建已交卷的考试记录
+     *
+     * @param examRecordId
+     * @param examRecordDataId
+     * @param studentId
+     */
+    void createHandInExamRecord(Long examRecordId, Long examRecordDataId, Long studentId);
 
-	/**
-	 * 删除进行中考试记录id
-	 * @param examRecordId
-	 */
-	void deleteExamingRecord(Long examRecordId);
+    /**
+     * 删除进行中考试记录id
+     *
+     * @param examRecordId
+     */
+    void deleteExamingRecord(Long examRecordId);
 
     void deleteHandInExamRecord(Long examRecordId);
 
-	/**
-	 * 获取指定数量的考试中的数据
-	 * @param startId
-	 * @param limit
-	 * @return
-	 */
-	List<ExamingRecordEntity> getLimitExamingRecords(Long startId, int limit);
-
-	/**
-	 * 获取指定数量的已交卷的考试数据
-	 * @param startId
-	 * @param limit
-	 * @return
-	 */
-	List<HandInExamRecordEntity> getLimitHandInExamRecords(Long startId, int limit);
+    /**
+     * 获取指定数量的考试中的数据
+     *
+     * @param startId
+     * @param limit
+     * @return
+     */
+    List<ExamingRecordEntity> getLimitExamingRecords(Long startId, int limit);
+
+    /**
+     * 获取指定数量的已交卷的考试数据
+     *
+     * @param startId
+     * @param limit
+     * @return
+     */
+    List<HandInExamRecordEntity> getLimitHandInExamRecords(Long startId, int limit);
 
     /**
      * 计算活体检测结果
+     *
      * @param examRecordDataEntity
      */
-	ExamRecordDataEntity calculateFaceLivenessVerifyResult(ExamRecordDataEntity examRecordDataEntity);
-    
+    ExamRecordDataEntity calculateFaceLivenessVerifyResult(ExamRecordDataEntity examRecordDataEntity);
+
     /**
      * 创建离线考试记录
+     *
      * @param examRecord
      * @param fullyObjective
      * @return
      */
-	ExamRecordDataEntity createOfflineExamRecordData(ExamRecordEntity examRecord, Boolean fullyObjective);
-	
-	/**
-	 * 违纪自动审核
-	 * @return
-	 */
-	ExamRecordDataEntity examRecordAutoAudit(Boolean isNoPhotoAndIllegality, ExamRecordDataEntity examRecordData);
-
-	/**
-	 * 考试记录是否已结束
-	 * @param examRecordData 考试记录
-	 * @return boolean
-	 */
-	boolean isExamRecordEnded(ExamRecordDataEntity examRecordData);
-
-	/**
-	 * 考试记录是否已结束
-	 * @param examRecordDataId 考试记录id
-	 * @return boolean
-	 */
+    ExamRecordDataEntity createOfflineExamRecordData(ExamRecordEntity examRecord, Boolean fullyObjective);
+
+    /**
+     * 违纪自动审核
+     *
+     * @return
+     */
+    ExamRecordDataEntity examRecordAutoAudit(Boolean isNoPhotoAndIllegality, ExamRecordDataEntity examRecordData);
+
+    /**
+     * 考试记录是否已结束
+     *
+     * @param examRecordData 考试记录
+     * @return boolean
+     */
+    boolean isExamRecordEnded(ExamRecordDataEntity examRecordData);
+
+    /**
+     * 考试记录是否已结束
+     *
+     * @param examRecordDataId 考试记录id
+     * @return boolean
+     */
     boolean isExamRecordEnded(Long examRecordDataId);
 
 }

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

@@ -28,11 +28,16 @@ public interface ExamStudentService {
 	 * @return
 	 */
 	public Integer countExamTimes(ExamStudentEntity examStudentInfo,ExamBean examBean);
-	
+
 	/**
 	 * 开始考试时,更新考生信息
-	 * @param examStudentInfo
-	 * @param examBean
+	 * @param id 考生主键id
+	 * @param isReExamine 是否重考
+	 * @param reExamineCompleted 重考是否完成
+	 * @param normalExamTimes 已考次数
+	 * @param examBean 考试实体
+	 * @return
 	 */
-	public ExamStudentEntity updateExamStudentByStartExam(ExamStudentEntity examStudentEntity,ExamBean examBean);
+	public void updateExamStudentByStartExam(Long id,Boolean isReExamine,Boolean reExamineCompleted,
+														  Integer normalExamTimes, final ExamBean examBean);
 }

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

@@ -186,33 +186,33 @@ public class ExamControlServiceImpl implements ExamControlService {
 
 //        try {
         long startTime = System.currentTimeMillis();
-        // 获取考生信息
-        ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(examStudentId);
+        // 获取原始考生信息
+        ExamStudentEntity originalExamStudent = examStudentRepo.findByExamStudentId(examStudentId);
         if (log.isDebugEnabled()) {
             log.debug("1 获取考生信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
-        if (examStudentEntity == null) {
+        if (originalExamStudent == null) {
             throw new StatusException("ExamControlServiceImpl-startExam-exception", "考生不存在");
         }
-        if (examStudentEntity.getStudentId().longValue() != user.getUserId().longValue()) {
+        if (originalExamStudent.getStudentId().longValue() != user.getUserId().longValue()) {
             throw new StatusException("ExamControlServiceImpl-startExam-exception", "考生与当前用户不吻合");
         }
         // 检查redis session
         ExamSessionInfo examSessionInfo = examSessionInfoService
-                .getExamSessionInfo(examStudentEntity.getStudentId());
+                .getExamSessionInfo(originalExamStudent.getStudentId());
         if (examSessionInfo != null) {
             throw new StatusException("ExamControlServiceImpl-startExam-exception", "已经有考试中的科目");
         }
         // 检查并获取考试信息
         startTime = System.currentTimeMillis();
-        ExamBean examBean = checkExam(examStudentEntity);
+        ExamBean examBean = checkExam(originalExamStudent);
         if (log.isDebugEnabled()) {
             log.debug("2 检查并获取考试信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
 
         // 检查并获取课程信息
         startTime = System.currentTimeMillis();
-        CourseBean courseBean = checkCourse(examStudentEntity);
+        CourseBean courseBean = checkCourse(originalExamStudent);
         if (log.isDebugEnabled()) {
             log.debug("3 检查并获取课程信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
@@ -222,20 +222,20 @@ public class ExamControlServiceImpl implements ExamControlService {
 
         //获取题库调卷规则
         ExtractConfigCacheBean extractConfig = CacheHelper.getExtractConfig(
-                examStudentEntity.getExamId(), courseBean.getCode());
+                originalExamStudent.getExamId(), courseBean.getCode());
         //随机生成试卷
         Map<String, String> paperTypeMaps = getExamPaperByProbability(extractConfig.getDetails());
         if (paperTypeMaps.isEmpty()) {
             throw new StatusException("100001", "生成试卷失败");
         }
 
-        String paperId = paperTypeMaps.get(examStudentEntity.getPaperType());
+        String paperId = paperTypeMaps.get(originalExamStudent.getPaperType());
         if (StringUtils.isEmpty(paperId)) {
             throw new StatusException("100002", "获取试卷失败");
         }
         //生成试卷结构
-        ExtractConfigPaperCacheBean extractConfigPaper = CacheHelper.getExtractConfigPaper(examStudentEntity.getExamId(),
-                courseBean.getCode(), examStudentEntity.getPaperType(), paperId);
+        ExtractConfigPaperCacheBean extractConfigPaper = CacheHelper.getExtractConfigPaper(originalExamStudent.getExamId(),
+                courseBean.getCode(), originalExamStudent.getPaperType(), paperId);
         if (log.isDebugEnabled()) {
             log.debug("4 获取题库试卷结构耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
@@ -258,17 +258,23 @@ public class ExamControlServiceImpl implements ExamControlService {
 
         // 更新考生信息
         startTime = System.currentTimeMillis();
-        examStudentEntity = examStudentService.updateExamStudentByStartExam(examStudentEntity, examBean);
+        examStudentService.updateExamStudentByStartExam(originalExamStudent.getId(),
+                originalExamStudent.getIsReExamine(), originalExamStudent.getReExamineCompleted(),
+                originalExamStudent.getNormalExamTimes(), examBean);
         if (log.isDebugEnabled()) {
             log.debug("7 更新考生信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
+        //获取更新完以后的考试记录实体
+        ExamStudentEntity newExamStudent = GlobalHelper.getEntity(examStudentRepo, originalExamStudent.getId(), ExamStudentEntity.class);
 
         // 生成考试记录
         startTime = System.currentTimeMillis();
-        ExamRecordEntity examRecord = examRecordService.createExamRecord(examStudentEntity, examBean, courseBean,
+        ExamRecordEntity examRecord = examRecordService.createExamRecord(newExamStudent, examBean, courseBean,
                 paperId, examRecordPaperStruct.getId());
         ExamRecordDataEntity examRecordData = examRecordDataService.createExamRecordData(examRecord,
-                examStudentEntity, examBean, extractConfigPaper.getDefaultPaper().getFullyObjective());
+                newExamStudent.getNormalExamTimes(), examBean.getExamTimes(), originalExamStudent.getIsReExamine(),
+                extractConfigPaper.getDefaultPaper().getFullyObjective());
+
         //生成进行中的考试记录
         examRecordDataService.createExamingRecord(examRecord.getId(), examRecordData.getId(),
                 examRecord.getStudentId(), examRecord.getExamType());
@@ -296,7 +302,7 @@ public class ExamControlServiceImpl implements ExamControlService {
         // 创建考试会话
         startTime = System.currentTimeMillis();
 
-        initializeExamRecordSession(examStudentEntity, examRecordData, examBean);
+        initializeExamRecordSession(newExamStudent, examRecordData, examBean);
         if (log.isDebugEnabled()) {
             log.debug("11 创建考试会话耗时:" + (System.currentTimeMillis() - startTime) + " ms");
         }
@@ -304,7 +310,7 @@ public class ExamControlServiceImpl implements ExamControlService {
         if (log.isDebugEnabled()) {
             log.debug("12 合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
         }
-        return buildStartExamInfo(examRecordData.getId(), examStudentEntity, examBean, courseBean);
+        return buildStartExamInfo(examRecordData.getId(), newExamStudent, examBean, courseBean);
 //        } finally {
 //
 //        }
@@ -689,10 +695,10 @@ public class ExamControlServiceImpl implements ExamControlService {
         //系统在请求结束后会,自动释放锁,无需手动解锁
         SequenceLockHelper.getLock(sequenceLockKey);
 
-        //如果当前考试记录状态不为考试中,则直接返回
-        if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
-            return;
-        }
+//        //如果当前考试记录状态不为考试中,则直接返回
+//        if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
+//            return;
+//        }
         long st = System.currentTimeMillis();
         long startTime = System.currentTimeMillis();
 
@@ -932,7 +938,6 @@ public class ExamControlServiceImpl implements ExamControlService {
             examSessionInfoService.deleteExamSessionInfo(studentId);
             ExamRecordDataEntity examRecordDataEntity = GlobalHelper.getEntity(examRecordDataRepo,
                     examingRecord.getExamRecordDataId(), ExamRecordDataEntity.class);
-            handInExam(examRecordDataEntity, HandInExamType.AUTO);
             delayHandInExamIfLocked(examRecordDataEntity);
             return null;
         }
@@ -940,7 +945,8 @@ public class ExamControlServiceImpl implements ExamControlService {
     }
 
     /**
-     *  如果有序列化锁,则延迟交卷
+     * 如果有序列化锁,则延迟交卷
+     *
      * @param examRecordData
      * @return
      */
@@ -978,10 +984,10 @@ public class ExamControlServiceImpl implements ExamControlService {
         ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examingRecord.getExamRecordDataId(), ExamRecordDataEntity.class);
 
         //只有考试状态为考试中,系统才需要执行交卷动作,因为有可能已经手动交卷,所以这里再做一次判断
-        if (examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_ING) {
-            cleanExamRecordTaskLog.debug("[CLEAN_EXAMING_RECORD_" + examRecordData.getId() + "]状态为进行中考试,执行交卷[handInExam],.");
-            handInExam(examRecordData, HandInExamType.AUTO);
-        }
+//        if (examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_ING) {
+        cleanExamRecordTaskLog.debug("[CLEAN_EXAMING_RECORD_" + examRecordData.getId() + "]状态为进行中考试,执行交卷[handInExam],.");
+        handInExam(examRecordData, HandInExamType.AUTO);
+//        }
 
         cleanExamRecordTaskLog.debug("[CLEAN_EXAMING_RECORD_" + examRecordData.getId() + "]考试记录交卷完成.");
     }

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

@@ -88,22 +88,22 @@ public class ExamRecordDataServiceImpl implements ExamRecordDataService {
     private static final Logger log = LoggerFactory.getLogger(ExamRecordDataServiceImpl.class);
 
     @Override
-    public ExamRecordDataEntity createExamRecordData(ExamRecordEntity examRecord, ExamStudentEntity examStudent,
-                                                     ExamBean examBean, boolean isFullyObjetive) {
+    public ExamRecordDataEntity createExamRecordData(ExamRecordEntity examRecord, Integer examedTimes, Long canExamTimes,
+                                                     Boolean isReExamine, Boolean isFullyObjetive) {
         ExamRecordDataEntity examRecordData = new ExamRecordDataEntity();
         examRecordData.setExamRecordId(examRecord.getId());
         examRecordData.setStartTime(new Date());
         examRecordData.setExamRecordStatus(ExamRecordStatus.EXAM_ING);
         //已考的考试次数
-        int examTimes = examStudent.getNormalExamTimes();
+
         //考试机会
-        Long canExamTimes = examBean.getExamTimes() == null ? 0 : examBean.getExamTimes();
-        Boolean isReExamine =examStudent.getIsReExamine()==null?false:examStudent.getIsReExamine();
+        int finalCanExamTimes = canExamTimes == null ? 0 : canExamTimes.intValue();
+        boolean finalIsReExamine = isReExamine == null ? false : isReExamine;
         //如果是重考,则考试次数加1
-        if (isReExamine && examTimes >= canExamTimes) {
-            examTimes = canExamTimes.intValue() + 1;
+        if (isReExamine && examedTimes >= finalCanExamTimes) {
+            examedTimes = finalCanExamTimes + 1;
         }
-        examRecordData.setExamOrder(examTimes);
+        examRecordData.setExamOrder(examedTimes);
         examRecordData.setIsAllObjectivePaper(isFullyObjetive);
         examRecordData.setIsWarn(false);
         examRecordData.setIsAudit(false);
@@ -115,9 +115,7 @@ public class ExamRecordDataServiceImpl implements ExamRecordDataService {
         examRecordData.setFaceTotalCount(0);
         examRecordData.setFaceFailedCount(0);
         examRecordData.setFaceStrangerCount(0);
-        if (examStudent.getIsReExamine() != null
-                && examStudent.getIsReExamine()
-                && examBean.getExamTimes() <= examStudent.getNormalExamTimes()) {
+        if (finalIsReExamine && finalCanExamTimes <= examedTimes) {
             examRecordData.setIsReexamine(true);
         }
         return examRecordDataRepo.save(examRecordData);

+ 12 - 21
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamStudentServiceImpl.java

@@ -180,40 +180,31 @@ public class ExamStudentServiceImpl implements ExamStudentService {
     }
 
     @Override
-    public ExamStudentEntity updateExamStudentByStartExam(ExamStudentEntity examStudent, ExamBean examBean) {
-        Boolean isReExamine = examStudent.getIsReExamine();//是否有重考
-        Boolean reExamineCompleted = examStudent.getReExamineCompleted();//重考是否已完成
+    public void updateExamStudentByStartExam(Long id,Boolean isReExamine,Boolean reExamineCompleted,
+                                                          Integer normalExamTimes,final ExamBean examBean) {
+        //考试完的最终状态
+        Boolean finalIsReExamine=isReExamine;
+        Boolean finalReExamineCompleted=reExamineCompleted;
         //考生的已考次数(不包括重考)
-        int normalExamTimes = examStudent.getNormalExamTimes() == null ? 0 : examStudent.getNormalExamTimes();
-
+        int finalNormalExamTimes=normalExamTimes == null ? 0 : normalExamTimes;
         //考试机会,即可考次数
         long canExamTimes = examBean.getExamTimes();
         //有可能中途改变考试次数
-        if (canExamTimes > normalExamTimes) {
-            normalExamTimes = normalExamTimes + 1;
-            isReExamine = null;
-            reExamineCompleted = null;
+        if (canExamTimes > finalNormalExamTimes) {
+            finalNormalExamTimes = finalNormalExamTimes + 1;
+            finalIsReExamine = null;
+            finalReExamineCompleted = null;
         }
 
-        //考试完的最终状态
-        Boolean finalIsReExamine=isReExamine;
-        Boolean finalReExamineCompleted=reExamineCompleted;
-        int finalNormalExamTimes=normalExamTimes;
         // 考生开始重考时,将重考已完成设置为true,并重置是否重考
-        if (CommonUtil.isTrue(isReExamine)) {
+        if (CommonUtil.isTrue(finalIsReExamine)) {
             finalIsReExamine = false;
             finalReExamineCompleted = true;
             finalNormalExamTimes=finalNormalExamTimes+1;
         }
         Date now = new Date();
         //更新相关属性
-        examStudentRepo.updateExamStudentStartExamStatusInfo(examStudent.getId(), true,
+        examStudentRepo.updateExamStudentStartExamStatusInfo(id, true,
                 finalNormalExamTimes, finalIsReExamine, finalReExamineCompleted, now);
-        examStudent.setFinished(true);
-        examStudent.setNormalExamTimes(normalExamTimes);
-        examStudent.setIsReExamine(isReExamine);
-        examStudent.setReExamineCompleted(reExamineCompleted);
-        examStudent.setUpdateTime(now);
-        return examStudent;
     }
 }