Răsfoiți Sursa

Merge branch 'dev'

# Conflicts:
#	themis-business/src/main/java/com/qmth/themis/business/cache/ExamRecordCacheUtil.java
wangliang 4 ani în urmă
părinte
comite
d6147981da
20 a modificat fișierele cu 313 adăugiri și 300 ștergeri
  1. 22 24
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamController.java
  2. 6 4
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamReexamController.java
  3. 7 9
      themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateCallMobileController.java
  4. 9 9
      themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java
  5. 6 6
      themis-backend/src/main/java/com/qmth/themis/backend/aspect/ApiControllerAspect.java
  6. 117 20
      themis-business/src/main/java/com/qmth/themis/business/cache/ExamRecordCacheUtil.java
  7. 5 1
      themis-business/src/main/java/com/qmth/themis/business/cache/MobileAuthCacheUtil.java
  8. 5 9
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEMobileServiceImpl.java
  9. 9 12
      themis-business/src/main/java/com/qmth/themis/business/service/impl/WarningServiceImpl.java
  10. 2 5
      themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java
  11. 23 64
      themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java
  12. 21 31
      themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallMobileController.java
  13. 20 36
      themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallOeController.java
  14. 2 1
      themis-exam/src/main/java/com/qmth/themis/exam/aspect/ApiControllerAspect.java
  15. 8 13
      themis-exam/src/main/java/com/qmth/themis/exam/listener/service/impl/MqOeLogicServiceImpl.java
  16. 2 4
      themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketMobileServer.java
  17. 6 10
      themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketOeServer.java
  18. 9 7
      themis-exam/src/main/java/com/qmth/themis/exam/websocketTemplete/WebSocketOeMessageTemplete.java
  19. 23 31
      themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java
  20. 11 4
      themis-task/src/main/java/com/qmth/themis/task/quartz/service/impl/QuartzLogicServiceImpl.java

+ 22 - 24
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamController.java

@@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.base.BasePage;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
 import com.qmth.themis.business.dto.ExamPropCountDto;
@@ -33,8 +35,6 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
@@ -401,28 +401,26 @@ public class TEExamController {
                 Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
                 if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
                     objectMap.forEach((k, v) -> {
-                        Map<String, Object> recordIdObjectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(Long.parseLong(k)));
-                        if (Objects.nonNull(recordIdObjectMap) && recordIdObjectMap.size() > 0) {
-                            //客户端通讯状态
-                            WebsocketStatusEnum clientStatus = Objects.isNull(recordIdObjectMap.get("clientWebsocketStatus")) ? null : WebsocketStatusEnum.valueOf(String.valueOf(recordIdObjectMap.get("clientWebsocketStatus")));
-                            if (Objects.nonNull(clientStatus) && Objects.equals(clientStatus, WebsocketStatusEnum.OFF_LINE)) {
-                                clientWebsocketStatusCount.getAndSet(clientWebsocketStatusCount.get() + 1);
-                            }
-                            //监控端通讯状态
-                            MonitorVideoSourceEnum source = null;
-                            if (Objects.nonNull(recordIdObjectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_CAMERA.name()))) {
-                                source = MonitorVideoSourceEnum.CLIENT_CAMERA;
-                            } else if (Objects.nonNull(recordIdObjectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()))) {
-                                source = MonitorVideoSourceEnum.CLIENT_SCREEN;
-                            } else if (Objects.nonNull(recordIdObjectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
-                                source = MonitorVideoSourceEnum.MOBILE_FIRST;
-                            } else if (Objects.nonNull(recordIdObjectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
-                                source = MonitorVideoSourceEnum.MOBILE_SECOND;
-                            }
-                            MonitorStatusSourceEnum status = Objects.isNull(source) ? null : MonitorStatusSourceEnum.valueOf(String.valueOf(recordIdObjectMap.get(SystemConstant.MONITOR_STATUS_ + source)));
-                            if (Objects.nonNull(status) && Objects.equals(status, MonitorStatusSourceEnum.STOP)) {
-                                monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
-                            }
+                        Long recordId = Long.parseLong(k);
+                        //客户端通讯状态
+                        WebsocketStatusEnum clientStatus = Objects.isNull(ExamRecordCacheUtil.getClientWebsocketStatus(recordId)) ? null : ExamRecordCacheUtil.getClientWebsocketStatus(recordId);
+                        if (Objects.nonNull(clientStatus) && Objects.equals(clientStatus, WebsocketStatusEnum.OFF_LINE)) {
+                            clientWebsocketStatusCount.getAndSet(clientWebsocketStatusCount.get() + 1);
+                        }
+                        //监控端通讯状态
+                        MonitorVideoSourceEnum source = null;
+                        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientCamera(recordId))) {
+                            source = MonitorVideoSourceEnum.CLIENT_CAMERA;
+                        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientScreen(recordId))) {
+                            source = MonitorVideoSourceEnum.CLIENT_SCREEN;
+                        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId))) {
+                            source = MonitorVideoSourceEnum.MOBILE_FIRST;
+                        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId))) {
+                            source = MonitorVideoSourceEnum.MOBILE_SECOND;
+                        }
+                        MonitorStatusSourceEnum status = Objects.isNull(source) ? null : ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
+                        if (Objects.nonNull(status) && Objects.equals(status, MonitorStatusSourceEnum.STOP)) {
+                            monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
                         }
                         ExamRecordStatusEnum examRecordStatusEnum = (ExamRecordStatusEnum) v;
                         //已待考

+ 6 - 4
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamReexamController.java

@@ -8,6 +8,7 @@ import com.qmth.themis.business.base.BasePage;
 import com.qmth.themis.business.bean.backend.ReexamListDoneBean;
 import com.qmth.themis.business.bean.backend.ReexamListNotDoneBean;
 import com.qmth.themis.business.bean.backend.ReexamListRequestBean;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
@@ -90,7 +91,8 @@ public class TEExamReexamController {
         List<TEExamReexamAuditing> teExamReexamAuditingList = new ArrayList<>();
         for (String s : recordIdList) {
             //获取考试记录缓存
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(Long.parseLong(s)));
+            Long recordId = Long.parseLong(s);
+            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
             if (Objects.isNull(objectMap) || objectMap.size() == 0) {
                 TOeExamRecord tOeExamRecord = tOeExamRecordService.getById(Long.parseLong(s));
                 if (Objects.isNull(tOeExamRecord)) {
@@ -100,9 +102,9 @@ public class TEExamReexamController {
                 examStudentId = tOeExamRecord.getExamStudentId();
                 examActivityId = tOeExamRecord.getExamActivityId();
             } else {
-                examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-                examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-                examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+                examId = ExamRecordCacheUtil.getExamId(recordId);
+                examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+                examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
             }
             ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);//考试缓存
             if (Objects.isNull(examCacheBean)) {

+ 7 - 9
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateCallMobileController.java

@@ -129,24 +129,22 @@ public class TIeInvigilateCallMobileController {
         }
         Long recordId = Long.parseLong(String.valueOf(mapParameter.get("recordId")));
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
         String liveUrl = null;
         MonitorVideoSourceEnum source = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId))) {
             source = MonitorVideoSourceEnum.MOBILE_FIRST;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()));
-        } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId);
+        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId))) {
             source = MonitorVideoSourceEnum.MOBILE_SECOND;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId);
         }
-        if (Objects.isNull(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name()))) {
+        if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source.name()))) {
             throw new BusinessException("推流状态为空");
         }
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), MonitorCallStatusSourceEnum.STOP);
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), MonitorCallStatusSourceEnum.STOP);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
-        MonitorStatusSourceEnum status = MonitorStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name())));
+        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP);
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         mqDtoService.assembleSendOneWayMsg(mqDto);

+ 9 - 9
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java

@@ -9,6 +9,7 @@ import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.base.BasePage;
 import com.qmth.themis.business.bean.backend.*;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
@@ -184,12 +185,11 @@ public class TIeInvigilateController {
             throw new BusinessException(ExceptionResultEnum.RECORD_ID_IS_NULL);
         }
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(examRecordId));
-        Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-        Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-        Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
-        ExamRecordStatusEnum status = (ExamRecordStatusEnum) objectMap.get("status");
-        Integer breachStatus = Objects.isNull(objectMap.get("breachStatus")) ? null : Integer.parseInt(String.valueOf(objectMap.get("breachStatus")));
+        Long examId = ExamRecordCacheUtil.getExamId(examRecordId);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(examRecordId);
+        Long examActivityId = ExamRecordCacheUtil.getExamActivityId(examRecordId);
+        ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(examRecordId);
+        Integer breachStatus = Objects.isNull(ExamRecordCacheUtil.getBreachStatus(examRecordId)) ? null : ExamRecordCacheUtil.getBreachStatus(examRecordId);
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
         String identity = examStudentCacheBean.getIdentity();
         String examStudentName = examStudentCacheBean.getName();
@@ -375,9 +375,9 @@ public class TIeInvigilateController {
                     examStudentId = tOeExamRecord.getExamStudentId();
                     examActivityId = tOeExamRecord.getExamActivityId();
                 } else {
-                    examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-                    examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-                    examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+                    examId = ExamRecordCacheUtil.getExamId(l);
+                    examStudentId = ExamRecordCacheUtil.getExamStudentId(l);
+                    examActivityId = ExamRecordCacheUtil.getExamActivityId(l);
                 }
                 TEExamBreachLog teExamBreachLog = new TEExamBreachLog(examId, examActivityId, l, examStudentId, type, description, status);
                 teExamBreachLog.setCreateId(tbUser.getId());

+ 6 - 6
themis-backend/src/main/java/com/qmth/themis/backend/aspect/ApiControllerAspect.java

@@ -1,7 +1,8 @@
 package com.qmth.themis.backend.aspect;
 
-import javax.servlet.http.HttpServletRequest;
-
+import com.qmth.themis.business.util.JacksonUtil;
+import com.qmth.themis.business.util.ServletUtil;
+import com.qmth.themis.common.util.ResultUtil;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
@@ -11,9 +12,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.business.util.ServletUtil;
-import com.qmth.themis.common.util.ResultUtil;
+import javax.servlet.http.HttpServletRequest;
 
 /**
  * @Description: api aspect
@@ -64,7 +63,8 @@ public class ApiControllerAspect {
             log.info("============耗时============:{}秒", (end - start) / 1000);
             return proceed;
         } catch (Exception e) {
-        	log.error("请求出错",e);
+            log.error("请求出错", e);
+            e.printStackTrace();
             return ResultUtil.error(e.getMessage());
         }
     }

+ 117 - 20
themis-business/src/main/java/com/qmth/themis/business/cache/ExamRecordCacheUtil.java

@@ -1,15 +1,14 @@
 package com.qmth.themis.business.cache;
 
-import java.util.Date;
-import java.util.Objects;
-
 import com.qmth.themis.business.constant.SpringContextHolder;
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
-import com.qmth.themis.business.enums.FinishTypeEnum;
-import com.qmth.themis.business.enums.VerifyExceptionEnum;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.RedisUtil;
 
+import java.util.Date;
+import java.util.Objects;
+
 /**
  * 考试记录缓存hash值操作
  *
@@ -23,15 +22,15 @@ public class ExamRecordCacheUtil {
     private static RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
 
     public static Long getId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "id");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "id")));
     }
 
     public static Long getExamStudentId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examStudentId");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examStudentId")));
     }
 
     public static Long getPaperId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "paperId");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "paperId")));
     }
 
     public static void setFirstStartTime(Long recordId, Date date) {
@@ -45,15 +44,15 @@ public class ExamRecordCacheUtil {
     }
 
     public static Integer getDurationSeconds(Long recordId) {
-        return (Integer) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "durationSeconds");
+        return Integer.parseInt(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "durationSeconds")));
     }
 
     public static Double getObjectiveScore(Long recordId) {
-        return (Double) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "objectiveScore");
+        return Double.parseDouble(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "objectiveScore")));
     }
 
     public static Long getExamId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examId");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examId")));
     }
 
     public static void setObjectiveScore(Long recordId, Double objectiveScore) {
@@ -89,7 +88,7 @@ public class ExamRecordCacheUtil {
     }
 
     public static Integer getLeftBreakResumeCount(Long recordId) {
-        return (Integer) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "leftBreakResumeCount");
+        return Integer.parseInt(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "leftBreakResumeCount")));
     }
 
     public static void setLeftBreakResumeCount(Long recordId, Integer leftBreakResumeCount) {
@@ -98,11 +97,11 @@ public class ExamRecordCacheUtil {
     }
 
     public static ExamRecordStatusEnum getStatus(Long recordId) {
-        return (ExamRecordStatusEnum) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "status");
+        return ExamRecordStatusEnum.valueOf(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "status")));
     }
 
     public static Long getLastBreakId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "lastBreakId");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "lastBreakId")));
     }
 
     public static Date getLastBreakTime(Long recordId) {
@@ -119,7 +118,7 @@ public class ExamRecordCacheUtil {
     }
 
     public static Long getEntryAuthenticationId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "entryAuthenticationId");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "entryAuthenticationId")));
     }
 
     public static void setEntryAuthenticationId(Long recordId, Long entryAuthenticationId) {
@@ -128,7 +127,7 @@ public class ExamRecordCacheUtil {
     }
 
     public static Long getExamActivityId(Long recordId) {
-        return (Long) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examActivityId");
+        return Long.parseLong(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "examActivityId")));
     }
 
     public static void setWarningCount(Long recordId, Integer warningCount) {
@@ -137,7 +136,7 @@ public class ExamRecordCacheUtil {
     }
 
     public static Integer getWarningCount(Long recordId) {
-        return (Integer) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "warningCount");
+        return Integer.parseInt(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "warningCount")));
     }
 
     public static void setBreachStatus(Long recordId, Integer breachStatus) {
@@ -146,7 +145,7 @@ public class ExamRecordCacheUtil {
     }
 
     public static Integer getBreachStatus(Long recordId) {
-        return (Integer) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "breachStatus");
+        return Integer.parseInt(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "breachStatus")));
     }
 
     public static void setInProcessLivenessVerifyCount(Long recordId, Integer inProcessLivenessVerifyCount) {
@@ -155,7 +154,7 @@ public class ExamRecordCacheUtil {
     }
 
     public static Integer getInProcessLivenessVerifyCount(Long recordId) {
-        return (Integer) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "inProcessLivenessVerifyCount");
+        return Integer.parseInt(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "inProcessLivenessVerifyCount")));
     }
 
     public static void setMonitorKey(Long recordId, String monitorKey) {
@@ -169,4 +168,102 @@ public class ExamRecordCacheUtil {
         }
         return (String) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "monitorKey");
     }
+
+    public static String getMonitorLiveUrl(Long recordId, String source) {
+        return (String) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_LIVE_URL_ + source);
+    }
+
+    public static String getMonitorLiveUrlMobileFirst(Long recordId) {
+        return (String) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name());
+    }
+
+    public static String getMonitorLiveUrlMobileSecond(Long recordId) {
+        return (String) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name());
+    }
+
+    public static String getMonitorLiveUrlClientCamera(Long recordId) {
+        return (String) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_CAMERA.name());
+    }
+
+    public static String getMonitorLiveUrlClientScreen(Long recordId) {
+        return (String) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name());
+    }
+
+    public static void setMonitorLiveUrl(Long recordId, String source, String liveUrl) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_LIVE_URL_ + source, liveUrl);
+        examRecordService.dataUpdateMq(recordId, "monitor_live_url", liveUrl);
+    }
+
+    public static MonitorStatusSourceEnum getMonitorStatus(Long recordId, String source) {
+        return MonitorStatusSourceEnum.valueOf(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_STATUS_ + source)));
+    }
+
+    public static void setMonitorStatus(Long recordId, String source, MonitorStatusSourceEnum statusSourceEnum) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_STATUS_ + source, statusSourceEnum);
+        examRecordService.dataUpdateMq(recordId, "monitor_status_source", statusSourceEnum);
+    }
+
+    public static MonitorCallStatusSourceEnum getMonitorCallStatus(Long recordId, String source) {
+        return MonitorCallStatusSourceEnum.valueOf(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_CALL_STATUS_ + source)));
+    }
+
+    public static void setMonitorCallStatus(Long recordId, String source, MonitorCallStatusSourceEnum callStatusSourceEnum) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), SystemConstant.MONITOR_CALL_STATUS_ + source, callStatusSourceEnum.name());
+    }
+
+    public static WebsocketStatusEnum getClientWebsocketStatus(Long recordId) {
+        return WebsocketStatusEnum.valueOf(String.valueOf(redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "clientWebsocketStatus")));
+    }
+
+    public static void setClientWebsocketStatus(Long recordId, WebsocketStatusEnum websocketStatusEnum) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "clientWebsocketStatus", websocketStatusEnum);
+        examRecordService.dataUpdateMq(recordId, "client_websocket_status", websocketStatusEnum);
+    }
+
+    public static void setClientCurrentIp(Long recordId, String ip) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "clientCurrentIp", ip);
+        examRecordService.dataUpdateMq(recordId, "client_current_ip", ip);
+    }
+
+    public static void setClientWebsocketId(Long recordId, String id) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "clientWebsocketId", id);
+        examRecordService.dataUpdateMq(recordId, "client_websocket_id", id);
+    }
+
+    public static void setClientLastSyncTime(Long recordId) {
+        Date now = new Date();
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "clientLastSyncTime", now);
+        examRecordService.dataUpdateMq(recordId, "client_last_sync_time", now);
+    }
+
+    public static void setPaperDownload(Long recordId, Integer paperDownload) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "paperDownload", paperDownload);
+        examRecordService.dataUpdateMq(recordId, "paper_download", paperDownload);
+    }
+
+    public static void setAnswerProgress(Long recordId, Double progress) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "answerProgress", progress);
+        examRecordService.dataUpdateMq(recordId, "answer_progress", progress);
+    }
+
+    public static void setLastBreakId(Long recordId, Long breakId) {
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "lastBreakId", breakId);
+        examRecordService.dataUpdateMq(recordId, "last_break_id", breakId);
+    }
+
+    public static void setLastBreakTime(Long recordId) {
+        Date now = new Date();
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "lastBreakTime", now);
+        examRecordService.dataUpdateMq(recordId, "last_break_time", now);
+    }
+
+    public static void setLastStartTime(Long recordId) {
+        Date now = new Date();
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), "lastStartTime", now);
+        examRecordService.dataUpdateMq(recordId, "last_start_time", now);
+    }
+
+    public static Date getLastStartTime(Long recordId) {
+        return (Date) redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), "lastStartTime");
+    }
 }

+ 5 - 1
themis-business/src/main/java/com/qmth/themis/business/cache/MobileAuthCacheUtil.java

@@ -111,7 +111,11 @@ public class MobileAuthCacheUtil {
         return (String) redisUtil.get(RedisKeyHelper.mobileAuthCacheKey(mode, code), "platformSource");
     }
 
-    public static void setPlatformSource(MobileModeEnum mode, String code, Source source) {
+    public static void setPlatformSource(MobileModeEnum mode, String code, String source) {
         redisUtil.set(RedisKeyHelper.mobileAuthCacheKey(mode, code), "platformSource", source);
     }
+
+    public static String getUserType(MobileModeEnum mode, String code) {
+        return (String) redisUtil.get(RedisKeyHelper.mobileAuthCacheKey(mode, code), "userType");
+    }
 }

+ 5 - 9
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEMobileServiceImpl.java

@@ -112,7 +112,6 @@ public class TEMobileServiceImpl implements TEMobileService {
         ret.setMonitorKey(monitorKey);
         ret.setMonitorVideoSource(monitorVideoSource);
         ret.setMonitorAudioEnable(monitorAudioEnable);
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.mobileAuthCacheKey(mode, code));
         ExamStudentCacheBean es = examStudentService
                 .getExamStudentCacheBean(ExamRecordCacheUtil.getExamStudentId(ret.getRecordId()));
         String source = null;
@@ -122,12 +121,11 @@ public class TEMobileServiceImpl implements TEMobileService {
         } else if (mode.equals(MobileModeEnum.PHOTO_UPLOAD) || mode.equals(MobileModeEnum.AUDIO_UPLOAD)) {
             source = Source.OE_ANSWER.name();
         }
-        String userType = String.valueOf(objectMap.get("userType"));
+        String userType = MobileAuthCacheUtil.getUserType(mode, code);
         AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.studentOauth + "::" + es.getStudentId());
         String sessionId = SessionUtil.digest(es.getIdentity(), Math.abs(authDto.getRoleCodes().toString().hashCode()), source);
-        objectMap.put("sessionId", sessionId);
-        objectMap.put("platformSource", source);
-        redisUtil.setForHash(RedisKeyHelper.mobileAuthCacheKey(mode, code), objectMap);
+        MobileAuthCacheUtil.setSessionId(mode, code, sessionId);
+        MobileAuthCacheUtil.setPlatformSource(mode, code, source);
         if (Objects.nonNull(userType) && userType.contains(RoleEnum.STUDENT.name())) {
             ret.setMonitorUserId("s_" + sessionId);
         } else {
@@ -145,7 +143,6 @@ public class TEMobileServiceImpl implements TEMobileService {
         if (MobileAuthCacheUtil.getMode(mode, code) == null) {
             throw new BusinessException("二维码已过期");
         }
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.mobileAuthCacheKey(mode, code));
         ExamStudentCacheBean es = examStudentService
                 .getExamStudentCacheBean(ExamRecordCacheUtil.getExamStudentId(recordId));
         String source = null;
@@ -157,9 +154,8 @@ public class TEMobileServiceImpl implements TEMobileService {
         }
         AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.studentOauth + "::" + es.getStudentId());
         String sessionId = SessionUtil.digest(es.getIdentity(), Math.abs(authDto.getRoleCodes().toString().hashCode()), source);
-        objectMap.put("sessionId", sessionId);
-        objectMap.put("platformSource", source);
-        redisUtil.setForHash(RedisKeyHelper.mobileAuthCacheKey(mode, code), objectMap);
+        MobileAuthCacheUtil.setSessionId(mode, code, sessionId);
+        MobileAuthCacheUtil.setPlatformSource(mode, code, source);
         MobileAuthorizationUploadBean ret = new MobileAuthorizationUploadBean();
         ret.setRecordId(recordId);
         ret.setMainNumber(mainNumber);

+ 9 - 12
themis-business/src/main/java/com/qmth/themis/business/service/impl/WarningServiceImpl.java

@@ -59,10 +59,9 @@ public class WarningServiceImpl implements WarningService {
         VerifyExceptionEnum warningEnum = warningDto.getWarningEnum();
         String photoUrl = warningDto.getPhotoUrl();
         TEConfig teConfig = teConfigService.getGlobalConfig();
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-        Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-        Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-        Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+        Long examId = ExamRecordCacheUtil.getExamId(recordId);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
         if (faceCount > 1) {//多张人脸
             Integer count = faceVerifyHistoryService.faceCountError(recordId, warningDto.getWarningEnum().name(), faceCount, true);
             count = Objects.isNull(count) ? 0 : count;
@@ -94,10 +93,9 @@ public class WarningServiceImpl implements WarningService {
         VerifyExceptionEnum warningEnum = warningDto.getWarningEnum();
         String photoUrl = warningDto.getPhotoUrl();
         TEConfig teConfig = teConfigService.getGlobalConfig();
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-        Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-        Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-        Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+        Long examId = ExamRecordCacheUtil.getExamId(recordId);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
         Integer count = faceVerifyHistoryService.faceCompareError(recordId, warningDto.getWarningEnum().name());
         count = Objects.isNull(count) ? 0 : count;
         if (count >= teConfig.getMatchFaceCompareErrorCount()) {
@@ -143,10 +141,9 @@ public class WarningServiceImpl implements WarningService {
         Long recordId = warningDto.getRecordId();
         VerifyExceptionEnum warningEnum = warningDto.getWarningEnum();
         TEConfig teConfig = teConfigService.getGlobalConfig();
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-        Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-        Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-        Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+        Long examId = ExamRecordCacheUtil.getExamId(recordId);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
         QueryWrapper<TOeFaceVerifyHistory> tOeFaceVerifyHistoryQueryWrapper = new QueryWrapper<>();
         tOeFaceVerifyHistoryQueryWrapper.lambda().eq(TOeFaceVerifyHistory::getExamRecordId, recordId).eq(TOeFaceVerifyHistory::getException, warningEnum.name());
         int count = faceVerifyHistoryService.count(tOeFaceVerifyHistoryQueryWrapper);

+ 2 - 5
themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java

@@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.bean.exam.*;
-import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.WebsocketDto;
@@ -27,8 +27,6 @@ import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
 import com.qmth.themis.exam.websocket.WebSocketMobileServer;
 import io.swagger.annotations.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -130,8 +128,7 @@ public class TEExamController {
             } else {
                 //mq发送消息start
                 MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.ANSWERING, MqTagEnum.STUDENT, String.valueOf(teStudent.getId()), teStudent.getIdentity());
-                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(param.getRecordId()));
-                teExamService.sendOeLogMessage(SystemOperationEnum.ANSWERING, Long.parseLong(String.valueOf(objectMap.get("examStudentId"))), param.getRecordId(), mqDto);
+                teExamService.sendOeLogMessage(SystemOperationEnum.ANSWERING, ExamRecordCacheUtil.getExamStudentId(param.getRecordId()), param.getRecordId(), mqDto);
                 //mq发送消息end
             }
             ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();

+ 23 - 64
themis-exam/src/main/java/com/qmth/themis/exam/api/TEStudentController.java

@@ -1,32 +1,12 @@
 package com.qmth.themis.exam.api;
 
-import java.security.NoSuchAlgorithmException;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import javax.annotation.Resource;
-
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.BeanUtils;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.gson.Gson;
 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.bean.exam.StudentBean;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
-import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
 import com.qmth.themis.business.cache.bean.ExamCourseCacheBean;
@@ -41,20 +21,8 @@ import com.qmth.themis.business.dto.response.TEExamResultDto;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.entity.TEConfig;
 import com.qmth.themis.business.entity.TEStudent;
-import com.qmth.themis.business.enums.ExamModeEnum;
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
-import com.qmth.themis.business.enums.FinishTypeEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.enums.SystemOperationEnum;
-import com.qmth.themis.business.service.CacheService;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.service.TEConfigService;
-import com.qmth.themis.business.service.TEExamActivityService;
-import com.qmth.themis.business.service.TEExamCourseService;
-import com.qmth.themis.business.service.TEExamService;
-import com.qmth.themis.business.service.TEExamStudentService;
-import com.qmth.themis.business.service.TEStudentService;
+import com.qmth.themis.business.enums.*;
+import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
 import com.qmth.themis.business.util.SessionUtil;
@@ -68,12 +36,17 @@ import com.qmth.themis.common.signature.SignatureType;
 import com.qmth.themis.common.util.AesUtil;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
+import javax.annotation.Resource;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
 
 /**
  * @Description: 考生 前端控制器
@@ -113,7 +86,7 @@ public class TEStudentController {
 
     @Resource
     TEExamCourseService teExamCourseService;
-    
+
     @Resource
     SystemConfig systemConfig;
 
@@ -155,10 +128,8 @@ public class TEStudentController {
         if (Objects.isNull(user)) {
             throw new BusinessException(ExceptionResultEnum.STUDENT_NO);
         }
-        StudentBean student=new StudentBean();
-        BeanUtils.copyProperties(user, student);
-        if(StringUtils.isNotBlank(student.getBasePhotoPath())) {
-        	student.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.url") + "/" + student.getBasePhotoPath());
+        if (StringUtils.isNotBlank(user.getBasePhotoPath())) {
+            user.setBasePhotoPath(systemConfig.getProperty("aliyun.oss.url") + "/" + user.getBasePhotoPath());
         }
         String loginPassword = AesUtil.decryptCs7(password, Constants.AES_RULE);
         //密码错误
@@ -166,7 +137,7 @@ public class TEStudentController {
         if (!Objects.equals(loginPassword, aesPassword)) {
             throw new BusinessException(ExceptionResultEnum.PASSWORD_ERROR);
         }
-        return userLoginCommon(student, examId, orgId);
+        return userLoginCommon(user, examId, orgId);
     }
 
     /**
@@ -178,7 +149,7 @@ public class TEStudentController {
      * @return
      * @throws NoSuchAlgorithmException
      */
-    public Result userLoginCommon(StudentBean teStudent, Long examId, Long orgId) throws NoSuchAlgorithmException {
+    public Result userLoginCommon(TEStudent teStudent, Long examId, Long orgId) throws NoSuchAlgorithmException {
         //停用
         if (teStudent.getEnable().intValue() == 0) {
             throw new BusinessException(ExceptionResultEnum.STUDENT_ENABLE);
@@ -229,25 +200,16 @@ public class TEStudentController {
         } else {
             Long recordId = teStudentCacheDto.getUnFinishedRecordId();
             //获取考试记录缓存
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-            ExamRecordStatusEnum status = (ExamRecordStatusEnum) objectMap.get("status");
+            ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(recordId);
             if (Objects.isNull(status)) {
                 throw new BusinessException("考试状态不能为空");
             }
-            Long examIdMap = Long.parseLong(String.valueOf(objectMap.get("examId")));
-            Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-            Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
-            Integer durationSeconds = null;
-            if (Objects.isNull(objectMap.get("durationSeconds"))) {
-                durationSeconds = 0;
-            } else {
-                durationSeconds = Integer.parseInt(String.valueOf(objectMap.get("durationSeconds")));
-            }
+            Long examIdMap = ExamRecordCacheUtil.getExamId(recordId);
+            Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+            Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
+            Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
             ExamCacheBean ec = teExamService.getExamCacheBean(examIdMap);//考试缓存
-            Integer breakExpireSeconds=ec.getBreakExpireSeconds();
-            if(breakExpireSeconds==null) {
-            	breakExpireSeconds=0;
-            }
+            Integer breakExpireSeconds = Objects.isNull(ec.getBreakExpireSeconds()) ? 0 : ec.getBreakExpireSeconds();
             ExamActivityCacheBean examActivityCacheBean = teExamActivityService.getExamActivityCacheBean(examActivityId);//考试场次缓存
             ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
 
@@ -305,9 +267,6 @@ public class TEStudentController {
             throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
         }
         Long recordId = Objects.isNull(teStudent.getExamingRecordId()) ? teStudent.getUnFinishedRecordId() : teStudent.getExamingRecordId();
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-        Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
         AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.studentOauth + "::" + teStudent.getId());
         redisUtil.deleteUserSession(tbSession.getId());
         //循环检查该用户下其他平台是否存在session,不存在则删除用户缓存和鉴权缓存

+ 21 - 31
themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallMobileController.java

@@ -3,7 +3,6 @@ package com.qmth.themis.exam.api;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
-import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.WebsocketDto;
@@ -83,10 +82,7 @@ public class TIeInvigilateCallMobileController {
             String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
             TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.INIT, monitorKey);
             //获取考试记录缓存
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-            objectMap.put(SystemConstant.MONITOR_LIVE_URL_ + source.name(), liveUrl);
-            objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), tIeExamInvigilateCallLog.getStatus());
-            redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+            ExamRecordCacheUtil.setMonitorLiveUrl(recordId, source.name(), liveUrl);
 
             //监考监控通话信息 发送mq start
             MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
@@ -119,27 +115,25 @@ public class TIeInvigilateCallMobileController {
         }
         Long recordId = Long.parseLong(String.valueOf(mapParameter.get("recordId")));
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
         String liveUrl = null;
         MonitorVideoSourceEnum source = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId))) {
             source = MonitorVideoSourceEnum.MOBILE_FIRST;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()));
-        } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId);
+        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId))) {
             source = MonitorVideoSourceEnum.MOBILE_SECOND;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId);
         }
-        if (Objects.isNull(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name()))) {
+        if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source.name()))) {
             throw new BusinessException("推流状态为空");
         }
-        MonitorStatusSourceEnum status = MonitorStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name())));
+        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
         if (!Objects.equals(status, MonitorStatusSourceEnum.START)) {
             throw new BusinessException("推流状态不正常");
         }
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), MonitorCallStatusSourceEnum.START);
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), MonitorCallStatusSourceEnum.START);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START);
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
@@ -178,25 +172,23 @@ public class TIeInvigilateCallMobileController {
             throw new BusinessException("网络连接失败");
         }
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
         String liveUrl = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + source.name()))) {
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + source.name()));
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrl(recordId, source.name()))) {
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrl(recordId, source.name());
         }
         MonitorCallStatusSourceEnum callStatus = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_CALL_STATUS_ + source.name()))) {
-            callStatus = MonitorCallStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_CALL_STATUS_ + source.name())));
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorCallStatus(recordId, source.name()))) {
+            callStatus = ExamRecordCacheUtil.getMonitorCallStatus(recordId, source.name());
         } else {
             callStatus = MonitorCallStatusSourceEnum.STOP;
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), status);
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), callStatus);
+        ExamRecordCacheUtil.setMonitorStatus(recordId, source.name(), status);
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), callStatus);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START, monitorKey, callStatus);
         if (Objects.nonNull(mapParameter.get("type")) && !Objects.equals(mapParameter.get("type"), "")) {
             tIeExamInvigilateCallLog.setType(ExceptionEnum.valueOf(String.valueOf(mapParameter.get("type"))));
         }
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
@@ -237,24 +229,22 @@ public class TIeInvigilateCallMobileController {
         }
         Long recordId = Long.parseLong(String.valueOf(mapParameter.get("recordId")));
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
         String liveUrl = null;
         MonitorVideoSourceEnum source = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId))) {
             source = MonitorVideoSourceEnum.MOBILE_FIRST;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()));
-        } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlMobileFirst(recordId);
+        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId))) {
             source = MonitorVideoSourceEnum.MOBILE_SECOND;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlMobileSecond(recordId);
         }
-        if (Objects.isNull(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name()))) {
+        if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source.name()))) {
             throw new BusinessException("推流状态为空");
         }
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), MonitorCallStatusSourceEnum.STOP);
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), MonitorCallStatusSourceEnum.STOP);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
-        MonitorStatusSourceEnum status = MonitorStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name())));
+        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP);
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         mqDtoService.assembleSendOneWayMsg(mqDto);

+ 20 - 36
themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallOeController.java

@@ -75,10 +75,8 @@ public class TIeInvigilateCallOeController {
             String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
             TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.INIT, monitorKey);
             //获取考试记录缓存
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-            objectMap.put(SystemConstant.MONITOR_LIVE_URL_ + source.name(), liveUrl);
-            objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), tIeExamInvigilateCallLog.getStatus());
-            redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+            ExamRecordCacheUtil.setMonitorLiveUrl(recordId, source.name(), liveUrl);
+            ExamRecordCacheUtil.setMonitorStatus(recordId, source.name(), tIeExamInvigilateCallLog.getStatus());
 
             //监考监控通话信息 发送mq start
             MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
@@ -125,25 +123,15 @@ public class TIeInvigilateCallOeController {
             throw new BusinessException("异常类型不能为空");
         }
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-        String liveUrl = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + source.name()))) {
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + source.name()));
-        }
-        MonitorCallStatusSourceEnum callStatus = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_CALL_STATUS_ + source.name()))) {
-            callStatus = MonitorCallStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_CALL_STATUS_ + source.name())));
-        }else{
-            callStatus = MonitorCallStatusSourceEnum.STOP;
-        }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), status);
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), callStatus);
+        String liveUrl = Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrl(recordId, source.name())) ? ExamRecordCacheUtil.getMonitorLiveUrl(recordId, source.name()) : null;
+        MonitorCallStatusSourceEnum callStatus = Objects.nonNull(ExamRecordCacheUtil.getMonitorCallStatus(recordId, source.name())) ? ExamRecordCacheUtil.getMonitorCallStatus(recordId, source.name()) : MonitorCallStatusSourceEnum.STOP;
+        ExamRecordCacheUtil.setMonitorStatus(recordId, source.name(), status);
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), callStatus);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START, monitorKey, callStatus);
         if (Objects.nonNull(mapParameter.get("type")) && !Objects.equals(mapParameter.get("type"), "")) {
             tIeExamInvigilateCallLog.setType(ExceptionEnum.valueOf(String.valueOf(mapParameter.get("type"))));
         }
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
@@ -167,27 +155,25 @@ public class TIeInvigilateCallOeController {
         }
         Long recordId = Long.parseLong(String.valueOf(mapParameter.get("recordId")));
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
         String liveUrl = null;
         MonitorVideoSourceEnum source = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_CAMERA.name()))) {
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientCamera(recordId))) {
             source = MonitorVideoSourceEnum.CLIENT_CAMERA;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_CAMERA.name()));
-        } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()))) {
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlClientCamera(recordId);
+        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientScreen(recordId))) {
             source = MonitorVideoSourceEnum.CLIENT_SCREEN;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()));
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlClientScreen(recordId);
         }
-        if (Objects.isNull(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name()))) {
+        if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source.name()))) {
             throw new BusinessException("推流状态为空");
         }
-        MonitorStatusSourceEnum status = MonitorStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name())));
+        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
         if (!Objects.equals(status, MonitorStatusSourceEnum.START)) {
             throw new BusinessException("推流状态不正常");
         }
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), MonitorCallStatusSourceEnum.START);
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), MonitorCallStatusSourceEnum.START);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START);
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
@@ -208,24 +194,22 @@ public class TIeInvigilateCallOeController {
         }
         Long recordId = Long.parseLong(String.valueOf(mapParameter.get("recordId")));
         //获取考试记录缓存
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
         String liveUrl = null;
         MonitorVideoSourceEnum source = null;
-        if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_CAMERA.name()))) {
+        if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientCamera(recordId))) {
             source = MonitorVideoSourceEnum.CLIENT_CAMERA;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_CAMERA.name()));
-        } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()))) {
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlClientCamera(recordId);
+        } else if (Objects.nonNull(ExamRecordCacheUtil.getMonitorLiveUrlClientScreen(recordId))) {
             source = MonitorVideoSourceEnum.CLIENT_SCREEN;
-            liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()));
+            liveUrl = ExamRecordCacheUtil.getMonitorLiveUrlClientScreen(recordId);
         }
-        if (Objects.isNull(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name()))) {
+        if (Objects.isNull(ExamRecordCacheUtil.getMonitorStatus(recordId, source.name()))) {
             throw new BusinessException("推流状态为空");
         }
-        MonitorStatusSourceEnum status = MonitorStatusSourceEnum.valueOf(String.valueOf(objectMap.get(SystemConstant.MONITOR_STATUS_ + source.name())));
-        objectMap.put(SystemConstant.MONITOR_CALL_STATUS_ + source.name(), MonitorCallStatusSourceEnum.STOP);
+        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source.name());
+        ExamRecordCacheUtil.setMonitorCallStatus(recordId, source.name(), MonitorCallStatusSourceEnum.STOP);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP);
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         mqDtoService.assembleSendOneWayMsg(mqDto);

+ 2 - 1
themis-exam/src/main/java/com/qmth/themis/exam/aspect/ApiControllerAspect.java

@@ -63,7 +63,8 @@ public class ApiControllerAspect {
             log.info("============耗时============:{}秒", (end - start) / 1000);
             return proceed;
         } catch (Exception e) {
-        	log.error("请求出错",e);
+            log.error("请求出错", e);
+            e.printStackTrace();
             return ResultUtil.error(e.getMessage());
         }
     }

+ 8 - 13
themis-exam/src/main/java/com/qmth/themis/exam/listener/service/impl/MqOeLogicServiceImpl.java

@@ -2,7 +2,7 @@ package com.qmth.themis.exam.listener.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.google.gson.Gson;
-import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
@@ -100,8 +100,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
             examRecordId.forEach(s -> {
                 Long recordId = Long.parseLong(String.valueOf(s));
                 if (Objects.nonNull(webSocketMap.get(recordId))) {
-                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                    Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                    Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
                     ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                     Map map = new HashMap<>();
@@ -118,8 +117,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
             examRecordId.forEach(s -> {
                 Long recordId = Long.parseLong(String.valueOf(s));
                 if (Objects.nonNull(webSocketMap.get(recordId))) {
-                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                    Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                    Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
                     ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                     Map map = new HashMap<>();
@@ -135,8 +133,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
             examRecordId.forEach(s -> {
                 Long recordId = Long.parseLong(String.valueOf(s));
                 if (Objects.nonNull(webSocketMap.get(recordId))) {
-                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                    Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                    Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
                     ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                     Map map = new HashMap<>();
@@ -150,10 +147,9 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
         } else if (tag.contains(MqTagEnum.OE_IM_CLUSTERING.name())) {//点对点消息
             Long recordId = Long.parseLong(String.valueOf(mqDto.getBody()));
             if (Objects.nonNull(webSocketMap.get(recordId))) {
-                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-                Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
-                Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+                Long examId = ExamRecordCacheUtil.getExamId(recordId);
+                Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+                Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
                 WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                 Map<String, Object> prop = mqDto.getProperties();
                 Map map = new HashMap<>();
@@ -173,8 +169,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
         } else if (tag.contains(MqTagEnum.OE_LIVENESS_VERIFY.name())) {//监考强制活体验证
             Long recordId = Long.parseLong(String.valueOf(mqDto.getBody()));
             if (Objects.nonNull(webSocketMap.get(recordId))) {
-                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
                 ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                 WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                 Map map = new HashMap<>();

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

@@ -2,7 +2,7 @@ package com.qmth.themis.exam.websocket;
 
 import com.alibaba.fastjson.JSONObject;
 import com.google.gson.Gson;
-import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.WebsocketDto;
@@ -137,9 +137,7 @@ public class WebSocketMobileServer {
             //从set中删除
             subOnlineCount();
             //判断是否是正常退出
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-            objectMap.put(SystemConstant.MONITOR_STATUS_ + this.source.name(), MonitorStatusSourceEnum.STOP);
-            redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+            ExamRecordCacheUtil.setMonitorStatus(recordId, this.source.name(), MonitorStatusSourceEnum.STOP);
             ConcurrentHashMap<Long, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
             if (Objects.nonNull(webSocketMap.get(recordId))) {
                 WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);

+ 6 - 10
themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketOeServer.java

@@ -2,7 +2,7 @@ package com.qmth.themis.exam.websocket;
 
 import com.alibaba.fastjson.JSONObject;
 import com.google.gson.Gson;
-import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
@@ -117,12 +117,10 @@ public class WebSocketOeServer implements Concurrently {
                     this.ip = addr.toString().replace("/", "").split(":")[0];
 //                    this.sendMessage("ip[" + this.ip + "]连接成功");
                     log.info("ip[:{}]连接成功", this.ip);
-                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                    objectMap.put("clientWebsocketStatus", WebsocketStatusEnum.ON_LINE);
-                    objectMap.put("clientCurrentIp", this.ip);
-                    objectMap.put("clientWebsocketId", this.session.getId());
-                    objectMap.put("clientLastSyncTime", new Date());
-                    redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+                    ExamRecordCacheUtil.setClientWebsocketStatus(recordId, WebsocketStatusEnum.ON_LINE);
+                    ExamRecordCacheUtil.setClientCurrentIp(recordId, this.ip);
+                    ExamRecordCacheUtil.setClientWebsocketId(recordId, this.session.getId());
+                    ExamRecordCacheUtil.setClientLastSyncTime(recordId);
                     tranMap = new HashMap<>();
                     tranMap.put("recordId", this.recordId);
                     tranMap.put("deviceId", this.deviceId);
@@ -150,9 +148,7 @@ public class WebSocketOeServer implements Concurrently {
             subOnlineCount();
             //判断是否是正常退出
             Date now = new Date();
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-            objectMap.put("clientWebsocketStatus", WebsocketStatusEnum.OFF_LINE);
-            redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+            ExamRecordCacheUtil.setClientWebsocketStatus(recordId, WebsocketStatusEnum.OFF_LINE);
             //大于等于超时时间,说明规定时间内都没有通信,非正常退出,因为期间会有心跳更新updateTime
             if ((now.getTime() - this.updateTime) / 1000 >= SystemConstant.WEBSOCKET_MAX_TIME_OUT / 1000) {
                 log.info("超时退出");

+ 9 - 7
themis-exam/src/main/java/com/qmth/themis/exam/websocketTemplete/WebSocketOeMessageTemplete.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.exam.websocketTemplete;
 
 import com.alibaba.fastjson.JSONObject;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.WebsocketDto;
@@ -13,7 +14,10 @@ import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
-import java.util.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
 
 /**
  * @Description: 考生端oe websocket模版
@@ -46,8 +50,7 @@ public class WebSocketOeMessageTemplete {
         if (Objects.isNull(objectMap)) {
             throw new BusinessException(ExceptionResultEnum.RECORD_NO);
         }
-        objectMap.put("paperDownload", 0);
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+        ExamRecordCacheUtil.setPaperDownload(recordId, 0);
         return new WebsocketDto(Collections.singletonMap("success", true));
     }
 
@@ -76,10 +79,9 @@ public class WebSocketOeMessageTemplete {
         if (Objects.isNull(objectMap)) {
             throw new BusinessException(ExceptionResultEnum.RECORD_NO);
         }
-        objectMap.put("answerProgress", progress);
-        objectMap.put("durationSeconds", durationSeconds);
-        objectMap.put("clientLastSyncTime", new Date());
-        redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+        ExamRecordCacheUtil.setAnswerProgress(recordId, progress);
+        ExamRecordCacheUtil.setDurationSeconds(recordId, durationSeconds);
+        ExamRecordCacheUtil.setClientLastSyncTime(recordId);
         return this.syncAck(body);
     }
 

+ 23 - 31
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -223,17 +223,16 @@ public class MqLogicServiceImpl implements MqLogicService {
             Integer diff = 0;
             if (Objects.nonNull(clientLastSyncTime)) {//大于等于当前时间,说明未重连或重登录
                 Long l = (System.currentTimeMillis() - clientLastSyncTime.getTime()) / 1000;
-                if (l >= 2 && !Objects.equals(objectMap.get("status"), ExamRecordStatusEnum.FINISHED)) {
+                if (l >= 2 && !Objects.equals(ExamRecordCacheUtil.getStatus(recordId), ExamRecordStatusEnum.FINISHED)) {
                     diff = l.intValue();
                     //是否增加断点记录或者交卷处理统一放登录逻辑里处理,这里只更新考试记录状态为中断
-                    objectMap.put("status", ExamRecordStatusEnum.BREAK_OFF);
-                    redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF);
                 }
             }
             //增加异常日志
-            Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-            Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
-            Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+            Long examId = ExamRecordCacheUtil.getExamId(recordId);
+            Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
+            Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
             TIeInvigilateExceptionInfo tIeInvigilateExceptionInfo = new TIeInvigilateExceptionInfo(examId, examActivityId, recordId, examStudentId, ExceptionEnum.NET_TIME_OUT.getCode(), ExceptionEnum.NET_TIME_OUT, diff);
             tIeInvigilateExceptionInfoService.saveOrUpdate(tIeInvigilateExceptionInfo);
         }
@@ -400,12 +399,12 @@ public class MqLogicServiceImpl implements MqLogicService {
         String tag = mqDto.getTag();
         if (tag.contains(MqTagEnum.MONITOR_LOG.name())) {//监考日志
             TIeExamInvigilateCallLog tIeExamInvigilateCallLog = JacksonUtil.readJson(JacksonUtil.parseJson(mqDto.getBody()), TIeExamInvigilateCallLog.class);
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(tIeExamInvigilateCallLog.getExamRecordId()));
+            Long recordId = tIeExamInvigilateCallLog.getExamRecordId();
             Long examId = null, examActivityId = null, examStudentId = null;
-            if (Objects.nonNull(objectMap.get("examActivityId"))) {
-                examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
-                examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-                examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+            if (Objects.nonNull(ExamRecordCacheUtil.getExamActivityId(recordId))) {
+                examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
+                examId = ExamRecordCacheUtil.getExamId(recordId);
+                examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
             } else {
                 TOeExamRecord tOeExamRecord = examRecordService.getById(tIeExamInvigilateCallLog.getExamRecordId());
                 examActivityId = tOeExamRecord.getExamActivityId();
@@ -439,7 +438,6 @@ public class MqLogicServiceImpl implements MqLogicService {
             JSONObject jsonObject = JSONObject.parseObject(String.valueOf(mqDto.getBody()));
             ExceptionEnum exceptionEnum = ExceptionEnum.valueOf(ExceptionEnum.convertToName(String.valueOf(jsonObject.getJSONObject("reason").get("type"))));
             Long recordId = Long.parseLong(mqDto.getObjId());
-            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
             //获取最近同步时间
             Date clientLastSyncTime = ExamRecordCacheUtil.getClientLastSyncTime(recordId);
             Integer diff = 0;
@@ -448,18 +446,13 @@ public class MqLogicServiceImpl implements MqLogicService {
                 diff = l.intValue();
             }
 
-            Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+            Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
             ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
             Integer leftBreakResumeCount = Objects.isNull(ExamRecordCacheUtil.getLeftBreakResumeCount(recordId)) ? 0 : ExamRecordCacheUtil.getLeftBreakResumeCount(recordId);
             leftBreakResumeCount--;
             leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
             if (leftBreakResumeCount <= 0) {
-                Integer durationSeconds = null;
-                if (Objects.isNull(objectMap.get("durationSeconds"))) {
-                    durationSeconds = 0;
-                } else {
-                    durationSeconds = Integer.parseInt(String.valueOf(objectMap.get("durationSeconds")));
-                }
+                Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
                 teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
             } else {
                 //先查询之前的断点记录
@@ -477,26 +470,25 @@ public class MqLogicServiceImpl implements MqLogicService {
                 tOeExamBreakHistoryService.save(tOeExamBreakHistory);
                 redisUtil.setForHash(RedisKeyHelper.examBreakCacheKey(tOeExamBreakHistory.getId()), SimpleBeanUtil.objectToMap(tOeExamBreakHistory));
 
-                objectMap.put("lastBreakId", tOeExamBreakHistory.getId());
-                objectMap.put("status", ExamRecordStatusEnum.RESUME_PREPARE);
-                objectMap.put("lastBreakTime", new Date());
-                objectMap.put("leftBreakResumeCount", leftBreakResumeCount);
-                objectMap.put("lastStartTime", new Date());
-                redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+                ExamRecordCacheUtil.setLastBreakId(recordId, tOeExamBreakHistory.getId());
+                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.RESUME_PREPARE);
+                ExamRecordCacheUtil.setLastBreakTime(recordId);
+                ExamRecordCacheUtil.setLeftBreakResumeCount(recordId, leftBreakResumeCount);
+                ExamRecordCacheUtil.setLastStartTime(recordId);
                 UpdateWrapper<TOeExamRecord> tOeExamRecordUpdateWrapper = new UpdateWrapper<>();
                 tOeExamRecordUpdateWrapper.lambda().set(TOeExamRecord::getLastBreakId, tOeExamBreakHistory.getId())
                         .set(TOeExamRecord::getStatus, ExamRecordStatusEnum.RESUME_PREPARE)
-                        .set(TOeExamRecord::getLastBreakTime, objectMap.get("lastBreakTime"))
+                        .set(TOeExamRecord::getLastBreakTime, ExamRecordCacheUtil.getLastBreakTime(recordId))
                         .set(TOeExamRecord::getLeftBreakResumeCount, leftBreakResumeCount)
-                        .set(TOeExamRecord::getLastStartTime, objectMap.get("lastStartTime"))
+                        .set(TOeExamRecord::getLastStartTime, ExamRecordCacheUtil.getLastStartTime(recordId))
                         .eq(TOeExamRecord::getId, recordId);
                 examRecordService.update(tOeExamRecordUpdateWrapper);
                 teExamStudentLogService.saveStudentLogInfo(SystemOperationEnum.RESUME_PREPARE.name(), SystemOperationEnum.RESUME_PREPARE.getCode(), SystemOperationEnum.RESUME_PREPARE.getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
             }
 
             //增加异常日志
-            Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
-            Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
+            Long examId = ExamRecordCacheUtil.getExamId(recordId);
+            Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
             TIeInvigilateExceptionInfo tIeInvigilateExceptionInfo = new TIeInvigilateExceptionInfo(examId, examActivityId, recordId, examStudentId, String.valueOf(jsonObject.getJSONObject("reason").get("reason")), exceptionEnum, diff);
             tIeInvigilateExceptionInfoService.saveOrUpdate(tIeInvigilateExceptionInfo);
         } else if (tag.contains(MqTagEnum.WARNING_LOG.name())) {//考试预警日志
@@ -508,7 +500,7 @@ public class MqLogicServiceImpl implements MqLogicService {
         tmRocketMessageService.saveOrUpdate(tmRocketMessage);
         redisUtil.delete(key, mqDto.getId());
     }
-    
+
     /**
      * 重新算分
      *
@@ -522,7 +514,7 @@ public class MqLogicServiceImpl implements MqLogicService {
         Map<String, Object> param = (Map<String, Object>) mqDto.getBody();
         Long examId = (Long) param.get("examId");
         Long taskId = (Long) param.get("taskId");
-        teExamService.calculateScore(examId,taskId);
+        teExamService.calculateScore(examId, taskId);
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
         tmRocketMessage.setBody(JacksonUtil.parseJson(tmRocketMessage.getBody()));

+ 11 - 4
themis-task/src/main/java/com/qmth/themis/task/quartz/service/impl/QuartzLogicServiceImpl.java

@@ -1,12 +1,15 @@
 package com.qmth.themis.task.quartz.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.entity.TEExamActivity;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.FinishTypeEnum;
 import com.qmth.themis.business.service.TEExamActivityService;
 import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.task.quartz.service.QuartzLogicService;
 import org.slf4j.Logger;
@@ -38,6 +41,9 @@ public class QuartzLogicServiceImpl implements QuartzLogicService {
     @Resource
     RedisUtil redisUtil;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     /**
      * 考试场次quartz逻辑
      *
@@ -58,11 +64,12 @@ public class QuartzLogicServiceImpl implements QuartzLogicService {
                     ExamRecordStatusEnum examRecordStatusEnum = (ExamRecordStatusEnum) v;
                     //获取该考试批次下所有未交卷的考生的考试记录
                     if (Objects.nonNull(examRecordStatusEnum) && !Objects.equals(ExamRecordStatusEnum.FINISHED, examRecordStatusEnum)) {
-                        Map<String, Object> recordObjectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(Long.parseLong(k)));
-                        Integer durationSeconds = Integer.parseInt(String.valueOf(recordObjectMap.get("durationSeconds")));
-                        Long studentId = Long.parseLong(String.valueOf(recordObjectMap.get("studentId")));
+                        Long recordId = Long.parseLong(k);
+                        Integer durationSeconds = ExamRecordCacheUtil.getDurationSeconds(recordId);
+                        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+                        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                         //交卷
-                        teExamService.finish(studentId, Long.parseLong(k), FinishTypeEnum.AUTO.name(), durationSeconds);
+                        teExamService.finish(examStudentCacheBean.getStudentId(), Long.parseLong(k), FinishTypeEnum.AUTO.name(), durationSeconds);
                     }
                 });
             }