wangliang 2 жил өмнө
parent
commit
7015bc703b

+ 16 - 0
themis-business/src/main/java/com/qmth/themis/business/dao/TSLogMapper.java

@@ -0,0 +1,16 @@
+package com.qmth.themis.business.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.themis.business.entity.TSLog;
+
+/**
+ * <p>
+ * 系统日志 Mapper 接口
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-09-22
+ */
+public interface TSLogMapper extends BaseMapper<TSLog> {
+
+}

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

@@ -200,6 +200,9 @@ public class TEExam extends BaseEntity {
     @TableField(value = "in_process_realness_verify")
     private Integer inProcessRealnessVerify;
 
+    @ApiModelProperty(value = "扫描时间")
+    private Long scanTime;
+
     public TEExam() {
 
     }
@@ -280,6 +283,14 @@ public class TEExam extends BaseEntity {
         this.monitorStatus = teExamDto.getMonitorStatus();
     }
 
+    public Long getScanTime() {
+        return scanTime;
+    }
+
+    public void setScanTime(Long scanTime) {
+        this.scanTime = scanTime;
+    }
+
     public Integer getInProcessRealnessVerify() {
         return inProcessRealnessVerify;
     }

+ 140 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TSLog.java

@@ -0,0 +1,140 @@
+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.LogEnum;
+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 2022-09-22
+ */
+@ApiModel(value = "TSLog对象", description = "系统日志")
+public class TSLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键")
+    private Long id;
+
+    @ApiModelProperty(value = "实体类别")
+    private LogEnum obj;
+
+    @ApiModelProperty(value = "实体名称")
+    private String objName;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "实体id")
+    private Long objId;
+
+    @ApiModelProperty(value = "更改前内容")
+    private String updateBeforeObj;
+
+    @ApiModelProperty(value = "更改后内容")
+    private String updateAfterObj;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "创建人id")
+    private Long createId;
+
+    @ApiModelProperty(value = "创建时间")
+    private Long createTime;
+
+    public TSLog() {
+
+    }
+
+    public TSLog(LogEnum obj, String objName, String updateBeforeObj, String updateAfterObj, Long createId) {
+        this.id = UidUtil.nextId();
+        this.obj = obj;
+        this.objName = objName;
+        this.updateBeforeObj = updateBeforeObj;
+        this.updateAfterObj = updateAfterObj;
+        this.createId = createId;
+        this.createTime = System.currentTimeMillis();
+    }
+
+    public TSLog(LogEnum obj, String objName, String updateBeforeObj, String updateAfterObj, Long createId, Long objId) {
+        this.id = UidUtil.nextId();
+        this.obj = obj;
+        this.objName = objName;
+        this.updateBeforeObj = updateBeforeObj;
+        this.updateAfterObj = updateAfterObj;
+        this.createId = createId;
+        this.createTime = System.currentTimeMillis();
+        this.objId = objId;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public LogEnum getObj() {
+        return obj;
+    }
+
+    public void setObj(LogEnum obj) {
+        this.obj = obj;
+    }
+
+    public String getObjName() {
+        return objName;
+    }
+
+    public void setObjName(String objName) {
+        this.objName = objName;
+    }
+
+    public Long getObjId() {
+        return objId;
+    }
+
+    public void setObjId(Long objId) {
+        this.objId = objId;
+    }
+
+    public String getUpdateBeforeObj() {
+        return updateBeforeObj;
+    }
+
+    public void setUpdateBeforeObj(String updateBeforeObj) {
+        this.updateBeforeObj = updateBeforeObj;
+    }
+
+    public String getUpdateAfterObj() {
+        return updateAfterObj;
+    }
+
+    public void setUpdateAfterObj(String updateAfterObj) {
+        this.updateAfterObj = updateAfterObj;
+    }
+
+    public Long getCreateId() {
+        return createId;
+    }
+
+    public void setCreateId(Long createId) {
+        this.createId = createId;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+}

+ 31 - 0
themis-business/src/main/java/com/qmth/themis/business/enums/LogEnum.java

@@ -0,0 +1,31 @@
+package com.qmth.themis.business.enums;
+
+/**
+ * @Description: 日志枚举
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/9/22
+ */
+public enum LogEnum {
+
+    JOB("定时任务"),
+
+    ORG("机构"),
+
+    STUDENT("学生"),
+
+    EXAM("考试批次"),
+
+    EXAM_ACTIVITY("考试场次");
+
+    private String title;
+
+    private LogEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+}

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

@@ -14,7 +14,6 @@ import java.util.Objects;
  */
 public enum TencentEventTypeEnum {
 
-
     EVENT_TYPE_CREATE_ROOM("101", "创建房间", null),
 
     EVENT_TYPE_DISMISS_ROOM("102", "解散房间", null),

+ 16 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TSLogService.java

@@ -0,0 +1,16 @@
+package com.qmth.themis.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.themis.business.entity.TSLog;
+
+/**
+ * <p>
+ * 系统日志 服务类
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-09-22
+ */
+public interface TSLogService extends IService<TSLog> {
+
+}

+ 27 - 24
themis-business/src/main/java/com/qmth/themis/business/service/impl/CommonServiceImpl.java

@@ -6,7 +6,6 @@ import com.qmth.themis.business.cache.ExamingDataCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
-import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.entity.TOeExamBreakHistory;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.MqTagEnum;
@@ -104,30 +103,34 @@ public class CommonServiceImpl implements CommonService {
      */
     @Override
     public void deleteExamStudentCache(Long recordId, Long studentId) {
-        //判断当前结束的考试记录ID是否是未完成的考试记录ID
-        if (Objects.equals(recordId, ExamingDataCacheUtil.getUnFinishedRecordId(studentId))) {
-            ExamingDataCacheUtil.deleteUnFinishedRecordId(studentId);
-        }
-        if (Objects.equals(recordId, ExamingDataCacheUtil.getExamingRecordId(studentId))) {
-            ExamingDataCacheUtil.deleteExamingRecordId(studentId);
-        }
+        try {
+            //判断当前结束的考试记录ID是否是未完成的考试记录ID
+            if (Objects.equals(recordId, ExamingDataCacheUtil.getUnFinishedRecordId(studentId))) {
+                ExamingDataCacheUtil.deleteUnFinishedRecordId(studentId);
+            }
+            if (Objects.equals(recordId, ExamingDataCacheUtil.getExamingRecordId(studentId))) {
+                ExamingDataCacheUtil.deleteExamingRecordId(studentId);
+            }
 
-        redisUtil.delete(RedisKeyHelper.examRecordCacheKey(recordId));
-        redisUtil.delete(RedisKeyHelper.examAnswerKey(recordId));
-        redisUtil.delete(RedisKeyHelper.audioLeftPlayCountKey(recordId));
-        redisUtil.delete(RedisKeyHelper.livenessVerifyCacheKey(recordId));
-        redisUtil.delete(RedisKeyHelper.faceVerifyCacheKey(recordId));
-        //2021-03-01新增
-        redisUtil.delete(RedisKeyHelper.studentPaperStructKey(recordId));
-        //先查询之前的断点记录
-        QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();
-        tOeExamBreakHistoryQueryWrapper.lambda().eq(TOeExamBreakHistory::getExamRecordId, recordId);
-        List<TOeExamBreakHistory> tOeExamBreakHistoryList = tOeExamBreakHistoryService.list(tOeExamBreakHistoryQueryWrapper);
-        //删除历史断点缓存
-        if (Objects.nonNull(tOeExamBreakHistoryList) && tOeExamBreakHistoryList.size() > 0) {
-            tOeExamBreakHistoryList.forEach(s -> {
-                redisUtil.delete(RedisKeyHelper.examBreakCacheKey(s.getId()));
-            });
+            redisUtil.delete(RedisKeyHelper.examRecordCacheKey(recordId));
+            redisUtil.delete(RedisKeyHelper.examAnswerKey(recordId));
+            redisUtil.delete(RedisKeyHelper.audioLeftPlayCountKey(recordId));
+            redisUtil.delete(RedisKeyHelper.livenessVerifyCacheKey(recordId));
+            redisUtil.delete(RedisKeyHelper.faceVerifyCacheKey(recordId));
+            //2021-03-01新增
+            redisUtil.delete(RedisKeyHelper.studentPaperStructKey(recordId));
+            //先查询之前的断点记录
+            QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();
+            tOeExamBreakHistoryQueryWrapper.lambda().eq(TOeExamBreakHistory::getExamRecordId, recordId);
+            List<TOeExamBreakHistory> tOeExamBreakHistoryList = tOeExamBreakHistoryService.list(tOeExamBreakHistoryQueryWrapper);
+            //删除历史断点缓存
+            if (Objects.nonNull(tOeExamBreakHistoryList) && tOeExamBreakHistoryList.size() > 0) {
+                tOeExamBreakHistoryList.forEach(s -> {
+                    redisUtil.delete(RedisKeyHelper.examBreakCacheKey(s.getId()));
+                });
+            }
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
         }
     }
 

+ 20 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TSLogServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qmth.themis.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.themis.business.dao.TSLogMapper;
+import com.qmth.themis.business.entity.TSLog;
+import com.qmth.themis.business.service.TSLogService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 系统日志 服务实现类
+ * </p>
+ *
+ * @author wangliang
+ * @since 2022-09-22
+ */
+@Service
+public class TSLogServiceImpl extends ServiceImpl<TSLogMapper, TSLog> implements TSLogService {
+
+}

+ 5 - 0
themis-business/src/main/resources/mapper/TSLogMapper.xml

@@ -0,0 +1,5 @@
+<?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.TSLogMapper">
+
+</mapper>

+ 11 - 12
themis-task/src/main/java/com/qmth/themis/task/ThemisTaskApplication.java

@@ -1,26 +1,16 @@
 package com.qmth.themis.task;
 
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.task.listener.MyJobListener;
 import org.mybatis.spring.annotation.MapperScan;
+import org.quartz.Scheduler;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Primary;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
 import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
-import org.springframework.web.multipart.MultipartResolver;
-import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 
 @SpringBootApplication
 @ComponentScan(basePackages = {"com.qmth.themis"})
@@ -36,4 +26,13 @@ public class ThemisTaskApplication {
     public static void main(String[] args) {
         SpringApplication.run(ThemisTaskApplication.class, args);
     }
+
+    @Bean
+    public Scheduler scheduler(Scheduler scheduler) throws Exception {
+        // 添加Scheduler 监听器
+//        KeyMatcher<JobKey> keyMatcher = KeyMatcher.keyEquals(JobKey.jobKey(QuartzTaskEnum.MQ_ACTIVITY_JOB_NAME.name(), QuartzTaskEnum.MQ_ACTIVITY_JOB_GROUP_NAME.name()));
+//        scheduler.getListenerManager().addJobListener(new MyJobListener(), keyMatcher);
+        scheduler.getListenerManager().addJobListener(new MyJobListener());
+        return scheduler;
+    }
 }

+ 1 - 2
themis-task/src/main/java/com/qmth/themis/task/enums/QuartzTaskEnum.java

@@ -23,8 +23,7 @@ public enum QuartzTaskEnum {
     
     OBJECTIVE_ANSWER_CACHE_LOAD_JOB_NAME("客观题缓存加载"),
     
-    OBJECTIVE_ANSWER_CACHE_LOAD_JOB_GROUP_NAME("客观题缓存加载")
-    ;
+    OBJECTIVE_ANSWER_CACHE_LOAD_JOB_GROUP_NAME("客观题缓存加载");
 
     private QuartzTaskEnum(String code) {
         this.code = code;

+ 66 - 0
themis-task/src/main/java/com/qmth/themis/task/listener/MyJobListener.java

@@ -0,0 +1,66 @@
+package com.qmth.themis.task.listener;
+
+import cn.hutool.core.date.DateUtil;
+import com.qmth.themis.business.constant.SpringContextHolder;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.entity.TSLog;
+import com.qmth.themis.business.enums.LogEnum;
+import com.qmth.themis.business.service.TSLogService;
+import com.qmth.themis.common.contanst.Constants;
+import com.qmth.themis.task.enums.QuartzTaskEnum;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.quartz.JobListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+
+/**
+ * @Description: job监听
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2022/9/22
+ */
+public class MyJobListener implements JobListener {
+    private final static Logger log = LoggerFactory.getLogger(MyJobListener.class);
+
+    @Override
+    public String getName() {
+        return "myJobListener";
+    }
+
+    @Override
+    public void jobToBeExecuted(JobExecutionContext context) {
+        log.info("定时任务:{}-开始执行", context.getTrigger().getJobKey());
+    }
+
+    @Override
+    public void jobExecutionVetoed(JobExecutionContext context) {
+
+    }
+
+    @Override
+    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
+        QuartzTaskEnum quartzTaskEnum = QuartzTaskEnum.valueOf(context.getTrigger().getJobKey().getGroup());
+        switch (quartzTaskEnum) {
+            case EXAM_ACTIVITY_JOB_GROUP_NAME:
+            case EXAM_STUDENT_JOB_GROUP_NAME:
+            case MQ_ACTIVITY_JOB_GROUP_NAME:
+                try {
+                    TSLogService tsLogService = SpringContextHolder.getBean(TSLogService.class);
+                    tsLogService.save(new TSLog(LogEnum.JOB, quartzTaskEnum.name(),
+                            Objects.nonNull(context.getPreviousFireTime()) ? DateUtil.format(context.getPreviousFireTime(), Constants.DEFAULT_DATE_PATTERN) : null,
+                            Objects.nonNull(context.getNextFireTime()) ? DateUtil.format(context.getNextFireTime(), Constants.DEFAULT_DATE_PATTERN) : null,
+                            -1L));
+                } catch (Exception e) {
+                    log.error(SystemConstant.LOG_ERROR, e);
+                }
+                break;
+            default:
+                break;
+        }
+        log.info("定时任务:{}-执行结束", context.getTrigger().getJobKey());
+    }
+}

+ 5 - 4
themis-task/src/main/java/com/qmth/themis/task/quartz/MqActivityJob.java

@@ -7,9 +7,9 @@ import com.qmth.themis.business.entity.TEExamActivity;
 import com.qmth.themis.business.entity.TOeExamRecord;
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
 import com.qmth.themis.business.enums.FinishTypeEnum;
-import com.qmth.themis.business.enums.InvigilateMonitorStatusEnum;
 import com.qmth.themis.business.service.*;
 import org.quartz.JobExecutionContext;
+import org.quartz.Trigger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.quartz.QuartzJobBean;
@@ -56,9 +56,8 @@ public class MqActivityJob extends QuartzJobBean {
         Long finishTime = System.currentTimeMillis();
         QueryWrapper<TEExam> teExamQueryWrapper = new QueryWrapper<>();
         teExamQueryWrapper.lambda().eq(TEExam::getEnable, 1)
-//                .eq(TEExam::getForceFinish, 0)
-                .ne(TEExam::getMonitorStatus, InvigilateMonitorStatusEnum.FINISHED)
-                .le(TEExam::getEndTime, finishTime);
+                .le(TEExam::getEndTime, finishTime)
+                .isNull(TEExam::getScanTime);
         List<TEExam> teExamList = teExamService.list(teExamQueryWrapper);
         if (Objects.nonNull(teExamList) && teExamList.size() > 0) {
             for (TEExam exam : teExamList) {
@@ -92,7 +91,9 @@ public class MqActivityJob extends QuartzJobBean {
                         }
                     });
                 }
+                exam.setScanTime(finishTime);
             }
+            teExamService.saveOrUpdateBatch(teExamList);
         }
     }
 }