wangliang 4 rokov pred
rodič
commit
0dddd31446

+ 1 - 3
themis-business/src/main/java/com/qmth/themis/business/enums/ExceptionEnum.java

@@ -21,9 +21,7 @@ public enum ExceptionEnum {
 
     POWER_CUT("停电", "异常处理"),
 
-    OTHER("其它", "异常处理"),
-
-    EXIT("退出", "异常处理");
+    OTHER("其它", "异常处理");
 
     private String code;
 

+ 19 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -397,9 +397,28 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
 
     /**
      * 查询成绩
+     *
      * @param markResultDto
      * @param recordSelectStrategyEnum
      * @return
      */
     TOeExamRecord findMarkResult(MarkResultDto markResultDto, RecordSelectStrategyEnum recordSelectStrategyEnum);
+
+    /**
+     * 设置断点信息
+     *
+     * @param alreadyBreakCount
+     * @param recordId
+     * @param examActivityId
+     */
+    void setExamBreak(Integer alreadyBreakCount, Long recordId, Long examActivityId);
+
+    /**
+     * 发送断点信息
+     *
+     * @param recordId
+     * @param setBreak
+     * @return
+     */
+    Boolean sendExamBreakMsg(Long recordId, boolean setBreak);
 }

+ 15 - 40
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -363,7 +363,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
      * 根据设定几率取出一套试卷
      */
     private int getPaperByWeight(List<Double> paperWeight) {
-    	BigDecimal r = new BigDecimal(new Random().nextInt(101));
+        BigDecimal r = new BigDecimal(new Random().nextInt(101));
         for (int i = 0; i < paperWeight.size(); i++) {
             r = r.subtract(new BigDecimal(paperWeight.get(i)));
             if (r.doubleValue() <= 0.0d) {
@@ -386,6 +386,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             throw new BusinessException(ExceptionResultEnum.NOT_FOUND_EXAM_RECORD);
         }
         Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
         ExamStudentCacheBean es = (ExamStudentCacheBean) redisUtil
                 .get(RedisKeyHelper.examStudentCacheKey(examStudentId));
         if (es == null) {
@@ -398,6 +399,10 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (es.getEnable().intValue() == 0) {
             throw new BusinessException(ExceptionResultEnum.EXAM_STUDENT_ENABLE);
         }
+        Boolean finished = toeExamRecordService.sendExamBreakMsg(recordId, false);
+        if (finished) {
+            return ret;
+        }
         ExamCacheBean exam = getExamCacheBeanNative(es.getExamId());
         Long activityId = es.getExamActivityId();
         ExamActivityCacheBean ac = teExamActivityService.getExamActivityCacheBean(activityId);
@@ -470,25 +475,6 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                 }
             }
         }
-
-        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
-        //获取断点时间
-        Long lastBreakTime = ExamRecordCacheUtil.getLastBreakTime(recordId);
-        //获取剩余断点次数
-        Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-        Integer leftBreakResumeCount = exam.getBreakResumeCount() - alreadyBreakCount;
-        Integer breakExpireSeconds = Objects.isNull(exam.getBreakExpireSeconds()) ? 0 : exam.getBreakExpireSeconds();
-        //如果断点时间大于整体断点时间,则强制交卷
-        if (Objects.nonNull(lastBreakTime) && (System.currentTimeMillis() - lastBreakTime) / 1000 > breakExpireSeconds) {
-            finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-        } else {
-            //如果断点次数小于0,也强制交卷
-            if (leftBreakResumeCount <= 0) {
-                finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-            }
-        }
-
         ret = new ExamStartBean();
         ret.setPaperDecryptSecret(ep.getDecryptSecret());
         ret.setPaperDecryptVector(ep.getDecryptVector());
@@ -526,6 +512,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                     calendar.add(Calendar.SECOND, finalMaxDurationSeconds.intValue());
                 }
                 Integer breakResumeCount = exam.getBreakResumeCount();
+                Integer breakExpireSeconds = Objects.isNull(exam.getBreakExpireSeconds()) ? 0 : exam.getBreakExpireSeconds();
                 Long finalFinishTime = (calendar.getTime().getTime() / 1000 + (breakResumeCount * breakExpireSeconds) + (breakResumeCount * 180)) * 1000;
                 ExamRecordCacheUtil.setExamFinalFinishTime(recordId, finalFinishTime);
                 //新增quartz任务,发送mq消息start
@@ -789,25 +776,13 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (ExamRecordStatusEnum.FINISHED.equals(sta) || ExamRecordStatusEnum.PERSISTED.equals(sta)) {
             throw new BusinessException(ExceptionResultEnum.NOT_FOUND_EXAM_STUDENT);
         }
-        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
-        //获取断点时间
-        Long lastBreakTime = ExamRecordCacheUtil.getLastBreakTime(recordId);
-        //获取剩余断点次数
-        Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-        Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
-        Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ? 0 : ec.getBreakExpireSeconds();
-        //如果断点时间大于整体断点时间,则强制交卷
-        if (Objects.nonNull(lastBreakTime) && (System.currentTimeMillis() - lastBreakTime) / 1000 > breakExpireSeconds) {
-            finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-        } else {
-            //如果断点次数小于0,也强制交卷
-            if (leftBreakResumeCount <= 0) {
-                finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-            }
-        }
 
-        ExamResumeBean ret = new ExamResumeBean();
+        ExamResumeBean ret = null;
+        Boolean finished = toeExamRecordService.sendExamBreakMsg(recordId, false);
+        if (finished) {
+            return ret;
+        }
+        ret = new ExamResumeBean();
         ret.setDurationSeconds(ExamRecordCacheUtil.getDurationSeconds(recordId));
         ret.setPaperUrl(OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), ep.getPaperPath()));
         ret.setStructUrl(OssUtil.getUrlForPrivateBucket(systemConfig.getOssEnv(3), ep.getStructPath()));
@@ -1246,7 +1221,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
                             toeExamRecordService.calculateScore(rc.getId());
                         }
                     }
-                    Double progress=getPercentage(index, total);
+                    Double progress = getPercentage(index, total);
                     task.setProgress(progress);
                     teExamMapper.updateScoreProgress(progress, examId);
                     tbTaskHistoryService.saveOrUpdate(task);
@@ -1287,7 +1262,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (b == 0) {
             return null;
         }
-        Double da = Double.valueOf(a*100);
+        Double da = Double.valueOf(a * 100);
         Double db = Double.valueOf(b);
         BigDecimal bd = new BigDecimal(da / db);
         Double tem = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

+ 82 - 10
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.bean.backend.*;
+import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.*;
@@ -71,6 +72,9 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     @Resource
     TEExamActivityService examActivityService;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     /**
      * 获取考试未完列表
      *
@@ -777,16 +781,16 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             }
         }
         if (cb.getStructType().intValue() == 3) {
-            if(StringUtils.isNotBlank(answer.getAnswer())) {
-        		String answerStr=answer.getAnswer().replaceAll("\n", "");
-        		if(StringUtils.isNotBlank(answerStr)) {
-		            if (Boolean.parseBoolean(answerStr) == cb.getBoolAnswer().booleanValue()) {
-		                answer.setScore(cb.getScore());
-		            } else {
-		                answer.setScore(0.0);
-		            }
-        		}
-        	}
+            if (StringUtils.isNotBlank(answer.getAnswer())) {
+                String answerStr = answer.getAnswer().replaceAll("\n", "");
+                if (StringUtils.isNotBlank(answerStr)) {
+                    if (Boolean.parseBoolean(answerStr) == cb.getBoolAnswer().booleanValue()) {
+                        answer.setScore(cb.getScore());
+                    } else {
+                        answer.setScore(0.0);
+                    }
+                }
+            }
         }
 
         examAnswerService.saveOrUpdate(answer);
@@ -906,6 +910,74 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         return tOeExamRecord;
     }
 
+    /**
+     * 设置断点信息
+     *
+     * @param alreadyBreakCount
+     * @param recordId
+     * @param examActivityId
+     */
+    @Override
+    @Transactional
+    public void setExamBreak(Integer alreadyBreakCount, Long recordId, Long examActivityId) {
+        alreadyBreakCount++;
+        Long breakId = Constants.idGen.next();
+        ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
+        ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
+        Long lastBreakTimeNow = System.currentTimeMillis();
+        ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
+        ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
+        Long lastStartTime = System.currentTimeMillis();
+        ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
+        String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
+        Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
+        TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
+        tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
+        //考试断点异常原因 发送mq start
+        MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
+        MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
+        mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
+        //考试断点异常原因 发送mq end
+        //更新场次-考试记录缓存
+        ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
+    }
+
+    /**
+     * 发送断点信息
+     *
+     * @param recordId
+     * @param setBreak
+     * @return
+     */
+    @Override
+    public Boolean sendExamBreakMsg(Long recordId, boolean setBreak) {
+        Boolean finished = false;
+        Long examId = ExamRecordCacheUtil.getExamId(recordId);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+        ExamCacheBean ec = examService.getExamCacheBean(examId);//考试缓存
+
+        Long lastBreakTime = ExamRecordCacheUtil.getLastBreakTime(recordId);
+        Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ? 0 : ec.getBreakExpireSeconds();
+        Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
+        Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
+        Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
+        if (Objects.nonNull(lastBreakTime) && (System.currentTimeMillis() - lastBreakTime) / 1000 >= breakExpireSeconds) {
+            examService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
+            finished = true;
+        } else {
+            if (leftBreakResumeCount <= 0) {
+                examService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
+                finished = true;
+            } else {
+                if (setBreak) {
+                    this.setExamBreak(alreadyBreakCount, recordId, examStudentCacheBean.getExamActivityId());
+                }
+            }
+        }
+        return finished;
+    }
+
     /**
      * 取最高分
      *

+ 8 - 3
themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java

@@ -15,6 +15,7 @@ import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
@@ -46,6 +47,9 @@ public class TEExamController {
     @Resource
     MqDtoService mqDtoService;
 
+    @Resource
+    TOeExamRecordService tOeExamRecordService;
+
     @ApiOperation(value = "验证考试口令接口")
     @RequestMapping(value = "/short_code", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "考试信息", response = TEExam.class)})
@@ -112,17 +116,18 @@ public class TEExamController {
         String recordId = (String) mapParameter.get("recordId");
         ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(Long.valueOf(recordId));
         if (Objects.nonNull(status) && Objects.equals(ExamRecordStatusEnum.ANSWERING, status)) {//答题状态,强制断点
-            ExamConstant.sendExamBreakMsg(Long.valueOf(recordId));
+            ExamConstant.sendExamStopMsg(Long.valueOf(recordId), true);
+            tOeExamRecordService.sendExamBreakMsg(Long.valueOf(recordId), true);
         } else if (Objects.nonNull(status) && Objects.equals(ExamRecordStatusEnum.FIRST_PREPARE, status)) {
             ExamConstant.sendExamStopMsg(Long.valueOf(recordId), false);
         } else {
-            if(Objects.nonNull(status)) {
+            if (Objects.nonNull(status)) {
                 throw new BusinessException("考试状态出错");
             }
         }
         ConcurrentHashMap<Long, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
         WebSocketOeServer webSocketOeServer = webSocketMap.get(Long.parseLong(recordId));
-        if(Objects.nonNull(webSocketOeServer)){
+        if (Objects.nonNull(webSocketOeServer)) {
             webSocketOeServer.onClose();
         }
         return ResultUtil.ok(Collections.singletonMap(SystemConstant.SUCCESS, true));

+ 31 - 44
themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java

@@ -6,10 +6,12 @@ import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.bean.exam.ExamActivityUnFinishBean;
 import com.qmth.themis.business.bean.exam.ExamUnFinishBean;
-import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.ExamingDataCacheUtil;
-import com.qmth.themis.business.cache.bean.*;
+import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
+import com.qmth.themis.business.cache.bean.ExamCacheBean;
+import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
@@ -252,52 +254,20 @@ public class TEStudentController {
             Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
             //如果断点时间大于整体断点时间,则强制交卷
             if (Objects.equals(status, ExamRecordStatusEnum.ANSWERING) || Objects.equals(status, ExamRecordStatusEnum.BREAK_OFF) || Objects.equals(status, ExamRecordStatusEnum.RESUME_PREPARE)) {
-                if (Objects.nonNull(lastBreakTime) && (System.currentTimeMillis() - lastBreakTime) / 1000 > breakExpireSeconds) {
-                    teExamService.finish(teStudentCacheDto.getId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-                    List<TEExamDto> list = teExamService.getWaitingExam(teStudent.getId(), examId, orgId);
-                    if (Objects.nonNull(list) && list.size() > 0) {
-                        map.put("waiting", list);
-                    }
+                Boolean finished = tOeExamRecordService.sendExamBreakMsg(recordId, false);
+                if (finished) {
+                    map = this.getWaitList(teStudent.getId(), examId, orgId, map);
                 } else {
-                    //如果断点次数小于0,也强制交卷
-                    if (leftBreakResumeCount <= 0) {
-                        teExamService.finish(teStudentCacheDto.getId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-                        List<TEExamDto> list = teExamService.getWaitingExam(teStudent.getId(), examId, orgId);
-                        if (Objects.nonNull(list) && list.size() > 0) {
-                            map.put("waiting", list);
-                        }
-                    } else {
-                        //只有ANSWERING状态才生成断点
-                        if (Objects.equals(status, ExamRecordStatusEnum.ANSWERING)) {
-                            alreadyBreakCount++;
-                            Long breakId = Constants.idGen.next();
-                            ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
-                            ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
-                            Long lastBreakTimeNow = System.currentTimeMillis();
-                            ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
-                            ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
-                            Long lastStartTime = System.currentTimeMillis();
-                            ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
-                            String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
-                            Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
-                            tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
-                            ExamConstant.sendExamStopMsg(recordId, true);
-                            //考试断点异常原因 发送mq start
-                            MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
-                            mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
-                            //考试断点异常原因 发送mq end
-                            //更新场次-考试记录缓存
-                            ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
-                        }
-                        ExamUnFinishBean examUnFinishBean = this.unFinishCommon(recordId, ec, examStudentCacheBean, examActivityCacheBean, examStudentId);
-                        map.put("unFinished", examUnFinishBean);
+                    //只有ANSWERING状态才生成断点
+                    if (Objects.equals(status, ExamRecordStatusEnum.ANSWERING)) {
+                        ExamConstant.sendExamStopMsg(recordId, true);
+                        tOeExamRecordService.setExamBreak(alreadyBreakCount, recordId, examActivityId);
                     }
+                    ExamUnFinishBean examUnFinishBean = this.unFinishCommon(recordId, ec, examStudentCacheBean, examActivityCacheBean, examStudentId);
+                    map.put("unFinished", examUnFinishBean);
                 }
             } else {
-                List<TEExamDto> list = teExamService.getWaitingExam(teStudent.getId(), examId, orgId);
-                if (Objects.nonNull(list) && list.size() > 0) {
-                    map.put("waiting", list);
-                }
+                map = this.getWaitList(teStudent.getId(), examId, orgId, map);
             }
         }
         //获取全局考试配置
@@ -365,4 +335,21 @@ public class TEStudentController {
         examActivityUnFinishBean.setRecordId(recordId);
         return new ExamUnFinishBean(ec.getId(), ec.getName(), ec.getPreNotice(), ec.getPreNoticeStaySeconds(), ec.getPostNotice(), examActivityUnFinishBean);
     }
+
+    /**
+     * 获取待考列表
+     *
+     * @param studentId
+     * @param examId
+     * @param orgId
+     * @param map
+     * @return
+     */
+    private Map<String, Object> getWaitList(Long studentId, Long examId, Long orgId, Map<String, Object> map) {
+        List<TEExamDto> list = teExamService.getWaitingExam(studentId, examId, orgId);
+        if (Objects.nonNull(list) && list.size() > 0) {
+            map.put("waiting", list);
+        }
+        return map;
+    }
 }

+ 2 - 56
themis-exam/src/main/java/com/qmth/themis/exam/config/ExamConstant.java

@@ -1,20 +1,9 @@
 package com.qmth.themis.exam.config;
 
-import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
-import com.qmth.themis.business.cache.ExamRecordCacheUtil;
-import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
-import com.qmth.themis.business.cache.bean.ExamCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
-import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
-import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.WebsocketDto;
-import com.qmth.themis.business.enums.*;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.service.TEExamService;
-import com.qmth.themis.business.service.TEExamStudentService;
-import com.qmth.themis.business.service.TOeExamRecordService;
-import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
+import com.qmth.themis.business.enums.WebsocketTypeEnum;
 import com.qmth.themis.exam.websocket.WebSocketMobileServer;
 import com.qmth.themis.exam.websocket.WebSocketOeServer;
 
@@ -92,47 +81,4 @@ public class ExamConstant {
             webSocketMobileServer.sendMessage(websocketDto);
         }
     }
-
-    /**
-     * 发送断点消息
-     *
-     * @param recordId
-     */
-    public static void sendExamBreakMsg(Long recordId) {
-        Long examId = ExamRecordCacheUtil.getExamId(recordId);
-        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
-        TEExamStudentService teExamStudentService = SpringContextHolder.getBean(TEExamStudentService.class);
-        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        TEExamService teExamService = SpringContextHolder.getBean(TEExamService.class);
-        ExamCacheBean ec = teExamService.getExamCacheBean(examId);//考试缓存
-
-        Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
-        Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-        Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
-        if (leftBreakResumeCount <= 0) {
-            teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-        } else {
-            alreadyBreakCount++;
-            Long breakId = Constants.idGen.next();
-            ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
-            ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
-            Long lastBreakTimeNow = System.currentTimeMillis();
-            ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
-            ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
-            Long lastStartTime = System.currentTimeMillis();
-            ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
-            String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
-            Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
-            TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
-            tOeExamRecordService.dataUpdatesMq(recordId, columns, values);
-            sendExamStopMsg(recordId, true);
-            //考试断点异常原因 发送mq start
-            MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.EXIT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
-            MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
-            mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
-            //考试断点异常原因 发送mq end
-            //更新场次-考试记录缓存
-            ExamActivityRecordCacheUtil.setExamRecordStatus(examStudentCacheBean.getExamActivityId(), recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
-        }
-    }
 }

+ 4 - 2
themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketOeServer.java

@@ -170,7 +170,9 @@ public class WebSocketOeServer implements Concurrently {
                     //发送延时mq消息end
                 } else {
                     log.info("正常退出");
-                    ExamConstant.sendExamBreakMsg(this.recordId);
+                    ExamConstant.sendExamStopMsg(this.recordId, true);
+                    TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
+                    tOeExamRecordService.sendExamBreakMsg(this.recordId, true);
                 }
             }
         }
@@ -204,7 +206,7 @@ public class WebSocketOeServer implements Concurrently {
                 }
             } catch (Exception e) {
                 log.error("请求出错", e);
-                if(log.isInfoEnabled()){
+                if (log.isInfoEnabled()) {
                     log.info("incoming message:" + message);
                 }
             }

+ 1 - 35
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -5,11 +5,8 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.google.gson.Gson;
-import com.qmth.themis.business.cache.ExamActivityRecordCacheUtil;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
-import com.qmth.themis.business.cache.bean.ExamActivityRecordCacheBean;
-import com.qmth.themis.business.cache.bean.ExamCacheBean;
 import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
@@ -246,38 +243,7 @@ public class MqLogicServiceImpl implements MqLogicService {
         ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(recordId);
         WebsocketStatusEnum websocketStatusEnum = ExamRecordCacheUtil.getClientWebsocketStatus(recordId);
         if (Objects.nonNull(websocketStatusEnum) && !Objects.equals(websocketStatusEnum, WebsocketStatusEnum.ON_LINE) && (!Objects.equals(status, ExamRecordStatusEnum.FIRST_PREPARE) || !Objects.equals(status, ExamRecordStatusEnum.FINISHED) || !Objects.equals(status, ExamRecordStatusEnum.PERSISTED))) {
-            Long examId = ExamRecordCacheUtil.getExamId(recordId);
-            Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
-            Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
-            ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-            ExamCacheBean ec = teExamService.getExamCacheBean(examId);//考试缓存
-            Long breakId = null;
-            //增加断点记录,获取剩余断点次数
-            Integer alreadyBreakCount = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-            Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
-            if (leftBreakResumeCount <= 0) {
-                Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
-                teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-            } else {
-                alreadyBreakCount++;
-                breakId = Constants.idGen.next();
-                ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
-                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
-                Long lastBreakTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTime, false);
-                ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
-                Long lastStartTime = System.currentTimeMillis();
-                ExamRecordCacheUtil.setLastStartTime(recordId, lastStartTime, false);
-                String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
-                Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTime, alreadyBreakCount, lastStartTime};
-                examRecordService.dataUpdatesMq(recordId, columns, values);
-                //考试断点异常原因 发送mq start
-                MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.NET_TIME_OUT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
-                mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
-                //考试断点异常原因 发送mq end
-                //更新场次-考试记录缓存
-                ExamActivityRecordCacheUtil.setExamRecordStatus(examActivityId, recordId, new ExamActivityRecordCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId), ExamRecordCacheUtil.getStatus(recordId)));
-            }
+            examRecordService.sendExamBreakMsg(recordId, true);
             //更新客户端摄像头推流状态为stop
             MonitorStatusSourceEnum cameraStatusSourceEnum = ExamRecordCacheUtil.getMonitorStatus(recordId, MonitorVideoSourceEnum.CLIENT_CAMERA);
             if (Objects.nonNull(cameraStatusSourceEnum)) {