wangliang пре 3 година
родитељ
комит
d24d32c0b9

+ 1 - 0
themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamStudentController.java

@@ -218,6 +218,7 @@ public class TEExamStudentController {
                 if (Objects.isNull(teStudent)) {//如果学生数据为空则插入学生数据
                     //先插入学生档案数据
                     teStudent = new TEStudent(tbOrg.getId(), s.getIdentity(), s.getName(), tbUser.getId());
+                    teStudent.setPassword(SystemConstant.DEFAULT_PASSWORD);
                     teStudentService.save(teStudent);
                     s.setStudentId(teStudent.getId());
                     s.setCreateId(tbUser.getId());

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

@@ -15,6 +15,7 @@ import com.qmth.themis.business.enums.ScoreStatusEnum;
 import com.qmth.themis.business.enums.SystemOperationEnum;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.security.NoSuchAlgorithmException;
 import java.util.List;
 import java.util.Map;
 

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

@@ -49,6 +49,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigDecimal;
+import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.regex.Matcher;

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

@@ -29,7 +29,6 @@ import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
 import com.qmth.themis.exam.config.ExamConstant;
-import com.qmth.themis.exam.websocket.WebSocketOeServer;
 import io.swagger.annotations.*;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -38,7 +37,6 @@ import javax.annotation.Resource;
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
 
 @Api(tags = "考试Controller")
 @RestController
@@ -143,12 +141,7 @@ public class TEExamController {
                 throw new BusinessException(ExceptionResultEnum.EXAM_STATUS_ERROR);
             }
         }
-        ConcurrentHashMap<String, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
-        String clientWebsocketId = ExamRecordCacheUtil.getClientWebsocketId(Long.parseLong(recordId));
-        if (Objects.nonNull(clientWebsocketId)) {
-            WebSocketOeServer webSocketOeServer = webSocketMap.get(clientWebsocketId);
-            WebSocketOeServer.close(webSocketOeServer);
-        }
+        ExamConstant.clientWebsocketClose(Long.parseLong(recordId));
 
         Long examStudentId = ExamRecordCacheUtil.getExamStudentId(Long.parseLong(recordId));
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
@@ -309,7 +302,7 @@ public class TEExamController {
     @ApiOperation(value = "结束考试")
     @RequestMapping(value = "/finish", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "试卷信息")})
-    public Result finish(@RequestBody FinishParamBean param) {
+    public Result finish(@RequestBody FinishParamBean param) throws IOException, NoSuchAlgorithmException {
         TEStudentCacheDto teStudent = (TEStudentCacheDto) ServletUtil.getRequestStudentAccount();
         String lockKey = SystemConstant.REDIS_LOCK_STUDENT_PREFIX + teStudent.getId();
         Boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_CACHE_TIME_OUT);
@@ -326,7 +319,13 @@ public class TEExamController {
             if (param.getDurationSeconds() == null) {
                 throw new BusinessException("总用时秒数不能为空");
             }
-            return ResultUtil.ok(teExamService.finish(teStudent.getId(), param.getRecordId(), param.getType(), param.getDurationSeconds()));
+            ExamFinishBean examFinishBean = teExamService.finish(teStudent.getId(), param.getRecordId(), param.getType(), param.getDurationSeconds());
+            SystemConstant.clientMonitorStatusStop(param.getRecordId());
+            ExamConstant.clientWebsocketClose(param.getRecordId());
+
+            SystemConstant.mobileMonitorStatusStop(teStudent.getId(), param.getRecordId(), false);
+            ExamConstant.mobileWebsocketClose(param.getRecordId());
+            return ResultUtil.ok(examFinishBean);
         } finally {
             redisUtil.releaseLock(lockKey);
         }

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

@@ -46,6 +46,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import java.io.File;
+import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
 import java.util.*;
 
@@ -108,7 +109,7 @@ public class TEStudentController {
                     @ApiJsonProperty(key = "password", description = "密码"),
                     @ApiJsonProperty(key = "orgId", type = "long", example = "1", description = "机构id"),
                     @ApiJsonProperty(key = "examId", type = "long", example = "1", description = "批次id")}) @ApiParam(value = "学生信息", required = true) @RequestBody Map<String, Object> mapParameter)
-            throws NoSuchAlgorithmException {
+            throws NoSuchAlgorithmException, IOException {
         if (Objects.isNull(mapParameter)) {
             throw new BusinessException(ExceptionResultEnum.STUDENT_IS_NULL);
         }
@@ -183,7 +184,7 @@ public class TEStudentController {
      * @return
      * @throws NoSuchAlgorithmException
      */
-    private Result userLoginCommon(TEStudent teStudent, Long examId, Long orgId) throws NoSuchAlgorithmException {
+    private Result userLoginCommon(TEStudent teStudent, Long examId, Long orgId) throws NoSuchAlgorithmException, IOException {
         //停用
         if (teStudent.getEnable().intValue() == 0) {
             throw new BusinessException(ExceptionResultEnum.STUDENT_ENABLE);

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

@@ -3,11 +3,13 @@ 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.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.entity.TIeExamInvigilateCallLog;
 import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.MqDtoService;
+import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.MqUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
@@ -15,6 +17,7 @@ import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
 import com.qmth.themis.exam.config.DictionaryConfig;
+import com.qmth.themis.exam.config.ExamConstant;
 import io.swagger.annotations.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -25,10 +28,9 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
 
 /**
  * @Description: mobile监考监控通话信息 前端控制器
@@ -55,6 +57,9 @@ public class TIeInvigilateCallMobileController {
     @Resource
     TOeExamRecordService tOeExamRecordService;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
 //    @Deprecated
 //    @ApiOperation(value = "监控观看地址更新接口")
 //    @RequestMapping(value = "/live_url", method = RequestMethod.POST)
@@ -155,7 +160,7 @@ public class TIeInvigilateCallMobileController {
             @ApiJsonProperty(key = "source", description = "监考视频源", required = true),
             @ApiJsonProperty(key = "status", description = "当前状态", required = true),
             @ApiJsonProperty(key = "type", description = "异常类型,status=stop时需要传递")
-    }) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) {
+    }) @ApiParam(value = "监控信息", required = true) @RequestBody Map<String, Object> mapParameter) throws IOException, NoSuchAlgorithmException {
         if (Objects.isNull(mapParameter.get("recordId")) || Objects.equals(mapParameter.get("recordId"), "")) {
             throw new BusinessException(ExceptionResultEnum.RECORD_ID_IS_NULL);
         }
@@ -200,6 +205,12 @@ public class TIeInvigilateCallMobileController {
             //监控结束
             MqDto mqDtoStop = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.MONITOR_STOP.name(), recordId, MqTagEnum.MONITOR_STOP, String.valueOf(recordId), mqMap, String.valueOf(recordId));
             mqDtoService.assembleSendOneOrderMsg(mqDtoStop);
+
+            Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+            ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+            Optional.ofNullable(examStudentCacheBean).orElseThrow(() -> new BusinessException("考生数据为空"));
+            SystemConstant.mobileMonitorStatusStop(examStudentCacheBean.getStudentId(), recordId, true);
+            ExamConstant.mobileWebsocketClose(recordId);
         }
         Map map = new HashMap();
         map.put("status", status.name());

+ 42 - 1
themis-exam/src/main/java/com/qmth/themis/exam/config/ExamConstant.java

@@ -13,9 +13,13 @@ import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.MqUtil;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.exam.websocket.WebSocketMobileServer;
+import com.qmth.themis.exam.websocket.WebSocketOeServer;
 
+import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * @Description: 考试系统常量
@@ -32,7 +36,7 @@ public class ExamConstant {
      * @param recordId
      * @param clientStop
      */
-    public static void sendExamStopMsg(Long recordId, boolean clientStop, boolean mobileStop) throws NoSuchAlgorithmException {
+    public static void sendExamStopMsg(Long recordId, boolean clientStop, boolean mobileStop) throws NoSuchAlgorithmException, IOException {
         MqUtil mqUtil = SpringContextHolder.getBean(MqUtil.class);
         MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
         TEExamStudentService teExamStudentService = SpringContextHolder.getBean(TEExamStudentService.class);
@@ -43,6 +47,7 @@ public class ExamConstant {
         if (clientStop) {
             MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.OE_WEBSOCKET_EXAM_STOP.name(), recordId, MqTagEnum.OE_WEBSOCKET_EXAM_STOP, String.valueOf(recordId), mapParameter, String.valueOf(recordId));
             mqDtoService.assembleSendOneOrderMsg(mqDto);
+            SystemConstant.clientMonitorStatusStop(recordId);
         } else {//结束推流状态
             SystemConstant.clientMonitorStatusStop(recordId);
             TOeExamRecordService toeExamRecordService = SpringContextHolder.getBean(TOeExamRecordService.class);
@@ -57,6 +62,7 @@ public class ExamConstant {
             MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_STOP.name(), recordId, MqTagEnum.EXAM_STOP, String.valueOf(recordId), mapParameter, String.valueOf(recordId));
             mqDtoService.assembleSendOneOrderMsg(mqDto);
             SystemConstant.mobileMonitorStatusStop(examStudentCacheBean.getStudentId(), recordId, false);
+            mobileWebsocketClose(recordId);
         }
     }
 
@@ -73,4 +79,39 @@ public class ExamConstant {
         MqDto mqDto = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.EXAM_START.name(), recordId, MqTagEnum.EXAM_START, String.valueOf(recordId), mapParameter, String.valueOf(recordId));
         mqDtoService.assembleSendOneOrderMsg(mqDto);
     }
+
+    /**
+     * 关闭客户端websocket
+     *
+     * @param recordId
+     * @throws IOException
+     */
+    public static void clientWebsocketClose(Long recordId) throws IOException {
+        ConcurrentHashMap<String, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
+        String clientWebsocketId = ExamRecordCacheUtil.getClientWebsocketId(recordId);
+        if (Objects.nonNull(clientWebsocketId)) {
+            WebSocketOeServer webSocketOeServer = webSocketMap.get(clientWebsocketId);
+            WebSocketOeServer.close(webSocketOeServer);
+        }
+    }
+
+    /**
+     * 关闭移动端websocket
+     *
+     * @param recordId
+     * @throws IOException
+     */
+    public static void mobileWebsocketClose(Long recordId) throws IOException {
+        ConcurrentHashMap<String, WebSocketMobileServer> webSocketMap = WebSocketMobileServer.getWebSocketMap();
+        String mobileFirstWebsocketId = ExamRecordCacheUtil.getMobileFirstWebsocketId(recordId);
+        if (Objects.nonNull(mobileFirstWebsocketId)) {
+            WebSocketMobileServer webSocketMobileFirstServer = webSocketMap.get(mobileFirstWebsocketId + "-" + MonitorVideoSourceEnum.MOBILE_FIRST.name());
+            WebSocketMobileServer.close(webSocketMobileFirstServer);
+        }
+        String mobileSecondWebsocketId = ExamRecordCacheUtil.getMobileSecondWebsocketId(recordId);
+        if (Objects.nonNull(mobileSecondWebsocketId)) {
+            WebSocketMobileServer webSocketMobileSecondServer = webSocketMap.get(mobileSecondWebsocketId + "-" + MonitorVideoSourceEnum.MOBILE_SECOND.name());
+            WebSocketMobileServer.close(webSocketMobileSecondServer);
+        }
+    }
 }

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

@@ -206,14 +206,6 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
                         case "OE_WEBSOCKET_EXAM_STOP":
                             if (!Objects.equals(ExamRecordStatusEnum.ANSWERING, examRecordStatusEnum)) {
                                 websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_STOP.name(), prop);
-                                SystemConstant.clientMonitorStatusStop(recordId);
-                                Map<String, Object> properties = mqDto.getProperties();
-                                if (Objects.nonNull(properties) && properties.size() > 0) {
-                                    Boolean removeWebsocket = (Boolean) properties.get(SystemConstant.REMOVE_WEBSOCKET);
-                                    if (Objects.nonNull(removeWebsocket) && removeWebsocket) {
-                                        WebSocketOeServer.close(webSocketOeServer);
-                                    }
-                                }
                             }
                             break;
                         case "MONITOR_START":
@@ -232,26 +224,6 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
                                     && Objects.nonNull(monitorStatusBean.getTimestamp())
                                     && mqDto.getTimestamp().longValue() >= monitorStatusBean.getTimestamp().longValue()) {
                                 websocketDto = new WebsocketDto(WebsocketTypeEnum.MOBILE_MONITOR_STOP.name(), prop);
-                                ConcurrentHashMap<String, WebSocketMobileServer> webSocketMobileMap = WebSocketMobileServer.getWebSocketMap();
-
-                                String mobileWebsocketId = null;
-//                                WebsocketStatusEnum websocketStatusEnum = null;
-                                if (source == MonitorVideoSourceEnum.MOBILE_FIRST) {
-                                    mobileWebsocketId = ExamRecordCacheUtil.getMobileFirstWebsocketId(recordId);
-//                                    websocketStatusEnum = ExamRecordCacheUtil.getMobileFirstWebsocketStatus(recordId);
-                                } else if (source == MonitorVideoSourceEnum.MOBILE_SECOND) {
-                                    mobileWebsocketId = ExamRecordCacheUtil.getMobileSecondWebsocketId(recordId);
-//                                    websocketStatusEnum = ExamRecordCacheUtil.getMobileSecondWebsocketStatus(recordId);
-                                }
-//                                if (Objects.nonNull(websocketStatusEnum) && websocketStatusEnum == WebsocketStatusEnum.ON_LINE) {
-                                WebSocketMobileServer webSocketMobileServer = webSocketMobileMap.get(mobileWebsocketId + "-" + source.name());
-                                Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
-                                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-                                Optional.ofNullable(examStudentCacheBean).orElseThrow(() -> new BusinessException("考生数据为空"));
-
-                                SystemConstant.mobileMonitorStatusStop(examStudentCacheBean.getStudentId(), recordId, true);
-                                WebSocketMobileServer.close(webSocketMobileServer);
-//                                }
                             }
                             break;
                         case "OE_WEBSOCKET_MOBILE_MONITOR_STATUS":
@@ -315,14 +287,6 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
                         case "EXAM_STOP":
                             if (!Objects.equals(ExamRecordStatusEnum.ANSWERING, examRecordStatusEnum)) {
                                 websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_STOP.name(), mqDto.getProperties());
-                                SystemConstant.mobileMonitorStatusStop(examStudentCacheBean.getStudentId(), recordId, false);
-                                Map<String, Object> properties = mqDto.getProperties();
-                                if (Objects.nonNull(properties) && properties.size() > 0) {
-                                    Boolean removeWebsocket = (Boolean) properties.get(SystemConstant.REMOVE_WEBSOCKET);
-                                    if (Objects.nonNull(removeWebsocket) && removeWebsocket) {
-                                        WebSocketMobileServer.close(webSocketFirstMobileServer);
-                                    }
-                                }
                             }
                             break;
                         case "EXAM_START":
@@ -348,14 +312,6 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
                         case "EXAM_STOP":
                             if (!Objects.equals(ExamRecordStatusEnum.ANSWERING, examRecordStatusEnum)) {
                                 websocketDto = new WebsocketDto(WebsocketTypeEnum.EXAM_STOP.name(), mqDto.getProperties());
-                                SystemConstant.mobileMonitorStatusStop(examStudentCacheBean.getStudentId(), recordId, false);
-                                Map<String, Object> properties = mqDto.getProperties();
-                                if (Objects.nonNull(properties) && properties.size() > 0) {
-                                    Boolean mobileRemoveWebsocket = (Boolean) properties.get(SystemConstant.REMOVE_WEBSOCKET);
-                                    if (Objects.nonNull(mobileRemoveWebsocket) && mobileRemoveWebsocket) {
-                                        WebSocketMobileServer.close(webSocketSecondMobileServer);
-                                    }
-                                }
                             }
                             break;
                         case "EXAM_START":

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

@@ -3,6 +3,7 @@ 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.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
@@ -10,6 +11,7 @@ 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.TEExamStudentService;
 import com.qmth.themis.business.service.TOeExamRecordService;
 import com.qmth.themis.business.util.*;
 import com.qmth.themis.common.contanst.Constants;
@@ -31,10 +33,8 @@ import javax.websocket.server.ServerEndpoint;
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -96,7 +96,7 @@ public class WebSocketMobileServer implements Concurrently {
      * 连接关闭调用的方法
      */
     @OnClose
-    public void onClose() {
+    public void onClose() throws NoSuchAlgorithmException, IOException {
         log.info("onClose is come in");
         if (webSocketMap.containsKey(this.websocketSessionId + "-" + this.source.name())) {
             webSocketMap.remove(this.websocketSessionId + "-" + this.source.name());
@@ -120,6 +120,12 @@ public class WebSocketMobileServer implements Concurrently {
             //监控结束
             MqDto mqDtoStop = new MqDto(mqUtil.getMqGroupDomain().getTopic(), MqTagEnum.MONITOR_STOP.name(), recordId, MqTagEnum.MONITOR_STOP, String.valueOf(recordId), mqMap, String.valueOf(recordId));
             mqDtoService.assembleSendOneOrderMsg(mqDtoStop);
+
+            TEExamStudentService teExamStudentService = SpringContextHolder.getBean(TEExamStudentService.class);
+            Long examStudentId = ExamRecordCacheUtil.getExamStudentId(this.recordId);
+            ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+            Optional.ofNullable(examStudentCacheBean).orElseThrow(() -> new BusinessException("考生数据为空"));
+            SystemConstant.mobileMonitorStatusStop(examStudentCacheBean.getStudentId(), this.recordId, true);
         }
         log.info("用户退出:{},当前在线人数为:{},updateTime:{}", this.sessionId, getOnlineCount(), this.updateTime);
     }

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

@@ -103,7 +103,7 @@ public class WebSocketOeServer implements Concurrently {
      * 连接关闭调用的方法
      */
     @OnClose
-    public void onClose() throws NoSuchAlgorithmException {
+    public void onClose() throws NoSuchAlgorithmException, IOException {
         log.info("onClose is come in");
         if (webSocketMap.containsKey(this.websocketSessionId)) {
             webSocketMap.remove(this.websocketSessionId);