Explorar o código

监考日志修改

wangliang %!s(int64=4) %!d(string=hai) anos
pai
achega
e190b40f7d
Modificáronse 17 ficheiros con 215 adicións e 92 borrados
  1. 2 2
      themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamController.java
  2. 9 1
      themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java
  3. 38 4
      themis-business/src/main/java/com/qmth/themis/business/entity/TEExamStudentLog.java
  4. 5 5
      themis-business/src/main/java/com/qmth/themis/business/entity/TEUserLog.java
  5. 36 8
      themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamInvigilateNotice.java
  6. 3 3
      themis-business/src/main/java/com/qmth/themis/business/entity/TOeExamRecord.java
  7. 1 1
      themis-business/src/main/java/com/qmth/themis/business/enums/MqGroupEnum.java
  8. 30 30
      themis-business/src/main/java/com/qmth/themis/business/enums/MqTagEnum.java
  9. 12 9
      themis-business/src/main/java/com/qmth/themis/business/enums/SystemOperationEnum.java
  10. 18 14
      themis-business/src/main/java/com/qmth/themis/business/enums/WebsocketStatusEnum.java
  11. 1 2
      themis-business/src/main/java/com/qmth/themis/business/service/TEExamStudentLogService.java
  12. 1 2
      themis-business/src/main/java/com/qmth/themis/business/service/TEUserLogService.java
  13. 9 3
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamStudentLogServiceImpl.java
  14. 7 3
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEUserLogServiceImpl.java
  15. 3 2
      themis-business/src/main/resources/db/init.sql
  16. 34 1
      themis-exam/src/main/java/com/qmth/themis/exam/listener/service/impl/MqOeLogicServiceImpl.java
  17. 6 2
      themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

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

@@ -392,8 +392,8 @@ public class TEExamController {
                     Map<String, Object> recordIdObjectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(k));
                     if (Objects.nonNull(recordIdObjectMap) && recordIdObjectMap.size() > 0) {
                         //客户端通讯状态
-                        Integer clientStatus = Objects.isNull(recordIdObjectMap.get("clientWebsocketStatus")) ? 0 : (Integer) recordIdObjectMap.get("clientWebsocketStatus");
-                        if (clientStatus == 0) {
+                        WebsocketStatusEnum clientStatus = Objects.isNull(recordIdObjectMap.get("clientWebsocketStatus")) ? null : (WebsocketStatusEnum) recordIdObjectMap.get("clientWebsocketStatus");
+                        if (Objects.equals(clientStatus, WebsocketStatusEnum.OFF_LINE)) {
                             clientCommunicationStatusCount.getAndSet(clientCommunicationStatusCount.get() + 1);
                         }
                         //监控端通讯状态

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

@@ -93,7 +93,15 @@ public class TIeInvigilateController {
         FinishTypeEnum type = FinishTypeEnum.valueOf(String.valueOf(mapParameter.get("type")));
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         //发送mq给客户端强制收卷start
-        MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.OE_MONITOR_FINISH.name(), JacksonUtil.parseJson(recordIdList), type.ordinal() == FinishTypeEnum.INTERRUPT.ordinal() ? MqTagEnum.OE_MONITOR_FINISH : MqTagEnum.OE_HARD_FINISH, String.valueOf(tbUser.getId()), mapParameter, tbUser.getName());
+        MqTagEnum mqTagEnum = null;
+        if (Objects.equals(type, FinishTypeEnum.INTERRUPT)) {
+            mqTagEnum = MqTagEnum.OE_MONITOR_FINISH;
+        } else if (Objects.equals(type, FinishTypeEnum.BREACH)) {
+            mqTagEnum = MqTagEnum.OE_WARNING_FINISH;
+        } else {
+            mqTagEnum = MqTagEnum.OE_HARD_FINISH;
+        }
+        MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), mqTagEnum.name(), JacksonUtil.parseJson(recordIdList), mqTagEnum, String.valueOf(tbUser.getId()), mapParameter, tbUser.getName());
         mqDtoService.assembleSendOneWayMsg(mqDto);
         //发送mq给客户端强制收卷end
         return ResultUtil.ok(SystemConstant.SUCCESS);

+ 38 - 4
themis-business/src/main/java/com/qmth/themis/business/entity/TEExamStudentLog.java

@@ -30,9 +30,17 @@ public class TEExamStudentLog implements Serializable {
     @TableField(value = "student_id")
     private Long studentId;
 
+    @ApiModelProperty(value = "考生id")
+    @TableField(value = "exam_student_id")
+    private Long examStudentId;
+
+    @ApiModelProperty(value = "考试记录id")
+    @TableField(value = "exam_record_id")
+    private Long examRecordId;
+
     @ApiModelProperty(value = "类型")
     @TableField(value = "type")
-    private Integer type;
+    private String type;
 
     @ApiModelProperty(value = "描述")
     @TableField(value = "description")
@@ -50,12 +58,38 @@ public class TEExamStudentLog implements Serializable {
 
     }
 
-    public TEExamStudentLog(Integer type, String description, String remark, Long studentId) {
+    public TEExamStudentLog(String type, String description, String remark, Long studentId) {
+        this.id = Constants.idGen.next();
+        this.type = type;
+        this.description = description;
+        this.remark = remark;
+        this.studentId = studentId;
+    }
+
+    public TEExamStudentLog(String type, String description, String remark, Long studentId, Long examStudentId, Long examRecordId) {
         this.id = Constants.idGen.next();
         this.type = type;
         this.description = description;
         this.remark = remark;
         this.studentId = studentId;
+        this.examStudentId = examStudentId;
+        this.examRecordId = examRecordId;
+    }
+
+    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 static long getSerialVersionUID() {
@@ -70,11 +104,11 @@ public class TEExamStudentLog implements Serializable {
         this.id = id;
     }
 
-    public Integer getType() {
+    public String getType() {
         return type;
     }
 
-    public void setType(Integer type) {
+    public void setType(String type) {
         this.type = type;
     }
 

+ 5 - 5
themis-business/src/main/java/com/qmth/themis/business/entity/TEUserLog.java

@@ -32,7 +32,7 @@ public class TEUserLog implements Serializable {
 
     @ApiModelProperty(value = "类型")
     @TableField(value = "type")
-    private Integer type;
+    private String type;
 
     @ApiModelProperty(value = "描述")
     @TableField(value = "description")
@@ -50,12 +50,12 @@ public class TEUserLog implements Serializable {
 
     }
 
-    public TEUserLog(Long userId, Integer type, String description, String remark) {
+    public TEUserLog(String type, String description, String remark, Long userId) {
         this.id = Constants.idGen.next();
-        this.userId = userId;
         this.type = type;
         this.description = description;
         this.remark = remark;
+        this.userId = userId;
     }
 
     public static long getSerialVersionUID() {
@@ -78,11 +78,11 @@ public class TEUserLog implements Serializable {
         this.userId = userId;
     }
 
-    public Integer getType() {
+    public String getType() {
         return type;
     }
 
-    public void setType(Integer type) {
+    public void setType(String type) {
         this.type = type;
     }
 

+ 36 - 8
themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamInvigilateNotice.java

@@ -2,8 +2,8 @@ package com.qmth.themis.business.entity;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
-import com.qmth.themis.business.enums.InvigilateNoticeEnum;
 import com.qmth.themis.business.enums.MessageTypeEnum;
+import com.qmth.themis.common.contanst.Constants;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -38,9 +38,13 @@ public class TIeExamInvigilateNotice implements Serializable {
     @TableField(value = "exam_record_id")
     private Long examRecordId;
 
-    @ApiModelProperty(value = "监考人ID")
-    @TableField(value = "user_id")
-    private Long userId;
+    @ApiModelProperty(value = "发送人id")
+    @TableField(value = "form_user_id")
+    private Long formUserId;
+
+    @ApiModelProperty(value = "接收人id")
+    @TableField(value = "receive_user_id")
+    private Long receiveUserId;
 
     @ApiModelProperty(value = "消息类型")
     @TableField(value = "type")
@@ -58,6 +62,22 @@ public class TIeExamInvigilateNotice implements Serializable {
     @TableField(value = "receive_time")
     private Date receiveTime;
 
+    public TIeExamInvigilateNotice() {
+
+    }
+
+    public TIeExamInvigilateNotice(Long examId, Long examActivityId, Long examRecordId, Long formUserId,Long receiveUserId, MessageTypeEnum type, String content) {
+        this.id = Constants.idGen.next();
+        this.examId = examId;
+        this.examActivityId = examActivityId;
+        this.examRecordId = examRecordId;
+        this.formUserId = formUserId;
+        this.receiveUserId = receiveUserId;
+        this.type = type;
+        this.content = content;
+        this.sendTime = new Date();
+    }
+
     public static long getSerialVersionUID() {
         return serialVersionUID;
     }
@@ -94,12 +114,20 @@ public class TIeExamInvigilateNotice implements Serializable {
         this.examRecordId = examRecordId;
     }
 
-    public Long getUserId() {
-        return userId;
+    public Long getFormUserId() {
+        return formUserId;
+    }
+
+    public void setFormUserId(Long formUserId) {
+        this.formUserId = formUserId;
+    }
+
+    public Long getReceiveUserId() {
+        return receiveUserId;
     }
 
-    public void setUserId(Long userId) {
-        this.userId = userId;
+    public void setReceiveUserId(Long receiveUserId) {
+        this.receiveUserId = receiveUserId;
     }
 
     public MessageTypeEnum getType() {

+ 3 - 3
themis-business/src/main/java/com/qmth/themis/business/entity/TOeExamRecord.java

@@ -74,7 +74,7 @@ public class TOeExamRecord implements Serializable {
 
     @ApiModelProperty(value = "客户端websocket状态")
     @TableField(value = "client_websocket_status")
-    private Integer clientWebsocketStatus;
+    private WebsocketStatusEnum clientWebsocketStatus;
 
     @ApiModelProperty(value = "客户端websocket连接标识")
     @TableField(value = "client_websocket_id")
@@ -312,11 +312,11 @@ public class TOeExamRecord implements Serializable {
         this.clientCurrentIp = clientCurrentIp;
     }
 
-    public Integer getClientWebsocketStatus() {
+    public WebsocketStatusEnum getClientWebsocketStatus() {
         return clientWebsocketStatus;
     }
 
-    public void setClientWebsocketStatus(Integer clientWebsocketStatus) {
+    public void setClientWebsocketStatus(WebsocketStatusEnum clientWebsocketStatus) {
         this.clientWebsocketStatus = clientWebsocketStatus;
     }
 

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

@@ -30,7 +30,7 @@ public enum MqGroupEnum {
     logConsumerGroup("themis-group-exam-log"),
 
     /**
-     * websocket超时退出 考生 group
+     * websocket oe 考生 group
      */
     websocketConsumerOeGroup("themis-group-exam-websocketOe"),
 

+ 30 - 30
themis-business/src/main/java/com/qmth/themis/business/enums/MqTagEnum.java

@@ -9,36 +9,36 @@ package com.qmth.themis.business.enums;
  */
 public enum MqTagEnum {
 
-    WEB("会话web标签", "用户session日志", "normal", 0),
-    WIN("会话win标签", "用户session日志", "normal", 1),
-    MAC("会话mac标签", "用户session日志", "normal", 2),
-    WXAPP("会话wxapp标签", "用户session日志", "normal", 3),
-    IOS("会话ios标签", "用户session日志", "normal", 4),
-    ANDROID("会话android标签", "用户session日志", "normal", 5),
-    USER("用户轨迹user标签", "用户轨迹日志", "normal", 6),
-    STUDENT("用户轨迹student标签", "考生轨迹日志", "normal", 7),
-    EXAM_STUDENT_IMPORT("考生导入任务标签", "考生导入任务日志", "normal", 8),
-    ROOM_CODE_EXPORT("考场导出任务标签", "考场导出任务日志", "normal", 9),
-    ROOM_CODE_IMPORT("考场导入任务标签", "考场导入任务日志", "normal", 10),
-    EXAM_PAPER_IMPORT("试卷导入任务标签", "试卷导入任务日志", "normal", 11),
-    OE_IM_CLUSTERING("websocket客户端点对点发送消息标签", "客户端点对点消息日志", "normal", 12),
-    OE_IM_BROADCASTING("websocket客户端广播发送消息标签", "客户端广播消息日志", "normal", 13),
-    OE_MONITOR_FINISH("websocket客户端监考强制离线(交卷)标签", "监考强制离线(交卷)日志", "normal", 14),
-    OE_WARNING_FINISH("websocket客户端预警强制离线(交卷)标签", "预警强制离线(交卷)日志", "normal", 15),
-    OE_HARD_FINISH("websocket客户端手动(交卷)标签", "手动(交卷)日志", "normal", 16),
-    OE_LIVENESS_VERIFY("websocket客户端监考强制活体验证标签", "监考强制活体验证日志", "normal", 17),
-    OE_UN_NORMAL("websocket超时退出标签", "websocket超时退出超时退出日志", "delay", 18),
-    EXAM_ACTIVITY("考场一次性延时任务标签", "考场一次性延时任务日志", "normal", 19),
-    QUARTZ("quartz标签", "quartz任务日志", "normal", 20),
-    CALCULATE_OBJECTIVE_SCORE("计算客观分标签", "计算客观分日志", "normal", 21),
-    FACE_VERIFY_SAVE("人脸验证保存", "人脸验证日志", "normal", 22),
-    LIVENESS_VERIFY_SAVE("活体验证保存", "活体验证日志", "normal", 23),
-    EXAM_RECORD_PERSISTED("考试记录数据持久化", "考试日志", "normal", 24),
-    EXAM_RECORD_UPDATE("考试记录数据更新", "考试日志", "normal", 25),
-    EXAM_RECORD_INIT("考试记录数据初始化", "考试日志", "normal", 26),
-    WARNING_LOG("预警日志标签", "预警日志", "normal", 27),
-    EXCEPTION_LOG("异常日志标签", "异常日志", "normal", 28),
-    MONITOR_LOG("监考监控日志标签", "监考监控日志", "normal", 29);
+    WEB("会话web标签", "用户session", "normal", 0),
+    WIN("会话win标签", "用户session", "normal", 1),
+    MAC("会话mac标签", "用户session", "normal", 2),
+    WXAPP("会话wxapp标签", "用户session", "normal", 3),
+    IOS("会话ios标签", "用户session", "normal", 4),
+    ANDROID("会话android标签", "用户session", "normal", 5),
+    USER("用户轨迹user标签", "用户轨迹", "normal", 6),
+    STUDENT("用户轨迹student标签", "考生轨迹", "normal", 7),
+    EXAM_STUDENT_IMPORT("考生导入任务标签", "考生导入任务", "normal", 8),
+    ROOM_CODE_EXPORT("考场导出任务标签", "考场导出任务", "normal", 9),
+    ROOM_CODE_IMPORT("考场导入任务标签", "考场导入任务", "normal", 10),
+    EXAM_PAPER_IMPORT("试卷导入任务标签", "试卷导入任务", "normal", 11),
+    OE_IM_CLUSTERING("websocket客户端点对点发送消息标签", "客户端点对点消息", "normal", 12),
+    OE_IM_BROADCASTING("websocket客户端广播发送消息标签", "客户端广播消息", "normal", 13),
+    OE_MONITOR_FINISH("websocket客户端监考强制离线(交卷)标签", "监考强制离线(交卷)", "normal", 14),
+    OE_WARNING_FINISH("websocket客户端预警强制离线(交卷)标签", "预警强制离线(交卷)", "normal", 15),
+    OE_HARD_FINISH("websocket客户端手动(交卷)标签", "手动(交卷)", "normal", 16),
+    OE_LIVENESS_VERIFY("websocket客户端监考强制活体验证标签", "监考强制活体验证", "normal", 17),
+    OE_UN_NORMAL("websocket超时退出标签", "websocket超时退出超时退出", "delay", 18),
+    EXAM_ACTIVITY("考场一次性延时任务标签", "考场一次性延时任务", "normal", 19),
+    QUARTZ("quartz标签", "quartz任务", "normal", 20),
+    CALCULATE_OBJECTIVE_SCORE("计算客观分标签", "计算客观分", "normal", 21),
+    FACE_VERIFY_SAVE("人脸验证保存", "人脸验证", "normal", 22),
+    LIVENESS_VERIFY_SAVE("活体验证保存", "活体验证", "normal", 23),
+    EXAM_RECORD_PERSISTED("考试记录数据持久化", "考试", "normal", 24),
+    EXAM_RECORD_UPDATE("考试记录数据更新", "考试", "normal", 25),
+    EXAM_RECORD_INIT("考试记录数据初始化", "考试", "normal", 26),
+    WARNING_LOG("预警标签", "预警", "normal", 27),
+    EXCEPTION_LOG("异常标签", "异常", "normal", 28),
+    MONITOR_LOG("监考监控标签", "监考监控", "normal", 29);
 
     private MqTagEnum(String desc, String code, String type, int id) {
         this.desc = desc;

+ 12 - 9
themis-business/src/main/java/com/qmth/themis/business/enums/SystemOperationEnum.java

@@ -9,23 +9,26 @@ package com.qmth.themis.business.enums;
  */
 public enum SystemOperationEnum {
 
-    LOGIN(1, "登录"),
+    LOGIN("登录"),
 
-    LOGOUT(2, "注销");
+    LOGOUT("注销"),
 
-    private int id;
+    PREPARE("进入候考"),
+
+    ANSWERING("进入考试"),
+
+    BREAK_OFF("断点"),
+
+    RESUME_PREPARE("断点恢复候考"),
+
+    FINISHED("交卷");
 
     private String code;
 
-    private SystemOperationEnum(int id, String code) {
-        this.id = id;
+    private SystemOperationEnum(String code) {
         this.code = code;
     }
 
-    public int getId() {
-        return id;
-    }
-
     public String getCode() {
         return code;
     }

+ 18 - 14
themis-business/src/main/java/com/qmth/themis/business/enums/WebsocketStatusEnum.java

@@ -1,21 +1,25 @@
 package com.qmth.themis.business.enums;
 
 /**
-* @Description: websocket 通讯状态
-* @Param:
-* @return:
-* @Author: wangliang
-* @Date: 2020/7/25
-*/
+ * @Description: websocket 通讯状态
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/25
+ */
 public enum WebsocketStatusEnum {
 
-    /**
-     * 在线
-     */
-    ONLINE,
+    ON_LINE("在线"),
 
-    /**
-     * 离线
-     */
-    UN_ONLINE;
+    OFF_LINE("离线");
+
+    private String code;
+
+    private WebsocketStatusEnum(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
 }

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

@@ -15,9 +15,8 @@ public interface TEExamStudentLogService extends IService<TEExamStudentLog> {
     /**
      * 保存学生轨迹
      *
-     * @param mqTimestamp
      * @param o
      * @return
      */
-    public boolean saveStudentLogInfo(long mqTimestamp, Object... o);
+    public boolean saveStudentLogInfo(Object... o);
 }

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

@@ -15,9 +15,8 @@ public interface TEUserLogService extends IService<TEUserLog> {
     /**
      * 保存用户轨迹
      *
-     * @param mqTimestamp
      * @param o
      * @return
      */
-    public boolean saveUserLogInfo(long mqTimestamp, Object... o);
+    public boolean saveUserLogInfo(Object... o);
 }

+ 9 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamStudentLogServiceImpl.java

@@ -6,6 +6,8 @@ import com.qmth.themis.business.entity.TEExamStudentLog;
 import com.qmth.themis.business.service.TEExamStudentLogService;
 import org.springframework.stereotype.Service;
 
+import java.util.Objects;
+
 /**
  * @Description: 考生轨迹 服务实现类
  * @Param:
@@ -19,13 +21,17 @@ public class TEExamStudentLogServiceImpl extends ServiceImpl<TEExamStudentLogMap
     /**
      * 保存学生轨迹
      *
-     * @param mqTimestamp
      * @param o
      * @return
      */
     @Override
-    public boolean saveStudentLogInfo(long mqTimestamp, Object... o) {
-        TEExamStudentLog teExamStudentLog = new TEExamStudentLog(Integer.parseInt(String.valueOf(o[0])), String.valueOf(o[1]), String.valueOf(o[2]), Long.parseLong(String.valueOf(o[3])));
+    public boolean saveStudentLogInfo(Object... o) {
+        TEExamStudentLog teExamStudentLog = null;
+        if (Objects.nonNull(o) && o.length == 4) {
+            teExamStudentLog = new TEExamStudentLog(String.valueOf(o[0]), String.valueOf(o[1]), String.valueOf(o[2]), Long.parseLong(String.valueOf(o[3])));
+        } else if (Objects.nonNull(o) && o.length == 6) {
+            teExamStudentLog = new TEExamStudentLog(String.valueOf(o[0]), String.valueOf(o[1]), String.valueOf(o[2]), Long.parseLong(String.valueOf(o[3])), Long.parseLong(String.valueOf(o[4])), Long.parseLong(String.valueOf(o[5])));
+        }
         this.save(teExamStudentLog);
         return true;
     }

+ 7 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEUserLogServiceImpl.java

@@ -8,6 +8,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import java.util.Objects;
+
 /**
  * @Description: 用户轨迹 服务实现类
  * @Param:
@@ -22,13 +24,15 @@ public class TEUserLogServiceImpl extends ServiceImpl<TEUserLogMapper, TEUserLog
     /**
      * 保存用户轨迹
      *
-     * @param mqTimestamp
      * @param o
      * @return
      */
     @Override
-    public boolean saveUserLogInfo(long mqTimestamp, Object... o) {
-        TEUserLog teUserLog = new TEUserLog(Long.parseLong(String.valueOf(o[0])), Integer.parseInt(String.valueOf(o[1])), String.valueOf(o[2]), String.valueOf(o[3]));
+    public boolean saveUserLogInfo(Object... o) {
+        TEUserLog teUserLog = null;
+        if (Objects.nonNull(o) && o.length == 4) {
+            teUserLog = new TEUserLog(String.valueOf(o[0]), String.valueOf(o[1]), String.valueOf(o[2]), Long.parseLong(String.valueOf(o[3])));
+        }
         this.save(teUserLog);
         return true;
     }

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

@@ -1131,7 +1131,8 @@ CREATE TABLE `t_ie_exam_invigilate_notice` (
   `exam_id` bigint NOT NULL COMMENT '考试ID',
   `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
   `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
-  `user_id` bigint NOT NULL COMMENT '监考人ID',
+  `form_user_id` bigint DEFAULT NULL COMMENT '发送人id',
+  `receive_user_id` bigint NOT NULL COMMENT '接收人id',
   `type` varchar(30) NOT NULL COMMENT '消息类型',
   `content` varchar(1000) NOT NULL COMMENT '消息内容',
   `send_time` datetime DEFAULT NULL COMMENT '发送时间',
@@ -1305,7 +1306,7 @@ CREATE TABLE `t_oe_exam_record` (
   `last_start_time` datetime DEFAULT NULL COMMENT '最近恢复开考时间',
   `left_break_resume_count` int DEFAULT NULL COMMENT '剩余断点续考次数',
   `client_current_ip` varchar(30) DEFAULT NULL COMMENT '客户端当前IP地址',
-  `client_websocket_status` tinyint DEFAULT NULL COMMENT '客户端websocket状态',
+  `client_websocket_status` varchar(30) DEFAULT NULL COMMENT '客户端websocket状态',
   `client_websocket_id` varchar(50) DEFAULT NULL COMMENT '客户端websocket连接标识',
   `client_last_sync_time` datetime DEFAULT NULL COMMENT '客户端最近同步时间',
   `answer_progress` double DEFAULT NULL COMMENT '答题进度',

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

@@ -2,14 +2,20 @@ package com.qmth.themis.exam.listener.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.google.gson.Gson;
+import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 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.entity.TIeExamInvigilateNotice;
 import com.qmth.themis.business.entity.TMRocketMessage;
 import com.qmth.themis.business.enums.FinishTypeEnum;
+import com.qmth.themis.business.enums.MessageTypeEnum;
 import com.qmth.themis.business.enums.MqTagEnum;
 import com.qmth.themis.business.enums.WebsocketTypeEnum;
 import com.qmth.themis.business.service.TEExamStudentLogService;
+import com.qmth.themis.business.service.TEExamStudentService;
+import com.qmth.themis.business.service.TIeExamInvigilateNoticeService;
 import com.qmth.themis.business.service.TMRocketMessageService;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
@@ -48,6 +54,12 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
     @Resource
     TEExamStudentLogService teExamStudentLogService;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
+    @Resource
+    TIeExamInvigilateNoticeService tIeExamInvigilateNoticeService;
+
     /**
      * mq最大重试次数逻辑
      *
@@ -88,6 +100,9 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
             examRecordId.forEach(s -> {
                 Long recordId = Long.parseLong(String.valueOf(s));
                 if (Objects.nonNull(webSocketMap.get(recordId))) {
+                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+                    Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                    ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                     Map map = new HashMap<>();
                     map.put("form", mqDto.getObjName());
@@ -95,6 +110,7 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
                     map.put(SystemConstant.MESSAGE, FinishTypeEnum.valueOf(String.valueOf(mqDto.getProperties().get("type"))).getCode());
                     WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.INVIGILATE_STOP_EXAM.name(), map);
                     webSocketOeServer.sendMessage(websocketDto);
+                    teExamStudentLogService.saveStudentLogInfo(mqDto.getType().name(), mqDto.getType().getCode(), mqDto.getType().getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
                 }
             });
         } else if (tag.contains(MqTagEnum.OE_HARD_FINISH.name())) {//手动交卷
@@ -102,12 +118,16 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
             examRecordId.forEach(s -> {
                 Long recordId = Long.parseLong(String.valueOf(s));
                 if (Objects.nonNull(webSocketMap.get(recordId))) {
+                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+                    Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                    ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                     Map map = new HashMap<>();
                     map.put(SystemConstant.RECORD_ID, recordId);
                     map.put(SystemConstant.MESSAGE, FinishTypeEnum.valueOf(String.valueOf(mqDto.getProperties().get("type"))).getCode());
                     WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.HAND_STOP_EXAM.name(), map);
                     webSocketOeServer.sendMessage(websocketDto);
+                    teExamStudentLogService.saveStudentLogInfo(mqDto.getType().name(), mqDto.getType().getCode(), mqDto.getType().getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
                 }
             });
         } else if (tag.contains(MqTagEnum.OE_WARNING_FINISH.name())) {//预警交卷
@@ -115,17 +135,25 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
             examRecordId.forEach(s -> {
                 Long recordId = Long.parseLong(String.valueOf(s));
                 if (Objects.nonNull(webSocketMap.get(recordId))) {
+                    Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+                    Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                    ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                     WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                     Map map = new HashMap<>();
                     map.put(SystemConstant.RECORD_ID, recordId);
                     map.put(SystemConstant.BREACH_STATUS, FinishTypeEnum.valueOf(String.valueOf(mqDto.getProperties().get("type"))).getCode());
                     WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.BREACH_STOP_EXAM.name(), map);
                     webSocketOeServer.sendMessage(websocketDto);
+                    teExamStudentLogService.saveStudentLogInfo(mqDto.getType().name(), mqDto.getType().getCode(), mqDto.getType().getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
                 }
             });
         } else if (tag.contains(MqTagEnum.OE_IM_CLUSTERING.name())) {//点对点消息
             Long recordId = Long.parseLong(String.valueOf(mqDto.getBody()));
             if (Objects.nonNull(webSocketMap.get(recordId))) {
+                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+                Long examId = Long.parseLong(String.valueOf(objectMap.get("examId")));
+                Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                Long examActivityId = Long.parseLong(String.valueOf(objectMap.get("examActivityId")));
                 WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                 Map<String, Object> prop = mqDto.getProperties();
                 Map map = new HashMap<>();
@@ -135,6 +163,8 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
                 map.put("content", prop.get("content"));
                 WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.INVIGILATE_NOTICE.name(), map);
                 webSocketOeServer.sendMessage(websocketDto);
+                TIeExamInvigilateNotice tIeExamInvigilateNotice = new TIeExamInvigilateNotice(examId, examActivityId, recordId, Long.parseLong(mqDto.getObjId()), examStudentId, MessageTypeEnum.valueOf(String.valueOf(prop.get("type"))), String.valueOf(prop.get("content")));
+                tIeExamInvigilateNoticeService.saveOrUpdate(tIeExamInvigilateNotice);
             }
         } else if (tag.contains(MqTagEnum.OE_IM_BROADCASTING.name())) {//广播消息
             JSONArray jsonArray = JSONArray.parseArray(String.valueOf(mqDto.getBody()));
@@ -143,15 +173,18 @@ public class MqOeLogicServiceImpl implements MqOeLogicService {
         } else if (tag.contains(MqTagEnum.OE_LIVENESS_VERIFY.name())) {//监考强制活体验证
             Long recordId = Long.parseLong(String.valueOf(mqDto.getBody()));
             if (Objects.nonNull(webSocketMap.get(recordId))) {
+                Map<String, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(recordId));
+                Long examStudentId = Long.parseLong(String.valueOf(objectMap.get("examStudentId")));
+                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
                 WebSocketOeServer webSocketOeServer = webSocketMap.get(recordId);
                 Map map = new HashMap<>();
                 map.put(SystemConstant.RECORD_ID, recordId);
                 WebsocketDto websocketDto = new WebsocketDto(WebsocketTypeEnum.INVIGILATE_LIVENESS_VERIFY.name(), map);
                 webSocketOeServer.sendMessage(websocketDto);
+                teExamStudentLogService.saveStudentLogInfo(mqDto.getType().name(), mqDto.getType().getCode(), mqDto.getType().getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
             }
         }
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
-//        teExamStudentLogService.saveStudentLogInfo(mqDto.getTimestamp(), MqTagEnum.valueOf(String.valueOf(mqDto.getType())).getId(), mqDto.getType().getCode(), JacksonUtil.parseJson(mqDto));
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
         tmRocketMessage.setBody(JacksonUtil.parseJson(tmRocketMessage.getBody()));
         tmRocketMessageService.saveOrUpdate(tmRocketMessage);

+ 6 - 2
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -123,9 +123,13 @@ public class MqLogicServiceImpl implements MqLogicService {
         Gson gson = new Gson();
         String tag = mqDto.getTag();
         if (tag.contains(MqTagEnum.USER.name())) {
-            teUserLogService.saveUserLogInfo(mqDto.getTimestamp(), mqDto.getObjId(), MqTagEnum.valueOf(String.valueOf(mqDto.getType())).getId(), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), JacksonUtil.parseJson(mqDto));
+            teUserLogService.saveUserLogInfo(String.valueOf(mqDto.getBody()), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), mqDto.getObjId());
         } else if (tag.contains(MqTagEnum.STUDENT.name())) {
-            teExamStudentLogService.saveStudentLogInfo(mqDto.getTimestamp(), MqTagEnum.valueOf(String.valueOf(mqDto.getType())).getId(), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), JacksonUtil.parseJson(mqDto), mqDto.getObjId());
+            if (Objects.nonNull(mqDto.getProperties())) {
+                teExamStudentLogService.saveStudentLogInfo(String.valueOf(mqDto.getBody()), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), mqDto.getProperties().get("remark"), mqDto.getObjId(), mqDto.getProperties().get("examStudentId"), mqDto.getProperties().get("examRecordId"));
+            } else {
+                teExamStudentLogService.saveStudentLogInfo(String.valueOf(mqDto.getBody()), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), mqDto.getObjId());
+            }
         }
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);