wangliang 4 anni fa
parent
commit
9a3ff19bbe

+ 0 - 41
themis-business/src/main/java/com/qmth/themis/business/domain/QuartzConfigDomain.java

@@ -1,41 +0,0 @@
-package com.qmth.themis.business.domain;
-
-import java.io.Serializable;
-
-/**
- * @Description: quartz配置
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/7/1
- */
-public class QuartzConfigDomain implements Serializable {
-
-    private String mqJobName;
-    private String mqJobGroupName;
-    private String examActivityJobGroupName;
-
-    public String getMqJobName() {
-        return mqJobName;
-    }
-
-    public void setMqJobName(String mqJobName) {
-        this.mqJobName = mqJobName;
-    }
-
-    public String getMqJobGroupName() {
-        return mqJobGroupName;
-    }
-
-    public void setMqJobGroupName(String mqJobGroupName) {
-        this.mqJobGroupName = mqJobGroupName;
-    }
-
-    public String getExamActivityJobGroupName() {
-        return examActivityJobGroupName;
-    }
-
-    public void setExamActivityJobGroupName(String examActivityJobGroupName) {
-        this.examActivityJobGroupName = examActivityJobGroupName;
-    }
-}

+ 2 - 0
themis-exam/src/main/java/com/qmth/themis/exam/start/StartRunning.java

@@ -3,6 +3,7 @@ package com.qmth.themis.exam.start;
 import javax.annotation.Resource;
 
 import com.qmth.themis.business.constant.SpringContextHolder;
+import com.qmth.themis.exam.websocket.WebSocketOeServer;
 import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -78,6 +79,7 @@ public class StartRunning implements CommandLineRunner {
          * websocket mq start
          */
         rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.websocketConsumerUnNormalGroup.getCode(), MqTopicEnum.themisTopic.getCode(), MqTagEnum.unNormal.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(WebsocketUnNormalConcurrentlyImpl.class));
+        rocketMessageConsumer.setRocketMQConsumer(nameServer, MqGroupEnum.websocketConsumerOeGroup.getCode(), MqTopicEnum.themisTopic.getCode(), MqTagEnum.oe.name(), MessageModel.CLUSTERING, SpringContextHolder.getBean(WebSocketOeServer.class));
         /**
          * websocket mq end
          */

+ 7 - 29
themis-exam/src/main/java/com/qmth/themis/exam/websocket/WebSocketOeServer.java

@@ -24,6 +24,7 @@ import com.qmth.themis.mq.dto.MqDto;
 import com.qmth.themis.mq.enums.MqTagEnum;
 import com.qmth.themis.mq.enums.MqTopicEnum;
 import com.qmth.themis.mq.service.MqDtoService;
+import com.qmth.themis.mq.templete.Concurrently;
 import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
 import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
@@ -62,8 +63,7 @@ import java.util.concurrent.ConcurrentHashMap;
  */
 @ServerEndpoint("/oe")
 @Component
-public class WebSocketOeServer
-        implements MessageListenerConcurrently {
+public class WebSocketOeServer implements Concurrently {
     private final static Logger log = LoggerFactory.getLogger(WebSocketOeServer.class);
     private volatile static ConcurrentHashMap<String, WebSocketOeServer> webSocketMap = new ConcurrentHashMap<>();
     /**
@@ -290,7 +290,6 @@ public class WebSocketOeServer
     }
 
     @Override
-    @Transactional
     public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
         RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
         TMRocketMessageService tmRocketMessageService = SpringContextHolder.getBean(TMRocketMessageService.class);
@@ -324,6 +323,9 @@ public class WebSocketOeServer
                         } else if (oper.contains(MessageModel.BROADCASTING.name())) {//广播消息
 
                         }
+                    }else {
+                        log.info(":{}-:{} 消息ack未确认,重发", threadId, threadName);
+                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
                     }
                 }
 //                log.info(":{}-:{} websocketConsumer 重试次数:{}", threadId, threadName, messageExt.getReconsumeTimes());
@@ -349,11 +351,8 @@ public class WebSocketOeServer
             }
         } catch (Exception e) {
             e.printStackTrace();
-            if (e instanceof BusinessException) {
-                throw new BusinessException(e.getMessage());
-            } else {
-                throw new RuntimeException(e);
-            }
+            return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+
         } finally {
             if (Objects.nonNull(mqDto)) {
                 redisUtil.releaseLock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId());
@@ -361,26 +360,5 @@ public class WebSocketOeServer
         }
         return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;//成功
     }
-
-    /**
-     * websocket oe
-     */
-    @Service
-    @RocketMQMessageListener(consumerGroup = "${mq.config.websocketConsumerOeGroup}", topic = "${mq.config.websocketTopic}", selectorType = SelectorType.TAG, selectorExpression = "${mq.config.websocketTopicOeTag}")
-    public class taskConsumerQuartzStudent implements RocketMQListener<Message>, RocketMQPushConsumerLifecycleListener {
-
-        @Override
-        public void onMessage(Message message) {
-            //实现RocketMQPushConsumerLifecycleListener监听器之后,此方法不调用
-        }
-
-        @Override
-        public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
-            defaultMQPushConsumer.setConsumeMessageBatchMaxSize(SystemConstant.CONSUME_MESSAGE_BATCH_MAX_SIZE);//每次拉取10条
-            defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
-            defaultMQPushConsumer.setMaxReconsumeTimes(SystemConstant.MAXRECONSUMETIMES);//最大重试次数
-            defaultMQPushConsumer.registerMessageListener(WebSocketOeServer.this::consumeMessage);
-        }
-    }
 }
 

+ 4 - 4
themis-exam/src/main/resources/application.properties

@@ -119,10 +119,10 @@ rocketmq.producer.enable-msg-trace=true
 #\u81EA\u5B9A\u4E49\u7684\u6D88\u606F\u8F68\u8FF9\u4E3B\u9898
 rocketmq.producer.customized-trace-topic=my-trace-topic
 
-#websocket
-mq.config.websocketTopic=themis-topic-exam
-mq.config.websocketConsumerOeGroup=themis-group-exam-websocketOe
-mq.config.websocketTopicOeTag=oe
+##websocket
+#mq.config.websocketTopic=themis-topic-exam
+#mq.config.websocketConsumerOeGroup=themis-group-exam-websocketOe
+#mq.config.websocketTopicOeTag=oe
 
 #\u963F\u91CC\u4E91OSS\u914D\u7F6E
 aliyun.oss.name=oss-cn-shenzhen.aliyuncs.com

+ 27 - 20
themis-mq/src/main/java/com/qmth/themis/mq/enums/MqTagEnum.java

@@ -9,24 +9,31 @@ package com.qmth.themis.mq.enums;
  */
 public enum MqTagEnum {
 
-    web,
-    win,
-    mac,
-    wxapp,
-    ios,
-    android,
-    user,
-    student,
-    examStudentImport,
-    roomCodeExport,
-    roomCodeImport,
-    examPaperImport,
-    oe,
-    unNormal,
-    examActivity,
-    quartz,
-    /**
-     * 计算客观分
-     */
-    calculateObjectiveScore;
+    web("会话web标签"),
+    win("会话win标签"),
+    mac("会话mac标签"),
+    wxapp("会话wxapp标签"),
+    ios("会话ios标签"),
+    android("会话android标签"),
+    user("用户轨迹user标签"),
+    student("用户轨迹student标签"),
+    examStudentImport("考生导入任务标签"),
+    roomCodeExport("考场导出任务标签"),
+    roomCodeImport("考场导入任务标签"),
+    examPaperImport("试卷导入任务标签"),
+    oe("websocket客户端标签"),
+    unNormal("websocket超时退出标签"),
+    examActivity("考场一次性延时任务标签"),
+    quartz("quartz标签"),
+    calculateObjectiveScore("计算客观分标签");
+
+    private MqTagEnum(String code) {
+        this.code = code;
+    }
+
+    private String code;
+
+    public String getCode() {
+        return code;
+    }
 }

+ 0 - 12
themis-task/src/main/java/com/qmth/themis/task/config/DictionaryConfig.java

@@ -1,7 +1,6 @@
 package com.qmth.themis.task.config;
 
 import com.qmth.themis.business.domain.AliYunOssDomain;
-import com.qmth.themis.business.domain.QuartzConfigDomain;
 import com.qmth.themis.business.domain.SysDomain;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
@@ -28,17 +27,6 @@ public class DictionaryConfig {
         return new SysDomain();
     }
 
-    /**
-     * quartz配置
-     *
-     * @return
-     */
-    @Bean
-    @ConfigurationProperties(prefix = "quartz.config", ignoreUnknownFields = false)
-    public QuartzConfigDomain quartzConfigDomain() {
-        return new QuartzConfigDomain();
-    }
-
     /**
      * 阿里云oss配置
      *

+ 27 - 0
themis-task/src/main/java/com/qmth/themis/task/enums/QuartzTaskEnum.java

@@ -0,0 +1,27 @@
+package com.qmth.themis.task.enums;
+
+/**
+ * @Description: quartz task enum
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/31
+ */
+public enum QuartzTaskEnum {
+
+    mqJobName("mqjob"),
+
+    mqJobGroupName("mqjob group"),
+
+    examActivityJobGroupName("考场一次性延时job group");
+
+    private QuartzTaskEnum(String code) {
+        this.code = code;
+    }
+
+    private String code;
+
+    public String getCode() {
+        return code;
+    }
+}

+ 3 - 3
themis-task/src/main/java/com/qmth/themis/task/listener/QuartzOrderlyImpl.java

@@ -32,7 +32,7 @@ public class QuartzOrderlyImpl implements Orderly {
     @Override
     public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext consumeConcurrentlyContext) {
         RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
-        MqTaskLogicService mqLogicService = SpringContextHolder.getBean(MqTaskLogicService.class);
+        MqTaskLogicService mqTaskLogicService = SpringContextHolder.getBean(MqTaskLogicService.class);
         MqDto mqDto = null;
         try {
             long threadId = Thread.currentThread().getId();
@@ -43,10 +43,10 @@ public class QuartzOrderlyImpl implements Orderly {
                 log.info(":{}-:{} quartz Consumer接收到的消息:{}", threadId, threadName, JacksonUtil.parseJson(mqDto));
                 int reconsumeTime = messageExt.getReconsumeTimes();
                 if (reconsumeTime >= SystemConstant.MAXRECONSUMETIMES) {
-                    mqLogicService.execMqMaxReconsumeTime(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
+                    mqTaskLogicService.execMqMaxReconsumeTime(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
                 } else {
                     if (Objects.nonNull(mqDto.getAck()) && mqDto.getAck().intValue() != SystemConstant.STANDARD_ACK_TYPE && Objects.nonNull(redisUtil.get(SystemConstant.MQ_TOPIC_BUFFER_LIST, mqDto.getId())) && redisUtil.lock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId(), SystemConstant.REDIS_LOCK_MQ_TIME_OUT)) {
-                        mqLogicService.execMqQuartzLogic(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
+                        mqTaskLogicService.execMqQuartzLogic(mqDto, SystemConstant.MQ_TOPIC_BUFFER_LIST);
                         return ConsumeOrderlyStatus.SUCCESS;
                     } else {
                         log.info(":{}-:{} 消息ack未确认,重发", threadId, threadName);

+ 6 - 8
themis-task/src/main/java/com/qmth/themis/task/listener/service/impl/MqTaskLogicServiceImpl.java

@@ -13,7 +13,7 @@ import com.qmth.themis.business.service.TMRocketMessageService;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.mq.dto.MqDto;
-import com.qmth.themis.task.config.DictionaryConfig;
+import com.qmth.themis.task.enums.QuartzTaskEnum;
 import com.qmth.themis.task.listener.service.MqTaskLogicService;
 import com.qmth.themis.task.quartz.ExamActivityJob;
 import com.qmth.themis.task.service.QuartzService;
@@ -46,9 +46,6 @@ public class MqTaskLogicServiceImpl implements MqTaskLogicService {
     @Resource
     QuartzService quartzService;
 
-    @Resource
-    DictionaryConfig dictionaryConfig;
-
     /**
      * mq最大重试次数逻辑
      *
@@ -79,7 +76,7 @@ public class MqTaskLogicServiceImpl implements MqTaskLogicService {
         for (int i = 0; i < jsonArray.size(); i++) {
             TEExamActivity teExamActivity = JSONObject.toJavaObject((JSON) jsonArray.get(i), TEExamActivity.class);
             if (Objects.equals("delete", oper)) {
-                quartzService.deleteJob(teExamActivity.getCode(), dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName());
+                quartzService.deleteJob(teExamActivity.getCode(), QuartzTaskEnum.examActivityJobGroupName.name());
             } else {
                 Integer forceFinish = teExam.getForceFinish();
                 Date startTime = teExamActivity.getStartTime();
@@ -91,7 +88,8 @@ public class MqTaskLogicServiceImpl implements MqTaskLogicService {
                     Calendar calendar = Calendar.getInstance();
                     if (Objects.nonNull(finalMaxDurationSeconds)) {
                         calendar.setTime(startTime);
-                        calendar.add(Calendar.SECOND, (activityMaxDurationSeconds.intValue() + 60));
+//                        calendar.add(Calendar.SECOND, (activityMaxDurationSeconds.intValue() + 60));
+                        calendar.add(Calendar.SECOND, (activityMaxDurationSeconds.intValue()));
                     } else {
                         calendar.setTime(finishTime);
                     }
@@ -109,8 +107,8 @@ public class MqTaskLogicServiceImpl implements MqTaskLogicService {
                         //执行一次性延时任务
                         Map mapJob = new HashMap();
                         mapJob.put("name", activityCode);
-                        quartzService.deleteJob(activityCode, dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName());
-                        quartzService.addJob(SpringContextHolder.getBean(ExamActivityJob.class).getClass(), activityCode, dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName(), cron, mapJob);
+                        quartzService.deleteJob(activityCode, QuartzTaskEnum.examActivityJobGroupName.name());
+                        quartzService.addJob(ExamActivityJob.class, activityCode, QuartzTaskEnum.examActivityJobGroupName.name(), cron, mapJob);
                     }
                 }
             }

+ 8 - 76
themis-task/src/main/java/com/qmth/themis/task/quartz/ExamActivityJob.java

@@ -1,28 +1,16 @@
 package com.qmth.themis.task.quartz;
 
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.qmth.themis.business.entity.TEExamActivity;
-import com.qmth.themis.business.entity.TEExamStudent;
-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.service.TEExamActivityService;
-import com.qmth.themis.business.service.TEExamStudentService;
-import com.qmth.themis.business.service.TOeExamRecordService;
-import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.task.quartz.service.QuartzLogicService;
 import org.quartz.JobDetail;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.quartz.QuartzJobBean;
+import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
 import java.util.Objects;
 
 /**
@@ -32,76 +20,20 @@ import java.util.Objects;
  * @Author: wangliang
  * @Date: 2020/7/27
  */
-@Service
+@Component
 public class ExamActivityJob extends QuartzJobBean {
     private final static Logger log = LoggerFactory.getLogger(ExamActivityJob.class);
 
     @Resource
-    TEExamActivityService teExamActivityService;
-
-    @Resource
-    TEExamStudentService teExamStudentService;
-
-    @Resource
-    TOeExamRecordService tOeExamRecordService;
+    QuartzLogicService quartzLogicService;
 
     @Override
-    @Transactional
     protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
         log.info("exam_acvitity_job进来了,context:{}", context);
-        try {
-            JobDetail jobDetail = context.getJobDetail();
-            String key = String.valueOf(jobDetail.getKey());
-            if (Objects.nonNull(key)) {
-                String[] strings = key.split("\\.");
-                QueryWrapper<TEExamActivity> teExamActivityQueryWrapper = new QueryWrapper<>();
-                teExamActivityQueryWrapper.lambda().eq(TEExamActivity::getCode, strings[1]);
-                TEExamActivity teExamActivity = teExamActivityService.getOne(teExamActivityQueryWrapper);
-                if (Objects.nonNull(teExamActivity)) {
-                    log.info("key:{}", key);
-
-                    //获取该考试批次下所有未交卷的考生的考试记录
-                    QueryWrapper<TOeExamRecord> tOeExamRecordQueryWrapper = new QueryWrapper<>();
-                    tOeExamRecordQueryWrapper.lambda().eq(TOeExamRecord::getExamActivityId, teExamActivity.getId()).ne(TOeExamRecord::getStatus, ExamRecordStatusEnum.finished.ordinal());
-                    List<TOeExamRecord> tOeExamRecordList = tOeExamRecordService.list(tOeExamRecordQueryWrapper);
-                    List<Long> examStudentIdList = null;
-                    if (Objects.nonNull(tOeExamRecordList) && tOeExamRecordList.size() > 0) {
-                        examStudentIdList = new ArrayList<>();
-                    }
-                    List<Long> finalExamStudentIdList = examStudentIdList;
-                    tOeExamRecordList.forEach(s -> {
-                        s.setStatus(ExamRecordStatusEnum.finished);
-                        s.setFinishTime(new Date());
-                        s.setFinishType(FinishTypeEnum.interrupt);
-                        finalExamStudentIdList.add(s.getExamStudentId());
-                    });
-                    tOeExamRecordService.updateBatchById(tOeExamRecordList);
-
-                    if (Objects.nonNull(examStudentIdList) && examStudentIdList.size() > 0) {
-                        //获取该考试批次下所有考生,考试次数减1
-                        QueryWrapper<TEExamStudent> teExamStudentQueryWrapper = new QueryWrapper<>();
-                        teExamStudentQueryWrapper.lambda().in(TEExamStudent::getId, examStudentIdList);
-                        List<TEExamStudent> teExamStudentList = teExamStudentService.list(teExamStudentQueryWrapper);
-                        teExamStudentList.forEach(s -> {
-                            int count = Objects.isNull(s.getLeftExamCount()) ? 0 : s.getLeftExamCount();
-                            count--;
-                            s.setLeftExamCount(count < 0 ? 0 : count);
-                            //加入踢下线mq
-                        });
-                        teExamStudentService.updateBatchById(teExamStudentList);
-                    }
-                    //todo 未完待续,需要加入交卷逻辑
-                } else {
-                    log.info("考试场次:{}已删除", key);
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            if (e instanceof BusinessException) {
-                throw new BusinessException(e.getMessage());
-            } else {
-                throw new RuntimeException(e);
-            }
+        JobDetail jobDetail = context.getJobDetail();
+        String key = String.valueOf(jobDetail.getKey());
+        if (Objects.nonNull(key)) {
+            quartzLogicService.execExamActivityJobLogic(key);
         }
     }
 }

+ 0 - 2
themis-task/src/main/java/com/qmth/themis/task/quartz/MqJob.java

@@ -9,7 +9,6 @@ import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.quartz.QuartzJobBean;
-import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.util.Map;
@@ -22,7 +21,6 @@ import java.util.Objects;
  * @Author: wangliang
  * @Date: 2020/7/1
  */
-@Service
 public class MqJob extends QuartzJobBean {
     private final static Logger log = LoggerFactory.getLogger(MqJob.class);
 

+ 18 - 0
themis-task/src/main/java/com/qmth/themis/task/quartz/service/QuartzLogicService.java

@@ -0,0 +1,18 @@
+package com.qmth.themis.task.quartz.service;
+
+/**
+ * @Description: quartz逻辑
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/31
+ */
+public interface QuartzLogicService {
+
+    /**
+     * 考试场次quartz逻辑
+     *
+     * @param key
+     */
+    public void execExamActivityJobLogic(String key);
+}

+ 97 - 0
themis-task/src/main/java/com/qmth/themis/task/quartz/service/impl/QuartzLogicServiceImpl.java

@@ -0,0 +1,97 @@
+package com.qmth.themis.task.quartz.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qmth.themis.business.entity.TEExamActivity;
+import com.qmth.themis.business.entity.TEExamStudent;
+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.service.TEExamActivityService;
+import com.qmth.themis.business.service.TEExamStudentService;
+import com.qmth.themis.business.service.TOeExamRecordService;
+import com.qmth.themis.mq.service.MqDtoService;
+import com.qmth.themis.task.quartz.service.QuartzLogicService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Description: quartz逻辑 impl
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/31
+ */
+@Service
+public class QuartzLogicServiceImpl implements QuartzLogicService {
+    private final static Logger log = LoggerFactory.getLogger(QuartzLogicServiceImpl.class);
+
+    @Resource
+    TEExamActivityService teExamActivityService;
+
+    @Resource
+    TEExamStudentService teExamStudentService;
+
+    @Resource
+    TOeExamRecordService tOeExamRecordService;
+
+    @Resource
+    MqDtoService mqDtoService;
+
+    /**
+     * 考试场次quartz逻辑
+     *
+     * @param key
+     */
+    @Override
+    @Transactional
+    public void execExamActivityJobLogic(String key) {
+        log.info("key:{}", key);
+        String[] strings = key.split("\\.");
+        QueryWrapper<TEExamActivity> teExamActivityQueryWrapper = new QueryWrapper<>();
+        teExamActivityQueryWrapper.lambda().eq(TEExamActivity::getCode, strings[1]);
+        TEExamActivity teExamActivity = teExamActivityService.getOne(teExamActivityQueryWrapper);
+        if (Objects.nonNull(teExamActivity)) {
+            //获取该考试批次下所有未交卷的考生的考试记录
+            QueryWrapper<TOeExamRecord> tOeExamRecordQueryWrapper = new QueryWrapper<>();
+            tOeExamRecordQueryWrapper.lambda().eq(TOeExamRecord::getExamActivityId, teExamActivity.getId()).ne(TOeExamRecord::getStatus, ExamRecordStatusEnum.finished.ordinal());
+            List<TOeExamRecord> tOeExamRecordList = tOeExamRecordService.list(tOeExamRecordQueryWrapper);
+            List<Long> examStudentIdList = null;
+            if (Objects.nonNull(tOeExamRecordList) && tOeExamRecordList.size() > 0) {
+                examStudentIdList = new ArrayList<>();
+            }
+            List<Long> finalExamStudentIdList = examStudentIdList;
+            tOeExamRecordList.forEach(s -> {
+                s.setStatus(ExamRecordStatusEnum.finished);
+                s.setFinishTime(new Date());
+                s.setFinishType(FinishTypeEnum.interrupt);
+                finalExamStudentIdList.add(s.getExamStudentId());
+            });
+            tOeExamRecordService.updateBatchById(tOeExamRecordList);
+
+            if (Objects.nonNull(examStudentIdList) && examStudentIdList.size() > 0) {
+                //获取该考试批次下所有考生,考试次数减1
+                QueryWrapper<TEExamStudent> teExamStudentQueryWrapper = new QueryWrapper<>();
+                teExamStudentQueryWrapper.lambda().in(TEExamStudent::getId, examStudentIdList);
+                List<TEExamStudent> teExamStudentList = teExamStudentService.list(teExamStudentQueryWrapper);
+                teExamStudentList.forEach(s -> {
+                    int count = Objects.isNull(s.getLeftExamCount()) ? 0 : s.getLeftExamCount();
+                    count--;
+                    s.setLeftExamCount(count < 0 ? 0 : count);
+                    //加入踢下线mq
+                });
+                teExamStudentService.updateBatchById(teExamStudentList);
+            }
+            //todo 未完待续,需要加入交卷逻辑
+        } else {
+            log.info("考试场次:{}已删除", key);
+        }
+    }
+}

+ 3 - 5
themis-task/src/main/java/com/qmth/themis/task/start/StartRunning.java

@@ -7,6 +7,7 @@ import com.qmth.themis.mq.enums.MqTopicEnum;
 import com.qmth.themis.mq.listener.RocketMessageConsumer;
 import com.qmth.themis.mq.templete.impl.*;
 import com.qmth.themis.task.config.DictionaryConfig;
+import com.qmth.themis.task.enums.QuartzTaskEnum;
 import com.qmth.themis.task.listener.QuartzOrderlyImpl;
 import com.qmth.themis.task.quartz.MqJob;
 import com.qmth.themis.task.service.QuartzService;
@@ -35,9 +36,6 @@ public class StartRunning implements CommandLineRunner {
     @Resource
     QuartzService quartzService;
 
-    @Resource
-    DictionaryConfig dictionaryConfig;
-
     @Resource
     RocketMessageConsumer rocketMessageConsumer;
 
@@ -50,8 +48,8 @@ public class StartRunning implements CommandLineRunner {
         log.info("增加mqjob start");
         Map mqMap = new HashMap();
         mqMap.put("name", MqJob.class.getName());
-        quartzService.deleteJob(dictionaryConfig.quartzConfigDomain().getMqJobName(), dictionaryConfig.quartzConfigDomain().getMqJobGroupName());
-        quartzService.addJob(MqJob.class, dictionaryConfig.quartzConfigDomain().getMqJobName(), dictionaryConfig.quartzConfigDomain().getMqJobGroupName(), "0 0/1 * * * ?", mqMap);
+        quartzService.deleteJob(QuartzTaskEnum.mqJobName.name(), QuartzTaskEnum.mqJobGroupName.name());
+        quartzService.addJob(MqJob.class, QuartzTaskEnum.mqJobName.name(), QuartzTaskEnum.mqJobGroupName.name(), "0 0/1 * * * ?", mqMap);
         log.info("增加mqjob end");
 
         /**

+ 1 - 9
themis-task/src/main/resources/application.properties

@@ -142,9 +142,6 @@ spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThre
 spring.quartz.properties.org.quartz.threadPool.threadCount=10
 # \u8BBE\u7F6E\u7EBF\u7A0B\u7684\u4F18\u5148\u7EA7(\u53EF\u4EE5\u662FThread.MIN_PRIORITY\uFF08\u53731\uFF09\u548CThread.MAX_PRIORITY\uFF08\u8FD9\u662F10\uFF09\u4E4B\u95F4\u7684\u4EFB\u4F55int \u3002\u9ED8\u8BA4\u503C\u4E3AThread.NORM_PRIORITY\uFF085\uFF09\u3002)
 spring.quartz.properties.org.quartz.threadPool.threadPriority=5
-quartz.config.mqJobName=mqJob
-quartz.config.mqJobGroupName=mqGroupName
-quartz.config.examActivityJobGroupName=examActivityGroupName
 
 #============================================================================
 # \u914D\u7F6Erocketmq
@@ -170,9 +167,4 @@ rocketmq.producer.secret-key=SK
 #\u542F\u7528\u6D88\u606F\u8F68\u8FF9\uFF0C\u9ED8\u8BA4\u503Ctrue
 rocketmq.producer.enable-msg-trace=true
 #\u81EA\u5B9A\u4E49\u7684\u6D88\u606F\u8F68\u8FF9\u4E3B\u9898
-rocketmq.producer.customized-trace-topic=my-trace-topic
-
-##quartz-\u8003\u8BD5\u573A\u6B21task
-#mq.config.quartzTopic=themis-topic-exam
-#mq.config.quartzConsumerExamActivityGroup=themis-group-exam-quartzExamActivity
-#mq.config.quartzTopicExamActivityTag=examActivity
+rocketmq.producer.customized-trace-topic=my-trace-topic