Przeglądaj źródła

监考端接口

wangliang 4 lat temu
rodzic
commit
79bd25f870

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

@@ -101,7 +101,7 @@ public class TIeInvigilateCallMobileController {
             source = MonitorVideoSourceEnum.MOBILE_SECOND;
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, MonitorStatusSourceEnum.STOP.name());
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), MonitorStatusSourceEnum.STOP);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.STOP);
         redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
         //监考监控通话信息 发送mq start

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

@@ -7,19 +7,19 @@ 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.InvigilateListBean;
+import com.qmth.themis.business.bean.backend.InvigilateListDetailBean;
 import com.qmth.themis.business.bean.backend.InvigilateListVideoBean;
 import com.qmth.themis.business.cache.RedisKeyHelper;
+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.TBUser;
 import com.qmth.themis.business.entity.TEExamBreachLog;
 import com.qmth.themis.business.entity.TOeExamRecord;
-import com.qmth.themis.business.enums.BreachTypeEnum;
-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.*;
 import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TEExamBreachLogService;
+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;
@@ -61,6 +61,9 @@ public class TIeInvigilateController {
     @Resource
     TOeExamRecordService tOeExamRecordService;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     @ApiOperation(value = "实时监控台列表接口")
     @RequestMapping(value = "/list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListBean.class)})
@@ -89,7 +92,7 @@ public class TIeInvigilateController {
 
     @ApiOperation(value = "实时监控台视频列表接口")
     @RequestMapping(value = "/list/video", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListBean.class)})
+    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListVideoBean.class)})
     public Result listVideo(@ApiParam(value = "考试批次id") @RequestParam Long examId,
                             @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long examActivityId,
                             @ApiParam(value = "虚拟考场代码", required = false) @RequestParam(required = false) String roomCode,
@@ -113,6 +116,30 @@ public class TIeInvigilateController {
         return ResultUtil.ok(map);
     }
 
+    @ApiOperation(value = "实时监控台列表明细接口")
+    @RequestMapping(value = "/list/detail", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListDetailBean.class)})
+    public Result listDetail(@ApiParam(value = "考试记录id") @RequestParam Long examRecordId) {
+        if (Objects.isNull(examRecordId) || Objects.equals(examRecordId, "")) {
+            throw new BusinessException(ExceptionResultEnum.EXAM_STUDENT_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");
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+        String identity = examStudentCacheBean.getIdentity();
+        String examStudentName = examStudentCacheBean.getName();
+        String courseNameCode = examStudentCacheBean.getCourseName() + "(" + examStudentCacheBean.getCourseCode() + ")";
+        String roomCode = examStudentCacheBean.getRoomCode();
+        InvigilateListDetailBean invigilateListDetailBean = new InvigilateListDetailBean(examId, examActivityId, examStudentId, examRecordId, identity, examStudentName, courseNameCode, status, roomCode);
+
+        //预警、异常、人脸
+        return ResultUtil.ok(invigilateListDetailBean);
+    }
+
     @ApiOperation(value = "强制/手动交卷接口")
     @RequestMapping(value = "/finish", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})

+ 180 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListDetailBean.java

@@ -0,0 +1,180 @@
+package com.qmth.themis.business.bean.backend;
+
+import com.qmth.themis.business.enums.ExamRecordStatusEnum;
+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 InvigilateListDetailBean implements Serializable {
+
+    @ApiModelProperty(name = "考试id")
+    private Long examId;
+
+    @ApiModelProperty(name = "场次id")
+    private Long examActivityId;
+
+    @ApiModelProperty(name = "考生id")
+    private Long examStudentId;
+
+    @ApiModelProperty(name = "考试记录id")
+    private Long examRecordId;
+
+    @ApiModelProperty(name = "证件号")
+    private String identity;
+
+    @ApiModelProperty(name = "考生姓名")
+    private String examStudentName;
+
+    @ApiModelProperty(name = "科目名称(编码)")
+    private String courseNameCode;
+
+    @ApiModelProperty(name = "考生状态")
+    private String status;
+
+    @ApiModelProperty(name = "考生状态值")
+    private ExamRecordStatusEnum statusCode;
+
+    @ApiModelProperty(name = "虚拟考场代码")
+    private String roomCode;
+
+    @ApiModelProperty(name = "系统预警")
+    private Integer warningCount;
+
+    @ApiModelProperty(name = "陌生人脸")
+    private Integer multipleFaceCount;
+
+    @ApiModelProperty(name = "异常处理")
+    private Integer exceptionCount;
+
+    public InvigilateListDetailBean() {
+
+    }
+
+    public InvigilateListDetailBean(Long examId, Long examActivityId, Long examStudentId, Long examRecordId, String identity, String examStudentName, String courseNameCode, ExamRecordStatusEnum statusCode, String roomCode) {
+        this.examId = examId;
+        this.examActivityId = examActivityId;
+        this.examStudentId = examStudentId;
+        this.examRecordId = examRecordId;
+        this.identity = identity;
+        this.examStudentName = examStudentName;
+        this.courseNameCode = courseNameCode;
+        this.statusCode = statusCode;
+        this.roomCode = roomCode;
+    }
+
+    public Integer getWarningCount() {
+        return warningCount;
+    }
+
+    public void setWarningCount(Integer warningCount) {
+        this.warningCount = warningCount;
+    }
+
+    public Integer getMultipleFaceCount() {
+        return multipleFaceCount;
+    }
+
+    public void setMultipleFaceCount(Integer multipleFaceCount) {
+        this.multipleFaceCount = multipleFaceCount;
+    }
+
+    public Integer getExceptionCount() {
+        return exceptionCount;
+    }
+
+    public void setExceptionCount(Integer exceptionCount) {
+        this.exceptionCount = exceptionCount;
+    }
+
+    public String getRoomCode() {
+        return roomCode;
+    }
+
+    public void setRoomCode(String roomCode) {
+        this.roomCode = roomCode;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public Long getExamActivityId() {
+        return examActivityId;
+    }
+
+    public void setExamActivityId(Long examActivityId) {
+        this.examActivityId = examActivityId;
+    }
+
+    public Long getExamStudentId() {
+        return examStudentId;
+    }
+
+    public void setExamStudentId(Long examStudentId) {
+        this.examStudentId = examStudentId;
+    }
+
+    public Long getExamRecordId() {
+        return examRecordId;
+    }
+
+    public void setExamRecordId(Long examRecordId) {
+        this.examRecordId = examRecordId;
+    }
+
+    public String getIdentity() {
+        return identity;
+    }
+
+    public void setIdentity(String identity) {
+        this.identity = identity;
+    }
+
+    public String getExamStudentName() {
+        return examStudentName;
+    }
+
+    public void setExamStudentName(String examStudentName) {
+        this.examStudentName = examStudentName;
+    }
+
+    public String getCourseNameCode() {
+        return courseNameCode;
+    }
+
+    public void setCourseNameCode(String courseNameCode) {
+        this.courseNameCode = courseNameCode;
+    }
+
+    public String getStatus() {
+        if (statusCode != null) {
+            return statusCode.getCode();
+        }
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public ExamRecordStatusEnum getStatusCode() {
+        return statusCode;
+    }
+
+    public void setStatusCode(ExamRecordStatusEnum statusCode) {
+        this.statusCode = statusCode;
+    }
+}

+ 116 - 92
themis-business/src/main/java/com/qmth/themis/business/cache/bean/ExamStudentCacheBean.java

@@ -4,128 +4,152 @@ import java.io.Serializable;
 
 public class ExamStudentCacheBean implements Serializable {
 
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -7154063361894874051L;
+    /**
+     *
+     */
+    private static final long serialVersionUID = -7154063361894874051L;
 
-	// 主键
-	private Long id;
+    // 主键
+    private Long id;
 
-	// 批次id
-	private Long examId;
+    // 批次id
+    private Long examId;
 
-	// 场次id
-	private Long examActivityId;
+    // 场次id
+    private Long examActivityId;
 
-	// 学生id
-	private Long studentId;
+    // 学生id
+    private Long studentId;
 
-	// 科目代码
-	private String courseCode;
+    // 科目代码
+    private String courseCode;
 
-	// 科目名称
-	private String courseName;
+    // 科目名称
+    private String courseName;
 
-	// 虚拟考场代码,考试唯一
-	private String roomCode;
+    // 虚拟考场代码,考试唯一
+    private String roomCode;
 
-	// 考场名称
-	private String roomName;
+    // 考场名称
+    private String roomName;
 
-	// 剩余考试次数
-	private Integer leftExamCount;
-	// 当前考试是第几次
-	private Integer currentSerialNumber;
-	// 当前考试记录ID
-	private Long currentRecordId;
+    // 剩余考试次数
+    private Integer leftExamCount;
+    // 当前考试是第几次
+    private Integer currentSerialNumber;
+    // 当前考试记录ID
+    private Long currentRecordId;
 
-	public Integer getCurrentSerialNumber() {
-		return currentSerialNumber;
-	}
+    private String identity;//证件号
 
-	public void setCurrentSerialNumber(Integer currentSerialNumber) {
-		this.currentSerialNumber = currentSerialNumber;
-	}
+    private String name;//考生姓名
 
-	public String getCourseName() {
-		return courseName;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
-	public String getRoomName() {
-		return roomName;
-	}
+    public static long getSerialVersionUID() {
+        return serialVersionUID;
+    }
 
-	public void setRoomName(String roomName) {
-		this.roomName = roomName;
-	}
+    public String getIdentity() {
+        return identity;
+    }
 
-	public Long getExamId() {
-		return examId;
-	}
+    public void setIdentity(String identity) {
+        this.identity = identity;
+    }
 
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
+    public Integer getCurrentSerialNumber() {
+        return currentSerialNumber;
+    }
 
-	public Long getExamActivityId() {
-		return examActivityId;
-	}
+    public void setCurrentSerialNumber(Integer currentSerialNumber) {
+        this.currentSerialNumber = currentSerialNumber;
+    }
 
-	public void setExamActivityId(Long examActivityId) {
-		this.examActivityId = examActivityId;
-	}
+    public String getCourseName() {
+        return courseName;
+    }
 
-	public Long getStudentId() {
-		return studentId;
-	}
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
 
-	public void setStudentId(Long studentId) {
-		this.studentId = studentId;
-	}
+    public String getRoomName() {
+        return roomName;
+    }
 
-	public String getCourseCode() {
-		return courseCode;
-	}
+    public void setRoomName(String roomName) {
+        this.roomName = roomName;
+    }
 
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
+    public Long getExamId() {
+        return examId;
+    }
 
-	public String getRoomCode() {
-		return roomCode;
-	}
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
 
-	public void setRoomCode(String roomCode) {
-		this.roomCode = roomCode;
-	}
+    public Long getExamActivityId() {
+        return examActivityId;
+    }
 
-	public Integer getLeftExamCount() {
-		return leftExamCount;
-	}
+    public void setExamActivityId(Long examActivityId) {
+        this.examActivityId = examActivityId;
+    }
 
-	public void setLeftExamCount(Integer leftExamCount) {
-		this.leftExamCount = leftExamCount;
-	}
+    public Long getStudentId() {
+        return studentId;
+    }
 
-	public Long getCurrentRecordId() {
-		return currentRecordId;
-	}
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
 
-	public void setCurrentRecordId(Long currentRecordId) {
-		this.currentRecordId = currentRecordId;
-	}
+    public String getCourseCode() {
+        return courseCode;
+    }
 
-	public Long getId() {
-		return id;
-	}
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
 
-	public void setId(Long id) {
-		this.id = id;
-	}
+    public String getRoomCode() {
+        return roomCode;
+    }
+
+    public void setRoomCode(String roomCode) {
+        this.roomCode = roomCode;
+    }
+
+    public Integer getLeftExamCount() {
+        return leftExamCount;
+    }
+
+    public void setLeftExamCount(Integer leftExamCount) {
+        this.leftExamCount = leftExamCount;
+    }
+
+    public Long getCurrentRecordId() {
+        return currentRecordId;
+    }
+
+    public void setCurrentRecordId(Long currentRecordId) {
+        this.currentRecordId = currentRecordId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
 
 }

+ 2 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamStudentServiceImpl.java

@@ -103,6 +103,8 @@ public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, T
         ret.setLeftExamCount(es.getLeftExamCount());
         ret.setCurrentRecordId(es.getCurrentRecordId());
         ret.setCurrentSerialNumber(null);
+        ret.setIdentity(es.getIdentity());
+        ret.setName(es.getName());
         return ret;
     }
 }

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

@@ -612,6 +612,8 @@ INSERT INTO `t_b_role_privilege` VALUES (93, 'STUDENT', 100);
 INSERT INTO `t_b_role_privilege` VALUES (94, 'STUDENT', 101);
 INSERT INTO `t_b_role_privilege` VALUES (95, 'STUDENT', 102);
 INSERT INTO `t_b_role_privilege` VALUES (96, 'STUDENT', 103);
+INSERT INTO `t_b_role_privilege` VALUES (97, 'STUDENT', 104);
+INSERT INTO `t_b_role_privilege` VALUES (98, 'STUDENT', 105);
 COMMIT;
 
 -- ----------------------------

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

@@ -77,7 +77,7 @@ public class TIeInvigilateCallMobileController {
             //获取考试记录缓存
             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().name());
+            objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), tIeExamInvigilateCallLog.getStatus());
             redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
             //监考监控通话信息 发送mq start
@@ -123,7 +123,7 @@ public class TIeInvigilateCallMobileController {
             source = MonitorVideoSourceEnum.MOBILE_SECOND;
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, MonitorStatusSourceEnum.START.name());
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), MonitorStatusSourceEnum.START);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START);
         redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
@@ -169,7 +169,7 @@ public class TIeInvigilateCallMobileController {
         } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, status);
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), status);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START);
         if (Objects.nonNull(mapParameter.get("type")) || !Objects.equals(mapParameter.get("type"), "")) {
             tIeExamInvigilateCallLog.setType((ExceptionEnum) mapParameter.get("type"));
@@ -225,7 +225,7 @@ public class TIeInvigilateCallMobileController {
             source = MonitorVideoSourceEnum.MOBILE_SECOND;
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, MonitorStatusSourceEnum.STOP.name());
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), MonitorStatusSourceEnum.STOP);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.STOP);
         redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
         //监考监控通话信息 发送mq start

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

@@ -8,7 +8,6 @@ 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.TIeExamInvigilateCallService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
@@ -75,7 +74,7 @@ public class TIeInvigilateCallOeController {
             //获取考试记录缓存
             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().name());
+            objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), tIeExamInvigilateCallLog.getStatus());
             redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
             //监考监控通话信息 发送mq start
@@ -132,7 +131,7 @@ public class TIeInvigilateCallOeController {
         } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()))) {
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, status);
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), status);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START);
         if (Objects.nonNull(mapParameter.get("type")) || !Objects.equals(mapParameter.get("type"), "")) {
             tIeExamInvigilateCallLog.setType((ExceptionEnum) mapParameter.get("type"));
@@ -171,7 +170,7 @@ public class TIeInvigilateCallOeController {
             source = MonitorVideoSourceEnum.CLIENT_SCREEN;
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, MonitorStatusSourceEnum.START.name());
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), MonitorStatusSourceEnum.START);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START);
         redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
 
@@ -206,7 +205,7 @@ public class TIeInvigilateCallOeController {
             source = MonitorVideoSourceEnum.CLIENT_SCREEN;
             liveUrl = String.valueOf(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.CLIENT_SCREEN.name()));
         }
-        objectMap.put(SystemConstant.MONITOR_STATUS_ + source, MonitorStatusSourceEnum.STOP.name());
+        objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), MonitorStatusSourceEnum.STOP);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.STOP);
         redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
         //监考监控通话信息 发送mq start

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

@@ -2,10 +2,13 @@ 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.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.WebsocketDto;
 import com.qmth.themis.business.entity.TBSession;
+import com.qmth.themis.business.enums.MonitorStatusSourceEnum;
+import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
 import com.qmth.themis.business.enums.WebsocketTypeEnum;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
@@ -24,10 +27,7 @@ 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.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -131,6 +131,29 @@ public class WebSocketMobileServer {
             webSocketMap.remove(this.recordId);
             //从set中删除
             subOnlineCount();
+            //判断是否是正常退出
+            Date now = new Date();
+            //大于等于超时时间,说明规定时间内都没有通信,非正常退出,因为期间会有心跳更新updateTime
+            if ((now.getTime() - this.updateTime) / 1000 >= SystemConstant.WEBSOCKET_MAX_TIME_OUT / 1000) {
+                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+                MonitorVideoSourceEnum source = null;
+                if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_FIRST.name()))) {
+                    source = MonitorVideoSourceEnum.MOBILE_FIRST;
+                } else if (Objects.nonNull(objectMap.get(SystemConstant.MONITOR_LIVE_URL_ + MonitorVideoSourceEnum.MOBILE_SECOND.name()))) {
+                    source = MonitorVideoSourceEnum.MOBILE_SECOND;
+                }
+                objectMap.put(SystemConstant.MONITOR_STATUS_ + source.name(), MonitorStatusSourceEnum.STOP);
+                redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
+                ConcurrentHashMap<Long, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
+                if (Objects.nonNull(webSocketMap.get(recordId))) {
+                    WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
+                    Map map = new HashMap<>();
+                    map.put(SystemConstant.RECORD_ID, recordId);
+                    map.put("monitorVideoSource", source.name());
+                    WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.MOBILE_MONITOR_STOP.name(), map);
+                    webSocketOeServer.sendMessage(websocketDto);
+                }
+            }
         }
         log.info("用户退出:{},当前在线人数为:{},updateTime:{}", this.sessionId, getOnlineCount(), this.updateTime);
     }

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

@@ -156,9 +156,6 @@ public class WebSocketOeServer implements Concurrently {
             //大于等于超时时间,说明规定时间内都没有通信,非正常退出,因为期间会有心跳更新updateTime
             if ((now.getTime() - this.updateTime) / 1000 >= SystemConstant.WEBSOCKET_MAX_TIME_OUT / 1000) {
                 log.info("超时退出");
-                objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
-                objectMap.put("clientWebsocketStatus", WebsocketStatusEnum.OFF_LINE);
-                redisUtil.setForHash(RedisKeyHelper.examRecordCacheKey(recordId), objectMap);
                 //发送延时mq消息start
                 MqDtoService mqDtoService = SpringContextHolder.getBean(MqDtoService.class);
                 String level = "2m";