Răsfoiți Sursa

3.3.0 生成评卷任务

xiaofei 1 an în urmă
părinte
comite
f4afc41518
27 a modificat fișierele cu 356 adăugiri și 14 ștergeri
  1. 6 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkStudentMapper.java
  2. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkArbitrateHistoryService.java
  3. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkGroupService.java
  4. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkGroupStudentService.java
  5. 1 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkHeaderTrackService.java
  6. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkProblemHistoryService.java
  7. 7 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java
  8. 4 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java
  9. 1 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkSubjectiveScoreService.java
  10. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTaskService.java
  11. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTrackService.java
  12. 9 6
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkArbitrateHistoryServiceImpl.java
  13. 12 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkGroupServiceImpl.java
  14. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkGroupStudentServiceImpl.java
  15. 7 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkHeaderTrackServiceImpl.java
  16. 8 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkProblemHistoryServiceImpl.java
  17. 154 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  18. 12 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java
  19. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSubjectiveScoreServiceImpl.java
  20. 8 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java
  21. 7 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTrackServiceImpl.java
  22. 34 0
      teachcloud-mark/src/main/resources/mapper/MarkStudentMapper.xml
  23. 3 1
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/enums/JobEnum.java
  24. 29 0
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/BuildMarkTaskJob.java
  25. 5 0
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/service/JobService.java
  26. 15 0
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/service/impl/JobServiceImpl.java
  27. 4 4
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/start/StartRunning.java

+ 6 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkStudentMapper.java

@@ -7,6 +7,8 @@ import com.qmth.teachcloud.mark.dto.mark.score.StudentScoreDetailDto;
 import com.qmth.teachcloud.mark.entity.MarkStudent;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * <p>
  * 考试考生库 Mapper 接口
@@ -18,4 +20,8 @@ import org.apache.ibatis.annotations.Param;
 public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
 
     IPage<StudentScoreDetailDto> pageStudentScore(@Param("page") Page<StudentScoreDetailDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("college") String college, @Param("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter, @Param("absent") Boolean absent, @Param("breach") Boolean breach, @Param("startScore") Double startScore, @Param("endScore") Double endScore, @Param("subScore") Double subScore, @Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName, @Param("studentCode") String studentCode);
+
+    List<MarkStudent> listAbsentOrBreachMarkTaskStudent(@Param("examId") Long examId, @Param("paperNumber") String paperNumber);
+
+    IPage<MarkStudent> listUnMarkTaskStudent(@Param("page") Page<MarkStudent> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber);
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkArbitrateHistoryService.java

@@ -32,4 +32,6 @@ public interface MarkArbitrateHistoryService extends IService<MarkArbitrateHisto
     Task getArbitrateTask(Long arbitrateId);
 
     void saveArbitrateTask(MarkResult markResult);
+
+    void deleteByStudentId(Long studentId);
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkGroupService.java

@@ -41,4 +41,6 @@ public interface MarkGroupService extends IService<MarkGroup> {
     void saveGroupBatch(MarkGroupTaskDto markGroupTaskDto);
 
     void updateGroup(MarkGroupSingleDto markGroupSingleDto);
+
+    void updateTaskCount(Long examId, String paperNumber, Integer groupNumber, int taskCount);
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkGroupStudentService.java

@@ -15,4 +15,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
 public interface MarkGroupStudentService extends IService<MarkGroupStudent> {
 
     long countByStudentIdAndStatus(Long studentId, SubjectiveStatus marked);
+
+    void deleteByStudentId(Long studentId);
 }

+ 1 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkHeaderTrackService.java

@@ -21,4 +21,5 @@ public interface MarkHeaderTrackService extends IService<MarkHeaderTrack> {
 
     void deleteByExamIdAndPaperNumberAndGroupNumberAndStudentId(Long examId, String paperNumber, Integer groupNumber, Long studentId);
 
+    void deleteByStudentId(Long studentId);
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkProblemHistoryService.java

@@ -23,4 +23,6 @@ public interface MarkProblemHistoryService extends IService<MarkProblemHistory>
     void resetProblem(List<Long> taskIds);
 
     void resetByMarkTaskId(Long id, MarkProblemStatus waiting, Long userId, MarkProblemStatus back, Long now);
+
+    void deleteByStudentId(Long studentId);
 }

+ 7 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java

@@ -1,8 +1,6 @@
 package com.qmth.teachcloud.mark.service;
 
-import com.qmth.teachcloud.mark.entity.MarkGroup;
-import com.qmth.teachcloud.mark.entity.MarkTask;
-import com.qmth.teachcloud.mark.entity.MarkUserGroup;
+import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.params.MarkResult;
 
 /**
@@ -32,4 +30,10 @@ public interface MarkService {
     void processArbitrate(MarkResult markResult, Long userId);
 
     void checkStudentSubjective(Long studentId, long groupCount, long unGroupQuestionCount);
+
+    void buildMarkTask(MarkPaper markPaper);
+
+    void deleteMarkTaskByStudent(MarkStudent student);
+
+    void updateGroupAllCount(Long examId, String paperNumber);
 }

+ 4 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java

@@ -52,4 +52,8 @@ public interface MarkStudentService extends IService<MarkStudent> {
     int countUploadedByExamIdAndPaperNumber(Long examId, String paperNumber);
 
     boolean updateScanInfo(MarkStudent student);
+
+    List<MarkStudent> listAbsentOrBreachMarkTaskStudent(Long examId, String paperNumber);
+
+    List<MarkStudent> listUnMarkTaskStudent(Long examId, String paperNumber, Integer groupNumber, int pageSize);
 }

+ 1 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkSubjectiveScoreService.java

@@ -22,4 +22,5 @@ public interface MarkSubjectiveScoreService extends IService<MarkSubjectiveScore
 
     List<MarkSubjectiveScore> listByStudentIdAndUncalculate(Long studentId, boolean uncalculate);
 
+    void deleteByStudentId(Long studentId);
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTaskService.java

@@ -45,4 +45,6 @@ public interface MarkTaskService extends IService<MarkTask> {
     List<MarkTask> listByStudentIdAndGroupNumber(Long studentId, Integer groupNumber);
 
     void updateHeaderResult(Long examId, String paperNumber, Integer groupNumber, Long studentId, Long updateUserId, Double totalScore, String scoreList, Long updateTime, MarkTaskStatus arbitrated);
+
+    void deleteByStudentId(Long studentId);
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTrackService.java

@@ -18,4 +18,6 @@ public interface MarkTrackService extends IService<MarkTrack> {
     void deleteByTaskId(Long taskId);
 
     List<MarkTrack> listByTaskIdAndQuestionNumber(Long taskId, String questionNumber);
+
+    void deleteByStudentId(Long studentId);
 }

+ 9 - 6
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkArbitrateHistoryServiceImpl.java

@@ -1,10 +1,10 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qmth.teachcloud.mark.entity.MarkPaper;
-import com.qmth.teachcloud.mark.entity.MarkStudent;
+import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.service.*;
@@ -13,10 +13,6 @@ import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateMarkerDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateSettingDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.Task;
-import com.qmth.teachcloud.mark.entity.MarkArbitrateHistory;
-import com.qmth.teachcloud.mark.entity.MarkGroup;
-import com.qmth.teachcloud.mark.entity.MarkTask;
-import com.qmth.teachcloud.mark.entity.MarkUserGroup;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.lock.LockService;
 import com.qmth.teachcloud.mark.mapper.MarkArbitrateHistoryMapper;
@@ -171,6 +167,13 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
         }
     }
 
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkArbitrateHistory> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkArbitrateHistory::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
+
     private void releaseTask(Long taskId) {
         synchronized (currentTaskMap) {
             currentTaskMap.remove(taskId);

+ 12 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkGroupServiceImpl.java

@@ -278,4 +278,16 @@ public class MarkGroupServiceImpl extends ServiceImpl<MarkGroupMapper, MarkGroup
             }
         }
     }
+
+    @Override
+    public void updateTaskCount(Long examId, String paperNumber, Integer groupNumber, int taskCount) {
+        MarkGroup markGroup = this.getByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, groupNumber);
+        UpdateWrapper<MarkGroup> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkGroup::getTaskCount, taskCount)
+                .set(MarkGroup::getLeftCount, taskCount - markGroup.getMarkedCount())
+                .eq(MarkGroup::getExamId, examId)
+                .eq(MarkGroup::getPaperNumber, paperNumber)
+                .eq(MarkGroup::getNumber, groupNumber);
+        this.update(updateWrapper);
+    }
 }

+ 9 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkGroupStudentServiceImpl.java

@@ -1,9 +1,11 @@
 package com.qmth.teachcloud.mark.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
 import com.qmth.teachcloud.mark.entity.MarkGroupStudent;
+import com.qmth.teachcloud.mark.entity.MarkHeaderTrack;
 import com.qmth.teachcloud.mark.mapper.MarkGroupStudentMapper;
 import com.qmth.teachcloud.mark.service.MarkGroupStudentService;
 import org.springframework.stereotype.Service;
@@ -26,4 +28,11 @@ public class MarkGroupStudentServiceImpl extends ServiceImpl<MarkGroupStudentMap
                 .eq(MarkGroupStudent::getStatus, marked);
         return this.count(queryWrapper);
     }
+
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkGroupStudent> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkGroupStudent::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
 }

+ 7 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkHeaderTrackServiceImpl.java

@@ -49,4 +49,11 @@ public class MarkHeaderTrackServiceImpl extends ServiceImpl<MarkHeaderTrackMappe
         this.remove(updateWrapper);
     }
 
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkHeaderTrack> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkHeaderTrack::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
+
 }

+ 8 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkProblemHistoryServiceImpl.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkProblemDto;
+import com.qmth.teachcloud.mark.entity.MarkHeaderTrack;
 import com.qmth.teachcloud.mark.entity.MarkStudent;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.mark.MarkProblemStatus;
@@ -112,4 +113,11 @@ public class MarkProblemHistoryServiceImpl extends ServiceImpl<MarkProblemHistor
                 .eq(MarkProblemHistory::getStatus, waiting);
         this.update(updateWrapper);
     }
+
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkProblemHistory> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkProblemHistory::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
 }

+ 154 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java

@@ -16,7 +16,10 @@ import com.qmth.teachcloud.mark.utils.BigDecimalUtils;
 import com.qmth.teachcloud.mark.utils.TaskLock;
 import com.qmth.teachcloud.mark.utils.TaskLockUtil;
 import org.apache.commons.collections4.CollectionUtils;
+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.math.BigDecimal;
@@ -26,6 +29,8 @@ import java.util.concurrent.ConcurrentHashMap;
 @Service
 public class MarkServiceImpl implements MarkService {
 
+    private final static Logger log = LoggerFactory.getLogger(MarkServiceImpl.class);
+
     public static final int UN_SELECTIVE_SCORE = -1;
 
     private Map<Long, Long> markerLastUpdateTime = new ConcurrentHashMap<>();
@@ -297,6 +302,155 @@ public class MarkServiceImpl implements MarkService {
         }
     }
 
+    @Override
+    public void buildMarkTask(MarkPaper markPaper) {
+        try {
+            lockService.watch(LockType.EXAM_SUBJECT, markPaper.getExamId(), markPaper.getPaperNumber());
+            log.info("start create library for examId=" + markPaper.getExamId() + ", paperNumber=" + markPaper.getPaperNumber());
+            // 清除缺考考生和违纪考生
+            List<MarkStudent> markStudentList = markStudentService.listAbsentOrBreachMarkTaskStudent(markPaper.getExamId(), markPaper.getPaperNumber());
+            if (CollectionUtils.isNotEmpty(markStudentList)) {
+                for (MarkStudent student : markStudentList) {
+                    try {
+                        lockService.waitlock(LockType.STUDENT, student.getId());
+                        log.info("delete library for studentId=" + student.getId());
+                        this.deleteMarkTaskByStudent(student);
+                    } catch (Exception e) {
+                        log.error("delete student library error", e);
+                    } finally {
+                        lockService.unlock(LockType.STUDENT, student.getId());
+                    }
+                }
+            }
+            // 处理正常考生
+            List<MarkGroup> groups = markGroupService.listGroupByExamIdAndPaperNumber(markPaper.getExamId(), markPaper.getPaperNumber());
+            for (MarkGroup group : groups) {
+                // 生成正评任务
+                buildFormalLibrary(group);
+            }
+        } finally {
+            lockService.unwatch(LockType.EXAM_SUBJECT, markPaper.getExamId(), markPaper.getPaperNumber());
+        }
+    }
+
+    private void buildFormalLibrary(MarkGroup group) {
+        int pageSize = 100;
+        try {
+            lockService.watch(LockType.GROUP, group.getExamId(), group.getPaperNumber(), group.getNumber());
+            // 上锁后重复验证分组状态
+            MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(group.getExamId(), group.getPaperNumber());
+            if (MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
+                return;
+            }
+            int count = 0;
+            List<MarkStudent> studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(), group.getNumber(), pageSize);
+            while (CollectionUtils.isNotEmpty(studentList)) {
+                List<MarkTask> taskList = new ArrayList<>();
+                int doubleCount = 0;
+                int studentCount = studentList.size();
+                for (MarkStudent student : studentList) {
+                    MarkTask markTask = new MarkTask();
+                    markTask.setExamId(student.getExamId());
+                    markTask.setPaperNumber(student.getPaperNumber());
+                    markTask.setGroupNumber(group.getNumber());
+                    markTask.setStudentId(student.getId());
+                    markTask.setStudentCode(student.getStudentCode());
+                    markTask.setSecretNumber(student.getSecretNumber());
+                    markTask.setTaskNumber(1);
+                    markTask.setStatus(MarkTaskStatus.WAITING);
+                    taskList.add(markTask);
+                    // 开启双评时需要判断是否生成第二份评卷任务
+                    if (group.getDoubleRate() != null && group.getDoubleRate() > 0) {
+                        boolean needDouble = false;
+                        if (group.getDoubleRate() == 1) {
+                            needDouble = true;
+                        } else {
+                            double libraryCount = taskList.size();
+                            int expectCount = (int) (studentCount * group.getDoubleRate());
+                            // 随机数判断加入当前已经生成双评任务的比例加权
+                            // 实际双评任务数小于理论生成数 &&(剩余未生成双评的考生数量小于剩余应生成的数量||随机比例)
+                            needDouble = doubleCount < expectCount
+                                    && ((studentCount - libraryCount + doubleCount) <= (expectCount - doubleCount) || Math
+                                    .random() < group.getDoubleRate() + 0.1);
+                        }
+                        if (needDouble) {
+                            markTask = new MarkTask();
+                            markTask.setExamId(student.getExamId());
+                            markTask.setPaperNumber(student.getPaperNumber());
+                            markTask.setGroupNumber(group.getNumber());
+                            markTask.setStudentId(student.getId());
+                            markTask.setStudentCode(student.getStudentCode());
+                            markTask.setSecretNumber(student.getSecretNumber());
+                            markTask.setTaskNumber(2);
+                            markTask.setStatus(MarkTaskStatus.WAITING);
+                            taskList.add(markTask);
+                            doubleCount++;
+                        }
+                    }
+                }
+                // 有新任务创建
+                if (CollectionUtils.isNotEmpty(taskList)) {
+                    count += taskList.size();
+                    // 任务乱序
+                    Collections.shuffle(taskList);
+                    // 批量保存
+                    markTaskService.saveBatch(taskList);
+                    // 正评状态才需要更新任务数量
+                    if (MarkPaperStatus.FORMAL.equals(markPaper.getStatus())) {
+                        this.updateMarkTaskCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
+                        this.updateMarkedCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
+                    }
+                }
+                studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(), group.getNumber(), pageSize);
+            }
+            if (count != 0) {
+                log.info("finish create " + count + " markTask for examId=" + group.getExamId() + ", paperNumber=" + group.getPaperNumber() + ", groupNumber=" + group.getNumber());
+            }
+        } catch (Exception e) {
+            log.error(
+                    "build formal markTask error for examId=" + group.getExamId() + ", paperNumber=" + group.getPaperNumber() + ", groupNumber=" + group.getNumber(), e);
+        } finally {
+            lockService.unwatch(LockType.GROUP, group.getExamId(), group.getPaperNumber(), group.getNumber());
+        }
+    }
+
+    @Transactional
+    @Override
+    public void deleteMarkTaskByStudent(MarkStudent student) {
+        // 正评相关数据
+        markTrackService.deleteByStudentId(student.getId());
+//        specialTagDao.deleteByStudentId(student.getId());
+//        headerTagDao.deleteByStudentId(student.getId());
+        markHeaderTrackService.deleteByStudentId(student.getId());
+        markArbitrateHistoryService.deleteByStudentId(student.getId());
+        markProblemHistoryService.deleteByStudentId(student.getId());
+        markTaskService.deleteByStudentId(student.getId());
+        // 主观状态与得分明细
+        markGroupStudentService.deleteByStudentId(student.getId());
+        markSubjectiveScoreService.deleteByStudentId(student.getId());
+//        selectiveStudentDao.deleteByStudentId(student.getId());
+        updateGroupAllCount(student.getExamId(), student.getPaperNumber());
+        // 复核记录
+//        inspectedService.clearByStudent(student.getId());
+        // 打回记录
+//        rejectHistoryDao.deleteByStudentId(student.getId());
+    }
+
+    @Transactional
+    @Override
+    public void updateGroupAllCount(Long examId, String paperNumber) {
+        List<MarkGroup> groups = markGroupService.listGroupByExamIdAndPaperNumber(examId, paperNumber);
+        for (MarkGroup group : groups) {
+            updateMarkedCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
+            updateMarkTaskCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
+        }
+    }
+
+    private void updateMarkTaskCount(Long examId, String paperNumber, Integer groupNumber) {
+        int count = markTaskService.countByExamIdAndPaperNumberAndGroupNumberAndUserId(examId, paperNumber, groupNumber, null);
+        markGroupService.updateTaskCount(examId, paperNumber, groupNumber, count);
+    }
+
     private boolean calculateGroup(MarkGroup group, Long studentId) {
         double score = 0;
         List<ScoreItem> detail = new ArrayList<>();

+ 12 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java

@@ -342,6 +342,18 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
 
     }
 
+    @Override
+    public List<MarkStudent> listAbsentOrBreachMarkTaskStudent(Long examId, String paperNumber) {
+        return this.baseMapper.listAbsentOrBreachMarkTaskStudent(examId, paperNumber);
+    }
+
+    @Override
+    public List<MarkStudent> listUnMarkTaskStudent(Long examId, String paperNumber, Integer groupNumber, int pageSize) {
+        Page<MarkStudent> page = new Page<>(1, pageSize);
+        IPage<MarkStudent> markStudentIPage = this.baseMapper.listUnMarkTaskStudent(page, examId, paperNumber, groupNumber);
+        return markStudentIPage.getRecords();
+    }
+
     private boolean saveUploadStudent(MarkStudent student) {
         MarkStudent old = this.getById(student.getId());
         if (!student.getAbsent()) {// 正考

+ 9 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSubjectiveScoreServiceImpl.java

@@ -1,7 +1,9 @@
 package com.qmth.teachcloud.mark.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.teachcloud.mark.entity.MarkHeaderTrack;
 import com.qmth.teachcloud.mark.entity.MarkSubjectiveScore;
 import com.qmth.teachcloud.mark.mapper.MarkSubjectiveScoreMapper;
 import com.qmth.teachcloud.mark.service.MarkSubjectiveScoreService;
@@ -55,6 +57,13 @@ public class MarkSubjectiveScoreServiceImpl extends ServiceImpl<MarkSubjectiveSc
         return this.list(queryWrapper);
     }
 
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkSubjectiveScore> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkSubjectiveScore::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
+
     private void sort(List<MarkSubjectiveScore> list) {
         list.sort((o1, o2) -> {
             int i = o1.getMainNumber() - o2.getMainNumber();

+ 8 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java

@@ -10,6 +10,7 @@ import com.qmth.teachcloud.common.util.ExcelUtil;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkManageDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkerInfoDto;
 import com.qmth.teachcloud.mark.entity.MarkGroup;
+import com.qmth.teachcloud.mark.entity.MarkHeaderTrack;
 import com.qmth.teachcloud.mark.entity.MarkTask;
 import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
 import com.qmth.teachcloud.mark.mapper.MarkTaskMapper;
@@ -186,4 +187,11 @@ public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> i
                 .eq(MarkTask::getStudentId, studentId);
         this.update(updateWrapper);
     }
+
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkTask> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkTask::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
 }

+ 7 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTrackServiceImpl.java

@@ -35,4 +35,11 @@ public class MarkTrackServiceImpl extends ServiceImpl<MarkTrackMapper, MarkTrack
                 .eq(MarkTrack::getQuestionNumber, questionNumber);
         return this.list(queryWrapper);
     }
+
+    @Override
+    public void deleteByStudentId(Long studentId) {
+        UpdateWrapper<MarkTrack> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkTrack::getStudentId, studentId);
+        this.remove(updateWrapper);
+    }
 }

+ 34 - 0
teachcloud-mark/src/main/resources/mapper/MarkStudentMapper.xml

@@ -120,5 +120,39 @@
                 AND ms.student_code = #{studentCode}
             </if>
     </select>
+    <select id="listAbsentOrBreachMarkTaskStudent" resultMap="BaseResultMap">
+        SELECT
+            *
+        FROM
+            mark_student ms
+        WHERE
+            ms.exam_id = 1 AND ms.paper_number = 1
+          AND ms.is_upload = TRUE
+          AND (is_absent = TRUE OR is_breach = TRUE)
+          AND EXISTS( SELECT
+                          1
+                      FROM
+                          mark_task mt
+                      WHERE
+                          ms.id = mt.student_id)
+    </select>
+    <select id="listUnMarkTaskStudent" resultMap="BaseResultMap">
+        SELECT
+            *
+        FROM
+            mark_student ms
+        WHERE
+            ms.exam_id = #{examId} AND ms.paper_number = #{paperNumber}
+          AND ms.is_upload = TRUE
+          AND is_absent = FALSE
+          AND is_breach = FALSE
+          AND NOT EXISTS( SELECT
+                              1
+                          FROM
+                              mark_task mt
+                          WHERE
+                              ms.id = mt.student_id
+                            AND mt.group_number = #{groupNumber})
+    </select>
 
 </mapper>

+ 3 - 1
teachcloud-task/src/main/java/com/qmth/teachcloud/task/enums/JobEnum.java

@@ -39,7 +39,9 @@ public enum JobEnum {
 
     REDIS_MQ_JOB_GROUP("学校信息同步定时任务组"),
     UPDATE_MARKER_QUALITY("更新评卷员质量监控指标"),
-    UPDATE_MARKER_QUALITY_GROUP("更新评卷员质量监控指标任务组");
+    UPDATE_MARKER_QUALITY_GROUP("更新评卷员质量监控指标任务组"),
+    BUILD_MARK_TASK("创建评卷任务"),
+    BUILD_MARK_TASK_GROUP("创建评卷任务任务组");
 
     private String title;
 

+ 29 - 0
teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/BuildMarkTaskJob.java

@@ -0,0 +1,29 @@
+package com.qmth.teachcloud.task.job;
+
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.task.job.service.JobService;
+import org.quartz.JobExecutionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import javax.annotation.Resource;
+
+/**
+ * 生成评卷任务
+ */
+public class BuildMarkTaskJob extends QuartzJobBean {
+    private final static Logger log = LoggerFactory.getLogger(BuildMarkTaskJob.class);
+
+    @Resource
+    JobService jobService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) {
+        try {
+            jobService.updateBuildMarkTask();
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+    }
+}

+ 5 - 0
teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/service/JobService.java

@@ -51,4 +51,9 @@ public interface JobService {
     void machineHeart();
 
     void updateMarkerQuality();
+
+    /**
+     * 创建评卷任务
+     */
+    void updateBuildMarkTask();
 }

+ 15 - 0
teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/service/impl/JobServiceImpl.java

@@ -6,6 +6,7 @@ import com.qmth.teachcloud.common.bean.dto.MqDto;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
+import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.service.MarkPaperService;
 import com.qmth.teachcloud.common.util.RedisUtil;
 import com.qmth.teachcloud.mark.entity.MarkGroup;
@@ -126,6 +127,20 @@ public class JobServiceImpl implements JobService {
         }
     }
 
+    @Override
+    public void updateBuildMarkTask() {
+        log.info("start auto-create library");
+        try {
+            List<MarkPaper> markPaperList = markPaperService.listQualityMarkPaperByStatus(MarkPaperStatus.FORMAL, 0);
+            for (MarkPaper markPaper : markPaperList) {
+                markService.buildMarkTask(markPaper);
+            }
+        } catch (Exception e) {
+            log.error("auto-create library error", e);
+        } finally {
+            log.info("finish auto-create library");
+        }
+    }
     /**
      * 组装job
      *

+ 4 - 4
teachcloud-task/src/main/java/com/qmth/teachcloud/task/start/StartRunning.java

@@ -90,10 +90,10 @@ public class StartRunning implements CommandLineRunner {
 
         // 每1分钟一次
         log.info("增加更新评卷员质量监控指标定时任务 start");
-        Map qualityJobMap = new HashMap();
-        qualityJobMap.computeIfAbsent("name", v -> SubjectCalculateJob.class.getName());
-        quartzService.deleteJob(JobEnum.UPDATE_MARKER_QUALITY.name(), JobEnum.UPDATE_MARKER_QUALITY_GROUP.name());
-        quartzService.addJob(SubjectCalculateJob.class, JobEnum.UPDATE_MARKER_QUALITY.name(), JobEnum.UPDATE_MARKER_QUALITY_GROUP.name(), "0 */1 * * * ?", qualityJobMap);
+        Map buildMarkTaskJobMap = new HashMap();
+        buildMarkTaskJobMap.computeIfAbsent("name", v -> BuildMarkTaskJob.class.getName());
+        quartzService.deleteJob(JobEnum.BUILD_MARK_TASK.name(), JobEnum.BUILD_MARK_TASK_GROUP.name());
+        quartzService.addJob(BuildMarkTaskJob.class, JobEnum.BUILD_MARK_TASK.name(), JobEnum.BUILD_MARK_TASK_GROUP.name(), "0 */1 * * * ?", buildMarkTaskJobMap);
         log.info("增加更新评卷员质量监控指标定时任务 end");
 
         log.info("服务器启动时执行 end");