wangliang пре 5 година
родитељ
комит
25c250328a

+ 5 - 0
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamActivityController.java

@@ -14,6 +14,7 @@ import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import com.qmth.themis.mq.service.MqDtoService;
 import io.swagger.annotations.*;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.transaction.annotation.Transactional;
@@ -40,6 +41,9 @@ public class TEExamActivityController {
     @Resource
     TEExamActivityService teExamActivityService;
 
+    @Resource
+    MqDtoService mqDtoService;
+
     @ApiOperation(value = "考试场次修改/新增接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
@@ -59,6 +63,7 @@ public class TEExamActivityController {
                 }
             });
             teExamActivityService.saveOrUpdateBatch(teExamActivityList);
+
         } catch (Exception e) {
             e.printStackTrace();
             if (e instanceof DuplicateKeyException) {

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

@@ -3,6 +3,7 @@ package com.qmth.themis.backend.api;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.themis.backend.config.DictionaryConfig;
 import com.qmth.themis.backend.util.ServletUtil;
 import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
@@ -11,7 +12,9 @@ import com.qmth.themis.business.entity.TBOrg;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEExamActivity;
+import com.qmth.themis.business.enums.ExamModeEnum;
 import com.qmth.themis.business.enums.FieldUniqueEnum;
+import com.qmth.themis.business.enums.MqEnum;
 import com.qmth.themis.business.service.TEExamActivityService;
 import com.qmth.themis.business.service.TEExamService;
 import com.qmth.themis.business.util.JacksonUtil;
@@ -20,16 +23,16 @@ import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import com.qmth.themis.mq.dto.MqDto;
+import com.qmth.themis.mq.service.MqDtoService;
 import io.swagger.annotations.*;
+import org.springframework.beans.BeanUtils;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * @Description: 考试批次 前端控制器
@@ -49,6 +52,12 @@ public class TEExamController {
     @Resource
     TEExamActivityService teExamActivityService;
 
+    @Resource
+    MqDtoService mqDtoService;
+
+    @Resource
+    DictionaryConfig dictionaryConfig;
+
     @ApiOperation(value = "考试批次修改/新增接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
@@ -66,13 +75,65 @@ public class TEExamController {
                 }
                 teExam.setOrgId(tbOrg.getId());
             }
-            if (Objects.nonNull(teExam.getId())) {
+            Long oldId = teExam.getId();
+            TEExam oldTeExam = null;
+            if (Objects.nonNull(oldId)) {
                 teExam.setUpdateId(tbUser.getId());
+                oldTeExam = teExamService.getById(oldId);
             } else {
                 teExam.setId(Constants.idGen.next());
                 teExam.setCreateId(tbUser.getId());
             }
             teExamService.saveOrUpdate(teExam);
+            if (Objects.nonNull(oldTeExam) && oldTeExam.getMode().intValue() != teExam.getMode().intValue()) {//如果模式改变,则删除之前模式的全部quartz
+                QueryWrapper<TEExamActivity> teExamActivityQueryWrapper = new QueryWrapper<>();
+                teExamActivityQueryWrapper.lambda().eq(TEExamActivity::getExamId, oldId);
+                List<TEExamActivity> teExamActivityList = teExamActivityService.list(teExamActivityQueryWrapper);
+                //删除quartz任务,发送mq消息start
+                Map<String, Object> prop = new HashMap<>();
+                prop.put("oper", "delete");
+                MqDto mqDto = new MqDto(dictionaryConfig.mqConfigDomain().getQuartzTopic(), dictionaryConfig.mqConfigDomain().getQuartzTopicExamActivityTag(), JacksonUtil.parseJson(teExamActivityList), MqEnum.QUARTZ_LOG, String.valueOf(teExam.getId()), prop, tbUser.getName());
+                mqDtoService.assembleSendOneWayMsg(mqDto);
+                //删除quartz任务,发送mq消息end
+
+                //删除数据
+                teExamActivityService.remove(teExamActivityQueryWrapper);
+            }
+            //如果是随到随考,则默认插入一条场次信息
+            if (teExam.getMode().intValue() == ExamModeEnum.anytime.ordinal()) {//随到随考模式
+                if (Objects.isNull(oldId)) {//如果是新增
+                    if (teExam.getMode().intValue() == ExamModeEnum.anytime.ordinal()) {
+                        TEExamActivity teExamActivity = new TEExamActivity(teExam.getId(), teExam.getPrepareSeconds(), teExam.getMaxDurationSeconds(), teExam.getOpeningSeconds(), teExam.getStartTime(), teExam.getEndTime(), tbUser.getId());
+                        teExamActivityService.saveOrUpdate(teExamActivity);
+
+                        //新增quartz任务,发送mq消息start
+                        Map<String, Object> prop = new HashMap<>();
+                        prop.put("oper", "insert");
+                        prop.put("exam", teExam);
+                        MqDto mqDto = new MqDto(dictionaryConfig.mqConfigDomain().getQuartzTopic(), dictionaryConfig.mqConfigDomain().getQuartzTopicExamActivityTag(), JacksonUtil.parseJson(Arrays.asList(teExamActivity)), MqEnum.QUARTZ_LOG, String.valueOf(teExam.getId()), prop, tbUser.getName());
+                        mqDtoService.assembleSendOneWayMsg(mqDto);
+                        //新增quartz任务,发送mq消息end
+                    }
+                } else {//修改需删除之前生成的全部quartz任务
+                    QueryWrapper<TEExamActivity> teExamActivityQueryWrapper = new QueryWrapper<>();
+                    teExamActivityQueryWrapper.lambda().eq(TEExamActivity::getExamId, oldId);
+                    List<TEExamActivity> teExamActivityList = teExamActivityService.list(teExamActivityQueryWrapper);
+                    //修改数据
+                    teExamActivityList.forEach(s -> {
+                        s.setStartTime(teExam.getStartTime());
+                        s.setFinishTime(teExam.getEndTime());
+                        s.setUpdateId(tbUser.getId());
+                    });
+                    teExamActivityService.saveOrUpdateBatch(teExamActivityList);
+                    //新增quartz任务,发送mq消息start
+                    Map<String, Object> prop = new HashMap<>();
+                    prop.put("oper", "insert");
+                    prop.put("exam", teExam);
+                    MqDto mqDto = new MqDto(dictionaryConfig.mqConfigDomain().getQuartzTopic(), dictionaryConfig.mqConfigDomain().getQuartzTopicExamActivityTag(), JacksonUtil.parseJson(teExamActivityList), MqEnum.QUARTZ_LOG, String.valueOf(teExam.getId()), prop, tbUser.getName());
+                    mqDtoService.assembleSendOneWayMsg(mqDto);
+                    //新增quartz任务,发送mq消息end
+                }
+            }
         } catch (Exception e) {
             e.printStackTrace();
             if (e instanceof DuplicateKeyException) {

+ 8 - 0
themis-backend/src/main/resources/application.properties

@@ -210,6 +210,14 @@ mq.config.websocketUnNormalConsumerGroup=${mq.config.server}-group-websocketUnNo
 mq.config.websocketUnNormalTopicOeTag=oe
 mq.config.websocketUnNormalConsumerOeGroup=${mq.config.websocketUnNormalConsumerGroup}-${mq.config.websocketUnNormalTopicOeTag}
 
+#quartz
+mq.config.quartzTopic=${mq.config.server}-topic-quartz
+mq.config.quartzConsumerGroup=${mq.config.server}-group-quartz
+
+#quartz-\u8003\u8BD5\u573A\u6B21task
+mq.config.quartzTopicExamActivityTag=examActivity
+mq.config.quartzConsumerExamActivityGroup=${mq.config.quartzConsumerGroup}-${mq.config.quartzTopicExamActivityTag}
+
 #dlq\u6B7B\u4FE1\u961F\u5217
 #mq.config.sessionConsumerGroupDlq=${mq.config.sessionConsumerGroup}-dlq
 #mq.config.sessionTopicDlq=%DLQ%${mq.config.sessionConsumerGroup}

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

@@ -50,6 +50,7 @@ public class SystemConstant {
     public static final String USERLOG_TOPIC_BUFFER_LIST = "userLog:topic:buffer:list";
     public static final String STUDENTLOG_TOPIC_BUFFER_LIST = "studentLog:topic:buffer:list";
     public static final String TASKLOG_TOPIC_BUFFER_LIST = "taskLog:topic:buffer:list";
+    public static final String QUARTZLOG_TOPIC_BUFFER_LIST = "quartzLog:topic:buffer:list";
     public static final String WEBSOCKET_UN_NORMAL_LOG_TOPIC_BUFFER_LIST = "websocketUnNormal:topic:buffer:list";
     public static final String TYPE = "type";
     public static final String LOCAL = "local";

+ 40 - 0
themis-business/src/main/java/com/qmth/themis/business/domain/MqConfigDomain.java

@@ -61,6 +61,46 @@ public class MqConfigDomain implements Serializable {
     private String websocketUnNormalTopicOeTag;
     private String websocketUnNormalConsumerOeGroup;
 
+    /**
+     * quartz
+     */
+    private String quartzTopic;
+    private String quartzConsumerGroup;
+    private String quartzTopicExamActivityTag;
+    private String quartzConsumerExamActivityGroup;
+
+    public String getQuartzTopic() {
+        return quartzTopic;
+    }
+
+    public void setQuartzTopic(String quartzTopic) {
+        this.quartzTopic = quartzTopic;
+    }
+
+    public String getQuartzConsumerGroup() {
+        return quartzConsumerGroup;
+    }
+
+    public void setQuartzConsumerGroup(String quartzConsumerGroup) {
+        this.quartzConsumerGroup = quartzConsumerGroup;
+    }
+
+    public String getQuartzTopicExamActivityTag() {
+        return quartzTopicExamActivityTag;
+    }
+
+    public void setQuartzTopicExamActivityTag(String quartzTopicExamActivityTag) {
+        this.quartzTopicExamActivityTag = quartzTopicExamActivityTag;
+    }
+
+    public String getQuartzConsumerExamActivityGroup() {
+        return quartzConsumerExamActivityGroup;
+    }
+
+    public void setQuartzConsumerExamActivityGroup(String quartzConsumerExamActivityGroup) {
+        this.quartzConsumerExamActivityGroup = quartzConsumerExamActivityGroup;
+    }
+
     public String getWebsocketUnNormalTopic() {
         return websocketUnNormalTopic;
     }

+ 17 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TEExamActivity.java

@@ -2,6 +2,7 @@ package com.qmth.themis.business.entity;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.qmth.themis.business.base.BaseEntity;
+import com.qmth.themis.common.contanst.Constants;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -49,6 +50,22 @@ public class TEExamActivity extends BaseEntity {
     @TableField(value = "finish_time")
     private Date finishTime;
 
+    public TEExamActivity() {
+
+    }
+
+    public TEExamActivity(Long examId, Integer prepareSeconds, Integer maxDurationSeconds, Integer openingSeconds, Date startTime, Date finishTime, Long createId) {
+        setId(Constants.idGen.next());
+        this.examId = examId;
+        this.code = "examActivity" + Constants.idGen.next();
+        this.prepareSeconds = prepareSeconds;
+        this.maxDurationSeconds = maxDurationSeconds;
+        this.openingSeconds = openingSeconds;
+        this.startTime = startTime;
+        this.finishTime = finishTime;
+        setCreateId(createId);
+    }
+
     public Long getExamId() {
         return examId;
     }

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

@@ -48,7 +48,12 @@ public enum MqEnum {
     /**
      * websocket超时退出
      */
-    WEBSOCKET_UN_NORMAL_LOG(8, "websocket超时退出");
+    WEBSOCKET_UN_NORMAL_LOG(8, "websocket超时退出"),
+
+    /**
+     * quartz
+     */
+    QUARTZ_LOG(9, "quartz任务");
 
     private int id;
 
@@ -80,6 +85,8 @@ public enum MqEnum {
             return TASK_LOG.getId();
         } else if (Objects.equals(value.trim(), WEBSOCKET_UN_NORMAL_LOG.name())) {
             return WEBSOCKET_UN_NORMAL_LOG.getId();
+        } else if (Objects.equals(value.trim(), QUARTZ_LOG.name())) {
+            return QUARTZ_LOG.getId();
         } else {
             return MESSAGE_LOG.getId();
         }
@@ -106,6 +113,8 @@ public enum MqEnum {
             return TASK_LOG.name();
         } else if (Objects.equals(value.trim(), WEBSOCKET_UN_NORMAL_LOG.getCode())) {
             return WEBSOCKET_UN_NORMAL_LOG.name();
+        } else if (Objects.equals(value.trim(), QUARTZ_LOG.getCode())) {
+            return QUARTZ_LOG.name();
         } else {
             return MESSAGE_LOG.name();
         }

+ 3 - 0
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqDtoServiceImpl.java

@@ -170,6 +170,9 @@ public class MqDtoServiceImpl implements MqDtoService {
                 case 7:
                     redisUtil.set(SystemConstant.WEBSOCKET_UN_NORMAL_LOG_TOPIC_BUFFER_LIST, mqDto.getId(), mqDto);
                     break;
+                case 8:
+                    redisUtil.set(SystemConstant.QUARTZLOG_TOPIC_BUFFER_LIST, mqDto.getId(), mqDto);
+                    break;
                 default:
                     break;
             }

+ 168 - 0
themis-task/src/main/java/com/qmth/themis/task/listener/RocketQuartzConsumer.java

@@ -0,0 +1,168 @@
+package com.qmth.themis.task.listener;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.entity.TEExam;
+import com.qmth.themis.business.entity.TEExamActivity;
+import com.qmth.themis.business.entity.TMRocketMessage;
+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.common.contanst.Constants;
+import com.qmth.themis.mq.dto.MqDto;
+import com.qmth.themis.task.config.DictionaryConfig;
+import com.qmth.themis.task.quartz.ExamActivityJob;
+import com.qmth.themis.task.service.QuartzService;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+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;
+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.*;
+
+/**
+ * @Description: 普通消息监听 task
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/2
+ */
+@Service
+public class RocketQuartzConsumer implements MessageListenerConcurrently {
+    private final static Logger log = LoggerFactory.getLogger(RocketQuartzConsumer.class);
+
+    @Resource
+    RedisUtil redisUtil;
+
+    @Resource
+    TMRocketMessageService tmRocketMessageService;
+
+    @Resource
+    QuartzService quartzService;
+
+    @Resource
+    DictionaryConfig dictionaryConfig;
+
+    /**
+     * 导入任务监听
+     */
+    @Override
+    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+        MqDto mqDto = null;
+        try {
+            long threadId = Thread.currentThread().getId();
+            String threadName = Thread.currentThread().getName();
+            Gson gson = new Gson();
+            for (MessageExt messageExt : msgs) {
+                log.info(":{}-:{} quartz Consumer重试次数:{}", threadId, threadName, messageExt.getReconsumeTimes());
+                mqDto = JacksonUtil.readJson(new String(messageExt.getBody(), Constants.CHARSET), MqDto.class);
+                log.info(":{}-:{} quartz Consumer接收到的消息:{}", threadId, threadName, JacksonUtil.parseJson(mqDto));
+                int reconsumeTime = messageExt.getReconsumeTimes();
+                if (reconsumeTime >= SystemConstant.MAXRECONSUMETIMES) {
+                    //超过最大重试次数,保存到数据库,后续可以发短信通知系统管理人员
+                    mqDto.setAck(SystemConstant.POSION_ACK_TYPE);
+                    TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
+                    tmRocketMessageService.saveOrUpdate(tmRocketMessage);
+                    redisUtil.delete(SystemConstant.TASKLOG_TOPIC_BUFFER_LIST, mqDto.getId());
+                } else {
+                    if (Objects.nonNull(mqDto.getAck()) && mqDto.getAck().intValue() != SystemConstant.STANDARD_ACK_TYPE && Objects.nonNull(redisUtil.get(SystemConstant.QUARTZLOG_TOPIC_BUFFER_LIST, mqDto.getId())) && redisUtil.lock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId(), SystemConstant.REDIS_LOCK_MQ_TIME_OUT)) {
+                        Map<String, Object> tranMap = mqDto.getProperties();
+                        String oper = String.valueOf(tranMap.get("oper"));
+                        Object o = JacksonUtil.parseJson(tranMap.get("exam"));
+                        TEExam teExam = JSONObject.toJavaObject(JSONObject.parseObject(String.valueOf(o)), TEExam.class);
+                        mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
+                        JSONArray jsonArray = (JSONArray) JSONArray.parse(String.valueOf(mqDto.getBody()));
+                        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());
+                            } else {
+                                Integer forceFinish = teExam.getForceFinish();
+                                Date startTime = teExamActivity.getStartTime();
+                                Date finishTime = teExamActivity.getFinishTime();
+                                if (Objects.nonNull(forceFinish) && forceFinish.intValue() == 1) {//强制收卷
+                                    Integer activityMaxDurationSeconds = Objects.nonNull(teExamActivity.getMaxDurationSeconds()) ? teExamActivity.getMaxDurationSeconds() : null;
+                                    Integer maxDurationSeconds = Objects.nonNull(teExam.getMaxDurationSeconds()) ? teExam.getMaxDurationSeconds() : null;
+                                    Integer finalMaxDurationSeconds = Objects.nonNull(activityMaxDurationSeconds) ? activityMaxDurationSeconds : maxDurationSeconds;
+                                    Calendar calendar = Calendar.getInstance();
+                                    if (Objects.nonNull(finalMaxDurationSeconds)) {
+                                        calendar.setTime(startTime);
+                                        calendar.add(Calendar.SECOND, activityMaxDurationSeconds.intValue());
+                                    } else {
+                                        calendar.setTime(finishTime);
+                                    }
+//                                    calendar.setTime(new Date());
+                                    int year = calendar.get(Calendar.YEAR);//获取年份
+                                    int month = calendar.get(Calendar.MONTH) + 1;//获取月份
+                                    int day = calendar.get(Calendar.DATE);//获取日
+                                    int hour = calendar.get(Calendar.HOUR_OF_DAY);//小时
+                                    int minute = calendar.get(Calendar.MINUTE);//分
+                                    int second = calendar.get(Calendar.SECOND);//秒
+//                                    String cron = (second + 20) + " " + (minute) + " " + hour + " " + day + " " + month + " ? " + year;
+                                    String cron = second + " " + (minute + 1) + " " + hour + " " + day + " " + month + " ? " + year;
+                                    log.info("cron:{}", cron);
+                                    String activityCode = teExamActivity.getCode();
+                                    //执行一次性延时任务
+                                    Map mapJob = new HashMap();
+                                    mapJob.put("name", activityCode);
+                                    quartzService.deleteJob(activityCode, dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName());
+                                    quartzService.addJob(ExamActivityJob.class, activityCode, dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName(), cron, mapJob);
+                                }
+                            }
+                        }
+                        TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
+                        tmRocketMessageService.saveOrUpdate(tmRocketMessage);
+                        redisUtil.delete(SystemConstant.QUARTZLOG_TOPIC_BUFFER_LIST + mqDto.getId());
+                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+                    } else {
+                        log.info(":{}-:{} 消息ack未确认,重发", threadId, threadName);
+                        return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ConsumeConcurrentlyStatus.RECONSUME_LATER;//重试
+        } finally {
+            if (Objects.nonNull(mqDto)) {
+                redisUtil.releaseLock(SystemConstant.REDIS_LOCK_MQ_PREFIX + mqDto.getId());
+            }
+        }
+        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;//成功
+    }
+
+    /**
+     * quartz
+     */
+    @Service
+    @RocketMQMessageListener(consumerGroup = "${mq.config.quartzConsumerExamActivityGroup}", topic = "${mq.config.quartzTopic}", selectorType = SelectorType.TAG, selectorExpression = "${mq.config.quartzTopicExamActivityTag}")
+    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(RocketQuartzConsumer.this::consumeMessage);
+        }
+    }
+}

+ 0 - 77
themis-task/src/main/java/com/qmth/themis/task/quartz/ExamJob.java

@@ -1,77 +0,0 @@
-package com.qmth.themis.task.quartz;
-
-import com.qmth.themis.business.service.TEExamService;
-import com.qmth.themis.business.util.JacksonUtil;
-import com.qmth.themis.task.config.DictionaryConfig;
-import com.qmth.themis.task.service.QuartzService;
-import org.quartz.JobExecutionContext;
-import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.scheduling.quartz.QuartzJobBean;
-
-import javax.annotation.Resource;
-import java.util.*;
-
-/**
- * @Description: 考试job
- * @Param:
- * @return:
- * @Author: wangliang
- * @Date: 2020/7/27
- */
-public class ExamJob extends QuartzJobBean {
-    private final static Logger log = LoggerFactory.getLogger(ExamJob.class);
-
-    @Resource
-    TEExamService teExamService;
-
-    @Resource
-    QuartzService quartzService;
-
-    @Resource
-    DictionaryConfig dictionaryConfig;
-
-    @Override
-    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
-        log.info("exam_job进来了,context:{}", context);
-        List<Map> teExamList = teExamService.getWaitingExamForJob();
-        if (Objects.nonNull(teExamList) && teExamList.size() > 0) {
-            for (int i = 0; i < teExamList.size(); i++) {
-                Map map = teExamList.get(i);
-                log.info("map:{}", JacksonUtil.parseJson(map));
-                Integer forceFinish = Integer.parseInt(String.valueOf(map.get("forceFinish")));
-                Date startTime = (Date) map.get("startTime");
-                Date finishTime = (Date) map.get("finishTime");
-                if (Objects.nonNull(forceFinish) && forceFinish.intValue() == 1) {//强制收卷
-                    Long activityMaxDurationSeconds = Objects.nonNull(map.get("activityMaxDurationSeconds")) ? Long.parseLong(String.valueOf(map.get("activityMaxDurationSeconds"))) : null;
-                    Long maxDurationSeconds = Objects.nonNull(map.get("maxDurationSeconds")) ? Long.parseLong(String.valueOf(map.get("maxDurationSeconds"))) : null;
-                    Long finalMaxDurationSeconds = Objects.nonNull(activityMaxDurationSeconds) ? activityMaxDurationSeconds : maxDurationSeconds;
-                    Calendar calendar = Calendar.getInstance();
-                    if (Objects.nonNull(finalMaxDurationSeconds)) {
-                        calendar.setTime(startTime);
-                        calendar.add(Calendar.SECOND, activityMaxDurationSeconds.intValue());
-                    } else {
-                        calendar.setTime(finishTime);
-                    }
-//                    calendar.setTime(new Date());
-                    int year = calendar.get(Calendar.YEAR);//获取年份
-                    int month = calendar.get(Calendar.MONTH) + 1;//获取月份
-                    int day = calendar.get(Calendar.DATE);//获取日
-                    int hour = calendar.get(Calendar.HOUR_OF_DAY);//小时
-                    int minute = calendar.get(Calendar.MINUTE);//分
-                    int second = calendar.get(Calendar.SECOND);//秒
-//                    String cron = (second + 30) + " " + (minute) + " " + hour + " " + day + " " + month + " ? " + year;
-                    String cron = second + " " + (minute + 1) + " " + hour + " " + day + " " + month + " ? " + year;
-                    log.info("cron:{}", cron);
-                    String activityCode = String.valueOf(map.get("activityCode"));
-                    //执行一次性延时任务
-                    Map mapJob = new HashMap();
-                    mapJob.put("name", activityCode);
-                    quartzService.deleteJob(activityCode, dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName());
-                    quartzService.addJob(ExamActivityJob.class, activityCode, dictionaryConfig.quartzConfigDomain().getExamActivityJobGroupName(), cron, mapJob);
-                }
-            }
-        }
-    }
-}

+ 0 - 11
themis-task/src/main/java/com/qmth/themis/task/start/StartRunning.java

@@ -1,8 +1,6 @@
 package com.qmth.themis.task.start;
 
-import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.task.config.DictionaryConfig;
-import com.qmth.themis.task.quartz.ExamJob;
 import com.qmth.themis.task.quartz.MqJob;
 import com.qmth.themis.task.service.QuartzService;
 import org.slf4j.Logger;
@@ -12,7 +10,6 @@ import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -41,14 +38,6 @@ public class StartRunning implements CommandLineRunner {
         quartzService.deleteJob(dictionaryConfig.quartzConfigDomain().getMqJobName(), dictionaryConfig.quartzConfigDomain().getMqJobGroupName());
         quartzService.addJob(MqJob.class, dictionaryConfig.quartzConfigDomain().getMqJobName(), dictionaryConfig.quartzConfigDomain().getMqJobGroupName(), "0 0/1 * * * ?", mqMap);
         log.info("增加mqjob end");
-
-        log.info("增加examjob start");
-        Map examMap = new HashMap();
-        examMap.put("name", ExamJob.class.getName());
-        quartzService.deleteJob(dictionaryConfig.quartzConfigDomain().getExamJobName(), dictionaryConfig.quartzConfigDomain().getExamJobGroupName());
-        quartzService.addJob(ExamJob.class, dictionaryConfig.quartzConfigDomain().getExamJobName(), dictionaryConfig.quartzConfigDomain().getExamJobGroupName(), "0 0 0 * * ?", examMap);
-//        quartzService.addJob(ExamJob.class, dictionaryConfig.quartzConfigDomain().getExamJobName(), dictionaryConfig.quartzConfigDomain().getExamJobGroupName(), "0 26 14 27 7 ? 2020", examMap);
-        log.info("增加examjob end");
         log.info("服务器启动时执行 end");
     }
 }

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

@@ -228,4 +228,12 @@ mq.config.websocketUnNormalConsumerGroup=${mq.config.server}-group-websocketUnNo
 
 #oe\u8003\u751F\u7AEF
 mq.config.websocketUnNormalTopicOeTag=oe
-mq.config.websocketUnNormalConsumerOeGroup=${mq.config.websocketUnNormalConsumerGroup}-${mq.config.websocketUnNormalTopicOeTag}
+mq.config.websocketUnNormalConsumerOeGroup=${mq.config.websocketUnNormalConsumerGroup}-${mq.config.websocketUnNormalTopicOeTag}
+
+#quartz
+mq.config.quartzTopic=${mq.config.server}-topic-quartz
+mq.config.quartzConsumerGroup=${mq.config.server}-group-quartz
+
+#quartz-\u8003\u8BD5\u573A\u6B21task
+mq.config.quartzTopicExamActivityTag=examActivity
+mq.config.quartzConsumerExamActivityGroup=${mq.config.quartzConsumerGroup}-${mq.config.quartzTopicExamActivityTag}