Преглед изворни кода

Merge branch 'dev' into release
1

wangliang пре 4 година
родитељ
комит
c9c9e6c2b4

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

@@ -346,7 +346,7 @@ public class TIeInvigilateController {
     @ApiOperation(value = "进度查询列表导出接口")
     @RequestMapping(value = "/progress/list/export", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "监考进度信息", response = InvigilateListProgressBean.class)})
-    public Result progressListExport(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
+    public void progressListExport(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
                                      @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long examActivityId,
                                      @ApiParam(value = "虚拟考场代码", required = false) @RequestParam(required = false) String roomCode,
                                      @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
@@ -360,9 +360,8 @@ public class TIeInvigilateController {
         if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
             userId = tbUser.getId();
         }
-        List<InvigilateListProgressBean> invigilateListProgressBeanList = tOeExamRecordService.invigilatePageProgressListExport(examId, examActivityId, roomCode, courseCode, name, identity, userId);
-        ExportUtils.exportEXCEL("进度信息", InvigilateListProgressBean.class, invigilateListProgressBeanList, response);
-        return ResultUtil.ok(Collections.singletonMap("success", true));
+        List<InvigilateListProgressExcelBean> invigilateListProgressExcelBeanList = tOeExamRecordService.invigilatePageProgressListExport(examId, examActivityId, roomCode, courseCode, name, identity, userId);
+        ExportUtils.exportEXCEL("进度信息", InvigilateListProgressExcelBean.class, invigilateListProgressExcelBeanList, response);
     }
 
     @ApiOperation(value = "违纪处理接口")

+ 125 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListProgressExcelBean.java

@@ -0,0 +1,125 @@
+package com.qmth.themis.business.bean.backend;
+
+import com.qmth.themis.business.excel.ExcelProperty;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 进度查询返回对象
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/8/22
+ */
+@ApiModel("进度查询返回对象")
+public class InvigilateListProgressExcelBean implements Serializable {
+
+    @ExcelProperty(name = "批次名称(代码)", width = 30, index = 1)
+    private String examName;
+
+    @ApiModelProperty(name = "考试场次")
+    @ExcelProperty(name = "场次名称(代码)", width = 30, index = 2)
+    private String examActivityCode;
+
+    @ApiModelProperty(name = "证件号")
+    @ExcelProperty(name = "证件号", width = 30, index = 4)
+    private String identity;
+
+    @ApiModelProperty(name = "虚拟考场名称")
+    @ExcelProperty(name = "考场名称(代码)", width = 30, index = 3)
+    private String roomName;
+
+    @ApiModelProperty(name = "姓名")
+    @ExcelProperty(name = "姓名", width = 30, index = 5)
+    private String name;
+
+    @ApiModelProperty(name = "考生状态")
+    @ExcelProperty(name = "完成状态", width = 30, index = 9)
+    private String status;
+
+    @ApiModelProperty(name = "联系电话")
+    @ExcelProperty(name = "联系电话", width = 30, index = 6)
+    private String mobileNumber;
+
+    @ApiModelProperty(name = "科目名称")
+    @ExcelProperty(name = "科目(代码)", width = 30, index = 7)
+    private String courseName;
+
+    @ApiModelProperty(value = "剩余考试次数")
+    @ExcelProperty(name = "剩余考试次数", width = 30, index = 8)
+    private Integer leftExamCount;
+
+    public String getRoomName() {
+        return roomName;
+    }
+
+    public void setRoomName(String roomName) {
+        this.roomName = roomName;
+    }
+
+    public String getExamName() {
+        return examName;
+    }
+
+    public void setExamName(String examName) {
+        this.examName = examName;
+    }
+
+    public String getExamActivityCode() {
+        return examActivityCode;
+    }
+
+    public void setExamActivityCode(String examActivityCode) {
+        this.examActivityCode = examActivityCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getIdentity() {
+        return identity;
+    }
+
+    public void setIdentity(String identity) {
+        this.identity = identity;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getMobileNumber() {
+        return mobileNumber;
+    }
+
+    public void setMobileNumber(String mobileNumber) {
+        this.mobileNumber = mobileNumber;
+    }
+
+    public Integer getLeftExamCount() {
+        return leftExamCount;
+    }
+
+    public void setLeftExamCount(Integer leftExamCount) {
+        this.leftExamCount = leftExamCount;
+    }
+}

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java

@@ -220,7 +220,7 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      * @param userId
      * @return
      */
-    public List<InvigilateListProgressBean> invigilatePageProgressListExport(@Param("examId") Long examId,
+    public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(@Param("examId") Long examId,
                                                                          @Param("examActivityId") Long examActivityId,
                                                                          @Param("roomCode") String roomCode,
                                                                          @Param("courseCode") String courseCode,

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

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

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

@@ -282,7 +282,7 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      * @param userId
      * @return
      */
-    public List<InvigilateListProgressBean> invigilatePageProgressListExport(Long examId,
+    public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(Long examId,
                                                                         Long examActivityId,
                                                                         String roomCode,
                                                                         String courseCode,

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

@@ -612,7 +612,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      * @return
      */
     @Override
-    public List<InvigilateListProgressBean> invigilatePageProgressListExport(Long examId, Long examActivityId, String roomCode, String courseCode, String name, String identity, Long userId) {
+    public List<InvigilateListProgressExcelBean> invigilatePageProgressListExport(Long examId, Long examActivityId, String roomCode, String courseCode, String name, String identity, Long userId) {
         return tOeExamRecordMapper.invigilatePageProgressListExport(examId, examActivityId, roomCode, courseCode, name, identity, userId);
     }
 

+ 10 - 6
themis-business/src/main/resources/mapper/TOeExamRecordMapper.xml

@@ -366,13 +366,15 @@
 		(tee.exam_count - tees.already_exam_count) as leftExamCount,
 		if((select count(1) from t_oe_exam_record toer where toer.exam_student_id =
 		tees.id and (toer.status = 'FINISHED' or toer.status = 'PERSISTED') >
-		0),'已完成','未完成') as status
+		0),'已完成','未完成') as status,
+		tes.mobile_number as mobileNumber
 		from
 		t_e_exam_student tees
 		left join t_e_exam tee on
 		tee.id = tees.exam_id
 		left join t_e_exam_activity teea on
 		teea.id = tees.exam_activity_id
+		left join t_e_student tes on tees.student_id = tes.id
 		inner join (select distinct tbeiu.room_code from t_b_exam_invigilate_user
 		tbeiu
 		<if test="userId != null and userId != ''">
@@ -405,28 +407,29 @@
 		order by tees.room_code
 	</select>
 
-	<select id="invigilatePageProgressListExport" resultType="com.qmth.themis.business.bean.backend.InvigilateListProgressBean">
+	<select id="invigilatePageProgressListExport" resultType="com.qmth.themis.business.bean.backend.InvigilateListProgressExcelBean">
 		select
 		distinct tee.id as examId,
 		tee.name as examName,
 		teea.id as examActivityId,
 		teea.code as examActivityCode,
 		tees.room_code as roomCode,
-		tees.room_name as roomName,
+		group_concat(tees.room_name,CONCAT(CONCAT('(',tees.room_code),')')) as roomName,
 		tees.`identity`,
 		tees.name,
-		tees.course_code as courseCode,
-		tees.course_name as courseName,
+		group_concat(tees.course_name,CONCAT(CONCAT('(',tees.course_code),')')) as courseName,
 		(tee.exam_count - tees.already_exam_count) as leftExamCount,
 		if((select count(1) from t_oe_exam_record toer where toer.exam_student_id =
 		tees.id and (toer.status = 'FINISHED' or toer.status = 'PERSISTED') >
-		0),'已完成','未完成') as status
+		0),'已完成','未完成') as status,
+		tes.mobile_number as mobileNumber
 		from
 		t_e_exam_student tees
 		left join t_e_exam tee on
 		tee.id = tees.exam_id
 		left join t_e_exam_activity teea on
 		teea.id = tees.exam_activity_id
+		left join t_e_student tes on tees.student_id = tes.id
 		inner join (select distinct tbeiu.room_code from t_b_exam_invigilate_user
 		tbeiu
 		<if test="userId != null and userId != ''">
@@ -456,6 +459,7 @@
 			and teea.enable = 1
 			and tees.enable = 1
 		</where>
+		group by tee.id,tees.room_code,tee.name,teea.id,teea.code,tees.`identity`,tees.name,leftExamCount,status,tes.mobile_number
 		order by tees.room_code
 	</select>
 

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

@@ -143,8 +143,8 @@ public class TEExamController {
                 teExamService.sendOeLogMessage(SystemOperationEnum.ANSWERING, ExamRecordCacheUtil.getExamStudentId(param.getRecordId()), param.getRecordId(), mqDto);
                 //mq发送消息end
             }
-            ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
-            if (Objects.nonNull(webSocketMap.get(param.getRecordId()))) {
+            ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
+            if (Objects.nonNull(webSocketMap.get(param.getRecordId() + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
                 WebSocketMobileServer webSocketMobileServer = webSocketMap.get(param.getRecordId());
                 Map map = new HashMap<>();
                 map.put(SystemConstant.RECORD_ID, param.getRecordId());
@@ -267,7 +267,7 @@ public class TEExamController {
                 throw new BusinessException("总用时秒数不能为空");
             }
             Result re = ResultUtil.ok(teExamService.finish(teStudent.getId(), param.getRecordId(), param.getType(), param.getDurationSeconds()));
-            ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
+            ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
             if (Objects.nonNull(webSocketMap.get(param.getRecordId()))) {
                 WebSocketMobileServer webSocketMobileServer = webSocketMap.get(param.getRecordId());
                 Map map = new HashMap<>();

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

@@ -249,7 +249,7 @@ public class TEStudentController {
                             alreadyBreakCount++;
                             Long breakId = Constants.idGen.next();
                             ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
-                            ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.RESUME_PREPARE, false);
+                            ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
                             Date lastBreakTimeNow = new Date();
                             ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
                             ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);

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

@@ -74,8 +74,8 @@ public class TIeInvigilateCallMobileController {
             if (Objects.isNull(mapParameter.get("liveUrl")) || Objects.equals(mapParameter.get("liveUrl"), "")) {
                 throw new BusinessException("观看地址不能为空");
             }
-            ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
-            if (Objects.isNull(webSocketMap.get(recordId))) {
+            ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
+            if (Objects.isNull(webSocketMap.get(recordId + source.name()))) {
                 throw new BusinessException("网络连接失败");
             }
             String liveUrl = String.valueOf(mapParameter.get("liveUrl"));
@@ -167,8 +167,8 @@ public class TIeInvigilateCallMobileController {
         if (Objects.equals(status, MonitorStatusSourceEnum.STOP.name()) && (Objects.isNull(mapParameter.get("type")) || Objects.equals(mapParameter.get("type"), ""))) {
             throw new BusinessException("异常类型不能为空");
         }
-        ConcurrentHashMap<Long, WebSocketMobileServer> mobileWebSocketMap = WebSocketMobileServer.getWebSocketMap();
-        if (Objects.isNull(mobileWebSocketMap.get(recordId))) {
+        ConcurrentHashMap<String, WebSocketMobileServer> mobileWebSocketMap = WebSocketMobileServer.getWebSocketMap();
+        if (Objects.isNull(mobileWebSocketMap.get(recordId + source.name()))) {
             throw new BusinessException("网络连接失败");
         }
         //获取考试记录缓存

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

@@ -206,9 +206,9 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
     @Override
     public void execMqOeMobileLogic(MqDto mqDto, String key) {
         Gson gson = new Gson();
-        ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
+        ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
         String tag = mqDto.getTag();
-        if (Objects.equals(MqTagEnum.EXAM_STOP.name(), tag)) {//考试暂停
+        if (Objects.equals(MqTagEnum.EXAM_STOP.name(), tag)) {//考试退出
             Long recordId = Long.parseLong(String.valueOf(mqDto.getBody()));
             if (Objects.nonNull(webSocketMap.get(recordId))) {
                 WebSocketMobileServer webSocketMobileServer = webSocketMap.get(recordId);

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

@@ -51,7 +51,7 @@ import java.util.concurrent.ConcurrentHashMap;
 @Component
 public class WebSocketMobileServer implements Concurrently {
     private final static Logger log = LoggerFactory.getLogger(WebSocketMobileServer.class);
-    private volatile static ConcurrentHashMap<Long, WebSocketMobileServer> webSocketMap = new ConcurrentHashMap<>();
+    private volatile static ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = new ConcurrentHashMap<>();
     /**
      * 与某个客户端的连接会话,需要通过它来给客户端发送数据
      */
@@ -103,12 +103,12 @@ public class WebSocketMobileServer implements Concurrently {
                     this.session = session;
                     session.setMaxIdleTimeout(SystemConstant.WEBSOCKET_MAX_TIME_OUT);
                     this.sessionId = tbSession.getId();
-                    if (webSocketMap.containsKey(this.recordId)) {
-                        webSocketMap.remove(this.recordId);
-                        webSocketMap.put(this.recordId, this);
+                    if (webSocketMap.containsKey(this.recordId + this.source.name())) {
+                        webSocketMap.remove(this.recordId + this.source.name());
+                        webSocketMap.put(this.recordId + this.source.name(), this);
                         //加入set中
                     } else {
-                        webSocketMap.put(this.recordId, this);
+                        webSocketMap.put(this.recordId + this.source.name(), this);
                         //加入set中
                         addOnlineCount();
                         //在线数加1
@@ -139,15 +139,15 @@ public class WebSocketMobileServer implements Concurrently {
     @OnClose
     public void onClose() {
         log.info("onClose is come in");
-        if (webSocketMap.containsKey(this.recordId)) {
-            webSocketMap.remove(this.recordId);
+        if (webSocketMap.containsKey(this.recordId + this.source.name())) {
+            webSocketMap.remove(this.recordId + this.source.name());
             //从set中删除
             subOnlineCount();
             //判断是否是正常退出
             ExamRecordCacheUtil.setMonitorStatus(recordId, this.source.name(), MonitorStatusSourceEnum.STOP, true);
             ConcurrentHashMap<Long, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
-            if (Objects.nonNull(webSocketMap.get(recordId))) {
-                WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
+            if (Objects.nonNull(webSocketMap.get(recordId + this.source.name()))) {
+                WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId + this.source.name());
                 Map map = new HashMap<>();
                 map.put(SystemConstant.RECORD_ID, recordId);
                 map.put("monitorVideoSource", this.source.name());
@@ -253,7 +253,7 @@ public class WebSocketMobileServer implements Concurrently {
         }
     }
 
-    public static ConcurrentHashMap<Long, WebSocketMobileServer> getWebSocketMap() {
+    public static ConcurrentHashMap<String, WebSocketMobileServer> getWebSocketMap() {
         return webSocketMap;
     }
 

+ 37 - 0
themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketOeServer.java

@@ -3,6 +3,8 @@ package com.qmth.themis.exam.websocket;
 import com.alibaba.fastjson.JSONObject;
 import com.google.gson.Gson;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
+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;
@@ -10,6 +12,8 @@ import com.qmth.themis.business.dto.WebsocketDto;
 import com.qmth.themis.business.entity.TBSession;
 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.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
@@ -171,6 +175,39 @@ public class WebSocketOeServer implements Concurrently {
                 MqDto mqDto = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.OE_UN_NORMAL.name(), MqTagEnum.OE_UN_NORMAL, MqTagEnum.OE_UN_NORMAL, String.valueOf(this.recordId), this.tranMap, this.sessionId);
                 mqDtoService.assembleSendAsyncDelayMsg(mqDto);
                 //发送延时mq消息end
+            } else {
+                Long ecExamId = 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(ecExamId);//考试缓存
+
+                Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
+                Integer alreadyBreakCount = ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
+                Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
+                leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
+                if (leftBreakResumeCount <= 0) {
+                    teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
+                } else {
+                    Long breakId = Constants.idGen.next();
+                    ExamRecordCacheUtil.setLastBreakId(recordId, breakId, false);
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, false);
+                    Date lastBreakTimeNow = new Date();
+                    ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTimeNow, false);
+                    ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
+                    Date lastStartTime = new Date();
+                    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.RESUME_PREPARE, 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.EXIT, MqTagEnum.EXAM_BREAK, String.valueOf(recordId), String.valueOf(recordId));
+                    MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
+                    mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
+                    //考试断点异常原因 发送mq end
+                }
             }
         }
         log.info("用户退出:{},当前在线人数为:{},updateTime:{}", this.sessionId, getOnlineCount(), this.updateTime);

+ 52 - 50
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -231,59 +231,61 @@ public class MqLogicServiceImpl implements MqLogicService {
         Map<String, Object> tranMap = mqDto.getProperties();
         Long recordId = Long.parseLong(String.valueOf(tranMap.get("recordId")));
         Date clientLastSyncTime = ExamRecordCacheUtil.getClientLastSyncTime(recordId);
-        Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-        if (Objects.nonNull(objectMap)) {
-            Integer diff = 0;
-            if (Objects.nonNull(clientLastSyncTime)) {//大于等于当前时间,说明未重连或重登录
-                Long l = (System.currentTimeMillis() - clientLastSyncTime.getTime()) / 1000;
-                if (l >= 2 && !Objects.equals(ExamRecordCacheUtil.getStatus(recordId), ExamRecordStatusEnum.FINISHED)) {
-                    diff = l.intValue();
-                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, true);
+        ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(recordId);
+        if (!Objects.equals(status, ExamRecordStatusEnum.BREAK_OFF) || !Objects.equals(status, ExamRecordStatusEnum.FINISHED)|| !Objects.equals(status, ExamRecordStatusEnum.PERSISTED)) {
+            Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+            if (Objects.nonNull(objectMap)) {
+                Integer diff = 0;
+                if (Objects.nonNull(clientLastSyncTime)) {//大于等于当前时间,说明未重连或重登录
+                    Long l = (System.currentTimeMillis() - clientLastSyncTime.getTime()) / 1000;
+                    if (l >= 2 && !Objects.equals(ExamRecordCacheUtil.getStatus(recordId), ExamRecordStatusEnum.FINISHED)) {
+                        diff = l.intValue();
+                        ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.BREAK_OFF, true);
+                    }
                 }
-            }
-            ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(recordId);
-            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;
-            if (!Objects.equals(status, ExamRecordStatusEnum.FIRST_PREPARE)) {
-                //增加断点记录,获取剩余断点次数
-                Integer alreadyBreakCount = ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-                Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
-                leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
-                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);
-                    Date lastBreakTime = new Date();
-                    ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTime, false);
-                    ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
-                    Date lastStartTime = new Date();
-                    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
+                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;
+                if (!Objects.equals(status, ExamRecordStatusEnum.FIRST_PREPARE)) {
+                    //增加断点记录,获取剩余断点次数
+                    Integer alreadyBreakCount = ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
+                    Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
+                    leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
+                    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);
+                        Date lastBreakTime = new Date();
+                        ExamRecordCacheUtil.setLastBreakTime(recordId, lastBreakTime, false);
+                        ExamRecordCacheUtil.setAlreadyBreakCount(recordId, alreadyBreakCount, false);
+                        Date lastStartTime = new Date();
+                        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
+                    }
+                    //增加异常日志
+                    TIeInvigilateExceptionInfo tIeInvigilateExceptionInfo = new TIeInvigilateExceptionInfo(examId, examActivityId, recordId, examStudentId, ExceptionEnum.NET_TIME_OUT.getCode(), ExceptionEnum.NET_TIME_OUT, diff);
+                    tIeInvigilateExceptionInfoService.saveOrUpdate(tIeInvigilateExceptionInfo);
+                    TEExamStudentLog teExamStudentLog = new TEExamStudentLog(SystemOperationEnum.BREAK_OFF.name(), SystemOperationEnum.BREAK_OFF.getCode(), SystemOperationEnum.BREAK_OFF.getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId, breakId);
+                    teExamStudentLogService.save(teExamStudentLog);
                 }
-                //增加异常日志
-                TIeInvigilateExceptionInfo tIeInvigilateExceptionInfo = new TIeInvigilateExceptionInfo(examId, examActivityId, recordId, examStudentId, ExceptionEnum.NET_TIME_OUT.getCode(), ExceptionEnum.NET_TIME_OUT, diff);
-                tIeInvigilateExceptionInfoService.saveOrUpdate(tIeInvigilateExceptionInfo);
-                TEExamStudentLog teExamStudentLog = new TEExamStudentLog(SystemOperationEnum.BREAK_OFF.name(), SystemOperationEnum.BREAK_OFF.getCode(), SystemOperationEnum.BREAK_OFF.getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId, breakId);
-                teExamStudentLogService.save(teExamStudentLog);
+                //发送移动端监考退出考试mq消息 start
+                MqDto mqDtoExamStop = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_STOP.name(), recordId, MqTagEnum.EXAM_STOP, String.valueOf(recordId), String.valueOf(recordId));
+                mqDtoService.assembleSendOneWayMsg(mqDtoExamStop);
+                //发送移动端监考退出考试mq消息 end
             }
-            //发送移动端监考退出考试mq消息 start
-            MqDto mqDtoExamStop = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_STOP.name(), recordId, MqTagEnum.EXAM_STOP, String.valueOf(recordId), String.valueOf(recordId));
-            mqDtoService.assembleSendOneWayMsg(mqDtoExamStop);
-            //发送移动端监考退出考试mq消息 end
         }
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
         tmRocketMessage.setBody(JacksonUtil.parseJson(tmRocketMessage.getBody()));