Эх сурвалжийг харах

Merge remote-tracking branch 'origin/release_v5.0.6'

deason 4 долоо хоног өмнө
parent
commit
e8d794a79e

+ 144 - 0
examcloud-task-base/src/main/java/cn/com/qmth/examcloud/task/base/multithread/ResultProducer.java

@@ -0,0 +1,144 @@
+package cn.com.qmth.examcloud.task.base.multithread;
+
+import java.util.Map;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+
+public abstract class ResultProducer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ResultProducer.class);
+
+    private Basket basket;
+
+    /**
+     * 业务参数
+     */
+    private Map<String, Object> param;
+
+    /**
+     * 消费线程class
+     */
+    private Class<? extends Consumer<?>> consumer;
+
+    /**
+     * 处理开始方法
+     * 
+     * @param consumer
+     *            消费线程class
+     * @param consumerCount
+     *            消费线程数
+     * @param param
+     *            生产者业务参数
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     */
+    public Object startDispose(Class<? extends Consumer<?>> consumer, int consumerCount, Map<String, Object> param)
+            throws InstantiationException, IllegalAccessException {
+        Basket basket = new Basket(consumerCount);
+        this.basket = basket;
+        this.consumer = consumer;
+        this.param = param;
+        // 启动消费者
+        startConsumer();
+        // 开始处理
+        return dispose();
+    }
+
+    private Object dispose() {
+        try {
+            LOG.info("*******************Producer:开始处理");
+            // 生产数据
+            Object result = produce(param);
+            LOG.info("*******************Producer:生产结束");
+            // 发送生产结束信息
+            endConsumer();
+            LOG.info("*******************Producer:成功发送生产结束信息");
+            // 等待子线程结束
+            LOG.info("*******************Producer:等待消费线程结束");
+            await();
+            LOG.info("*******************Producer:消费线程已结束");
+            // 判断子线程是否正常结束
+            if (basket.isExcuteError()) {
+                throw new StatusException("1000001", "处理失败,线程异常");
+            }
+            LOG.info("*******************Producer:结束处理");
+            return result;
+        } catch (StatusException e) {
+            // 获取异常时发送异常结束信息
+            endConsumerAsError();
+            throw e;
+        } catch (Exception e) {
+            // 获取异常时发送异常结束信息
+            endConsumerAsError();
+            throw new StatusException("1000002", "处理失败", e);
+        }
+    }
+
+    /**
+     * 启动消费者
+     * 
+     * @param consumer
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     */
+    private void startConsumer() throws InstantiationException, IllegalAccessException {
+        int count = basket.getConsumerCount();
+        for (int i = 0; i < count; i++) {
+            Consumer<?> co = (Consumer<?>) consumer.newInstance();
+            co.setBasket(basket);
+            co.setTraceId(ThreadContext.get("TRACE_ID"));
+            co.start();
+        }
+
+    }
+
+    /**
+     * 出异常后修改标识
+     * 
+     */
+    private void endConsumerAsError() {
+        basket.setExcuteError(true);
+    }
+
+    /**
+     * 正常结束消费者
+     * 
+     * @throws InterruptedException
+     */
+    private void endConsumer() throws InterruptedException {
+        int count = basket.getConsumerCount();
+        EndObject eo = new EndObject();
+        for (int i = 0; i < count; i++) {
+            basket.offer(eo);
+        }
+
+    }
+
+    /**
+     * 生产数据
+     * 
+     * @param ob
+     * @throws InterruptedException
+     */
+    protected void offer(Object ob) throws InterruptedException {
+        synchronized (basket) {
+            basket.offer(ob);
+        }
+    }
+
+    /**
+     * 等待所有消费者结束
+     * 
+     * @throws InterruptedException
+     */
+    private void await() throws InterruptedException {
+        basket.await();
+    }
+
+    protected abstract Object produce(Map<String, Object> param) throws Exception;
+
+}

+ 19 - 0
examcloud-task-service/src/main/java/cn/com/qmth/examcloud/task/service/consumer/MarkWorkCreateRangeConsumer.java

@@ -0,0 +1,19 @@
+package cn.com.qmth.examcloud.task.service.consumer;
+
+import cn.com.qmth.examcloud.marking.api.MarkTaskCloudService;
+import cn.com.qmth.examcloud.marking.api.bean.MarkRangeBean;
+import cn.com.qmth.examcloud.marking.api.request.CreateMarkRangeReq;
+import cn.com.qmth.examcloud.task.base.multithread.Consumer;
+import cn.com.qmth.examcloud.web.support.SpringContextHolder;
+
+public class MarkWorkCreateRangeConsumer extends Consumer<MarkRangeBean> {
+
+    private MarkTaskCloudService markTaskCloudService = SpringContextHolder.getBean(MarkTaskCloudService.class);
+
+    @Override
+    public void consume(MarkRangeBean dto) {
+        CreateMarkRangeReq req = new CreateMarkRangeReq();
+        req.setBean(dto);
+        markTaskCloudService.createMarkRange(req);
+    }
+}

+ 151 - 86
examcloud-task-service/src/main/java/cn/com/qmth/examcloud/task/service/job/MarkWorkPaperCreateTask.java

@@ -1,86 +1,151 @@
-package cn.com.qmth.examcloud.task.service.job;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.marking.api.MarkWorkCloudService;
-import cn.com.qmth.examcloud.marking.api.bean.MarkWorkBean;
-import cn.com.qmth.examcloud.marking.api.bean.MarkWorkMainBean;
-import cn.com.qmth.examcloud.marking.api.request.UpdateMarkWorkReq;
-import cn.com.qmth.examcloud.marking.api.response.GetTodoMarkWorkMainResp;
-import cn.com.qmth.examcloud.task.service.consumer.MarkWorkCreateConsumer;
-import cn.com.qmth.examcloud.task.service.consumer.MarkWorkCreateItemsConsumer;
-import cn.com.qmth.examcloud.task.service.producer.MarkWorkCreateItemsProducer;
-import cn.com.qmth.examcloud.task.service.producer.MarkWorkCreateProducer;
-import cn.com.qmth.examcloud.web.task.AbstractTask;
-import cn.com.qmth.examcloud.web.task.ScheduleJob;
-import cn.com.qmth.examcloud.web.task.TaskTracker;
-
-@Component("markWorkPaperCreateTask")
-public class MarkWorkPaperCreateTask extends AbstractTask {
-
-
-    @Autowired
-    private MarkWorkCloudService markWorkCloudService;
-
-
-    @Autowired
-    TaskTracker TaskTracker;
-
-    @Override
-    public void run(ScheduleJob scheduleJob) throws Exception {
-        GetTodoMarkWorkMainResp res = markWorkCloudService.getTodoMarkWorkMain();
-        MarkWorkMainBean bean = res.getBean();
-        if (res.getBean() != null) {
-            UpdateMarkWorkReq req = new UpdateMarkWorkReq();
-            MarkWorkBean wbean = new MarkWorkBean();
-            wbean.setId(bean.getId());
-            wbean.setName(bean.getName());
-            wbean.setRemark(bean.getRemark());
-            wbean.setAppendTime(bean.getAppendTime());
-            req.setMarkWorkBean(wbean);
-            try {
-                for (Long examId : bean.getExamIds()) {
-//                    if(CallType.WHOLE_SET.equals(bean.getCallType())) {
-                	createMarkItems(examId, bean.getId());
-//                    }
-                    createStudentPapers(examId, bean.getId());
-                }
-                wbean.setStatus(1);
-            } catch (StatusException e) {
-                wbean.setStatus(2);
-                throw e;
-            } catch (Exception e) {
-                wbean.setStatus(2);
-                throw new StatusException("100001", "评卷工作试卷生成出错 ", e);
-            } finally {
-                markWorkCloudService.updateMarkWork(req);
-            }
-        }
-    }
-
-    private void createMarkItems(Long examId, Long workId) throws InstantiationException, IllegalAccessException{
-    	MarkWorkCreateItemsProducer producer = new MarkWorkCreateItemsProducer();
-        Map<String, Object> param = new HashMap<String, Object>();
-        param.put("examId", examId);
-        param.put("workId", workId);
-        producer.startDispose(MarkWorkCreateItemsConsumer.class, 10, param);
-    }
-
-    private void createStudentPapers(Long examId, Long workId) throws InstantiationException, IllegalAccessException {
-        MarkWorkCreateProducer producer = new MarkWorkCreateProducer();
-        Map<String, Object> param = new HashMap<String, Object>();
-        param.put("examId", examId);
-        param.put("workId", workId);
-        producer.startDispose(MarkWorkCreateConsumer.class, 10, param);
-    }
-
-    @Override
-    public TaskTracker getTaskTracker() {
-        return TaskTracker;
-    }
-}
+package cn.com.qmth.examcloud.task.service.job;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordForMarkingBean;
+import cn.com.qmth.examcloud.marking.api.MarkWorkCloudService;
+import cn.com.qmth.examcloud.marking.api.bean.MarkRangeBean;
+import cn.com.qmth.examcloud.marking.api.bean.MarkWorkBean;
+import cn.com.qmth.examcloud.marking.api.bean.MarkWorkExamBean;
+import cn.com.qmth.examcloud.marking.api.bean.MarkWorkMainBean;
+import cn.com.qmth.examcloud.marking.api.request.GetMarkWorkExamReq;
+import cn.com.qmth.examcloud.marking.api.request.UpdateMarkWorkExamDataEndReq;
+import cn.com.qmth.examcloud.marking.api.request.UpdateMarkWorkReq;
+import cn.com.qmth.examcloud.marking.api.response.GetMarkWorkExamResp;
+import cn.com.qmth.examcloud.marking.api.response.GetTodoMarkWorkMainResp;
+import cn.com.qmth.examcloud.support.cache.bean.ExamSettingsCacheBean;
+import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
+import cn.com.qmth.examcloud.task.service.consumer.MarkWorkCreateConsumer;
+import cn.com.qmth.examcloud.task.service.consumer.MarkWorkCreateItemsConsumer;
+import cn.com.qmth.examcloud.task.service.consumer.MarkWorkCreateRangeConsumer;
+import cn.com.qmth.examcloud.task.service.producer.MarkWorkCreateItemsProducer;
+import cn.com.qmth.examcloud.task.service.producer.MarkWorkCreateProducer;
+import cn.com.qmth.examcloud.task.service.producer.MarkWorkCreateRangeProducer;
+import cn.com.qmth.examcloud.web.task.AbstractTask;
+import cn.com.qmth.examcloud.web.task.ScheduleJob;
+import cn.com.qmth.examcloud.web.task.TaskTracker;
+
+@Component("markWorkPaperCreateTask")
+public class MarkWorkPaperCreateTask extends AbstractTask {
+
+    @Autowired
+    private MarkWorkCloudService markWorkCloudService;
+
+    @Autowired
+    TaskTracker TaskTracker;
+
+    @Override
+    public void run(ScheduleJob scheduleJob) throws Exception {
+        // 该任务只获取非千卷的basepaperid来创建item,千卷的不用创建
+        // 运行一次处理完所有待处理的评卷任务
+        for (;;) {
+            GetTodoMarkWorkMainResp res = markWorkCloudService.getTodoMarkWorkMain();
+            MarkWorkMainBean bean = res.getBean();
+            if (res.getBean() == null) {
+                break;
+            }
+
+            UpdateMarkWorkReq req = new UpdateMarkWorkReq();
+            MarkWorkBean wbean = new MarkWorkBean();
+            wbean.setId(bean.getId());
+            wbean.setName(bean.getName());
+            wbean.setRemark(bean.getRemark());
+            wbean.setAppendTime(bean.getAppendTime());
+            req.setMarkWorkBean(wbean);
+
+            GetMarkWorkExamReq we = new GetMarkWorkExamReq();
+            we.setWorkId(bean.getId());
+            GetMarkWorkExamResp weres = markWorkCloudService.getMarkWorkExam(we);
+            Map<Long, Boolean> map = new HashMap<>();
+            for (MarkWorkExamBean web : weres.getData()) {
+                map.put(web.getExamId(), web.getDataEnd());
+            }
+
+            try {
+                for (Long examId : bean.getExamIds()) {
+                    boolean dataEnd = false;
+                    if (!map.get(examId)) {
+                        ExamSettingsCacheBean eb = ExamCacheTransferHelper.getDefaultCachedExam(examId);
+                        if (eb.getEndTime().getTime() <= System.currentTimeMillis()) {
+                            dataEnd = true;
+                        }
+                        List<ExamRecordForMarkingBean> markRangeData = createMarkItems(examId, bean.getId());
+                        createStudentPapers(examId, bean.getId());
+                        createMarkRange(markRangeData, bean.getId());
+                        if (dataEnd) {
+                            markWorkExamDataEnd(bean.getId(), examId);
+                        }
+                    }
+                }
+                wbean.setStatus(1);
+            } catch (StatusException e) {
+                wbean.setStatus(2);
+                throw e;
+            } catch (Exception e) {
+                wbean.setStatus(2);
+                throw new StatusException("100001", "评卷工作试卷生成出错 ", e);
+            } finally {
+                markWorkCloudService.updateMarkWork(req);
+            }
+        }
+    }
+
+    private void markWorkExamDataEnd(Long workId, Long examId) {
+        UpdateMarkWorkExamDataEndReq req = new UpdateMarkWorkExamDataEndReq(workId, examId);
+        markWorkCloudService.updateMarkWorkExamDataEnd(req);
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<ExamRecordForMarkingBean> createMarkItems(Long examId, Long workId)
+            throws InstantiationException, IllegalAccessException {
+        MarkWorkCreateItemsProducer producer = new MarkWorkCreateItemsProducer();
+        Map<String, Object> param = new HashMap<String, Object>();
+        param.put("examId", examId);
+        param.put("workId", workId);
+        return (List<ExamRecordForMarkingBean>) producer.startDispose(MarkWorkCreateItemsConsumer.class, 10, param);
+    }
+
+    private void createStudentPapers(Long examId, Long workId) throws InstantiationException, IllegalAccessException {
+        MarkWorkCreateProducer producer = new MarkWorkCreateProducer();
+        Map<String, Object> param = new HashMap<String, Object>();
+        param.put("examId", examId);
+        param.put("workId", workId);
+        producer.startDispose(MarkWorkCreateConsumer.class, 10, param);
+    }
+
+    private void createMarkRange(List<ExamRecordForMarkingBean> beans, Long workId)
+            throws InstantiationException, IllegalAccessException {
+        List<MarkRangeBean> data = new ArrayList<>();
+        Set<String> set = new HashSet<>();
+        for (ExamRecordForMarkingBean bean : beans) {
+            if (!set.contains(bean.getBasePaperId())) {
+                set.add(bean.getBasePaperId());
+                MarkRangeBean mb = new MarkRangeBean();
+                mb.setBasePaperId(bean.getBasePaperId());
+                mb.setCourseId(bean.getCourseId());
+                mb.setRandomPaper(bean.getRandomPaper());
+                mb.setWorkId(workId);
+                data.add(mb);
+            }
+        }
+
+        MarkWorkCreateRangeProducer producer = new MarkWorkCreateRangeProducer();
+        Map<String, Object> param = new HashMap<String, Object>();
+        param.put("data", data);
+        producer.startDispose(MarkWorkCreateRangeConsumer.class, 10, param);
+    }
+
+    @Override
+    public TaskTracker getTaskTracker() {
+        return TaskTracker;
+    }
+}

+ 191 - 82
examcloud-task-service/src/main/java/cn/com/qmth/examcloud/task/service/producer/MarkWorkCreateItemsProducer.java

@@ -1,82 +1,191 @@
-package cn.com.qmth.examcloud.task.service.producer;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordForMarkingCloudService;
-import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordForMarkingBean;
-import cn.com.qmth.examcloud.core.oe.admin.api.request.FindExamRecordForMarkingInfoReq;
-import cn.com.qmth.examcloud.core.oe.admin.api.response.FindExamRecordForMarkingInfoResp;
-import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
-import cn.com.qmth.examcloud.task.base.multithread.Producer;
-import cn.com.qmth.examcloud.task.service.dto.MarkWorkCreateItemsDto;
-import cn.com.qmth.examcloud.web.support.SpringContextHolder;
-
-public class MarkWorkCreateItemsProducer extends Producer {
-
-    private ExamRecordForMarkingCloudService examRecordForMarkingCloudService = SpringContextHolder
-            .getBean(ExamRecordForMarkingCloudService.class);
-
-
-    private static final Logger LOG = LoggerFactory.getLogger(MarkWorkCreateItemsProducer.class);
-
-    @Override
-    protected void produce(Map<String, Object> param) throws Exception {
-        Long examId = (Long) param.get("examId");
-        Long workId = (Long) param.get("workId");
-        Long batchSize = 50L;
-        SysPropertyCacheBean spc = CacheHelper.getSysProperty("marking.rpc.saveMarkItems.batchSize");
-        if (spc != null && spc.getValue() != null) {
-            batchSize = (Long) spc.getValue();
-        }
-        
-        FindExamRecordForMarkingInfoReq markingReq = new FindExamRecordForMarkingInfoReq();
-        markingReq.setExamId(examId);
-        markingReq.setBatchNum(workId + "");
-        FindExamRecordForMarkingInfoResp markingResp = examRecordForMarkingCloudService
-                .findExamRecordForMarkingInfo(markingReq);
-        List<ExamRecordForMarkingBean> examRecordForMarkingBeanList = markingResp.getExamRecordForMarkingBeanList();
-        if(examRecordForMarkingBeanList!=null&&examRecordForMarkingBeanList.size()>0) {
-        	List<String> result=duplicateRemoval(examRecordForMarkingBeanList);
-        	LOG.info("创建评卷工作评分项,试卷套数:" + result.size());
-        	subListDispose(result, workId, batchSize);
-        }else {
-        	LOG.info("创建评卷工作评分项,试卷套数:0");
-        }
-    }
-
-
-    private List<String> duplicateRemoval(List<ExamRecordForMarkingBean> list){
-    	Set<String> set=new HashSet<String>();
-    	for(ExamRecordForMarkingBean bean:list) {
-    		set.add(bean.getBasePaperId());
-    	}
-    	List<String> result = new ArrayList<>(set);
-    	return result;
-    }
-    
-    private void subListDispose(List<String> list, Long workId, Long batchSize) throws InterruptedException {
-        if (list.size() <= batchSize) {
-            // 生产需处理的数据
-            offer(new MarkWorkCreateItemsDto(list, workId));
-        } else {
-            int size = list.size();
-            int len = batchSize.intValue();
-            int count = (size + len - 1) / len;
-
-            for (int i = 0; i < count; i++) {
-                List<String> subList = list.subList(i * len,
-                        ((i + 1) * len > size ? size : len * (i + 1)));
-                // 生产需处理的数据
-                offer(new MarkWorkCreateItemsDto(subList, workId));
-            }
-        }
-    }
-}
+package cn.com.qmth.examcloud.task.service.producer;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.examcloud.api.commons.enums.CallType;
+import cn.com.qmth.examcloud.api.commons.enums.ExamType;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordForMarkingCloudService;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordForMarkingBean;
+import cn.com.qmth.examcloud.core.oe.admin.api.request.FindExamRecordForMarkingInfoReq;
+import cn.com.qmth.examcloud.core.oe.admin.api.response.FindExamRecordForMarkingInfoResp;
+import cn.com.qmth.examcloud.core.questions.api.ExtractConfigCloudService;
+import cn.com.qmth.examcloud.core.questions.api.bean.ExtractConfigBean;
+import cn.com.qmth.examcloud.core.questions.api.bean.ExtractConfigDetailBean;
+import cn.com.qmth.examcloud.core.questions.api.request.GetExtractConfigBeanReq;
+import cn.com.qmth.examcloud.core.questions.api.response.GetExtractConfigBeanResp;
+import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
+import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
+import cn.com.qmth.examcloud.examwork.api.request.GetExamReq;
+import cn.com.qmth.examcloud.examwork.api.response.GetExamResp;
+import cn.com.qmth.examcloud.support.cache.CacheHelper;
+import cn.com.qmth.examcloud.support.cache.bean.ExamPropertyCacheBean;
+import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
+import cn.com.qmth.examcloud.support.enums.ExamProperties;
+import cn.com.qmth.examcloud.support.enums.MarkingType;
+import cn.com.qmth.examcloud.support.enums.MarkingWorkType;
+import cn.com.qmth.examcloud.task.base.multithread.ResultProducer;
+import cn.com.qmth.examcloud.task.service.dto.MarkWorkCreateItemsDto;
+import cn.com.qmth.examcloud.web.support.SpringContextHolder;
+
+public class MarkWorkCreateItemsProducer extends ResultProducer {
+
+    private ExamRecordForMarkingCloudService examRecordForMarkingCloudService = SpringContextHolder
+            .getBean(ExamRecordForMarkingCloudService.class);
+
+    private ExamCloudService examCloudService = SpringContextHolder.getBean(ExamCloudService.class);
+
+    private ExtractConfigCloudService extractConfigCloudService = SpringContextHolder
+            .getBean(ExtractConfigCloudService.class);
+
+    private static final Logger LOG = LoggerFactory.getLogger(MarkWorkCreateItemsProducer.class);
+
+    @Override
+    protected List<ExamRecordForMarkingBean> produce(Map<String, Object> param) throws Exception {
+        Long examId = (Long) param.get("examId");
+        Long workId = (Long) param.get("workId");
+        Long batchSize = 50L;
+        SysPropertyCacheBean spc = CacheHelper.getSysProperty("marking.rpc.saveMarkItems.batchSize");
+        if (spc != null && spc.getValue() != null) {
+            batchSize = (Long) spc.getValue();
+        }
+
+        GetExamReq getExamReq = new GetExamReq();
+        getExamReq.setId(examId);
+        GetExamResp getExamResp = examCloudService.getExam(getExamReq);
+        ExamBean examBean = getExamResp.getExamBean();
+        List<ExamRecordForMarkingBean> examRecordForMarkingBeanList = null;
+        if (ExamType.ONLINE.name().equals(examBean.getExamType()) && checkIsAnyTimeMark(examId)) {
+            // 在线考试且是随考随阅的,从调卷规则和考试记录合并拉取所有试卷。因为调卷规则随时会修改
+            examRecordForMarkingBeanList = getAllBasePaperForAnyTimeMark(workId, examId);
+            List<String> result = exludeRandomPaper(examRecordForMarkingBeanList);
+            if (CollectionUtils.isNotEmpty(result)) {
+                LOG.info("创建评卷工作评分项,试卷套数:" + result.size());
+                subListDispose(result, workId, batchSize);
+            } else {
+                LOG.info("创建评卷工作评分项,试卷套数:0");
+            }
+        } else {
+            // 从阅卷数据取
+            examRecordForMarkingBeanList = getAllBasePaperFromMarkingData(workId, examId);
+            if (examRecordForMarkingBeanList != null && examRecordForMarkingBeanList.size() > 0) {
+                List<String> result = exludeRandomPaper(examRecordForMarkingBeanList);
+                LOG.info("创建评卷工作评分项,试卷套数:" + result.size());
+                subListDispose(result, workId, batchSize);
+            } else {
+                LOG.info("创建评卷工作评分项,试卷套数:0");
+            }
+        }
+        if (CollectionUtils.isEmpty(examRecordForMarkingBeanList)) {
+            throw new StatusException("既没有调卷规则信息也没有考试记录信息");
+        }
+        return examRecordForMarkingBeanList;
+    }
+
+    private List<ExamRecordForMarkingBean> getAllBasePaperForAnyTimeMark(Long workId, Long examId) {
+        // 从调卷规则取
+        List<ExamRecordForMarkingBean> ret = new ArrayList<>();
+        GetExtractConfigBeanReq req = new GetExtractConfigBeanReq();
+        req.setExamId(examId);
+        GetExtractConfigBeanResp res = extractConfigCloudService.getExtractConfigBean(req);
+        if (CollectionUtils.isNotEmpty(res.getData())) {
+            for (ExtractConfigBean ec : res.getData()) {
+                boolean randomPaper = CallType.RANDOM_PAPER.equals(ec.getCallType());
+                if (!randomPaper) {
+                    for (ExtractConfigDetailBean ecb : ec.getDetails()) {
+                        ExamRecordForMarkingBean bean = new ExamRecordForMarkingBean();
+                        bean.setBasePaperId(ecb.getPaperId());
+                        bean.setCourseId(ec.getCourseId());
+                        bean.setRandomPaper(false);
+                        ret.add(bean);
+                    }
+                } else {
+                    ExamRecordForMarkingBean bean = new ExamRecordForMarkingBean();
+                    bean.setBasePaperId(ec.getRandomPaperId());
+                    bean.setCourseId(ec.getCourseId());
+                    bean.setRandomPaper(true);
+                    ret.add(bean);
+                }
+            }
+        }
+        // 从阅卷数据取
+        ret.addAll(getAllBasePaperFromMarkingData(workId, examId));
+        return ret;
+    }
+
+    private List<ExamRecordForMarkingBean> getAllBasePaperFromMarkingData(Long workId, Long examId) {
+        FindExamRecordForMarkingInfoReq markingReq = new FindExamRecordForMarkingInfoReq();
+        markingReq.setExamId(examId);
+        markingReq.setBatchNum(workId + "");
+        // 包含千卷
+        markingReq.setIncludeRandomPaper(true);
+        FindExamRecordForMarkingInfoResp markingResp = examRecordForMarkingCloudService
+                .findExamRecordForMarkingInfo(markingReq);
+        return markingResp.getExamRecordForMarkingBeanList();
+    }
+
+    private List<String> exludeRandomPaper(List<ExamRecordForMarkingBean> list) {
+        Set<String> set = new HashSet<String>();
+        for (ExamRecordForMarkingBean bean : list) {
+
+            if (bean.getRandomPaper() == null || !bean.getRandomPaper()) {
+                set.add(bean.getBasePaperId());
+            }
+        }
+        List<String> result = new ArrayList<>(set);
+        return result;
+    }
+
+    private boolean checkIsAnyTimeMark(Long examId) {
+        ExamPropertyCacheBean mt = CacheHelper.getExamProperty(examId, ExamProperties.MARKING_TYPE.name());
+        if (mt == null) {
+            return false;
+        }
+        if (!MarkingType.ALL.name().equals(mt.getValue())) {
+            return false;
+        }
+        ExamPropertyCacheBean es = CacheHelper.getExamProperty(examId, ExamProperties.MARKING_WORK_TYPE.name());
+        if (es == null) {
+            return false;
+        }
+        if (MarkingWorkType.ANYTIME.name().equals(es.getValue())) {
+            return true;
+        }
+        return false;
+    }
+
+    // private List<String> duplicateRemoval(List<ExamRecordForMarkingBean>
+    // list) {
+    // Set<String> set = new HashSet<String>();
+    // for (ExamRecordForMarkingBean bean : list) {
+    // set.add(bean.getBasePaperId());
+    // }
+    // List<String> result = new ArrayList<>(set);
+    // return result;
+    // }
+
+    private void subListDispose(List<String> list, Long workId, Long batchSize) throws InterruptedException {
+        if (list.size() <= batchSize) {
+            // 生产需处理的数据
+            offer(new MarkWorkCreateItemsDto(list, workId));
+        } else {
+            int size = list.size();
+            int len = batchSize.intValue();
+            int count = (size + len - 1) / len;
+
+            for (int i = 0; i < count; i++) {
+                List<String> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
+                // 生产需处理的数据
+                offer(new MarkWorkCreateItemsDto(subList, workId));
+            }
+        }
+    }
+}

+ 20 - 0
examcloud-task-service/src/main/java/cn/com/qmth/examcloud/task/service/producer/MarkWorkCreateRangeProducer.java

@@ -0,0 +1,20 @@
+package cn.com.qmth.examcloud.task.service.producer;
+
+import java.util.List;
+import java.util.Map;
+
+import cn.com.qmth.examcloud.marking.api.bean.MarkRangeBean;
+import cn.com.qmth.examcloud.task.base.multithread.Producer;
+
+public class MarkWorkCreateRangeProducer extends Producer {
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void produce(Map<String, Object> param) throws Exception {
+        List<MarkRangeBean> data = (List<MarkRangeBean>) param.get("data");
+        for (MarkRangeBean bean : data) {
+            offer(bean);
+        }
+    }
+
+}