Browse Source

新增用户轨迹

wangliang 5 năm trước cách đây
mục cha
commit
1e79f4f2d1
18 tập tin đã thay đổi với 1552 bổ sung66 xóa
  1. 10 29
      themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java
  2. 14 0
      themis-business/src/main/java/com/qmth/themis/business/entity/TEUserLog.java
  3. 10 1
      themis-business/src/main/java/com/qmth/themis/business/enums/MqEnum.java
  4. 6 4
      themis-business/src/main/java/com/qmth/themis/business/listener/RocketSessionConsumer.java
  5. 46 4
      themis-business/src/main/java/com/qmth/themis/business/listener/RocketUserLogConsumer.java
  6. 2 2
      themis-business/src/main/java/com/qmth/themis/business/service/EhcacheService.java
  7. 21 0
      themis-business/src/main/java/com/qmth/themis/business/service/MqDtoService.java
  8. 7 7
      themis-business/src/main/java/com/qmth/themis/business/service/ProducerServer.java
  9. 10 10
      themis-business/src/main/java/com/qmth/themis/business/service/QuartzService.java
  10. 1 1
      themis-business/src/main/java/com/qmth/themis/business/service/TBPrivilegeService.java
  11. 1 1
      themis-business/src/main/java/com/qmth/themis/business/service/TBSessionService.java
  12. 1 1
      themis-business/src/main/java/com/qmth/themis/business/service/TBUserService.java
  13. 8 0
      themis-business/src/main/java/com/qmth/themis/business/service/TEUserLogService.java
  14. 68 0
      themis-business/src/main/java/com/qmth/themis/business/service/impl/MqDtoServiceImpl.java
  15. 16 0
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TEUserLogServiceImpl.java
  16. 9 6
      themis-business/src/main/java/com/qmth/themis/business/util/RedisUtil.java
  17. 1318 0
      themis-business/src/main/resources/db/init.sql
  18. 4 0
      themis-common/src/main/java/com/qmth/themis/common/contanst/Constants.java

+ 10 - 29
themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java

@@ -11,10 +11,9 @@ import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.enums.MqEnum;
-import com.qmth.themis.business.service.EhcacheService;
-import com.qmth.themis.business.service.ProducerServer;
-import com.qmth.themis.business.service.QuartzService;
-import com.qmth.themis.business.service.TBUserService;
+import com.qmth.themis.business.enums.RoleEnum;
+import com.qmth.themis.business.enums.SystemOperationEnum;
+import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.EhcacheUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.SessionUtil;
@@ -66,9 +65,6 @@ public class TBUserController {
     @Resource
     EhcacheService ehcacheService;
 
-    @Resource
-    ProducerServer producerServer;
-
     @Resource
     QuartzService quartzService;
 
@@ -78,6 +74,9 @@ public class TBUserController {
     @Resource
     RedisUtil redisUtil;
 
+    @Resource
+    MqDtoService mqDtoService;
+
     @ApiOperation(value = "用户登录接口")
     @RequestMapping(value = "/login/account", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = TBUser.class)})
@@ -122,28 +121,10 @@ public class TBUserController {
         Date expire = SystemConstant.getExpireTime(platform);
         TBSession tbSession = new TBSession(sessionId, String.valueOf(user.getId()), authDto.getRoleEnum().name(), platform.getSource(), platform.name(), deviceId, request.getLocalAddr(), token, expire);
         redisUtil.setUserSession(sessionId, tbSession);
-
-        MqDto mqDto = null;
-        try {
-//            for (int i = 0; i < 100; i++) {
-//                TBSession tbSession = new TBSession(sessionId, String.valueOf(user.getId()), authDto.getRoleEnum().name(), platform.getSource(), platform.name(), deviceId, request.getLocalAddr(), token, expire);
-//                redisUtil.setUserSession(sessionId, tbSession);
-//                int random = (int) (Math.random() * Source.values().length);
-            //往mq发送消息插入会话信息
-            mqDto = new MqDto(dictionaryConfig.mqConfigDomain().getSessionTopic(), platform.getSource(), tbSession, MqEnum.SESSION, tbSession.getId());
-//                mqDto = new MqDto(SystemConstant.SESSION_TOPIC, Source.values()[random].name(), tbSession, MqEnum.SESSION, tbSession.getId());
-//                mqDto.setSequence(i);
-            mqDto.setAck(SystemConstant.UNSEND_ACK_TYPE);
-            producerServer.sendOneWay(mqDto);
-            mqDto.setAck(SystemConstant.DELIVERED_ACK_TYPE);
-            redisUtil.setSessionTopicList(mqDto.getId(), mqDto);
-//            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            if (Objects.nonNull(mqDto)) {
-                mqDto.setAck(SystemConstant.UNSEND_ACK_TYPE);
-            }
-        }
+        //mq发送消息start
+        mqDtoService.assembleSendOneWayMsg(dictionaryConfig.mqConfigDomain().getSessionTopic(), platform.getSource(), tbSession, MqEnum.SESSION.name(), tbSession.getId());
+        mqDtoService.assembleSendOneWayMsg(dictionaryConfig.mqConfigDomain().getUserLogTopic(), Objects.equals(authDto.getRoleEnum().name(), RoleEnum.STUDENT.name()) ? dictionaryConfig.mqConfigDomain().getUserLogTopicStudentTag() : dictionaryConfig.mqConfigDomain().getUserLogTopicUserTag(), SystemOperationEnum.LOGIN, MqEnum.USER_LOG.name(), user.getId());
+        //mq发送消息end
         //测试
         String test = SignatureInfo.build(SignatureType.TOKEN, sessionId, token);
         Map<String, Object> map = new HashMap<>();

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

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.entity;
 
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.qmth.themis.common.contanst.Constants;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -43,6 +44,19 @@ public class TEUserLog implements Serializable {
     @TableId(value = "create_time")
     private Date createTime;
 
+    public TEUserLog() {
+
+    }
+
+    public TEUserLog(Long userId, Integer type, String description, String remark) {
+        this.id = Constants.idGen.next();
+        this.userId = userId;
+        this.type = type;
+        this.description = description;
+        this.remark = remark;
+        this.createTime = new Date();
+    }
+
     public static long getSerialVersionUID() {
         return serialVersionUID;
     }

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

@@ -33,7 +33,12 @@ public enum MqEnum {
     /**
      * 消息日志
      */
-    MESSAGE_LOG(5, "消息日志");
+    MESSAGE_LOG(5, "消息日志"),
+
+    /**
+     * 用户轨迹
+     */
+    USER_LOG(6, "用户轨迹");
 
     private int id;
 
@@ -59,6 +64,8 @@ public enum MqEnum {
             return WARMING_LOG.getId();
         } else if (Objects.equals(value.trim(), EXCEPTION_LOG.name())) {
             return EXCEPTION_LOG.getId();
+        } else if (Objects.equals(value.trim(), USER_LOG.name())) {
+            return USER_LOG.getId();
         } else {
             return MESSAGE_LOG.getId();
         }
@@ -79,6 +86,8 @@ public enum MqEnum {
             return WARMING_LOG.name();
         } else if (Objects.equals(value.trim(), EXCEPTION_LOG.getCode())) {
             return EXCEPTION_LOG.name();
+        } else if (Objects.equals(value.trim(), USER_LOG.getCode())) {
+            return USER_LOG.name();
         } else {
             return MESSAGE_LOG.name();
         }

+ 6 - 4
themis-business/src/main/java/com/qmth/themis/business/listener/RocketSessionConsumer.java

@@ -9,7 +9,9 @@ import com.qmth.themis.business.service.TBSessionService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.contanst.Constants;
 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
-import org.apache.rocketmq.client.consumer.listener.*;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
 import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
 import org.apache.rocketmq.common.message.Message;
 import org.apache.rocketmq.common.message.MessageExt;
@@ -63,13 +65,13 @@ public class RocketSessionConsumer implements
                 log.info("sessionConsumer重试次数:{}", messageExt.getReconsumeTimes());
                 MqDto mqDto = (MqDto) toJavaObject(parseObject(new String(messageExt.getBody(), Constants.CHARSET)), MqDto.class);
                 log.info("sessionConsumer接受到的消息:{}", JSONObject.toJSONString(mqDto));
-                log.info("mqDto sequence:{},tag:{}", mqDto.getSequence(), mqDto.getTag());
-                MqDto redisMqdto = (MqDto) redisUtil.getSessionTopicList(mqDto.getId());
+                log.info("sessionConsumer mqDto sequence:{},tag:{}", mqDto.getSequence(), mqDto.getTag());
+                MqDto redisMqdto = (MqDto) redisUtil.getSessionTopicList(SystemConstant.SESSION_TOPIC_ERROR_LIST, mqDto.getId());
                 if (Objects.nonNull(redisMqdto)) {
                     if (Objects.nonNull(redisMqdto.getAck()) && redisMqdto.getAck().intValue() != SystemConstant.STANDARD_ACK_TYPE) {
                         log.info("更新db");
                         tbSessionService.saveSessionInfo(toJavaObject((JSON) mqDto.getBody(), TBSession.class), redisMqdto.getTimestamp());
-                        redisUtil.deleteSessionTopicList(redisMqdto.getId());
+                        redisUtil.deleteSessionTopicList(SystemConstant.SESSION_TOPIC_ERROR_LIST, redisMqdto.getId());
                         return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                     } else {
                         log.info("消息ack未确认,重发");

+ 46 - 4
themis-business/src/main/java/com/qmth/themis/business/listener/RocketUserLogConsumer.java

@@ -1,6 +1,13 @@
 package com.qmth.themis.business.listener;
 
+import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.dto.MqDto;
+import com.qmth.themis.business.enums.MqEnum;
+import com.qmth.themis.business.enums.SystemOperationEnum;
+import com.qmth.themis.business.service.TEUserLogService;
+import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.common.contanst.Constants;
 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
@@ -12,9 +19,16 @@ import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
 import org.apache.rocketmq.spring.annotation.SelectorType;
 import org.apache.rocketmq.spring.core.RocketMQListener;
 import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.util.List;
+import java.util.Objects;
+
+import static com.alibaba.fastjson.JSON.parseObject;
+import static com.alibaba.fastjson.JSON.toJavaObject;
 
 /**
  * @Description: 普通消息监听 用户日志
@@ -23,13 +37,41 @@ import java.util.List;
  * @Author: wangliang
  * @Date: 2020/7/2
  */
+@Service
 public class RocketUserLogConsumer implements MessageListenerConcurrently {
+    private final static Logger log = LoggerFactory.getLogger(RocketUserLogConsumer.class);
 
-    @Override
-    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
-        try{
+    @Resource
+    RedisUtil redisUtil;
 
-        }catch(Exception e){
+    @Resource
+    TEUserLogService teUserLogService;
+
+    @Override
+    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+        try {
+            for (MessageExt messageExt : msgs) {
+                log.info("userLogConsumer重试次数:{}", messageExt.getReconsumeTimes());
+                MqDto mqDto = (MqDto) toJavaObject(parseObject(new String(messageExt.getBody(), Constants.CHARSET)), MqDto.class);
+                log.info("userLogConsumer接受到的消息:{}", JSONObject.toJSONString(mqDto));
+                log.info("userLogConsumer mqDto sequence:{},tag:{}", mqDto.getSequence(), mqDto.getTag());
+                MqDto redisMqdto = (MqDto) redisUtil.getSessionTopicList(SystemConstant.USERLOG_TOPIC_ERROR_LIST, mqDto.getId());
+                if (Objects.nonNull(redisMqdto)) {
+                    if (Objects.nonNull(redisMqdto.getAck()) && redisMqdto.getAck().intValue() != SystemConstant.STANDARD_ACK_TYPE) {
+                        log.info("插入用户轨迹日志");
+                        teUserLogService.saveUserLogInfo(redisMqdto.getTimestamp(), mqDto.getBid(), MqEnum.valueOf(String.valueOf(mqDto.getType())).getId(), SystemOperationEnum.valueOf(String.valueOf(mqDto.getBody())).getCode(), JSONObject.toJSONString(mqDto));
+                        redisUtil.deleteSessionTopicList(SystemConstant.USERLOG_TOPIC_ERROR_LIST, redisMqdto.getId());
+                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+                    } else {
+                        log.info("消息ack未确认,重发");
+                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+                    }
+                } else {
+                    log.info("消息数据为空,重发消息");
+                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+                }
+            }
+        } catch (Exception e) {
             e.printStackTrace();
             return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
         }

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

@@ -17,12 +17,12 @@ public interface EhcacheService {
      * @param o
      * @return
      */
-    AuthDto addAccountCache(Object o);
+    public AuthDto addAccountCache(Object o);
 
     /**
      * 删除用户缓存
      *
      * @param userId
      */
-    void removeAccountCache(Long userId);
+    public void removeAccountCache(Long userId);
 }

+ 21 - 0
themis-business/src/main/java/com/qmth/themis/business/service/MqDtoService.java

@@ -0,0 +1,21 @@
+package com.qmth.themis.business.service;
+
+import com.qmth.themis.business.dto.MqDto;
+
+/**
+ * @Description: mqdto 服务类
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/2
+ */
+public interface MqDtoService {
+
+    /**
+     * 组装单向消息
+     *
+     * @param o
+     * @return
+     */
+    public MqDto assembleSendOneWayMsg(Object... o);
+}

+ 7 - 7
themis-business/src/main/java/com/qmth/themis/business/service/ProducerServer.java

@@ -18,7 +18,7 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result syncMsg(MqDto mqDto);
+    public Result syncMsg(MqDto mqDto);
 
     /**
      * 同步顺序消息
@@ -26,7 +26,7 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result syncOrderlyMsg(MqDto mqDto);
+    public Result syncOrderlyMsg(MqDto mqDto);
 
     /**
      * 异步消息
@@ -34,7 +34,7 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result asyncMsg(MqDto mqDto);
+    public Result asyncMsg(MqDto mqDto);
 
     /**
      * 异步顺序消息
@@ -42,7 +42,7 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result asyncOrderlyMsg(MqDto mqDto);
+    public Result asyncOrderlyMsg(MqDto mqDto);
 
     /**
      * 单向消息
@@ -50,7 +50,7 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result sendOneWay(MqDto mqDto);
+    public Result sendOneWay(MqDto mqDto);
 
     /**
      * 单向顺序消息
@@ -58,7 +58,7 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result sendOneWayOrderly(MqDto mqDto);
+    public Result sendOneWayOrderly(MqDto mqDto);
 
 
     /**
@@ -67,5 +67,5 @@ public interface ProducerServer {
      * @param mqDto
      * @return
      */
-    Result sendMsgTran(MqDto mqDto);
+    public Result sendMsgTran(MqDto mqDto);
 }

+ 10 - 10
themis-business/src/main/java/com/qmth/themis/business/service/QuartzService.java

@@ -24,8 +24,8 @@ public interface QuartzService {
      * @param jobTimes
      * @param jobData
      */
-    void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
-                int jobTimes, Map jobData);
+    public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
+                       int jobTimes, Map jobData);
 
     /**
      * 增加一个job
@@ -36,7 +36,7 @@ public interface QuartzService {
      * @param jobTime
      * @param jobData
      */
-    void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData);
+    public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime, Map jobData);
 
     /**
      * 修改一个job的 时间表达式
@@ -45,7 +45,7 @@ public interface QuartzService {
      * @param jobGroupName
      * @param jobTime
      */
-    void updateJob(String jobName, String jobGroupName, String jobTime);
+    public void updateJob(String jobName, String jobGroupName, String jobTime);
 
     /**
      * 删除任务一个job
@@ -53,7 +53,7 @@ public interface QuartzService {
      * @param jobName
      * @param jobGroupName
      */
-    void deleteJob(String jobName, String jobGroupName);
+    public void deleteJob(String jobName, String jobGroupName);
 
     /**
      * 暂停一个job
@@ -61,7 +61,7 @@ public interface QuartzService {
      * @param jobName
      * @param jobGroupName
      */
-    void pauseJob(String jobName, String jobGroupName);
+    public void pauseJob(String jobName, String jobGroupName);
 
     /**
      * 恢复一个job
@@ -69,7 +69,7 @@ public interface QuartzService {
      * @param jobName
      * @param jobGroupName
      */
-    void resumeJob(String jobName, String jobGroupName);
+    public void resumeJob(String jobName, String jobGroupName);
 
     /**
      * 立即执行一个job
@@ -77,19 +77,19 @@ public interface QuartzService {
      * @param jobName
      * @param jobGroupName
      */
-    void runAJobNow(String jobName, String jobGroupName);
+    public void runAJobNow(String jobName, String jobGroupName);
 
     /**
      * 获取所有job
      *
      * @return
      */
-    List<Map<String, Object>> queryAllJob();
+    public List<Map<String, Object>> queryAllJob();
 
     /**
      * 查询正在运行的job
      *
      * @return
      */
-    List<Map<String, Object>> queryRunJob();
+    public List<Map<String, Object>> queryRunJob();
 }

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

@@ -20,5 +20,5 @@ public interface TBPrivilegeService extends IService<TBPrivilege> {
      * @param userId
      * @return
      */
-    List<TBPrivilege> getMenu(Long userId);
+    public List<TBPrivilege> getMenu(Long userId);
 }

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

@@ -19,5 +19,5 @@ public interface TBSessionService extends IService<TBSession> {
      * @param redisTimestamp
      * @return
      */
-    boolean saveSessionInfo(TBSession tbSession, long redisTimestamp);
+    public boolean saveSessionInfo(TBSession tbSession, long redisTimestamp);
 }

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

@@ -14,5 +14,5 @@ import java.util.List;
  */
 public interface TBUserService extends IService<TBUser> {
 
-    List<TBUser> selectAllUser();
+    public List<TBUser> selectAllUser();
 }

+ 8 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TEUserLogService.java

@@ -12,4 +12,12 @@ import com.qmth.themis.business.entity.TEUserLog;
  */
 public interface TEUserLogService extends IService<TEUserLog> {
 
+    /**
+     * 保存用户轨迹
+     *
+     * @param redisTimestamp
+     * @param o
+     * @return
+     */
+    public boolean saveUserLogInfo(long redisTimestamp, Object... o);
 }

+ 68 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/MqDtoServiceImpl.java

@@ -0,0 +1,68 @@
+package com.qmth.themis.business.service.impl;
+
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.dto.MqDto;
+import com.qmth.themis.business.enums.MqEnum;
+import com.qmth.themis.business.service.MqDtoService;
+import com.qmth.themis.business.service.ProducerServer;
+import com.qmth.themis.business.util.RedisUtil;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+/**
+ * @Description: mqdto 服务实现类
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/2
+ */
+@Service
+public class MqDtoServiceImpl implements MqDtoService {
+
+    @Resource
+    ProducerServer producerServer;
+
+    @Resource
+    RedisUtil redisUtil;
+
+    /**
+     * 组装单向消息
+     *
+     * @param o
+     * @return
+     */
+    @Override
+    public MqDto assembleSendOneWayMsg(Object... o) {
+        MqDto mqDto = null;
+        try {
+//            for (int i = 0; i < 100; i++) {
+//                TBSession tbSession = new TBSession(sessionId, String.valueOf(user.getId()), authDto.getRoleEnum().name(), platform.getSource(), platform.name(), deviceId, request.getLocalAddr(), token, expire);
+//                redisUtil.setUserSession(sessionId, tbSession);
+//                int random = (int) (Math.random() * Source.values().length);
+            //往mq发送消息插入会话信息
+            MqEnum mqEnum = MqEnum.valueOf(String.valueOf(o[3]));
+            mqDto = new MqDto(String.valueOf(o[0]), String.valueOf(o[1]), o[2], mqEnum, String.valueOf(o[4]));
+//                mqDto = new MqDto(SystemConstant.SESSION_TOPIC, Source.values()[random].name(), tbSession, MqEnum.SESSION, tbSession.getId());
+//                mqDto.setSequence(i);
+            mqDto.setAck(SystemConstant.DELIVERED_ACK_TYPE);
+            producerServer.sendOneWay(mqDto);
+            switch (mqEnum.ordinal()) {
+                case 0:
+                    redisUtil.setSessionTopicList(SystemConstant.SESSION_TOPIC_ERROR_LIST, mqDto.getId(), mqDto);
+                    break;
+                default:
+                    redisUtil.setSessionTopicList(SystemConstant.USERLOG_TOPIC_ERROR_LIST, mqDto.getId(), mqDto);
+                    break;
+            }
+//            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            if (Objects.nonNull(mqDto)) {
+                mqDto.setAck(SystemConstant.UNSEND_ACK_TYPE);
+            }
+        }
+        return mqDto;
+    }
+}

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

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.dao.TEUserLogMapper;
 import com.qmth.themis.business.entity.TEUserLog;
 import com.qmth.themis.business.service.TEUserLogService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 /**
@@ -15,5 +17,19 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class TEUserLogServiceImpl extends ServiceImpl<TEUserLogMapper, TEUserLog> implements TEUserLogService {
+    private final static Logger log = LoggerFactory.getLogger(TEUserLogServiceImpl.class);
 
+    /**
+     * 保存用户轨迹
+     *
+     * @param redisTimestamp
+     * @param o
+     * @return
+     */
+    @Override
+    public boolean saveUserLogInfo(long redisTimestamp, 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]));
+        this.save(teUserLog);
+        return true;
+    }
 }

+ 9 - 6
themis-business/src/main/java/com/qmth/themis/business/util/RedisUtil.java

@@ -146,30 +146,33 @@ public class RedisUtil {
     /**
      * 设置hash
      *
+     * @param key
      * @param hashKey
      * @param hashValue
      */
-    public void setSessionTopicList(String hashKey, Object hashValue) {
-        redisTemplate.opsForHash().put(SystemConstant.SESSION_TOPIC_ERROR_LIST, hashKey, hashValue);
+    public void setSessionTopicList(String key, String hashKey, Object hashValue) {
+        redisTemplate.opsForHash().put(key, hashKey, hashValue);
     }
 
     /**
      * 获取hash
      *
+     * @param key
      * @param hashKey
      * @return
      */
-    public Object getSessionTopicList(String hashKey) {
-        return redisTemplate.opsForHash().get(SystemConstant.SESSION_TOPIC_ERROR_LIST, hashKey);
+    public Object getSessionTopicList(String key, String hashKey) {
+        return redisTemplate.opsForHash().get(key, hashKey);
     }
 
     /**
      * hash删除
      *
+     * @param key
      * @param hashKey
      */
-    public void deleteSessionTopicList(String hashKey) {
-        redisTemplate.opsForHash().delete(SystemConstant.SESSION_TOPIC_ERROR_LIST, hashKey);
+    public void deleteSessionTopicList(String key, String hashKey) {
+        redisTemplate.opsForHash().delete(key, hashKey);
     }
 
     /**

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

@@ -0,0 +1,1318 @@
+-- MySQL dump 10.13  Distrib 5.7.26, for macos10.14 (x86_64)
+--
+-- Host: localhost    Database: themis
+-- ------------------------------------------------------
+-- Server version	8.0.20
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `QRTZ_BLOB_TRIGGERS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_BLOB_TRIGGERS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `TRIGGER_NAME` varchar(200) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  `BLOB_DATA` blob,
+  PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_BLOB_TRIGGERS`
+--
+
+LOCK TABLES `QRTZ_BLOB_TRIGGERS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_BLOB_TRIGGERS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_BLOB_TRIGGERS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_CALENDARS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_CALENDARS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `CALENDAR_NAME` varchar(200) NOT NULL,
+  `CALENDAR` blob NOT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_CALENDARS`
+--
+
+LOCK TABLES `QRTZ_CALENDARS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_CALENDARS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_CALENDARS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_CRON_TRIGGERS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_CRON_TRIGGERS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `TRIGGER_NAME` varchar(200) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  `CRON_EXPRESSION` varchar(120) NOT NULL,
+  `TIME_ZONE_ID` varchar(80) DEFAULT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_CRON_TRIGGERS`
+--
+
+LOCK TABLES `QRTZ_CRON_TRIGGERS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_CRON_TRIGGERS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_CRON_TRIGGERS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_FIRED_TRIGGERS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_FIRED_TRIGGERS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `ENTRY_ID` varchar(95) NOT NULL,
+  `TRIGGER_NAME` varchar(200) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  `INSTANCE_NAME` varchar(200) NOT NULL,
+  `FIRED_TIME` bigint NOT NULL,
+  `SCHED_TIME` bigint NOT NULL,
+  `PRIORITY` int NOT NULL,
+  `STATE` varchar(16) NOT NULL,
+  `JOB_NAME` varchar(200) DEFAULT NULL,
+  `JOB_GROUP` varchar(200) DEFAULT NULL,
+  `IS_NONCONCURRENT` varchar(1) DEFAULT NULL,
+  `REQUESTS_RECOVERY` varchar(1) DEFAULT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`),
+  KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`),
+  KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`),
+  KEY `IDX_QRTZ_FT_J_G` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
+  KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`),
+  KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_FIRED_TRIGGERS`
+--
+
+LOCK TABLES `QRTZ_FIRED_TRIGGERS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_FIRED_TRIGGERS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_FIRED_TRIGGERS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_JOB_DETAILS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_JOB_DETAILS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `JOB_NAME` varchar(200) NOT NULL,
+  `JOB_GROUP` varchar(200) NOT NULL,
+  `DESCRIPTION` varchar(250) DEFAULT NULL,
+  `JOB_CLASS_NAME` varchar(250) NOT NULL,
+  `IS_DURABLE` varchar(1) NOT NULL,
+  `IS_NONCONCURRENT` varchar(1) NOT NULL,
+  `IS_UPDATE_DATA` varchar(1) NOT NULL,
+  `REQUESTS_RECOVERY` varchar(1) NOT NULL,
+  `JOB_DATA` blob,
+  PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
+  KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`),
+  KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_JOB_DETAILS`
+--
+
+LOCK TABLES `QRTZ_JOB_DETAILS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_JOB_DETAILS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_JOB_DETAILS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_LOCKS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_LOCKS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_LOCKS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `LOCK_NAME` varchar(40) NOT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_LOCKS`
+--
+
+LOCK TABLES `QRTZ_LOCKS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_LOCKS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_LOCKS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_PAUSED_TRIGGER_GRPS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_PAUSED_TRIGGER_GRPS`
+--
+
+LOCK TABLES `QRTZ_PAUSED_TRIGGER_GRPS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_PAUSED_TRIGGER_GRPS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_PAUSED_TRIGGER_GRPS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_SCHEDULER_STATE`
+--
+
+DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_SCHEDULER_STATE` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `INSTANCE_NAME` varchar(200) NOT NULL,
+  `LAST_CHECKIN_TIME` bigint NOT NULL,
+  `CHECKIN_INTERVAL` bigint NOT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_SCHEDULER_STATE`
+--
+
+LOCK TABLES `QRTZ_SCHEDULER_STATE` WRITE;
+/*!40000 ALTER TABLE `QRTZ_SCHEDULER_STATE` DISABLE KEYS */;
+INSERT INTO `QRTZ_SCHEDULER_STATE` VALUES ('ClusterQuartz','kingdeMacBook-Air.local1593682790876',1593683183321,5000);
+/*!40000 ALTER TABLE `QRTZ_SCHEDULER_STATE` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_SIMPLE_TRIGGERS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_SIMPLE_TRIGGERS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `TRIGGER_NAME` varchar(200) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  `REPEAT_COUNT` bigint NOT NULL,
+  `REPEAT_INTERVAL` bigint NOT NULL,
+  `TIMES_TRIGGERED` bigint NOT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_SIMPLE_TRIGGERS`
+--
+
+LOCK TABLES `QRTZ_SIMPLE_TRIGGERS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_SIMPLE_TRIGGERS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_SIMPLE_TRIGGERS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_SIMPROP_TRIGGERS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_SIMPROP_TRIGGERS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `TRIGGER_NAME` varchar(200) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  `STR_PROP_1` varchar(512) DEFAULT NULL,
+  `STR_PROP_2` varchar(512) DEFAULT NULL,
+  `STR_PROP_3` varchar(512) DEFAULT NULL,
+  `INT_PROP_1` int DEFAULT NULL,
+  `INT_PROP_2` int DEFAULT NULL,
+  `LONG_PROP_1` bigint DEFAULT NULL,
+  `LONG_PROP_2` bigint DEFAULT NULL,
+  `DEC_PROP_1` decimal(13,4) DEFAULT NULL,
+  `DEC_PROP_2` decimal(13,4) DEFAULT NULL,
+  `BOOL_PROP_1` varchar(1) DEFAULT NULL,
+  `BOOL_PROP_2` varchar(1) DEFAULT NULL,
+  PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  CONSTRAINT `qrtz_simprop_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_SIMPROP_TRIGGERS`
+--
+
+LOCK TABLES `QRTZ_SIMPROP_TRIGGERS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_SIMPROP_TRIGGERS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_SIMPROP_TRIGGERS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `QRTZ_TRIGGERS`
+--
+
+DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `QRTZ_TRIGGERS` (
+  `SCHED_NAME` varchar(120) NOT NULL,
+  `TRIGGER_NAME` varchar(200) NOT NULL,
+  `TRIGGER_GROUP` varchar(200) NOT NULL,
+  `JOB_NAME` varchar(200) NOT NULL,
+  `JOB_GROUP` varchar(200) NOT NULL,
+  `DESCRIPTION` varchar(250) DEFAULT NULL,
+  `NEXT_FIRE_TIME` bigint DEFAULT NULL,
+  `PREV_FIRE_TIME` bigint DEFAULT NULL,
+  `PRIORITY` int DEFAULT NULL,
+  `TRIGGER_STATE` varchar(16) NOT NULL,
+  `TRIGGER_TYPE` varchar(8) NOT NULL,
+  `START_TIME` bigint NOT NULL,
+  `END_TIME` bigint DEFAULT NULL,
+  `CALENDAR_NAME` varchar(200) DEFAULT NULL,
+  `MISFIRE_INSTR` smallint DEFAULT NULL,
+  `JOB_DATA` blob,
+  PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
+  KEY `IDX_QRTZ_T_J` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
+  KEY `IDX_QRTZ_T_JG` (`SCHED_NAME`,`JOB_GROUP`),
+  KEY `IDX_QRTZ_T_C` (`SCHED_NAME`,`CALENDAR_NAME`),
+  KEY `IDX_QRTZ_T_G` (`SCHED_NAME`,`TRIGGER_GROUP`),
+  KEY `IDX_QRTZ_T_STATE` (`SCHED_NAME`,`TRIGGER_STATE`),
+  KEY `IDX_QRTZ_T_N_STATE` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
+  KEY `IDX_QRTZ_T_N_G_STATE` (`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
+  KEY `IDX_QRTZ_T_NEXT_FIRE_TIME` (`SCHED_NAME`,`NEXT_FIRE_TIME`),
+  KEY `IDX_QRTZ_T_NFT_ST` (`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`),
+  KEY `IDX_QRTZ_T_NFT_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`),
+  KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`),
+  KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
+  CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `QRTZ_JOB_DETAILS` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `QRTZ_TRIGGERS`
+--
+
+LOCK TABLES `QRTZ_TRIGGERS` WRITE;
+/*!40000 ALTER TABLE `QRTZ_TRIGGERS` DISABLE KEYS */;
+/*!40000 ALTER TABLE `QRTZ_TRIGGERS` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_app`
+--
+
+DROP TABLE IF EXISTS `t_b_app`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_app` (
+  `id` bigint NOT NULL COMMENT '主键\n',
+  `name` varchar(100) NOT NULL COMMENT '应用名',
+  `access_key` varchar(100) NOT NULL COMMENT '访问凭证',
+  `access_secret` varchar(100) NOT NULL COMMENT '访问密钥',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `last_access_time` datetime DEFAULT NULL COMMENT '最近访问时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='app信息';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_app`
+--
+
+LOCK TABLES `t_b_app` WRITE;
+/*!40000 ALTER TABLE `t_b_app` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_b_app` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_client_version`
+--
+
+DROP TABLE IF EXISTS `t_b_client_version`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_client_version` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `name` varchar(50) NOT NULL COMMENT '版本名',
+  `value` int NOT NULL COMMENT '版本号',
+  `url` varchar(100) NOT NULL COMMENT '版本详情链接',
+  `description` varchar(200) DEFAULT NULL COMMENT '版本描述',
+  `enable` tinyint NOT NULL DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
+  `user_id` bigint DEFAULT NULL COMMENT '更新人id',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='客户端版本';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_client_version`
+--
+
+LOCK TABLES `t_b_client_version` WRITE;
+/*!40000 ALTER TABLE `t_b_client_version` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_b_client_version` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_org`
+--
+
+DROP TABLE IF EXISTS `t_b_org`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_org` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `org_code` varchar(50) NOT NULL COMMENT '机构代码,通常用学校简称表示,全局唯一',
+  `name` varchar(100) NOT NULL COMMENT '名称',
+  `logo` varchar(100) DEFAULT NULL COMMENT 'logo图片url',
+  `enable` tinyint NOT NULL DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
+  `enable_simulate` tinyint DEFAULT NULL COMMENT '是否开启模考',
+  `simulate_paper_id` bigint DEFAULT NULL COMMENT '模考试卷id',
+  `access_key` varchar(50) NOT NULL COMMENT '外部访问凭证',
+  `access_secret` varchar(50) NOT NULL COMMENT '外部访问密钥',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='机构';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_org`
+--
+
+LOCK TABLES `t_b_org` WRITE;
+/*!40000 ALTER TABLE `t_b_org` DISABLE KEYS */;
+INSERT INTO `t_b_org` VALUES (1,'20200702001','测试机构1',NULL,1,NULL,NULL,'1','2','2020-07-02 12:08:31',NULL);
+/*!40000 ALTER TABLE `t_b_org` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_privilege`
+--
+
+DROP TABLE IF EXISTS `t_b_privilege`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_privilege` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `name` varchar(50) NOT NULL COMMENT '名称',
+  `url` varchar(100) NOT NULL COMMENT '地址',
+  `type` varchar(50) NOT NULL COMMENT '类型',
+  `parent_id` bigint DEFAULT NULL COMMENT '父id',
+  `sequence` int DEFAULT NULL COMMENT '序号',
+  `remark` varchar(100) DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单和权限';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_privilege`
+--
+
+LOCK TABLES `t_b_privilege` WRITE;
+/*!40000 ALTER TABLE `t_b_privilege` DISABLE KEYS */;
+INSERT INTO `t_b_privilege` VALUES (1,'基础管理','basicManager','MENU',NULL,1,NULL,'2020-07-02 12:08:31'),(2,'用户管理','userManager','MENU',NULL,1,NULL,'2020-07-02 12:08:31'),(3,'考务管理','examinationsManager','MENU',NULL,1,NULL,'2020-07-02 12:08:31'),(4,'监考管理','invigilateManager','MENU',NULL,1,NULL,'2020-07-02 12:08:31'),(5,'考情监控','invigilateMenu','MENU',4,1,NULL,'2020-07-02 12:08:31'),(6,'考情监控实时列表','/api/admin/invigilate/list','LINK',5,1,NULL,'2020-07-02 12:08:31'),(7,'考情监控实时视频列表','/api/admin/invigilate/list/video','LINK',5,2,NULL,'2020-07-02 12:08:31'),(8,'在线巡考','patrolMenuMenu','MENU',4,2,NULL,'2020-07-02 12:08:31');
+/*!40000 ALTER TABLE `t_b_privilege` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_role`
+--
+
+DROP TABLE IF EXISTS `t_b_role`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_role` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `role_code` varchar(30) NOT NULL COMMENT '角色编码',
+  `role_name` varchar(50) NOT NULL COMMENT '角色名称',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `t_b_role_role_code_Idx` (`role_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_role`
+--
+
+LOCK TABLES `t_b_role` WRITE;
+/*!40000 ALTER TABLE `t_b_role` DISABLE KEYS */;
+INSERT INTO `t_b_role` VALUES (1,'SUPER_ADMIN','系统管理员','2020-07-02 12:08:31'),(2,'TEACHER','老师','2020-07-02 12:08:31'),(3,'STUDENT','学生','2020-07-02 12:08:31');
+/*!40000 ALTER TABLE `t_b_role` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_role_privilege`
+--
+
+DROP TABLE IF EXISTS `t_b_role_privilege`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_role_privilege` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `role_code` varchar(50) NOT NULL COMMENT '角色编码',
+  `privilege_id` bigint NOT NULL COMMENT '权限id',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色权限';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_role_privilege`
+--
+
+LOCK TABLES `t_b_role_privilege` WRITE;
+/*!40000 ALTER TABLE `t_b_role_privilege` DISABLE KEYS */;
+INSERT INTO `t_b_role_privilege` VALUES (1,'TEACHER',1),(2,'TEACHER',2),(3,'TEACHER',3),(4,'TEACHER',6),(5,'STUDENT',8),(6,'STUDENT',7),(7,'TEACHER',4);
+/*!40000 ALTER TABLE `t_b_role_privilege` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_session`
+--
+
+DROP TABLE IF EXISTS `t_b_session`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_session` (
+  `id` varchar(100) NOT NULL COMMENT '主键',
+  `identity` varchar(100) NOT NULL COMMENT '用户标识',
+  `type` varchar(50) NOT NULL COMMENT '用户类型',
+  `source` varchar(50) NOT NULL COMMENT '访问来源',
+  `platform` varchar(50) NOT NULL COMMENT '设备分类',
+  `device_id` varchar(100) NOT NULL COMMENT '设备标识',
+  `address` varchar(100) NOT NULL COMMENT '登录IP地址',
+  `access_token` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '访问令牌',
+  `last_access_time` datetime DEFAULT NULL COMMENT '最近访问时间',
+  `last_access_ip` varchar(100) DEFAULT NULL COMMENT '最近访问IP地址',
+  `update_time` datetime DEFAULT NULL COMMENT '令牌更新时间',
+  `expire_time` datetime DEFAULT NULL COMMENT '令牌强制失效时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会话信息';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_session`
+--
+
+LOCK TABLES `t_b_session` WRITE;
+/*!40000 ALTER TABLE `t_b_session` DISABLE KEYS */;
+INSERT INTO `t_b_session` VALUES ('1_SUPER_ADMIN_pc','1','SUPER_ADMIN','pc','win','1234567891','0:0:0:0:0:0:0:1','AbdrBCUGKv9vVvlbQXhqxq7gx9yZ1yW7','2020-07-02 17:43:16',NULL,'2020-07-02 17:43:16','2020-07-03 17:43:16'),('2_TEACHER_pc','2','TEACHER','pc','win','1234567891','0:0:0:0:0:0:0:1','xM1AgSKivYmruH7Pxn5HiUjkqhQucR08','2020-07-02 17:43:54',NULL,'2020-07-02 17:43:54','2020-07-03 17:43:54'),('3_STUDENT_pc','3','STUDENT','pc','win','1234567891','0:0:0:0:0:0:0:1','x4plwyCN4XKtpkFDRJnE0ewxVz4pInI2','2020-07-02 17:41:52',NULL,'2020-07-02 17:41:52','2020-07-03 17:41:52');
+/*!40000 ALTER TABLE `t_b_session` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_user`
+--
+
+DROP TABLE IF EXISTS `t_b_user`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_user` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `login_name` varchar(50) NOT NULL COMMENT '用户名',
+  `password` varchar(30) NOT NULL COMMENT '密码',
+  `mobile_number` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '手机号',
+  `enable` tinyint NOT NULL DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
+  `org_id` bigint DEFAULT NULL COMMENT '机构id',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(100) DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_user`
+--
+
+LOCK TABLES `t_b_user` WRITE;
+/*!40000 ALTER TABLE `t_b_user` DISABLE KEYS */;
+INSERT INTO `t_b_user` VALUES (1,'sysadmin','yXVUkR45PFz0UfpbDB8/ew==','',1,NULL,'2020-07-02 12:08:31',NULL,'系统管理员'),(2,'t1','yXVUkR45PFz0UfpbDB8/ew==',NULL,1,1,'2020-07-02 12:08:31',NULL,NULL),(3,'s1','yXVUkR45PFz0UfpbDB8/ew==',NULL,1,1,'2020-07-02 12:08:31',NULL,NULL);
+/*!40000 ALTER TABLE `t_b_user` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_b_user_role`
+--
+
+DROP TABLE IF EXISTS `t_b_user_role`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_b_user_role` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `user_id` bigint NOT NULL COMMENT '用户id',
+  `role_code` varchar(30) NOT NULL COMMENT '角色编码',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户角色';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_b_user_role`
+--
+
+LOCK TABLES `t_b_user_role` WRITE;
+/*!40000 ALTER TABLE `t_b_user_role` DISABLE KEYS */;
+INSERT INTO `t_b_user_role` VALUES (1,1,'SUPER_ADMIN'),(2,2,'TEACHER'),(3,3,'STUDENT');
+/*!40000 ALTER TABLE `t_b_user_role` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam`
+--
+
+DROP TABLE IF EXISTS `t_e_exam`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `org_id` bigint NOT NULL COMMENT '机构ID',
+  `code` varchar(50) NOT NULL COMMENT '批次编码,机构唯一',
+  `name` varchar(100) NOT NULL COMMENT '批次名称',
+  `tag` varchar(50) NOT NULL COMMENT '批次标注,可用于多个考试批次归类',
+  `start_time` datetime NOT NULL COMMENT '批次开始时间',
+  `end_time` datetime NOT NULL COMMENT '批次结束时间',
+  `status` tinyint NOT NULL COMMENT '状态',
+  `short_code` varchar(50) NOT NULL COMMENT '考试口令',
+  `prepare_seconds` int DEFAULT NULL COMMENT '提前多长时间开始候考(秒)',
+  `min_duration_seconds` int DEFAULT NULL COMMENT '最短考试时长,相当于考试冻结时间(秒)',
+  `pre_notice` varchar(1000) DEFAULT NULL COMMENT '考前须知',
+  `pre_notice_stay_seconds` int DEFAULT NULL COMMENT '考试须知阅读时长(秒)',
+  `post_notice` varchar(1000) DEFAULT NULL COMMENT '考后说明,针对一个场次进行设置',
+  `exam_count` int DEFAULT NULL COMMENT '允许考试次数',
+  `break_expire_seconds` int DEFAULT NULL COMMENT '断点失效时间(秒)',
+  `break_resume_count` int DEFAULT NULL COMMENT '断点续考次数',
+  `liveness_action_count` int DEFAULT NULL COMMENT '活体动作个数',
+  `liveness_action_retry_count` int DEFAULT NULL COMMENT '活体单个动作重试次数',
+  `entry_face_verify` tinyint DEFAULT NULL COMMENT '是否开启/强制开考人脸识别',
+  `entry_liveness_verify` tinyint DEFAULT NULL COMMENT '是否开启/强制开考活体检测',
+  `constant_face_verify` tinyint DEFAULT NULL COMMENT '考试过程中人脸检测是否开启',
+  `constant_liveness_verify_count` int DEFAULT NULL COMMENT '考试过程中随机活体验证次数',
+  `constant_liveness_retry_count` int DEFAULT NULL COMMENT '考试过程中随机活体重试次数',
+  `client_video_push` tinyint DEFAULT NULL COMMENT '是否开启/强制客户端视频监控',
+  `client_video_record` tinyint DEFAULT NULL COMMENT '是否开启客户端视频转录',
+  `wxapp_video_push` tinyint DEFAULT NULL COMMENT '是否开启/强制微信小程序监控',
+  `wxapp_video_record` tinyint DEFAULT NULL COMMENT '是否开启微信小程序视频转录',
+  `camera_photo_upload` tinyint DEFAULT NULL COMMENT '是否允许使用摄像头拍照答题',
+  `wxapp_photo_upload` tinyint DEFAULT NULL COMMENT '是否允许使用微信拍照答题',
+  `reexam_auditing` tinyint DEFAULT NULL COMMENT '重考是否审批',
+  `select_strategy` tinyint DEFAULT NULL COMMENT '多次考试记录的选择逻辑:全部阅卷后取最高分;客观分最高;最后一次提交',
+  `ip_limit` varchar(1000) DEFAULT NULL COMMENT 'IP段限制',
+  `show_objective_score` tinyint DEFAULT NULL COMMENT '交卷后是否显示客观得分',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `t_e_exam_code_Idx` (`code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试批次';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam`
+--
+
+LOCK TABLES `t_e_exam` WRITE;
+/*!40000 ALTER TABLE `t_e_exam` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_activity`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_activity`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_activity` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '批次id',
+  `code` varchar(50) NOT NULL COMMENT '场次代码',
+  `name` varchar(100) NOT NULL COMMENT '场次名称',
+  `prepare_seconds` int NOT NULL COMMENT '提前多长时间开始候考(秒)',
+  `min_start_time` datetime NOT NULL COMMENT '最早开考时间',
+  `max_start_time` datetime NOT NULL COMMENT '最晚开考时间,相当于迟到时间',
+  `max_duration_seconds` int DEFAULT NULL COMMENT '最大考试时长',
+  `min_duration_seconds` int DEFAULT NULL COMMENT '最短考试时间,相当于考试冻结时间(秒)',
+  `max_finish_time` datetime DEFAULT NULL COMMENT '集中收卷时间',
+  `exam_count` int DEFAULT NULL COMMENT '允许考试次数',
+  `break_expire_seconds` int DEFAULT NULL COMMENT '断点失效时间(秒)',
+  `break_resume_count` int DEFAULT NULL COMMENT '断点续考次数',
+  `entry_face_verify` tinyint DEFAULT NULL COMMENT '是否开启/强制开考人脸识别',
+  `entry_liveness_verify` tinyint DEFAULT NULL COMMENT '是否开启/强制开考活体检测',
+  `constant_face_verify` tinyint DEFAULT NULL COMMENT '考试过程中人脸检测是否开启',
+  `constant_liveness_verify_count` int DEFAULT NULL COMMENT '考试过程中随机活体验证次数',
+  `client_video_push` tinyint DEFAULT NULL COMMENT '是否开启/强制客户端视频监控',
+  `client_video_record` tinyint DEFAULT NULL COMMENT '是否开启客户端视频转录',
+  `wxapp_video_push` tinyint DEFAULT NULL COMMENT '是否开启/强制微信小程序监控',
+  `wxapp_video_record` tinyint DEFAULT NULL COMMENT '是否开启微信小程序视频转录',
+  `camera_photo_upload` tinyint DEFAULT NULL COMMENT '是否允许使用摄像头拍照答题',
+  `wxapp_photo_upload` tinyint DEFAULT NULL COMMENT '是否允许使用微信拍照答题',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `t_e_exam_activity_code_Idx` (`code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试场次';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_activity`
+--
+
+LOCK TABLES `t_e_exam_activity` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_activity` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_activity` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_breach_log`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_breach_log`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_breach_log` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `exam_student_id` bigint NOT NULL COMMENT '考生id',
+  `type` tinyint DEFAULT NULL COMMENT '类型',
+  `description` varchar(1000) DEFAULT NULL COMMENT '描述',
+  `status` tinyint DEFAULT NULL COMMENT '状态,0:处理,1:撤销',
+  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `create_id` bigint DEFAULT NULL COMMENT '创建人',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `update_id` bigint DEFAULT NULL COMMENT '更新人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生违纪处理';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_breach_log`
+--
+
+LOCK TABLES `t_e_exam_breach_log` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_breach_log` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_breach_log` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_course`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_course`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_course` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
+  `course_code` varchar(30) NOT NULL COMMENT '科目编码',
+  `course_name` varchar(50) NOT NULL COMMENT '科目名称',
+  `objective_shuffle` tinyint DEFAULT NULL COMMENT '是否开启客观题乱序',
+  `option_shuffle` tinyint DEFAULT NULL COMMENT '是否选项乱序,针对一个科目进行设置',
+  `paper_ids` varchar(2000) NOT NULL COMMENT '所有绑定的考试试卷',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `t_e_exam_course_course_code_Idx` (`course_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试科目';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_course`
+--
+
+LOCK TABLES `t_e_exam_course` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_course` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_course` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_paper`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_paper`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_paper` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `name` varchar(100) NOT NULL COMMENT '试卷名称',
+  `total_score` double NOT NULL COMMENT '试卷总分',
+  `paper_path` varchar(100) DEFAULT NULL COMMENT '题干路径',
+  `standard_answer_path` varchar(100) DEFAULT NULL COMMENT '标答路径',
+  `decrypt_secret` varchar(50) DEFAULT NULL COMMENT '解密密钥',
+  `encrypt_mode` tinyint DEFAULT NULL COMMENT '自动、手动、不加密',
+  `has_video` tinyint DEFAULT NULL COMMENT '题干包含音视频',
+  `need_voice_answer` tinyint DEFAULT NULL COMMENT '是否需要语音作答',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试试卷';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_paper`
+--
+
+LOCK TABLES `t_e_exam_paper` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_paper` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_paper` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_reexam`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_reexam`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_reexam` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `exam_student_id` bigint NOT NULL COMMENT '考生id',
+  `apply_model` tinyint DEFAULT NULL COMMENT '重考方式,0:批次内,1:换批次',
+  `apply_reason` tinyint DEFAULT NULL COMMENT '重考原因',
+  `status` tinyint DEFAULT NULL COMMENT '状态,0:无需审核,1:待审核,2:已审核',
+  `auditing_id` bigint DEFAULT NULL COMMENT '待审核人id',
+  `auditing_status` tinyint DEFAULT NULL COMMENT '审核状态,0:通过,1:不通过',
+  `auditing_time` datetime DEFAULT NULL COMMENT '审核时间',
+  `auditing_suggest` varchar(1000) DEFAULT NULL COMMENT '审批意见',
+  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `create_id` bigint DEFAULT NULL COMMENT '创建人id',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生重考处理';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_reexam`
+--
+
+LOCK TABLES `t_e_exam_reexam` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_reexam` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_reexam` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_student`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_student`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_student` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '批次id',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次id',
+  `student_id` bigint NOT NULL COMMENT '学生id',
+  `course_code` varchar(50) NOT NULL COMMENT '科目代码',
+  `room_code` varchar(50) NOT NULL COMMENT '虚拟考场代码,考试唯一',
+  `identity` varchar(50) NOT NULL COMMENT '证件号,机构内唯一',
+  `name` varchar(50) NOT NULL COMMENT '姓名',
+  `parameter` varchar(1000) DEFAULT NULL COMMENT '扩展字段',
+  `left_exam_count` int DEFAULT NULL COMMENT '剩余考试次数',
+  `current_record_id` bigint DEFAULT NULL COMMENT '当前考试记录ID',
+  `select_record_id` bigint DEFAULT NULL COMMENT '最终生效的记录ID',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生库';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_student`
+--
+
+LOCK TABLES `t_e_exam_student` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_student` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_student` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_student_log`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_student_log`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_student_log` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `exam_student_id` bigint NOT NULL COMMENT '考生id',
+  `type` tinyint DEFAULT NULL COMMENT '类型',
+  `description` varchar(1000) DEFAULT NULL COMMENT '描述',
+  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生轨迹';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_student_log`
+--
+
+LOCK TABLES `t_e_exam_student_log` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_student_log` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_student_log` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_exam_user_privilege`
+--
+
+DROP TABLE IF EXISTS `t_e_exam_user_privilege`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_exam_user_privilege` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `user_id` bigint NOT NULL COMMENT '用户ID',
+  `role_code` varchar(30) NOT NULL COMMENT '角色编码',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '考试场次ID',
+  `course_code` varchar(30) NOT NULL COMMENT '科目编码',
+  `room_code` varchar(50) NOT NULL COMMENT '考场代码',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考务权限设置';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_exam_user_privilege`
+--
+
+LOCK TABLES `t_e_exam_user_privilege` WRITE;
+/*!40000 ALTER TABLE `t_e_exam_user_privilege` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_exam_user_privilege` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_student`
+--
+
+DROP TABLE IF EXISTS `t_e_student`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_student` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `org_id` bigint NOT NULL COMMENT '机构ID',
+  `identity` varchar(50) NOT NULL COMMENT '证件号',
+  `password` varchar(30) NOT NULL COMMENT '登陆密码,密文保存',
+  `idcard_number` varchar(30) NOT NULL COMMENT '身份证号',
+  `mobile_number` varchar(30) NOT NULL COMMENT '手机号',
+  `name` varchar(30) NOT NULL COMMENT '姓名',
+  `gender` tinyint NOT NULL COMMENT '性别',
+  `base_photo_path` varchar(100) DEFAULT NULL COMMENT '底照保存地址',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学生档案';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_student`
+--
+
+LOCK TABLES `t_e_student` WRITE;
+/*!40000 ALTER TABLE `t_e_student` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_student` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_e_user_log`
+--
+
+DROP TABLE IF EXISTS `t_e_user_log`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_e_user_log` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `user_id` bigint NOT NULL COMMENT '用户ID',
+  `type` tinyint DEFAULT NULL COMMENT '类型',
+  `description` varchar(1000) DEFAULT NULL COMMENT '描述',
+  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户轨迹';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_e_user_log`
+--
+
+LOCK TABLES `t_e_user_log` WRITE;
+/*!40000 ALTER TABLE `t_e_user_log` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_e_user_log` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_ie_exam_invigilate_notice`
+--
+
+DROP TABLE IF EXISTS `t_ie_exam_invigilate_notice`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_ie_exam_invigilate_notice` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `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',
+  `type` tinyint NOT NULL COMMENT '消息类型',
+  `content` varchar(1000) NOT NULL COMMENT '消息内容',
+  `send_time` datetime DEFAULT NULL COMMENT '发送时间',
+  `receive_time` datetime DEFAULT NULL COMMENT '接收时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监考通知消息记录';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_ie_exam_invigilate_notice`
+--
+
+LOCK TABLES `t_ie_exam_invigilate_notice` WRITE;
+/*!40000 ALTER TABLE `t_ie_exam_invigilate_notice` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_ie_exam_invigilate_notice` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_ie_invigilate_exception_info`
+--
+
+DROP TABLE IF EXISTS `t_ie_invigilate_exception_info`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_ie_invigilate_exception_info` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `exam_student_id` bigint NOT NULL COMMENT '考生id',
+  `info` varchar(1000) DEFAULT NULL COMMENT '异常信息',
+  `type` tinyint DEFAULT NULL COMMENT '类别',
+  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监考异常信息';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_ie_invigilate_exception_info`
+--
+
+LOCK TABLES `t_ie_invigilate_exception_info` WRITE;
+/*!40000 ALTER TABLE `t_ie_invigilate_exception_info` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_ie_invigilate_exception_info` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_ie_invigilate_warn_info`
+--
+
+DROP TABLE IF EXISTS `t_ie_invigilate_warn_info`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_ie_invigilate_warn_info` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_id` bigint NOT NULL COMMENT '考试ID',
+  `exam_activity_id` bigint NOT NULL COMMENT '场次ID',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `exam_student_id` bigint NOT NULL COMMENT '考生id',
+  `info` varchar(1000) DEFAULT NULL COMMENT '预警信息',
+  `level` tinyint DEFAULT NULL COMMENT '预警级别',
+  `type` tinyint DEFAULT NULL COMMENT '类别',
+  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
+  `approve_status` tinyint DEFAULT NULL COMMENT '审阅状态,0:未阅,1:已阅',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监考预警信息';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_ie_invigilate_warn_info`
+--
+
+LOCK TABLES `t_ie_invigilate_warn_info` WRITE;
+/*!40000 ALTER TABLE `t_ie_invigilate_warn_info` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_ie_invigilate_warn_info` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_oe_exam_answer`
+--
+
+DROP TABLE IF EXISTS `t_oe_exam_answer`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_oe_exam_answer` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_record_id` bigint NOT NULL COMMENT '作答记录ID',
+  `main_number` int DEFAULT NULL COMMENT '大题号',
+  `sub_number` int DEFAULT NULL COMMENT '小题号',
+  `sub_index` int DEFAULT NULL COMMENT '子题序号',
+  `answer` mediumtext COMMENT '作答内容',
+  `version` bigint DEFAULT NULL COMMENT '版本时间戳',
+  `history` mediumtext COMMENT '作答轨迹',
+  `duration_seconds` int DEFAULT NULL COMMENT '作答时长',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='作答结果';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_oe_exam_answer`
+--
+
+LOCK TABLES `t_oe_exam_answer` WRITE;
+/*!40000 ALTER TABLE `t_oe_exam_answer` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_oe_exam_answer` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_oe_exam_break_history`
+--
+
+DROP TABLE IF EXISTS `t_oe_exam_break_history`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_oe_exam_break_history` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `break_time` datetime NOT NULL COMMENT '断点发生时间',
+  `break_reason` tinyint NOT NULL COMMENT '断点判定原因',
+  `resume_reason` varchar(300) DEFAULT NULL COMMENT '提交异常原因',
+  `prepare_time` datetime DEFAULT NULL COMMENT '恢复候考时间',
+  `start_time` datetime DEFAULT NULL COMMENT '恢复开考时间',
+  `entry_face_verify_result` tinyint DEFAULT NULL COMMENT '恢复开考人脸验证结果',
+  `entry_face_verify_history_id` bigint DEFAULT NULL COMMENT '恢复开考人脸验证记录ID',
+  `entry_liveness_verify_result` tinyint DEFAULT NULL COMMENT '恢复开考活体验证结果',
+  `entry_liveness_verify_history_id` bigint DEFAULT NULL COMMENT '恢复开考活体验证记录ID',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试断点记录';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_oe_exam_break_history`
+--
+
+LOCK TABLES `t_oe_exam_break_history` WRITE;
+/*!40000 ALTER TABLE `t_oe_exam_break_history` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_oe_exam_break_history` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_oe_exam_record`
+--
+
+DROP TABLE IF EXISTS `t_oe_exam_record`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_oe_exam_record` (
+  `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',
+  `paper_id` bigint NOT NULL COMMENT '实际使用的试卷ID',
+  `paper_struct_path` varchar(100) DEFAULT NULL COMMENT '个人试卷结构保存地址',
+  `answer_path` varchar(100) DEFAULT NULL COMMENT '全部作答保存地址',
+  `order_number` int DEFAULT NULL COMMENT '第几次考试',
+  `status` tinyint DEFAULT NULL COMMENT '当前状态',
+  `first_prepare_time` datetime DEFAULT NULL COMMENT '首次进入候考时间',
+  `first_start_time` datetime DEFAULT NULL COMMENT '首次开考时间',
+  `last_break_time` datetime DEFAULT NULL COMMENT '最近断点时间',
+  `last_prepare_time` datetime DEFAULT NULL COMMENT '最近恢复候考时间',
+  `last_start_time` datetime DEFAULT NULL COMMENT '最近恢复开考时间',
+  `left_break_resume_count` int DEFAULT NULL COMMENT '剩余断点续考次数',
+  `entry_face_verify_result` tinyint DEFAULT NULL COMMENT '开考人脸验证结果',
+  `entry_face_verify_history_id` bigint DEFAULT NULL COMMENT '开考人脸验证记录ID',
+  `entry_liveness_verify_result` tinyint DEFAULT NULL COMMENT '开考活体验证结果',
+  `entry_liveness_verify_history_id` bigint DEFAULT NULL COMMENT '开考活体验证记录ID',
+  `last_face_verify_result` tinyint DEFAULT NULL COMMENT '最近过程人脸验证结果',
+  `last_face_verify_history_id` bigint DEFAULT NULL COMMENT '最近过程人脸验证记录ID',
+  `last_liveness_verify_result` tinyint DEFAULT NULL COMMENT '最近活体验证结果',
+  `last_liveness_verify_history_id` bigint DEFAULT NULL COMMENT '最近活体验证记录ID',
+  `client_current_ip` varchar(30) DEFAULT NULL COMMENT '客户端当前IP地址',
+  `client_websocket_status` tinyint DEFAULT NULL COMMENT '客户端websocket状态',
+  `client_websocket_id` varchar(50) DEFAULT NULL COMMENT '客户端websocket连接标识',
+  `client_last_sync_time` datetime DEFAULT NULL COMMENT '客户端最近同步时间',
+  `wxapp_websocket_status` tinyint DEFAULT NULL COMMENT '微信小程序websocket状态',
+  `wxapp_websocket_id` varchar(50) DEFAULT NULL COMMENT '微信小程序websocket连接标识',
+  `wxapp_last_sync_time` datetime DEFAULT NULL COMMENT '微信小程序最近同步时间',
+  `client_video_push_status` tinyint DEFAULT NULL COMMENT '客户端推流状态',
+  `client_video_push_key` varchar(100) DEFAULT NULL COMMENT '客户端推流地址',
+  `wxapp_video_push_status` tinyint DEFAULT NULL COMMENT '微信小程序推流状态',
+  `wxapp_video_push_key` varchar(100) DEFAULT NULL COMMENT '微信小程序推流地址',
+  `answer_progress` double DEFAULT NULL COMMENT '答题进度',
+  `duration_seconds` int DEFAULT NULL COMMENT '累计考试用时',
+  `finish_time` datetime DEFAULT NULL COMMENT '交卷时间',
+  `finish_type` tinyint DEFAULT NULL COMMENT '交卷原因',
+  `warning_count` int DEFAULT NULL COMMENT '预警次数',
+  `review_result` tinyint DEFAULT NULL COMMENT '审核结果',
+  `objective_score` double DEFAULT NULL COMMENT '客观题分数',
+  `paper_download` tinyint DEFAULT NULL COMMENT '试题下载,0:是,1:不是',
+  `breach_status` tinyint DEFAULT NULL COMMENT '是否违纪,0:是,1:不是',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试记录';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_oe_exam_record`
+--
+
+LOCK TABLES `t_oe_exam_record` WRITE;
+/*!40000 ALTER TABLE `t_oe_exam_record` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_oe_exam_record` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_oe_exam_simulate_history`
+--
+
+DROP TABLE IF EXISTS `t_oe_exam_simulate_history`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_oe_exam_simulate_history` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `student_id` bigint NOT NULL COMMENT '个人ID',
+  `paper_id` bigint NOT NULL COMMENT '模拟试卷ID',
+  `finish_time` datetime DEFAULT NULL COMMENT '最近完成时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='模拟考试记录  ';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_oe_exam_simulate_history`
+--
+
+LOCK TABLES `t_oe_exam_simulate_history` WRITE;
+/*!40000 ALTER TABLE `t_oe_exam_simulate_history` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_oe_exam_simulate_history` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_oe_face_verify_history`
+--
+
+DROP TABLE IF EXISTS `t_oe_face_verify_history`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_oe_face_verify_history` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `photo_path` varchar(100) DEFAULT NULL COMMENT '图片保存路径',
+  `similarity` double DEFAULT NULL COMMENT '相似度分数',
+  `realness` tinyint DEFAULT NULL COMMENT '真实性验证结果',
+  `local_pass` tinyint DEFAULT NULL COMMENT '本地验证是否通过',
+  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='人脸验证记录';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_oe_face_verify_history`
+--
+
+LOCK TABLES `t_oe_face_verify_history` WRITE;
+/*!40000 ALTER TABLE `t_oe_face_verify_history` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_oe_face_verify_history` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `t_oe_liveness_verify_history`
+--
+
+DROP TABLE IF EXISTS `t_oe_liveness_verify_history`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t_oe_liveness_verify_history` (
+  `id` bigint NOT NULL COMMENT '主键',
+  `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
+  `type` tinyint NOT NULL COMMENT '开考还是过程中',
+  `actions` varchar(2000) DEFAULT NULL COMMENT '随机动作与结果',
+  `result` tinyint DEFAULT NULL COMMENT '检测结果',
+  `create_time` datetime DEFAULT NULL COMMENT '完成时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活体验证记录';
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `t_oe_liveness_verify_history`
+--
+
+LOCK TABLES `t_oe_liveness_verify_history` WRITE;
+/*!40000 ALTER TABLE `t_oe_liveness_verify_history` DISABLE KEYS */;
+/*!40000 ALTER TABLE `t_oe_liveness_verify_history` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Dumping routines for database 'themis'
+--
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2020-07-02 17:46:36

+ 4 - 0
themis-common/src/main/java/com/qmth/themis/common/contanst/Constants.java

@@ -1,5 +1,7 @@
 package com.qmth.themis.common.contanst;
 
+import com.qmth.themis.common.uid.UidGenerator;
+
 import java.nio.charset.Charset;
 
 public interface Constants {
@@ -37,4 +39,6 @@ public interface Constants {
     public static final String AES_RULE = "1234567890123456";//aes密钥
 
     public static final String MD5 = "MD5";
+
+    public UidGenerator idGen = new UidGenerator(0L, 0L);
 }