소스 검색

考试记录新增预警记录未读数

wangliang 1 년 전
부모
커밋
b5d35d0299
25개의 변경된 파일614개의 추가작업 그리고 195개의 파일을 삭제
  1. 3 2
      themis-admin/src/main/java/com/qmth/themis/admin/api/TENotifyController.java
  2. 0 2
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateCallMobileController.java
  3. 11 14
      themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateController.java
  4. 41 0
      themis-business/src/main/java/com/qmth/themis/business/bean/status/WarningCountBean.java
  5. 41 0
      themis-business/src/main/java/com/qmth/themis/business/bean/status/WarningUnreadBean.java
  6. 50 12
      themis-business/src/main/java/com/qmth/themis/business/cache/ExamRecordCacheUtil.java
  7. 1 0
      themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java
  8. 26 0
      themis-business/src/main/java/com/qmth/themis/business/dao/TIeExamMediaLogMapper.java
  9. 11 0
      themis-business/src/main/java/com/qmth/themis/business/entity/TEExamStudentLog.java
  10. 7 31
      themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamInvigilateCall.java
  11. 11 26
      themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamInvigilateCallLog.java
  12. 208 0
      themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamMediaLog.java
  13. 3 1
      themis-business/src/main/java/com/qmth/themis/business/enums/FieldUniqueEnum.java
  14. 26 0
      themis-business/src/main/java/com/qmth/themis/business/service/TIeExamMediaLogService.java
  15. 17 0
      themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java
  16. 32 0
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TIeExamMediaLogServiceImpl.java
  17. 59 74
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java
  18. 26 0
      themis-business/src/main/resources/db/log/1.2.8.log
  19. 0 1
      themis-business/src/main/resources/mapper/TIeExamInvigilateNoticeMapper.xml
  20. 9 0
      themis-business/src/main/resources/mapper/TIeExamMediaLogMapper.xml
  21. 1 1
      themis-business/src/main/resources/mapper/TOeExamRecordMapper.xml
  22. 0 9
      themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java
  23. 0 2
      themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallMobileController.java
  24. 0 2
      themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallOeController.java
  25. 31 18
      themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

+ 3 - 2
themis-admin/src/main/java/com/qmth/themis/admin/api/TENotifyController.java

@@ -344,10 +344,11 @@ public class TENotifyController {
         }
         }
         String liveUrl = SystemConstant.setStreamId(sysConfig.getConfigValue(), recordId, source);
         String liveUrl = SystemConstant.setStreamId(sysConfig.getConfigValue(), recordId, source);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
-//        TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START, monitorKey, callStatus, null, null, ExamInvigilateCallCacheUtil.getBatchId(recordId));
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START, monitorKey, callStatus, null, null);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, MonitorStatusSourceEnum.START, monitorKey, callStatus, null, null);
-        if (callStatus == MonitorCallStatusSourceEnum.CALLING) {
+        if (callStatus == MonitorCallStatusSourceEnum.START) {
             tIeExamInvigilateCallLog.setStartTime(eventTime);
             tIeExamInvigilateCallLog.setStartTime(eventTime);
+        } else if (callStatus == MonitorCallStatusSourceEnum.CALLING) {
+            tIeExamInvigilateCallLog.setCallTime(eventTime);
         } else if (callStatus == MonitorCallStatusSourceEnum.STOP) {
         } else if (callStatus == MonitorCallStatusSourceEnum.STOP) {
             tIeExamInvigilateCallLog.setEndTime(eventTime);
             tIeExamInvigilateCallLog.setEndTime(eventTime);
         }
         }

+ 0 - 2
themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateCallMobileController.java

@@ -225,7 +225,6 @@ public class TIeInvigilateCallMobileController {
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-//        TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.CALLING, ExamRecordCacheUtil.getExamStudentId(recordId), tbUser.getId(), ExamInvigilateCallCacheUtil.getBatchId(recordId));
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.CALLING, ExamRecordCacheUtil.getExamStudentId(recordId), tbUser.getId());
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.CALLING, ExamRecordCacheUtil.getExamStudentId(recordId), tbUser.getId());
         //监考监控通话信息 发送mq start
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(),
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(),
@@ -285,7 +284,6 @@ public class TIeInvigilateCallMobileController {
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
         TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
-//        TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP, ExamRecordCacheUtil.getExamStudentId(recordId), tbUser.getId(), ExamInvigilateCallCacheUtil.getBatchId(recordId));
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP, ExamRecordCacheUtil.getExamStudentId(recordId), tbUser.getId());
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.STOP, ExamRecordCacheUtil.getExamStudentId(recordId), tbUser.getId());
         //监考监控通话信息 发送mq start
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(),
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(),

+ 11 - 14
themis-admin/src/main/java/com/qmth/themis/admin/api/TIeInvigilateController.java

@@ -95,6 +95,9 @@ public class TIeInvigilateController {
     @Resource
     @Resource
     TIeExamInvigilateNoticeService tIeExamInvigilateNoticeService;
     TIeExamInvigilateNoticeService tIeExamInvigilateNoticeService;
 
 
+    @Resource
+    TIeExamMediaLogService tIeExamMediaLogService;
+
     @ApiOperation(value = "实时监控台视频列表接口")
     @ApiOperation(value = "实时监控台视频列表接口")
     @RequestMapping(value = "/list/video", method = RequestMethod.POST)
     @RequestMapping(value = "/list/video", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListVideoBean.class)})
     @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListVideoBean.class)})
@@ -349,20 +352,6 @@ public class TIeInvigilateController {
                 .orderByAsc(TEExamStudentLog::getCreateTime);
                 .orderByAsc(TEExamStudentLog::getCreateTime);
         //                .and(w -> w.ne(TEExamStudentLog::getType, SystemOperationEnum.BREACH_HANDLE.name()).or().ne(TEExamStudentLog::getType, SystemOperationEnum.BREACH_REVOKE.name()));
         //                .and(w -> w.ne(TEExamStudentLog::getType, SystemOperationEnum.BREACH_HANDLE.name()).or().ne(TEExamStudentLog::getType, SystemOperationEnum.BREACH_REVOKE.name()));
         List<TEExamStudentLog> teExamStudentLogList = teExamStudentLogService.list(teExamStudentLogQueryWrapper);
         List<TEExamStudentLog> teExamStudentLogList = teExamStudentLogService.list(teExamStudentLogQueryWrapper);
-        if (!CollectionUtils.isEmpty(teExamStudentLogList)) {
-            for (TEExamStudentLog t : teExamStudentLogList) {
-                if (Objects.equals(t.getType(), MessageTypeEnum.MEDIA.name())) {
-                    t.setMsgType(MessageTypeEnum.MEDIA);
-                    t.setMsgTypeStr(MessageTypeEnum.MEDIA.getCode());
-                    t.setContent(t.getRemark());
-                    t.setFormUserName(t.getInfo());
-                    t.setType(null);
-                    t.setInfo(null);
-                    t.setRemark(null);
-                }
-            }
-            teExamStudentLogList = teExamStudentLogList.get(0).ipChange(teExamStudentLogList);
-        }
 
 
         //加入文本和语音消息轨迹
         //加入文本和语音消息轨迹
         List<TIeExamInvigilateNotice> tIeExamInvigilateNoticeList = tIeExamInvigilateNoticeService.queryNoticeByExamRecordId(examRecordId);
         List<TIeExamInvigilateNotice> tIeExamInvigilateNoticeList = tIeExamInvigilateNoticeService.queryNoticeByExamRecordId(examRecordId);
@@ -371,6 +360,14 @@ public class TIeInvigilateController {
                 teExamStudentLogList.add(new TEExamStudentLog(teStudent.getId(), examStudentId, t.getExamRecordId(), t.getType(), t.getContent(), t.getFormUserId(), t.getFormUserName(), t.getSendTime()));
                 teExamStudentLogList.add(new TEExamStudentLog(teStudent.getId(), examStudentId, t.getExamRecordId(), t.getType(), t.getContent(), t.getFormUserId(), t.getFormUserName(), t.getSendTime()));
             }
             }
         }
         }
+
+        //加入多媒体消息轨迹
+        List<TIeExamMediaLog> tIeExamMediaLogList = tIeExamMediaLogService.queryMediaByExamRecordId(examRecordId);
+        if (!CollectionUtils.isEmpty(tIeExamMediaLogList)) {
+            for (TIeExamMediaLog t : tIeExamMediaLogList) {
+                teExamStudentLogList.add(new TEExamStudentLog(teStudent.getId(), examStudentId, t.getExamRecordId(), t.getType(), t.getContent(), t.getCreateTime()));
+            }
+        }
         Collections.sort(teExamStudentLogList);
         Collections.sort(teExamStudentLogList);
         invigilateListDetailBean.setExamStudentLogList(teExamStudentLogList);
         invigilateListDetailBean.setExamStudentLogList(teExamStudentLogList);
         //预警、异常、人脸
         //预警、异常、人脸

+ 41 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/status/WarningCountBean.java

@@ -0,0 +1,41 @@
+package com.qmth.themis.business.bean.status;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 预警数bean
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/5
+ */
+public class WarningCountBean implements Serializable {
+
+    Integer number;
+    Long timestamp;//时间戳
+
+    public WarningCountBean() {
+
+    }
+
+    public WarningCountBean(Integer number, Long timestamp) {
+        this.number = number;
+        this.timestamp = timestamp;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+}

+ 41 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/status/WarningUnreadBean.java

@@ -0,0 +1,41 @@
+package com.qmth.themis.business.bean.status;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 预警未读数bean
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/5/5
+ */
+public class WarningUnreadBean implements Serializable {
+
+    Integer number;
+    Long timestamp;//时间戳
+
+    public WarningUnreadBean() {
+
+    }
+
+    public WarningUnreadBean(Integer number, Long timestamp) {
+        this.number = number;
+        this.timestamp = timestamp;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+}

+ 50 - 12
themis-business/src/main/java/com/qmth/themis/business/cache/ExamRecordCacheUtil.java

@@ -254,6 +254,22 @@ public class ExamRecordCacheUtil {
         }
         }
     }
     }
 
 
+    public static WarningCountBean getWarningCountBean(Long recordId) {
+        return Objects.nonNull(
+                redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_count.getCode())) ?
+                (WarningCountBean) redisUtil
+                        .get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_count.getCode()) :
+                null;
+    }
+
+    public static WarningUnreadBean getWarningUnreadBean(Long recordId) {
+        return Objects.nonNull(
+                redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_unread.getCode())) ?
+                (WarningUnreadBean) redisUtil
+                        .get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_unread.getCode()) :
+                null;
+    }
+
     public static ExamStatusBean getStatusBean(Long recordId) {
     public static ExamStatusBean getStatusBean(Long recordId) {
         return Objects.nonNull(
         return Objects.nonNull(
                 redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.status.getCode())) ?
                 redisUtil.get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.status.getCode())) ?
@@ -301,28 +317,50 @@ public class ExamRecordCacheUtil {
                 .get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.exam_activity_id.getCode());
                 .get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.exam_activity_id.getCode());
     }
     }
 
 
-    public static void setWarningCount(Long recordId, Integer warningCount) {
-        if (Objects.nonNull(getId(recordId))) {
-            redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_count.getCode(),
-                    warningCount);
+    public static void setWarningCount(Long recordId, Integer warningCount, Long timestamp) {
+        WarningCountBean warningCountBean = getWarningCountBean(recordId);
+        if (Objects.isNull(warningCountBean)) {
+            warningCountBean = new WarningCountBean(warningCount, timestamp);
+        } else {
+            if (Objects.nonNull(warningCountBean.getTimestamp()) && warningCountBean.getTimestamp().longValue() < timestamp
+                    .longValue()) {
+                warningCountBean.setNumber(warningCount);
+                warningCountBean.setTimestamp(timestamp);
+            }
         }
         }
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_count.getCode(), warningCountBean);
     }
     }
 
 
     public static Integer getWarningCount(Long recordId) {
     public static Integer getWarningCount(Long recordId) {
-        return (Integer) redisUtil
-                .get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_count.getCode());
+        WarningCountBean warningCountBean = getWarningCountBean(recordId);
+        if (Objects.isNull(warningCountBean) || Objects.isNull(warningCountBean.getNumber())) {
+            return null;
+        } else {
+            return warningCountBean.getNumber();
+        }
     }
     }
 
 
-    public static void setWarningUnread(Long recordId, Integer warningUnread) {
-        if (Objects.nonNull(getId(recordId))) {
-            redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_unread.getCode(),
-                    warningUnread);
+    public static void setWarningUnread(Long recordId, Integer warningUnread, Long timestamp) {
+        WarningUnreadBean warningUnreadBean = getWarningUnreadBean(recordId);
+        if (Objects.isNull(warningUnreadBean)) {
+            warningUnreadBean = new WarningUnreadBean(warningUnread, timestamp);
+        } else {
+            if (Objects.nonNull(warningUnreadBean.getTimestamp()) && warningUnreadBean.getTimestamp().longValue() < timestamp
+                    .longValue()) {
+                warningUnreadBean.setNumber(warningUnread);
+                warningUnreadBean.setTimestamp(timestamp);
+            }
         }
         }
+        redisUtil.set(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_unread.getCode(), warningUnreadBean);
     }
     }
 
 
     public static Integer getWarningUnread(Long recordId) {
     public static Integer getWarningUnread(Long recordId) {
-        return (Integer) redisUtil
-                .get(RedisKeyHelper.examRecordCacheKey(recordId), ExamRecordFieldEnum.warning_unread.getCode());
+        WarningUnreadBean warningUnreadBean = getWarningUnreadBean(recordId);
+        if (Objects.isNull(warningUnreadBean) || Objects.isNull(warningUnreadBean.getNumber())) {
+            return null;
+        } else {
+            return warningUnreadBean.getNumber();
+        }
     }
     }
 
 
     public static void setBreachStatus(Long recordId, Integer breachStatus, Long timestamp) {
     public static void setBreachStatus(Long recordId, Integer breachStatus, Long timestamp) {

+ 1 - 0
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -197,6 +197,7 @@ public class SystemConstant {
     public static final String OPER = "oper";
     public static final String OPER = "oper";
     public static final String EXAM = "exam";
     public static final String EXAM = "exam";
     public static final String WARNING_COUNT_UPDATE = "warning_count_update";
     public static final String WARNING_COUNT_UPDATE = "warning_count_update";
+    public static final String WARNING_UNREAD_UPDATE = "warning_unread_update";
     //    public static final String EXEC_TIME = "execTime";
     //    public static final String EXEC_TIME = "execTime";
 //    public static final String REAL_EXEC_TIME = "realExecTime";
 //    public static final String REAL_EXEC_TIME = "realExecTime";
     public static final String INSERT = "insert";
     public static final String INSERT = "insert";

+ 26 - 0
themis-business/src/main/java/com/qmth/themis/business/dao/TIeExamMediaLogMapper.java

@@ -0,0 +1,26 @@
+package com.qmth.themis.business.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.themis.business.entity.TIeExamMediaLog;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 多媒体日志表 Mapper 接口
+ * </p>
+ *
+ * @author wangliang
+ * @since 2023-10-26
+ */
+public interface TIeExamMediaLogMapper extends BaseMapper<TIeExamMediaLog> {
+
+    /**
+     * 根据考试记录id查询多媒体消息
+     *
+     * @param examRecordId
+     * @return
+     */
+    List<TIeExamMediaLog> queryMediaByExamRecordId(@Param("examRecordId") Long examRecordId);
+}

+ 11 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TEExamStudentLog.java

@@ -129,12 +129,23 @@ public class TEExamStudentLog implements Serializable, Comparable<TEExamStudentL
         this.examStudentId = examStudentId;
         this.examStudentId = examStudentId;
         this.examRecordId = examRecordId;
         this.examRecordId = examRecordId;
         this.msgType = msgType;
         this.msgType = msgType;
+        this.msgTypeStr = msgType.getCode();
         this.content = content;
         this.content = content;
         this.formUserId = formUserId;
         this.formUserId = formUserId;
         this.formUserName = formUserName;
         this.formUserName = formUserName;
         this.createTime = createTime;
         this.createTime = createTime;
     }
     }
 
 
+    public TEExamStudentLog(Long studentId, Long examStudentId, Long examRecordId, MessageTypeEnum msgType, String content, Long createTime) {
+        this.studentId = studentId;
+        this.examStudentId = examStudentId;
+        this.examRecordId = examRecordId;
+        this.msgType = msgType;
+        this.msgTypeStr = msgType.getCode();
+        this.content = content;
+        this.createTime = createTime;
+    }
+
     public TEExamStudentLog(String type, String info, String remark, Long studentId, String ip,
     public TEExamStudentLog(String type, String info, String remark, Long studentId, String ip,
                             String country, String region, String province, String city, String isp) {
                             String country, String region, String province, String city, String isp) {
         this.id = UidUtil.nextId();
         this.id = UidUtil.nextId();

+ 7 - 31
themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamInvigilateCall.java

@@ -70,6 +70,9 @@ public class TIeExamInvigilateCall extends BaseEntity {
     @ApiModelProperty(value = "开始通话时间")
     @ApiModelProperty(value = "开始通话时间")
     private Long startTime;
     private Long startTime;
 
 
+    @ApiModelProperty(value = "接通时间")
+    private Long callTime;
+
     @TableField(value = "end_time")
     @TableField(value = "end_time")
     @ApiModelProperty(value = "结束通话时间")
     @ApiModelProperty(value = "结束通话时间")
     private Long endTime;
     private Long endTime;
@@ -86,39 +89,12 @@ public class TIeExamInvigilateCall extends BaseEntity {
     @ApiModelProperty(value = "接收人id")
     @ApiModelProperty(value = "接收人id")
     private Long receiveUserId;
     private Long receiveUserId;
 
 
-    @ApiModelProperty(value = "发送人名称")
-    @TableField(exist = false)
-    private String formUserName;
-
-    @ApiModelProperty(value = "接收人名称")
-    @TableField(exist = false)
-    private String receiveUserName;
-
-//    @ApiModelProperty(value = "批次id")
-//    private String batchId;
-//
-//    public String getBatchId() {
-//        return batchId;
-//    }
-//
-//    public void setBatchId(String batchId) {
-//        this.batchId = batchId;
-//    }
-
-    public String getFormUserName() {
-        return formUserName;
-    }
-
-    public void setFormUserName(String formUserName) {
-        this.formUserName = formUserName;
-    }
-
-    public String getReceiveUserName() {
-        return receiveUserName;
+    public Long getCallTime() {
+        return callTime;
     }
     }
 
 
-    public void setReceiveUserName(String receiveUserName) {
-        this.receiveUserName = receiveUserName;
+    public void setCallTime(Long callTime) {
+        this.callTime = callTime;
     }
     }
 
 
     public Long getFormUserId() {
     public Long getFormUserId() {

+ 11 - 26
themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamInvigilateCallLog.java

@@ -82,13 +82,13 @@ public class TIeExamInvigilateCallLog extends BaseEntity {
     @ApiModelProperty(value = "开始通话时间")
     @ApiModelProperty(value = "开始通话时间")
     private Long startTime;
     private Long startTime;
 
 
+    @ApiModelProperty(value = "接通时间")
+    private Long callTime;
+
     @TableField(value = "end_time")
     @TableField(value = "end_time")
     @ApiModelProperty(value = "结束通话时间")
     @ApiModelProperty(value = "结束通话时间")
     private Long endTime;
     private Long endTime;
 
 
-//    @ApiModelProperty(value = "批次id")
-//    private String batchId;
-
     public TIeExamInvigilateCallLog() {
     public TIeExamInvigilateCallLog() {
 
 
     }
     }
@@ -106,29 +106,14 @@ public class TIeExamInvigilateCallLog extends BaseEntity {
         this.formUserId = formUserId;
         this.formUserId = formUserId;
         this.receiveUserId = receiveUserId;
         this.receiveUserId = receiveUserId;
     }
     }
-//
-//    public TIeExamInvigilateCallLog(Long examRecordId, MonitorVideoSourceEnum source, String liveUrl,
-//                                    MonitorStatusSourceEnum status, String monitorKey, MonitorCallStatusSourceEnum callStatus, Long formUserId, Long receiveUserId, String batchId
-//    ) {
-//        setId(UidUtil.nextId());
-//        setExamRecordId(examRecordId);
-//        setSource(source);
-//        setLiveUrl(liveUrl);
-//        setStatus(status);
-//        setCallStatus(callStatus);
-//        setMonitorKey(monitorKey);
-//        this.formUserId = formUserId;
-//        this.receiveUserId = receiveUserId;
-//        this.batchId = batchId;
-//    }
-
-//    public String getBatchId() {
-//        return batchId;
-//    }
-//
-//    public void setBatchId(String batchId) {
-//        this.batchId = batchId;
-//    }
+
+    public Long getCallTime() {
+        return callTime;
+    }
+
+    public void setCallTime(Long callTime) {
+        this.callTime = callTime;
+    }
 
 
     public Long getFormUserId() {
     public Long getFormUserId() {
         return formUserId;
         return formUserId;

+ 208 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TIeExamMediaLog.java

@@ -0,0 +1,208 @@
+package com.qmth.themis.business.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.themis.business.enums.MessageTypeEnum;
+import com.qmth.themis.business.enums.MonitorVideoSourceEnum;
+import com.qmth.themis.business.util.UidUtil;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 监控观看地址和通话申请表
+ * </p>
+ *
+ * @author wangliang
+ * @since 2023-10-26
+ */
+@ApiModel(value = "TIeExamMediaLog对象", description = "多媒体日志表")
+public class TIeExamMediaLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long id;
+
+    @ApiModelProperty(value = "考试id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examId;
+
+    @ApiModelProperty(value = "场次id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examActivityId;
+
+    @ApiModelProperty(value = "考生id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examStudentId;
+
+    @ApiModelProperty(value = "考试记录id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examRecordId;
+
+    @ApiModelProperty(value = "状态")
+    private MonitorVideoSourceEnum source;
+
+    @ApiModelProperty(value = "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty(value = "类型")
+    private MessageTypeEnum type;
+
+    @ApiModelProperty(value = "内容")
+    private String content;
+
+    @ApiModelProperty(value = "开始通话时间")
+    private Long startTime;
+
+    @ApiModelProperty(value = "接通时间")
+    private Long callTime;
+
+    @ApiModelProperty(value = "结束通话时间")
+    private Long endTime;
+
+    @ApiModelProperty(value = "发起人id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long formUserId;
+
+    @ApiModelProperty(value = "接收人id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long receiveUserId;
+
+    public TIeExamMediaLog() {
+
+    }
+
+    public TIeExamMediaLog(Long examId, Long examActivityId, Long examStudentId, Long examRecordId, MonitorVideoSourceEnum source,
+                           String content, Long startTime, Long callTime, Long endTime, Long formUserId, Long receiveUserId) {
+        this.id = UidUtil.nextId();
+        this.examId = examId;
+        this.examActivityId = examActivityId;
+        this.examStudentId = examStudentId;
+        this.examRecordId = examRecordId;
+        this.source = source;
+        this.type = MessageTypeEnum.MEDIA;
+        this.content = content;
+        this.startTime = startTime;
+        this.callTime = callTime;
+        this.endTime = endTime;
+        this.formUserId = formUserId;
+        this.receiveUserId = receiveUserId;
+        this.createTime = System.currentTimeMillis();
+    }
+
+    public Long getCallTime() {
+        return callTime;
+    }
+
+    public void setCallTime(Long callTime) {
+        this.callTime = callTime;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    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 MonitorVideoSourceEnum getSource() {
+        return source;
+    }
+
+    public void setSource(MonitorVideoSourceEnum source) {
+        this.source = source;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    public MessageTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(MessageTypeEnum type) {
+        this.type = type;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Long startTime) {
+        this.startTime = startTime;
+    }
+
+    public Long getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Long endTime) {
+        this.endTime = endTime;
+    }
+
+    public Long getFormUserId() {
+        return formUserId;
+    }
+
+    public void setFormUserId(Long formUserId) {
+        this.formUserId = formUserId;
+    }
+
+    public Long getReceiveUserId() {
+        return receiveUserId;
+    }
+
+    public void setReceiveUserId(Long receiveUserId) {
+        this.receiveUserId = receiveUserId;
+    }
+}

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

@@ -41,7 +41,9 @@ public enum FieldUniqueEnum {
 
 
     activity_idx("语音消息"),
     activity_idx("语音消息"),
 
 
-    soft_index("软件和进程名称");
+    soft_index("软件和进程名称"),
+
+    t_ie_exam_media_log_UN_content("多媒体消息");
 
 
     private String code;
     private String code;
 
 

+ 26 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TIeExamMediaLogService.java

@@ -0,0 +1,26 @@
+package com.qmth.themis.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.themis.business.entity.TIeExamInvigilateNotice;
+import com.qmth.themis.business.entity.TIeExamMediaLog;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 多媒体日志表 服务类
+ * </p>
+ *
+ * @author wangliang
+ * @since 2023-10-26
+ */
+public interface TIeExamMediaLogService extends IService<TIeExamMediaLog> {
+
+    /**
+     * 根据考试记录id查询多媒体消息
+     *
+     * @param examRecordId
+     * @return
+     */
+    List<TIeExamMediaLog> queryMediaByExamRecordId(Long examRecordId);
+}

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

@@ -68,6 +68,15 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      */
      */
     void sendExamRecordDataUpdateWarningCountMq(Long recordId, Long timestamp);
     void sendExamRecordDataUpdateWarningCountMq(Long recordId, Long timestamp);
 
 
+    /**
+     * 发送mq更新考试预警未读数量
+     *
+     * @param recordId
+     * @param timestamp
+     * @param number
+     */
+    void sendExamRecordDataUpdateWarningUnreadMq(Long recordId, Long timestamp, Integer number);
+
     /**
     /**
      * 发送mq更新考试记录
      * 发送mq更新考试记录
      *
      *
@@ -626,6 +635,14 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
      */
      */
     void updateWarningCount(Long id);
     void updateWarningCount(Long id);
 
 
+    /**
+     * 根据id更新预警未读数量
+     *
+     * @param id
+     * @param number
+     */
+    void updateWarningUnread(Long id, Integer number);
+
     /**
     /**
      * 更新预警总数
      * 更新预警总数
      *
      *

+ 32 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TIeExamMediaLogServiceImpl.java

@@ -0,0 +1,32 @@
+package com.qmth.themis.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.themis.business.dao.TIeExamMediaLogMapper;
+import com.qmth.themis.business.entity.TIeExamMediaLog;
+import com.qmth.themis.business.service.TIeExamMediaLogService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 多媒体日志表 服务实现类
+ * </p>
+ *
+ * @author wangliang
+ * @since 2023-10-26
+ */
+@Service
+public class TIeExamMediaLogServiceImpl extends ServiceImpl<TIeExamMediaLogMapper, TIeExamMediaLog> implements TIeExamMediaLogService {
+
+    /**
+     * 根据考试记录id查询多媒体消息
+     *
+     * @param examRecordId
+     * @return
+     */
+    @Override
+    public List<TIeExamMediaLog> queryMediaByExamRecordId(Long examRecordId) {
+        return this.baseMapper.queryMediaByExamRecordId(examRecordId);
+    }
+}

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

@@ -478,6 +478,12 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             if (Objects.nonNull(o) && o instanceof BreachStatusBean) {
             if (Objects.nonNull(o) && o instanceof BreachStatusBean) {
                 record.put(ExamRecordFieldEnum.breach_status.getCode(), ((BreachStatusBean) o).getStatus());
                 record.put(ExamRecordFieldEnum.breach_status.getCode(), ((BreachStatusBean) o).getStatus());
             }
             }
+            if (Objects.nonNull(o) && o instanceof WarningCountBean) {
+                record.put(ExamRecordFieldEnum.warning_count.getCode(), ((WarningCountBean) o).getNumber());
+            }
+            if (Objects.nonNull(o) && o instanceof WarningUnreadBean) {
+                record.put(ExamRecordFieldEnum.warning_unread.getCode(), ((WarningUnreadBean) o).getNumber());
+            }
             er = GsonUtil.fromJson(GsonUtil.toJson(record), TOeExamRecord.class);
             er = GsonUtil.fromJson(GsonUtil.toJson(record), TOeExamRecord.class);
         }
         }
         return er;
         return er;
@@ -513,6 +519,17 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         this.baseMapper.updateWarningCount(id);
         this.baseMapper.updateWarningCount(id);
     }
     }
 
 
+    /**
+     * 根据id更新预警未读数量
+     *
+     * @param id
+     * @param number
+     */
+    @Override
+    public void updateWarningUnread(Long id, Integer number) {
+        this.baseMapper.updateWarningUnread(id, number);
+    }
+
     /**
     /**
      * 更新预警总数
      * 更新预警总数
      *
      *
@@ -520,47 +537,20 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
      */
      */
     @Override
     @Override
     public void updateWarningCountCache(Long id) {
     public void updateWarningCountCache(Long id) {
-        boolean lock = false;
-        for (int i = 0; i < SystemConstant.MAX_EXAM_STATUS_COUNT; i++) {
-            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_WARN_COUNT_PREFIX + id, SystemConstant.REDIS_LOCK_EXAM_WARN_COUNT_TIME_OUT);
-            if (lock) {
-                try {
-                    Integer warningCount = ExamRecordCacheUtil.getWarningCount(id);
-                    if (Objects.nonNull(warningCount)) {
-                        ExamRecordCacheUtil.setWarningCount(id, warningCount + 1);
-                    } else {
-                        ExamRecordCacheUtil.setWarningCount(id, 1);
-                    }
-                    Integer warningUnread = ExamRecordCacheUtil.getWarningUnread(id);
-                    if (Objects.nonNull(warningUnread)) {
-                        ExamRecordCacheUtil.setWarningUnread(id, warningUnread + 1);
-                    } else {
-                        ExamRecordCacheUtil.setWarningUnread(id, 1);
-                    }
-                    this.sendExamRecordDataUpdateWarningCountMq(id, System.currentTimeMillis());
-                } catch (Exception e) {
-                    log.error(SystemConstant.LOG_ERROR, e);
-                    if (e instanceof BusinessException) {
-                        throw new BusinessException(e.getMessage());
-                    } else {
-                        throw new RuntimeException(e);
-                    }
-                } finally {
-                    if (Objects.nonNull(id)) {
-                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_WARN_COUNT_PREFIX + id);
-                    }
-                }
-            } else {
-                try {
-                    Thread.sleep(500);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-            }
+        Integer warningCount = ExamRecordCacheUtil.getWarningCount(id);
+        long timestamp = System.currentTimeMillis();
+        if (Objects.nonNull(warningCount)) {
+            ExamRecordCacheUtil.setWarningCount(id, warningCount + 1, timestamp);
+        } else {
+            ExamRecordCacheUtil.setWarningCount(id, 1, timestamp);
         }
         }
-        if (!lock) {
-            tgErrorService.saveExamTgError(id, "updateWarningCountCache");
+        Integer warningUnread = ExamRecordCacheUtil.getWarningUnread(id);
+        if (Objects.nonNull(warningUnread)) {
+            ExamRecordCacheUtil.setWarningUnread(id, warningUnread + 1, timestamp);
+        } else {
+            ExamRecordCacheUtil.setWarningUnread(id, 1, timestamp);
         }
         }
+        this.sendExamRecordDataUpdateWarningCountMq(id, System.currentTimeMillis());
     }
     }
 
 
     /**
     /**
@@ -572,42 +562,16 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     @Override
     @Override
     @Transactional
     @Transactional
     public void updateWarningUnreadCache(Long id, Integer number) {
     public void updateWarningUnreadCache(Long id, Integer number) {
-        boolean lock = false;
-        for (int i = 0; i < SystemConstant.MAX_EXAM_STATUS_COUNT; i++) {
-            lock = redisUtil.lock(SystemConstant.REDIS_LOCK_EXAM_WARN_UNREAD_PREFIX + id, SystemConstant.REDIS_LOCK_EXAM_WARN_UNREAD_TIME_OUT);
-            if (lock) {
-                try {
-                    Integer warningUnread = ExamRecordCacheUtil.getWarningUnread(id);
-                    if (Objects.nonNull(warningUnread) && warningUnread.intValue() == 0) {
-                        ExamRecordCacheUtil.setWarningUnread(id, number);
-                    } else if (Objects.nonNull(warningUnread) && warningUnread.intValue() > 0) {
-                        Integer warningCount = warningUnread - number;
-                        ExamRecordCacheUtil.setWarningUnread(id, warningCount.intValue() < 0 ? 0 : warningCount);
-                    }
-                    this.baseMapper.updateWarningUnread(id, number);
-                } catch (Exception e) {
-                    log.error(SystemConstant.LOG_ERROR, e);
-                    if (e instanceof BusinessException) {
-                        throw new BusinessException(e.getMessage());
-                    } else {
-                        throw new RuntimeException(e);
-                    }
-                } finally {
-                    if (Objects.nonNull(id)) {
-                        redisUtil.releaseLock(SystemConstant.REDIS_LOCK_EXAM_WARN_UNREAD_PREFIX + id);
-                    }
-                }
-            } else {
-                try {
-                    Thread.sleep(500);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        if (!lock) {
-            tgErrorService.saveExamTgError(id, "updateWarningUnreadCache");
+        long timestamp = System.currentTimeMillis();
+        Integer warningUnread = ExamRecordCacheUtil.getWarningUnread(id);
+        if (Objects.nonNull(warningUnread) && warningUnread.intValue() == 0) {
+            ExamRecordCacheUtil.setWarningUnread(id, number, timestamp);
+        } else if (Objects.nonNull(warningUnread) && warningUnread.intValue() > 0) {
+            ExamRecordCacheUtil.setWarningUnread(id, warningUnread - number, timestamp);
+        } else {
+            ExamRecordCacheUtil.setWarningUnread(id, 0, timestamp);
         }
         }
+        this.sendExamRecordDataUpdateWarningUnreadMq(id, System.currentTimeMillis(), number);
     }
     }
 
 
     @Override
     @Override
@@ -685,6 +649,27 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         }
         }
     }
     }
 
 
+    /**
+     * 发送mq更新考试预警未读数量
+     *
+     * @param recordId
+     * @param timestamp
+     * @param number
+     */
+    @Override
+    public void sendExamRecordDataUpdateWarningUnreadMq(Long recordId, Long timestamp, Integer number) {
+        try {
+            ExamRecordCacheUtil.setUpdateTime(recordId, timestamp);
+            Map<String, Object> properties = new HashMap<>();
+            properties.put(SystemConstant.NUMBER, number);
+            MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.EXAM_RECORD_UPDATE.name(), recordId.toString(), SystemConstant.WARNING_UNREAD_UPDATE, timestamp);
+            mqDto.setProperties(properties);
+            mqDtoService.assembleSendAsyncMsg(mqDto);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+    }
+
     /**
     /**
      * 发送mq更新考试记录
      * 发送mq更新考试记录
      *
      *

+ 26 - 0
themis-business/src/main/resources/db/log/1.2.8.log

@@ -33,6 +33,32 @@ ALTER TABLE t_ie_exam_invigilate_call_log ADD start_time BIGINT NULL COMMENT '
 ALTER TABLE t_ie_exam_invigilate_call_log ADD end_time BIGINT NULL COMMENT '结束通话时间';
 ALTER TABLE t_ie_exam_invigilate_call_log ADD end_time BIGINT NULL COMMENT '结束通话时间';
 ALTER TABLE t_oe_exam_record ADD warning_unread INTEGER NULL COMMENT '预警记录未读数';
 ALTER TABLE t_oe_exam_record ADD warning_unread INTEGER NULL COMMENT '预警记录未读数';
 
 
+ALTER TABLE t_ie_exam_invigilate_call ADD call_time BIGINT NULL COMMENT '接通时间';
+ALTER TABLE t_ie_exam_invigilate_call CHANGE call_time call_time BIGINT NULL COMMENT '接通时间' AFTER start_time;
+ALTER TABLE t_ie_exam_invigilate_call_log ADD call_time BIGINT NULL COMMENT '接通时间';
+ALTER TABLE t_ie_exam_invigilate_call_log CHANGE call_time call_time BIGINT NULL COMMENT '接通时间' AFTER start_time;
+
+DROP TABLE IF EXISTS `t_ie_exam_media_log`;
+CREATE TABLE `t_ie_exam_media_log` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试id',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次id',
+  `exam_student_id` bigint NOT NULL COMMENT '考生id',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录id',
+  `source` varchar(30) DEFAULT NULL COMMENT '状态',
+  `create_time` bigint DEFAULT NULL COMMENT '创建时间',
+  `type` varchar(20) DEFAULT NULL COMMENT '类型',
+  `content` varchar(500) DEFAULT NULL COMMENT '内容',
+  `start_time` bigint DEFAULT NULL COMMENT '开始通话时间',
+  `call_time` bigint DEFAULT NULL COMMENT '接通时间',
+  `end_time` bigint DEFAULT NULL COMMENT '结束通话时间',
+  `form_user_id` bigint DEFAULT NULL COMMENT '发起人id',
+  `receive_user_id` bigint DEFAULT NULL COMMENT '接收人id',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `t_ie_exam_media_log_UN_content` (`exam_record_id`,`source`,`content`,`start_time`,`end_time`),
+  KEY `t_ie_exam_media_log_exam_record_id_IDX` (`exam_record_id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='多媒体日志表';
+
 /*删除进度查询菜单*/
 /*删除进度查询菜单*/
 INSERT INTO t_b_role_privilege
 INSERT INTO t_b_role_privilege
 (id, role_code, privilege_id)
 (id, role_code, privilege_id)

+ 0 - 1
themis-business/src/main/resources/mapper/TIeExamInvigilateNoticeMapper.xml

@@ -12,7 +12,6 @@
         from
         from
             t_ie_exam_invigilate_notice t
             t_ie_exam_invigilate_notice t
             left join t_b_user tbu on tbu.id = t.form_user_id
             left join t_b_user tbu on tbu.id = t.form_user_id
-            left join t_b_user tbu1 on tbu1.id = t.receive_user_id
         where t.exam_record_id = #{examRecordId}
         where t.exam_record_id = #{examRecordId}
     </select>
     </select>
 </mapper>
 </mapper>

+ 9 - 0
themis-business/src/main/resources/mapper/TIeExamMediaLogMapper.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.themis.business.dao.TIeExamMediaLogMapper">
+
+    <select id="queryMediaByExamRecordId" resultType="com.qmth.themis.business.entity.TIeExamMediaLog">
+        select t.* from t_ie_exam_media_log t
+        where t.exam_record_id = #{examRecordId}
+    </select>
+</mapper>

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

@@ -1774,7 +1774,7 @@
     <update id="updateWarningUnread">
     <update id="updateWarningUnread">
         update t_oe_exam_record set
         update t_oe_exam_record set
         <choose>
         <choose>
-            <when test="number != null and number != '' and number == 0">
+            <when test="number != null and number != '' or number == 0">
                 warning_unread = #{number}
                 warning_unread = #{number}
             </when>
             </when>
             <otherwise>
             <otherwise>

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

@@ -147,8 +147,6 @@ public class TEExamController {
         SysConfig sysConfig = themisCacheService.addSysConfigCache(SystemConstant.MONITOR_CONFIG_PREFIX);
         SysConfig sysConfig = themisCacheService.addSysConfigCache(SystemConstant.MONITOR_CONFIG_PREFIX);
         Optional.ofNullable(sysConfig).orElseThrow(() -> new BusinessException("未配置监控前缀"));
         Optional.ofNullable(sysConfig).orElseThrow(() -> new BusinessException("未配置监控前缀"));
 
 
-        String liveUrl = SystemConstant.setStreamId(sysConfig.getConfigValue(), recordId, source);
-        MonitorStatusSourceEnum status = ExamRecordCacheUtil.getMonitorStatus(recordId, source);
         MonitorCallStatusSourceEnum callStatus = Objects.nonNull(ExamRecordCacheUtil.getMonitorCallStatus(recordId, source)) ? ExamRecordCacheUtil.getMonitorCallStatus(recordId, source) : null;
         MonitorCallStatusSourceEnum callStatus = Objects.nonNull(ExamRecordCacheUtil.getMonitorCallStatus(recordId, source)) ? ExamRecordCacheUtil.getMonitorCallStatus(recordId, source) : null;
         if (Objects.nonNull(callStatus) && (callStatus == MonitorCallStatusSourceEnum.START
         if (Objects.nonNull(callStatus) && (callStatus == MonitorCallStatusSourceEnum.START
                 || callStatus == MonitorCallStatusSourceEnum.CALLING)) {
                 || callStatus == MonitorCallStatusSourceEnum.CALLING)) {
@@ -159,13 +157,6 @@ public class TEExamController {
             }
             }
             ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, updateCallStatus, timestamp);
             ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, updateCallStatus, timestamp);
             tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
             tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
-//            String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
-//            TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, updateCallStatus, null, null);
-//            tIeExamInvigilateCallLog.setEndTime(System.currentTimeMillis());
-//            //监考监控通话信息 发送mq start
-//            MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
-//            mqDtoService.assembleSendAsyncMsg(mqDto);
-//            //监考监控通话信息 发送mq end
         }
         }
 
 
         ConcurrentHashMap<String, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();
         ConcurrentHashMap<String, WebSocketOeServer> webSocketMap = WebSocketOeServer.getWebSocketMap();

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

@@ -159,9 +159,7 @@ public class TIeInvigilateCallMobileController {
         ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.START, timestamp);
         ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.START, timestamp);
         tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
         tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
-//        TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START, ExamRecordCacheUtil.getExamStudentId(recordId), null, SystemConstant.getNanoId());
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START, ExamRecordCacheUtil.getExamStudentId(recordId), null);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START, ExamRecordCacheUtil.getExamStudentId(recordId), null);
-//        ExamInvigilateCallCacheUtil.expire(recordId, tIeExamInvigilateCallLog.getBatchId());
         //监考监控通话信息 发送mq start
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         mqDtoService.assembleSendAsyncMsg(mqDto);
         mqDtoService.assembleSendAsyncMsg(mqDto);

+ 0 - 2
themis-exam/src/main/java/com/qmth/themis/exam/api/TIeInvigilateCallOeController.java

@@ -240,9 +240,7 @@ public class TIeInvigilateCallOeController {
         ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.START, timestamp);
         ExamRecordCacheUtil.setMonitorCallStatus(recordId, source, MonitorCallStatusSourceEnum.START, timestamp);
         tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
         tOeExamRecordService.sendExamRecordDataSaveMq(recordId, timestamp);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
         String monitorKey = ExamRecordCacheUtil.getMonitorKey(recordId);
-//        TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START, ExamRecordCacheUtil.getExamStudentId(recordId), null, SystemConstant.getNanoId());
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START, ExamRecordCacheUtil.getExamStudentId(recordId), null);
         TIeExamInvigilateCallLog tIeExamInvigilateCallLog = new TIeExamInvigilateCallLog(recordId, source, liveUrl, status, monitorKey, MonitorCallStatusSourceEnum.START, ExamRecordCacheUtil.getExamStudentId(recordId), null);
-//        ExamInvigilateCallCacheUtil.expire(recordId, tIeExamInvigilateCallLog.getBatchId());
         //监考监控通话信息 发送mq start
         //监考监控通话信息 发送mq start
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         MqDto mqDto = new MqDto(mqUtil.getTopic(), MqTagEnum.MONITOR_LOG.name(), tIeExamInvigilateCallLog, MqTagEnum.MONITOR_LOG, String.valueOf(tIeExamInvigilateCallLog.getId()), source.name());
         mqDtoService.assembleSendAsyncMsg(mqDto);
         mqDtoService.assembleSendAsyncMsg(mqDto);

+ 31 - 18
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -132,6 +132,9 @@ public class MqLogicServiceImpl implements MqLogicService {
     @Resource
     @Resource
     TBUserService tbUserService;
     TBUserService tbUserService;
 
 
+    @Resource
+    TIeExamMediaLogService tIeExamMediaLogService;
+
     /**
     /**
      * mq最大重试次数逻辑
      * mq最大重试次数逻辑
      *
      *
@@ -700,6 +703,11 @@ public class MqLogicServiceImpl implements MqLogicService {
                 mqDto.getTimestamp().longValue() >= updateTime.longValue())) {
                 mqDto.getTimestamp().longValue() >= updateTime.longValue())) {
             if (Objects.nonNull(mqDto.getObjName()) && Objects.equals(mqDto.getObjName(), SystemConstant.WARNING_COUNT_UPDATE)) {
             if (Objects.nonNull(mqDto.getObjName()) && Objects.equals(mqDto.getObjName(), SystemConstant.WARNING_COUNT_UPDATE)) {
                 examRecordService.updateWarningCount(recordId);
                 examRecordService.updateWarningCount(recordId);
+            } else if (Objects.nonNull(mqDto.getObjName()) && Objects.equals(mqDto.getObjName(), SystemConstant.WARNING_UNREAD_UPDATE)) {
+                Map<String, Object> tranMap = mqDto.getProperties();
+                Integer number = (Integer) tranMap.get(SystemConstant.NUMBER);
+                number = Objects.isNull(number) || number < 0 ? 0 : number;
+                examRecordService.updateWarningUnread(recordId, number);
             } else {
             } else {
                 examRecordService.examRecordDataSave(recordId);
                 examRecordService.examRecordDataSave(recordId);
             }
             }
@@ -741,7 +749,6 @@ public class MqLogicServiceImpl implements MqLogicService {
             tIeExamInvigilateCallQueryWrapper.lambda()
             tIeExamInvigilateCallQueryWrapper.lambda()
                     .eq(TIeExamInvigilateCall::getExamRecordId, tIeExamInvigilateCallLog.getExamRecordId())
                     .eq(TIeExamInvigilateCall::getExamRecordId, tIeExamInvigilateCallLog.getExamRecordId())
                     .eq(TIeExamInvigilateCall::getSource, tIeExamInvigilateCallLog.getSource());
                     .eq(TIeExamInvigilateCall::getSource, tIeExamInvigilateCallLog.getSource());
-//                    .eq(TIeExamInvigilateCall::getBatchId, tIeExamInvigilateCallLog.getBatchId());
             TIeExamInvigilateCall tIeExamInvigilateCall = tIeExamInvigilateCallService.getOne(tIeExamInvigilateCallQueryWrapper);
             TIeExamInvigilateCall tIeExamInvigilateCall = tIeExamInvigilateCallService.getOne(tIeExamInvigilateCallQueryWrapper);
             //根据examRecordId和source取TIeExamInvigilateCall记录
             //根据examRecordId和source取TIeExamInvigilateCall记录
             if (Objects.isNull(tIeExamInvigilateCall)) {//没有新增
             if (Objects.isNull(tIeExamInvigilateCall)) {//没有新增
@@ -762,26 +769,32 @@ public class MqLogicServiceImpl implements MqLogicService {
                     tIeExamInvigilateCall.setStartTime(System.currentTimeMillis());
                     tIeExamInvigilateCall.setStartTime(System.currentTimeMillis());
                 }
                 }
                 if (Objects.equals(tIeExamInvigilateCallLog.getCallStatus(), MonitorCallStatusSourceEnum.CALLING)) {
                 if (Objects.equals(tIeExamInvigilateCallLog.getCallStatus(), MonitorCallStatusSourceEnum.CALLING)) {
-                    tIeExamInvigilateCall.setStartTime(tIeExamInvigilateCallLog.getStartTime());
+                    tIeExamInvigilateCall.setCallTime(tIeExamInvigilateCallLog.getCallTime());
                 }
                 }
                 if (Objects.equals(tIeExamInvigilateCallLog.getCallStatus(), MonitorCallStatusSourceEnum.STOP)) {
                 if (Objects.equals(tIeExamInvigilateCallLog.getCallStatus(), MonitorCallStatusSourceEnum.STOP)) {
                     tIeExamInvigilateCall.setEndTime(tIeExamInvigilateCallLog.getEndTime());
                     tIeExamInvigilateCall.setEndTime(tIeExamInvigilateCallLog.getEndTime());
-                    //往studentLog表里插数据
-                    String formUserName = null, receiveUserName = null;
-                    ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-                    TBUser formTbUser = tbUserService.getById(tIeExamInvigilateCall.getFormUserId());
-                    formUserName = Objects.isNull(formTbUser) ? examStudentCacheBean.getName() : formTbUser.getName();
-                    TBUser receiveTbUser = tbUserService.getById(tIeExamInvigilateCall.getReceiveUserId());
-                    receiveUserName = Objects.isNull(receiveTbUser) ? examStudentCacheBean.getName() : receiveTbUser.getName();
-                    Date startDate = new Date(tIeExamInvigilateCall.getStartTime());
-                    Date endDate = new Date(tIeExamInvigilateCall.getEndTime());
-                    StringJoiner stringJoiner = new StringJoiner("");
-                    stringJoiner.add("发起人:").add(formUserName).add("\r\n").add("接收人:").add(receiveUserName).add("\r\n")
-                            .add("通话时间段:").add(DateUtil.format(startDate, Constants.DEFAULT_DATE_PATTERN)).add("~").add(DateUtil.format(endDate, Constants.DEFAULT_DATE_PATTERN)).add("\r\n")
-                            .add("持续时长约:").add(DateUtil.formatBetween(startDate, endDate, BetweenFormater.Level.SECOND));
-                    TEExamStudentLog teExamStudentLog = new TEExamStudentLog(examStudentCacheBean.getStudentId(), examStudentId,
-                            recordId, MessageTypeEnum.MEDIA.name(), formUserName, stringJoiner.toString());
-                    teExamStudentLogService.saveOrUpdate(teExamStudentLog);
+                    if (Objects.nonNull(tIeExamInvigilateCall.getCallTime()) &&
+                            tIeExamInvigilateCall.getCallTime().longValue() > tIeExamInvigilateCall.getStartTime().longValue()) {
+                        try {
+                            String formUserName = null, receiveUserName = null;
+                            ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+                            TBUser formTbUser = tbUserService.getById(tIeExamInvigilateCall.getFormUserId());
+                            formUserName = Objects.isNull(formTbUser) ? examStudentCacheBean.getName() : formTbUser.getName();
+                            TBUser receiveTbUser = tbUserService.getById(tIeExamInvigilateCall.getReceiveUserId());
+                            receiveUserName = Objects.isNull(receiveTbUser) ? examStudentCacheBean.getName() : receiveTbUser.getName();
+                            Date callDate = new Date(tIeExamInvigilateCall.getCallTime());
+                            Date endDate = new Date(tIeExamInvigilateCall.getEndTime());
+                            StringJoiner stringJoiner = new StringJoiner("");
+                            stringJoiner.add("发起人:").add(formUserName).add("\r\n").add("接收人:").add(receiveUserName).add("\r\n")
+                                    .add("通话时间段:").add(DateUtil.format(callDate, Constants.DEFAULT_DATE_PATTERN)).add("~").add(DateUtil.format(endDate, Constants.DEFAULT_DATE_PATTERN)).add("\r\n")
+                                    .add("持续时长约:").add(DateUtil.formatBetween(callDate, endDate, BetweenFormater.Level.SECOND));
+                            TIeExamMediaLog tIeExamMediaLog = new TIeExamMediaLog(examId, examActivityId, examStudentId, recordId,
+                                    tIeExamInvigilateCall.getSource(), stringJoiner.toString(), tIeExamInvigilateCall.getStartTime(),
+                                    tIeExamInvigilateCall.getCallTime(), tIeExamInvigilateCall.getEndTime(), tIeExamInvigilateCall.getFormUserId(), tIeExamInvigilateCall.getReceiveUserId());
+                            tIeExamMediaLogService.save(tIeExamMediaLog);
+                        } catch (Exception e) {
+                        }
+                    }
                 }
                 }
             }
             }
             if (Objects.nonNull(tIeExamInvigilateCall.getUpdateTime())) {
             if (Objects.nonNull(tIeExamInvigilateCall.getUpdateTime())) {