Browse Source

Merge branch 'dev'
1

wangliang 4 years ago
parent
commit
a6dc9d504e

+ 2 - 0
themis-business/src/main/resources/db/init.sql

@@ -520,6 +520,7 @@ INSERT INTO `t_b_privilege` VALUES (153, '报表-考情监控-预警时间趋势
 INSERT INTO `t_b_privilege` VALUES (154, '实时监控台视频随机列表', '/api/admin/invigilate/list/video/random', 'LINK', 60, 39, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (154, '实时监控台视频随机列表', '/api/admin/invigilate/list/video/random', 'LINK', 60, 39, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (155, '进度查询列表导出', '/api/admin/invigilate/progress/list/export', 'LINK', 60, 40, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (155, '进度查询列表导出', '/api/admin/invigilate/progress/list/export', 'LINK', 60, 40, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (156, '报表-考情监控-预警时间趋势', '/api/admin/report/examination_monitor/warn_msg', 'LINK', 60, 41, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (156, '报表-考情监控-预警时间趋势', '/api/admin/report/examination_monitor/warn_msg', 'LINK', 60, 41, NULL, '2020-08-01 13:08:31');
+INSERT INTO `t_b_privilege` VALUES (157, '候考/答题状态退出', '/api/oe/exam/exit', 'LINK', 60, 42, NULL, '2020-08-01 13:08:31');
 COMMIT;
 COMMIT;
 
 
 -- ----------------------------
 -- ----------------------------
@@ -748,6 +749,7 @@ INSERT INTO `t_b_role_privilege` VALUES (190, 'ADMIN', 155);
 INSERT INTO `t_b_role_privilege` VALUES (191, 'INVIGILATE', 155);
 INSERT INTO `t_b_role_privilege` VALUES (191, 'INVIGILATE', 155);
 INSERT INTO `t_b_role_privilege` VALUES (192, 'ADMIN', 156);
 INSERT INTO `t_b_role_privilege` VALUES (192, 'ADMIN', 156);
 INSERT INTO `t_b_role_privilege` VALUES (193, 'INSPECTION', 156);
 INSERT INTO `t_b_role_privilege` VALUES (193, 'INSPECTION', 156);
+INSERT INTO `t_b_role_privilege` VALUES (194, 'STUDENT', 157);
 COMMIT;
 COMMIT;
 
 
 -- ----------------------------
 -- ----------------------------

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

@@ -13,10 +13,7 @@ import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamResultDto;
 import com.qmth.themis.business.dto.response.TEExamResultDto;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEExam;
-import com.qmth.themis.business.enums.ExceptionEnum;
-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.enums.*;
 import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TEExamService;
 import com.qmth.themis.business.service.TEExamService;
 import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.service.TEExamStudentService;
@@ -33,10 +30,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartFile;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 
 @Api(tags = "考试Controller")
 @Api(tags = "考试Controller")
 @RestController
 @RestController
@@ -110,6 +104,27 @@ public class TEExamController {
         }
         }
     }
     }
 
 
+    @ApiOperation(value = "候考/答题状态退出")
+    @RequestMapping(value = "/exit", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    public Result exit(@ApiJsonObject(name = "saveInvigilateUser", value = {
+            @ApiJsonProperty(key = "recordId", type = "long", example = "1", description = "考试记录id", required = true)
+    }) @ApiParam(value = "考试记录id", required = true) @RequestBody Map<String, Object> mapParameter) {
+        if (Objects.isNull(mapParameter.get("recordId")) || Objects.equals(mapParameter.get("recordId"), "")) {
+            throw new BusinessException(ExceptionResultEnum.RECORD_ID_IS_NULL);
+        }
+        Long recordId = (Long) mapParameter.get("recordId");
+        ExamRecordStatusEnum status = ExamRecordCacheUtil.getStatus(recordId);
+        if (Objects.nonNull(status) && Objects.equals(ExamRecordStatusEnum.ANSWERING, status)) {//答题状态,强制断点
+            ExamConstant.sendExamBreakMsg(recordId);
+        } else if (Objects.nonNull(status) && Objects.equals(ExamRecordStatusEnum.FIRST_PREPARE, status)) {
+            ExamConstant.sendExamStopMsg(recordId, false);
+        } else {
+            throw new BusinessException("考试状态出错");
+        }
+        return ResultUtil.ok(Collections.singletonMap("success", true));
+    }
+
     @ApiOperation(value = "开始考试")
     @ApiOperation(value = "开始考试")
     @RequestMapping(value = "/start", method = RequestMethod.POST)
     @RequestMapping(value = "/start", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})
     @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})

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

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

+ 1 - 35
themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketOeServer.java

@@ -176,41 +176,7 @@ public class WebSocketOeServer implements Concurrently {
                     //发送延时mq消息end
                     //发送延时mq消息end
                 } else {
                 } else {
                     log.info("正常退出");
                     log.info("正常退出");
-                    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 = Objects.isNull(ExamRecordCacheUtil.getAlreadyBreakCount(recordId)) ? 0 : ExamRecordCacheUtil.getAlreadyBreakCount(recordId);
-                    Integer leftBreakResumeCount = ec.getBreakResumeCount() - alreadyBreakCount;
-                    if (leftBreakResumeCount < 0) {
-                        teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-                    } else {
-                        alreadyBreakCount++;
-                        Long breakId = Constants.idGen.next();
-                        ExamRecordCacheUtil.setLastBreakId(this.recordId, breakId, false);
-                        ExamRecordCacheUtil.setStatus(this.recordId, ExamRecordStatusEnum.BREAK_OFF, false);
-                        Date lastBreakTimeNow = new Date();
-                        ExamRecordCacheUtil.setLastBreakTime(this.recordId, lastBreakTimeNow, false);
-                        ExamRecordCacheUtil.setAlreadyBreakCount(this.recordId, alreadyBreakCount, false);
-                        Date lastStartTime = new Date();
-                        ExamRecordCacheUtil.setLastStartTime(this.recordId, lastStartTime, false);
-                        String[] columns = new String[]{ExamRecordFieldEnum.last_break_id.name(), ExamRecordFieldEnum.status.name(), ExamRecordFieldEnum.last_break_time.name(), ExamRecordFieldEnum.already_break_count.name(), ExamRecordFieldEnum.last_start_time.name()};
-                        Object[] values = new Object[]{breakId, ExamRecordStatusEnum.BREAK_OFF, lastBreakTimeNow, alreadyBreakCount, lastStartTime};
-                        TOeExamRecordService tOeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
-                        tOeExamRecordService.dataUpdatesMq(this.recordId, columns, values);
-                        ExamConstant.sendExamStopMsg(this.recordId, true);
-                        //考试断点异常原因 发送mq start
-                        MqDto mqDtoBreak = new MqDto(MqTopicEnum.THEMIS_TOPIC.getCode(), MqTagEnum.EXAM_BREAK.name(), ExceptionEnum.EXIT, MqTagEnum.EXAM_BREAK, String.valueOf(this.recordId), String.valueOf(this.recordId));
-                        MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
-                        mqDtoService.assembleSendOneWayMsg(mqDtoBreak);
-                        //考试断点异常原因 发送mq end
-                        //更新场次-考试记录缓存
-                        ExamActivityRecordCacheUtil.setExamRecordStatus(examStudentCacheBean.getExamActivityId(), recordId, ExamRecordCacheUtil.getStatus(recordId));
-                    }
+                    ExamConstant.sendExamBreakMsg(this.recordId);
                 }
                 }
             }
             }
         }
         }