xiaofei 8 mesi fa
parent
commit
ad48cf1456
49 ha cambiato i file con 1936 aggiunte e 185 eliminazioni
  1. 1 8
      pom.xml
  2. 22 6
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/api/ParamApi.java
  3. 61 0
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/dto/PaperStudentExpDTO.java
  4. 91 11
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/exporter/PaperExporter.java
  5. 2 1
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/exporter/ScoreExporter.java
  6. 16 0
      stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java
  7. 1 1
      stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/lock/LockType.java
  8. 26 0
      stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/utils/DateUtil.java
  9. 21 2
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/ChangeLevel.java
  10. 175 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/ChangeLevelTask.java
  11. 6 2
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/MarkLogOperType.java
  12. 18 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/Paper.java
  13. 114 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/PaperCheck.java
  14. 90 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/PaperCheckStudent.java
  15. 13 4
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/ChangeLevelRepo.java
  16. 20 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/ChangeLevelTaskRepo.java
  17. 4 4
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskLevelRepo.java
  18. 2 2
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskRoughLevelRepo.java
  19. 2 2
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskScoreRepo.java
  20. 35 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperCheckRepo.java
  21. 22 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperCheckStudentRepo.java
  22. 17 2
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperRepo.java
  23. 1 1
      stmms-ms-main/install/config.ini
  24. 56 0
      stmms-ms-main/install/mysql/init/stmms_ms.sql
  25. 52 0
      stmms-ms-main/install/mysql/upgrade/3.1.2.sql
  26. 82 0
      stmms-ms-main/src/main/resources/application-base.properties
  27. 53 48
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/ChangeLevelApi.java
  28. 14 12
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MakrerApi.java
  29. 7 1
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkSubjectApi.java
  30. 30 3
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkTaskApi.java
  31. 59 6
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/PaperApi.java
  32. 346 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/PaperCheckApi.java
  33. 62 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/MarkTaskLevelAssembler.java
  34. 23 26
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/MarkTaskRoughLevelAssembler.java
  35. 77 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/PaperAssembler.java
  36. 2 2
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/QuestionStatAssembler.java
  37. 35 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/MarkTaskBatchNoDTO.java
  38. 82 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/PaperCheckExportDTO.java
  39. 21 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/PaperCheckImportStudentDTO.java
  40. 45 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/PaperCheckSelectInfoDTO.java
  41. 67 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/ChangeLevelTaskService.java
  42. 4 3
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkLogService.java
  43. 11 10
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkTaskLevelService.java
  44. 5 4
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkTaskRoughLevelService.java
  45. 10 12
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkTaskScoreService.java
  46. 6 3
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingLevelService.java
  47. 7 3
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingRoughLevelService.java
  48. 4 1
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingScoreService.java
  49. 16 5
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingService.java

+ 1 - 8
pom.xml

@@ -29,14 +29,12 @@
     <properties>
         <!-- non-dependencies -->
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <project.version>3.1.1</project.version>
+        <project.version>3.1.2</project.version>
         <java.version>1.8</java.version>
         <thymeleaf.version>3.0.0.RELEASE</thymeleaf.version>
         <thymeleaf-layout-dialect.version>2.0.0</thymeleaf-layout-dialect.version>
         <mysql.version>8.0.29</mysql.version>
         <poi.version>3.8</poi.version>
-        <!--反射工具类 -->
-        <reflectasm.version>1.11.3</reflectasm.version>
         <!-- 图片压缩 -->
         <thumbnailator.version>0.4.8</thumbnailator.version>
         <!-- maven plugins -->
@@ -101,11 +99,6 @@
                 <artifactId>json-lib</artifactId>
                 <version>2.4</version>
             </dependency>
-            <dependency>
-                <groupId>com.esotericsoftware</groupId>
-                <artifactId>reflectasm</artifactId>
-                <version>${reflectasm.version}</version>
-            </dependency>
             <dependency>
                 <groupId>net.coobird</groupId>
                 <artifactId>thumbnailator</artifactId>

+ 22 - 6
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/api/ParamApi.java

@@ -12,6 +12,8 @@ import cn.com.qmth.stmms.ms.core.domain.paramsetting.CollectConfig;
 import cn.com.qmth.stmms.ms.core.domain.paramsetting.LevelConfig;
 import cn.com.qmth.stmms.ms.core.domain.paramsetting.RoughLevelConfig;
 import cn.com.qmth.stmms.ms.core.domain.paramsetting.ScoreConfig;
+import cn.com.qmth.stmms.ms.core.domain.user.MarkerGroup;
+import cn.com.qmth.stmms.ms.core.domain.user.Role;
 import cn.com.qmth.stmms.ms.core.repository.*;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -48,6 +50,8 @@ public class ParamApi {
 
     @Resource
     private MarkTaskScoreRepo markTaskScoreRepo;
+    @Resource
+    private MarkerGroupRepo markerGroupRepo;
 
     /**
      * 查询
@@ -317,12 +321,24 @@ public class ParamApi {
         List<MarkSubject> markSubjects = markSubjectRepo.findByWorkIdAndTestAndStageIn(workId, TrialEnum.DEFAULT.ordinal(), markStageList);
 
         int countMarkTasks = markTaskScoreRepo.countByWorkId(workId);
-        if (markSubjects != null && !markSubjects.isEmpty() && countMarkTasks > 0) {
-            if (!Objects.equals(roundUp, oldScoreConfig.getRoundUp())) {
-                throw new RuntimeException("评卷工作已有正评数据,不能修改【分数处理方式】参数");
-            }
-            if (!Objects.equals(removeHighAndLow, oldScoreConfig.getRemoveHighAndLow())) {
-                throw new RuntimeException("评卷工作已有正评数据,不能修改【分数计算方式】参数");
+//        if (markSubjects != null && !markSubjects.isEmpty() && countMarkTasks > 0) {
+//            if (!Objects.equals(roundUp, oldScoreConfig.getRoundUp())) {
+//                throw new RuntimeException("评卷工作已有正评数据,不能修改【分数处理方式】参数");
+//            }
+//            if (!Objects.equals(removeHighAndLow, oldScoreConfig.getRemoveHighAndLow())) {
+//                throw new RuntimeException("评卷工作已有正评数据,不能修改【分数计算方式】参数");
+//            }
+//        }
+
+        // 分数计算方式为"去高去低加权平均"时,校验各科目各分组中评卷员数量是否小于3个
+        if (removeHighAndLow == 1) {
+            for (MarkSubject markSubject : markSubjects) {
+                List<MarkerGroup> markerGroups = markerGroupRepo.findByWorkIdAndSubjectAndStage(workId, markSubject.getSubject(), MarkStage.SCORE);
+                for (MarkerGroup markerGroup : markerGroups) {
+                    if (markerGroup.getMarkers().stream().filter(m -> Role.MARKER.equals(m.getRole())).count() < 3) {
+                        throw new RuntimeException("取分规则为去高低再平均,【" + markSubject.getName() + "】科目【" + markerGroup.getName() + "】评委数必须大于等于3");
+                    }
+                }
             }
         }
 

+ 61 - 0
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/dto/PaperStudentExpDTO.java

@@ -0,0 +1,61 @@
+package cn.com.qmth.stmms.ms.admin.dto;
+
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelProperty;
+
+public class PaperStudentExpDTO {
+
+
+    @ExcelProperty(name = "科目", index = 0, type = 1)
+    private String subject;
+
+    @ExcelProperty(name = "科目名称", index = 1, type = 1)
+    private String subjectName;
+    @ExcelProperty(name = "考区", index = 2, type = 1)
+    private String areaName;
+
+    @ExcelProperty(name = "考号", index = 3, type = 1)
+    private String examNumber;
+
+    @ExcelProperty(name = "姓名", index = 4, type = 1)
+    private String studentName;
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public String getAreaName() {
+        return areaName;
+    }
+
+    public void setAreaName(String areaName) {
+        this.areaName = areaName;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+}

+ 91 - 11
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/exporter/PaperExporter.java

@@ -1,23 +1,21 @@
 package cn.com.qmth.stmms.ms.admin.exporter;
 
-import cn.com.qmth.stmms.ms.admin.dto.MarkExpDTO;
-import cn.com.qmth.stmms.ms.admin.dto.OneClickExpDTO;
-import cn.com.qmth.stmms.ms.admin.dto.PaperExpDTO;
-import cn.com.qmth.stmms.ms.admin.dto.SampleExpDTO;
+import cn.com.qmth.stmms.ms.admin.dto.*;
 import cn.com.qmth.stmms.ms.commons.utils.DigitalToChineseUtil;
 import cn.com.qmth.stmms.ms.commons.utils.PdfUtils;
 import cn.com.qmth.stmms.ms.commons.utils.excel.ExportUtils;
 import cn.com.qmth.stmms.ms.core.domain.*;
-import cn.com.qmth.stmms.ms.core.repository.ChangeLevelRepo;
-import cn.com.qmth.stmms.ms.core.repository.MarkLogRepo;
-import cn.com.qmth.stmms.ms.core.repository.MarkSubjectRepo;
-import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
+import cn.com.qmth.stmms.ms.core.repository.*;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 import com.alibaba.fastjson.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
+import javax.persistence.criteria.Predicate;
 import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.util.ArrayList;
@@ -34,15 +32,15 @@ public class PaperExporter {
 
     @Autowired
     private PaperRepo paperRepo;
-
     @Autowired
     MarkLogRepo markLogRepo;
-
     @Autowired
     private MarkSubjectRepo markSubjectRepo;
-
     @Autowired
     private ChangeLevelRepo changeLevelRepo;
+    @Autowired
+    private ExamQuestionRepo examQuestionRepo;
+
 
     @Value("${sys.config.imageDir}")
     private String imagesFolder;
@@ -201,4 +199,86 @@ public class PaperExporter {
         }
         ExportUtils.exportEXCEL("标记试卷信息", MarkExpDTO.class, markExpDTOS, response);
     }
+
+    /**
+     * 试卷管理-导出
+     */
+    @GetMapping(value = "export")
+    public void export(@RequestParam Long workId,
+                       @RequestParam(required = false) String areaCode,
+                       @RequestParam Subject subject,
+                       @RequestParam(required = false) String startNumber,
+                       @RequestParam(required = false) String endNumber,
+                       @RequestParam(required = false) Boolean isManual,
+                       @RequestParam(required = false) Boolean missing,
+                       @RequestParam(required = false) Boolean isRelate,
+                       @RequestParam(required = false) String studentName,
+                       @RequestParam(required = false) Long scanUserId,
+                       @RequestParam(required = false) Boolean isMark,
+                       @RequestParam(required = false) Boolean sizeAbnormal, // 大小异常
+                       @RequestParam(required = false) String sortBy,
+                       HttpServletResponse response) {
+        Sort sort = null;
+        if (Objects.equals("1", sortBy)) {
+            sort = new Sort(Sort.Direction.DESC, "uploadedOn");
+        }
+        if (Objects.equals("2", sortBy)) {
+            sort = new Sort(Sort.Direction.ASC, "examNumber");
+        }
+        Specification<Paper> specification = (root, query, builder) -> {
+            List<Predicate> predicates = new ArrayList<>();
+            predicates.add(builder.equal(root.get("workId"), workId));
+            if (scanUserId != null) {
+                predicates.add(builder.equal(root.get("scanUserId"), scanUserId));
+            }
+            if (areaCode != null && !"".equals(areaCode)) {
+                predicates.add(builder.equal(root.get("areaCode"), areaCode));
+            }
+            if (subject != null) {
+                predicates.add(builder.equal(root.get("subject"), subject));
+            }
+            if (!StringUtils.isEmpty(startNumber) && !StringUtils.isEmpty(endNumber)) {
+                predicates.add(builder.between(root.get("examNumber"), startNumber, endNumber));
+            } else if (!StringUtils.isEmpty(startNumber) && StringUtils.isEmpty(endNumber)) {
+                predicates.add(builder.equal(root.get("examNumber"), startNumber));
+            } else if (StringUtils.isEmpty(startNumber) && !StringUtils.isEmpty(endNumber)) {
+                predicates.add(builder.equal(root.get("examNumber"), endNumber));
+            }
+            if (isManual != null) {
+                predicates.add(builder.equal(root.get("isManual"), isManual));
+            }
+            if (missing != null) {
+                predicates.add(builder.equal(root.get("isMissing"), missing));
+            }
+            if (isRelate != null) {
+                predicates.add(builder.equal(root.get("isRelate"), isRelate));
+            }
+            if (isMark != null) {
+                predicates.add(builder.equal(root.get("isAdminMark"), isMark));
+            }
+            if (sizeAbnormal != null) {
+                predicates.add(builder.equal(root.get("sizeAbnormal"), sizeAbnormal));
+            }
+            //考生姓名
+            if (studentName != null && !"".equals(studentName)) {
+                predicates.add(builder.equal(root.get("studentName"), studentName));
+            }
+            return builder.and(predicates.toArray(new Predicate[predicates.size()]));
+        };
+        List<Paper> paperList = paperRepo.findAll(specification, sort);
+
+        ExamQuestion examQuestion = examQuestionRepo.findByWorkIdAndSubjectAndAreaCode(workId, subject, areaCode);
+
+        List<PaperStudentExpDTO> paperStudentExpDTOS = new ArrayList<>();
+        for (Paper paper : paperList) {
+            PaperStudentExpDTO paperStudentExpDTO = new PaperStudentExpDTO();
+            paperStudentExpDTO.setSubject(paper.getSubject().name());
+            paperStudentExpDTO.setSubjectName(paper.getSubject().getName());
+            paperStudentExpDTO.setAreaName(examQuestion != null ? examQuestion.getAreaName() : "");
+            paperStudentExpDTO.setExamNumber(paper.getExamNumber());
+            paperStudentExpDTO.setStudentName(paper.getStudentName());
+            paperStudentExpDTOS.add(paperStudentExpDTO);
+        }
+        ExportUtils.exportEXCEL("试卷管理-考生信息", PaperStudentExpDTO.class, paperStudentExpDTOS, response);
+    }
 }

+ 2 - 1
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/exporter/ScoreExporter.java

@@ -16,6 +16,7 @@ import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
 import cn.com.qmth.stmms.ms.core.repository.StudentRepo;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 import com.google.gson.Gson;
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 import org.apache.poi.ss.usermodel.Cell;
@@ -564,7 +565,7 @@ public class ScoreExporter {
                                 drawExcelFixedHead(finalSheet, style, hssfRow, new HeaderNode(Objects.nonNull(v.getIsShift()) ? "是" : "否", firstRow, firstRow, level + (scMap == null ? 0 : scMap.size()) + (smMap == null ? 0 : smMap.size()) + 5 + 6, level + (scMap == null ? 0 : scMap.size()) + (smMap == null ? 0 : smMap.size()) + 5 + 6));
                             } else if (k.contains(Subject.SX.toString())) {
                                 ExportLevelResultDTO exportLevelResultDTO = sxMap.get(v.getTeacherName());
-                                drawExcelFixedHead(finalSheet, style, hssfRow, new HeaderNode(roughLevels[Integer.parseInt(v.getResult())], firstRow, firstRow, exportLevelResultDTO.getFirstCol(), exportLevelResultDTO.getFirstCol()));
+                                drawExcelFixedHead(finalSheet, style, hssfRow, new HeaderNode(StringUtils.isNotBlank(v.getResult()) ? roughLevels[Integer.parseInt(v.getResult())] : "", firstRow, firstRow, exportLevelResultDTO.getFirstCol(), exportLevelResultDTO.getFirstCol()));
                                 if (Objects.nonNull(v.getLevel())) {
                                     drawExcelFixedHead(finalSheet, style, hssfRow, new HeaderNode(roughLevels[Integer.parseInt(v.getLevel())], firstRow, firstRow, level + (scMap == null ? 0 : scMap.size()) + (smMap == null ? 0 : smMap.size()) + (sxMap == null ? 0 : sxMap.size()) + 6 * 2, level + (scMap == null ? 0 : scMap.size()) + (smMap == null ? 0 : smMap.size()) + (sxMap == null ? 0 : sxMap.size()) + 6 * 2));
                                 }

+ 16 - 0
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java

@@ -1402,6 +1402,22 @@ public class CollectApi {
         }
     }
 
+    /**
+     * 校验管理员密码
+     *
+     * @param password 密码
+     */
+    @PostMapping(value = "/validAdminPassword")
+    public boolean validAdminPassword(@RequestParam String password) {
+        if (StringUtils.isBlank(password)) {
+            throw new RuntimeException("密码长度不能小于6位");
+        }
+        if (!loginConfig.adminLoginConfig().getPassword().equals(password)) {
+            throw new RuntimeException("密码不正确");
+        }
+        return true;
+    }
+
     public static void main(String[] args) throws IOException {
         String msg1 = "90分";
         BufferedImage bi = createWaterImage(msg1);

+ 1 - 1
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/lock/LockType.java

@@ -1,7 +1,7 @@
 package cn.com.qmth.stmms.ms.commons.lock;
 
 public enum LockType {
-    ROUGH_LEVEL("roughLevel"),LEVEL("level"), SCORE("score");
+    ROUGH_LEVEL("roughLevel"),LEVEL("level"), SCORE("score"), PAPER("paper");
 
     private String name;
 

+ 26 - 0
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/utils/DateUtil.java

@@ -0,0 +1,26 @@
+package cn.com.qmth.stmms.ms.commons.utils;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class DateUtil {
+
+    public static String YYMMDDHHMM = "yyMMddHHmm";
+
+    /**
+     * 时间戳转指定日期格式
+     *
+     * @param format    日期格式
+     * @param timestamp 时间戳
+     */
+    public static final String parseDateToStr(final String format, final Long timestamp) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(timestamp); // 设置日历时间为给定的时间戳
+
+        Date date = calendar.getTime();
+
+        SimpleDateFormat sdf = new SimpleDateFormat(format); // 定义日期格式
+        return sdf.format(date); // 格式化日期
+    }
+}

+ 21 - 2
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/ChangeLevel.java

@@ -1,5 +1,7 @@
 package cn.com.qmth.stmms.ms.core.domain;
 
+import cn.com.qmth.stmms.ms.core.domain.user.Role;
+
 import javax.persistence.*;
 import javax.validation.constraints.NotNull;
 import java.util.Date;
@@ -29,11 +31,12 @@ public class ChangeLevel {
     private Integer auditStatus;
 
     private Long createId;
-
+    private Long paperCheckId;
+    @Enumerated(value = EnumType.STRING)
+    private Role role;
     private Date createDate;
 
     private Long auditId;
-
     private Date auditDate;
 
     private Integer isCurr;
@@ -114,6 +117,22 @@ public class ChangeLevel {
         this.createId = createId;
     }
 
+    public Long getPaperCheckId() {
+        return paperCheckId;
+    }
+
+    public void setPaperCheckId(Long paperCheckId) {
+        this.paperCheckId = paperCheckId;
+    }
+
+    public Role getRole() {
+        return role;
+    }
+
+    public void setRole(Role role) {
+        this.role = role;
+    }
+
     public Date getCreateDate() {
         return createDate;
     }

+ 175 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/ChangeLevelTask.java

@@ -0,0 +1,175 @@
+package cn.com.qmth.stmms.ms.core.domain;
+
+import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
+import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskScore;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+@Entity
+@Table(name = "change_level_task")
+public class ChangeLevelTask {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    private Long workId;
+    private Long questionId;
+    @NotNull
+    @ManyToOne
+    @JoinColumn(name = "paperId")
+    private Paper paper;
+    private String subject;
+    @NotNull
+    @Enumerated(value = EnumType.ORDINAL)
+    private MarkStage stage;
+    @NotNull
+    private Long markerId;
+    @NotNull
+    private String markerName;
+    private String secretNumber;
+    private String result;
+    private Boolean confirmChangeStage;
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date confirmOn;
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date createdOn;
+
+    public static ChangeLevelTask toChangeLevelTask(MarkTaskLevel m, String suggestLevel) {
+        ChangeLevelTask changeLevelTask = new ChangeLevelTask();
+        changeLevelTask.setWorkId(m.getWorkId());
+        changeLevelTask.setQuestionId(m.getQuestionId());
+        changeLevelTask.setPaper(m.getPaper());
+        changeLevelTask.setSubject(m.getSubject().name());
+        changeLevelTask.setStage(m.getStage());
+        changeLevelTask.setMarkerId(m.getMarkerId());
+        changeLevelTask.setMarkerName(m.getMarkerName());
+        changeLevelTask.setResult(suggestLevel);
+        changeLevelTask.setConfirmChangeStage(false);
+        changeLevelTask.setCreatedOn(new Date());
+        return changeLevelTask;
+    }
+
+    public static ChangeLevelTask toChangeLevelTask(MarkTaskScore m, String suggestLevel, Long random) {
+        ChangeLevelTask changeLevelTask = new ChangeLevelTask();
+        changeLevelTask.setWorkId(m.getWorkId());
+        changeLevelTask.setQuestionId(m.getQuestionId());
+        changeLevelTask.setPaper(m.getPaper());
+        changeLevelTask.setSubject(m.getSubject().name());
+        changeLevelTask.setStage(m.getStage());
+        changeLevelTask.setMarkerId(m.getMarkerId());
+        changeLevelTask.setMarkerName(m.getMarkerName());
+        // 默认加上前缀4
+        changeLevelTask.setSecretNumber(4 + String.valueOf(random));
+        changeLevelTask.setResult(suggestLevel);
+        changeLevelTask.setConfirmChangeStage(false);
+        changeLevelTask.setCreatedOn(new Date());
+        return changeLevelTask;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getWorkId() {
+        return workId;
+    }
+
+    public void setWorkId(Long workId) {
+        this.workId = workId;
+    }
+
+    public Long getQuestionId() {
+        return questionId;
+    }
+
+    public void setQuestionId(Long questionId) {
+        this.questionId = questionId;
+    }
+
+    public Paper getPaper() {
+        return paper;
+    }
+
+    public void setPaper(Paper paper) {
+        this.paper = paper;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public MarkStage getStage() {
+        return stage;
+    }
+
+    public void setStage(MarkStage stage) {
+        this.stage = stage;
+    }
+
+    public Long getMarkerId() {
+        return markerId;
+    }
+
+    public void setMarkerId(Long markerId) {
+        this.markerId = markerId;
+    }
+
+    public String getMarkerName() {
+        return markerName;
+    }
+
+    public void setMarkerName(String markerName) {
+        this.markerName = markerName;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public Boolean getConfirmChangeStage() {
+        return confirmChangeStage;
+    }
+
+    public void setConfirmChangeStage(Boolean confirmChangeStage) {
+        this.confirmChangeStage = confirmChangeStage;
+    }
+
+    public Date getConfirmOn() {
+        return confirmOn;
+    }
+
+    public void setConfirmOn(Date confirmOn) {
+        this.confirmOn = confirmOn;
+    }
+
+    public Date getCreatedOn() {
+        return createdOn;
+    }
+
+    public void setCreatedOn(Date createdOn) {
+        this.createdOn = createdOn;
+    }
+}

+ 6 - 2
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/MarkLogOperType.java

@@ -108,7 +108,11 @@ public enum MarkLogOperType {
     /**
      * 改档打档
      */
-    CANCEL_SAMPLE(20, "取消标准卷");
+    CANCEL_SAMPLE(20, "取消标准卷"),
+    /**
+     * 纪检改档申请
+     */
+    INSPECTION_CHANGE_LEVEL_APPLY(21, "纪检改档申请");
 
     private int id;
 
@@ -242,7 +246,7 @@ public enum MarkLogOperType {
      */
     public static List<Map> listTypes() {
         MarkLogOperType[] values = MarkLogOperType.values();
-        Integer[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 10, 15, 16, 17, 18, 19, 20};
+        Integer[] ints = {1, 2, 3, 4, 5, 6, 7, 8, 10, 15, 16, 17, 18, 19, 20, 21};
         List<Integer> intList = Arrays.asList(ints);
         List<Map> list = new ArrayList<>();
         for (MarkLogOperType value : values) {

+ 18 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/Paper.java

@@ -174,6 +174,8 @@ public class Paper implements Serializable {
      * 大小是否异常
      */
     private boolean sizeAbnormal;
+    private Long roughMarkLeaderId;
+    private Long markLeaderId;
 
     public int getTest() {
         return test;
@@ -691,4 +693,20 @@ public class Paper implements Serializable {
     public void setSizeAbnormal(boolean sizeAbnormal) {
         this.sizeAbnormal = sizeAbnormal;
     }
+
+    public Long getRoughMarkLeaderId() {
+        return roughMarkLeaderId;
+    }
+
+    public void setRoughMarkLeaderId(Long roughMarkLeaderId) {
+        this.roughMarkLeaderId = roughMarkLeaderId;
+    }
+
+    public Long getMarkLeaderId() {
+        return markLeaderId;
+    }
+
+    public void setMarkLeaderId(Long markLeaderId) {
+        this.markLeaderId = markLeaderId;
+    }
 }

+ 114 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/PaperCheck.java

@@ -0,0 +1,114 @@
+package cn.com.qmth.stmms.ms.core.domain;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+@Entity
+@Table(name = "paper_check")
+public class PaperCheck {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+    private Long workId;
+    private String subject;
+    @NotNull
+    @Enumerated(value = EnumType.ORDINAL)
+    private MarkStage stage;
+    private String name;
+    private String remark;
+    private int studentCount;
+    private Boolean startDeal;
+    private String selectInfo;
+    private Long createdId;
+    private Date createdOn;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getWorkId() {
+        return workId;
+    }
+
+    public void setWorkId(Long workId) {
+        this.workId = workId;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public MarkStage getStage() {
+        return stage;
+    }
+
+    public void setStage(MarkStage stage) {
+        this.stage = stage;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public int getStudentCount() {
+        return studentCount;
+    }
+
+    public void setStudentCount(int studentCount) {
+        this.studentCount = studentCount;
+    }
+
+    public Boolean getStartDeal() {
+        return startDeal;
+    }
+
+    public void setStartDeal(Boolean startDeal) {
+        this.startDeal = startDeal;
+    }
+
+    public String getSelectInfo() {
+        return selectInfo;
+    }
+
+    public void setSelectInfo(String selectInfo) {
+        this.selectInfo = selectInfo;
+    }
+
+    public Long getCreatedId() {
+        return createdId;
+    }
+
+    public void setCreatedId(Long createdId) {
+        this.createdId = createdId;
+    }
+
+    public Date getCreatedOn() {
+        return createdOn;
+    }
+
+    public void setCreatedOn(Date createdOn) {
+        this.createdOn = createdOn;
+    }
+}

+ 90 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/PaperCheckStudent.java

@@ -0,0 +1,90 @@
+package cn.com.qmth.stmms.ms.core.domain;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+@Entity
+@Table(name = "paper_check_student")
+public class PaperCheckStudent {
+
+    @Id
+    @GeneratedValue
+    private Long id;
+    private Long workId;
+    private String subject;
+    @NotNull
+    @Enumerated(value = EnumType.ORDINAL)
+    private MarkStage stage;
+    private Long paperCheckId;
+    private Long paperId;
+    private String secretNumber;
+
+    public PaperCheckStudent() {
+    }
+
+    public PaperCheckStudent(Long workId, String subject, MarkStage stage, Long paperCheckId, Long paperId, String secretNumber) {
+        this.workId = workId;
+        this.subject = subject;
+        this.stage = stage;
+        this.paperCheckId = paperCheckId;
+        this.paperId = paperId;
+        this.secretNumber = secretNumber;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getWorkId() {
+        return workId;
+    }
+
+    public void setWorkId(Long workId) {
+        this.workId = workId;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public MarkStage getStage() {
+        return stage;
+    }
+
+    public void setStage(MarkStage stage) {
+        this.stage = stage;
+    }
+
+    public Long getPaperCheckId() {
+        return paperCheckId;
+    }
+
+    public void setPaperCheckId(Long paperCheckId) {
+        this.paperCheckId = paperCheckId;
+    }
+
+    public Long getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Long paperId) {
+        this.paperId = paperId;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+}

+ 13 - 4
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/ChangeLevelRepo.java

@@ -2,6 +2,9 @@ package cn.com.qmth.stmms.ms.core.repository;
 
 import cn.com.qmth.stmms.ms.core.domain.ChangeLevel;
 import cn.com.qmth.stmms.ms.core.domain.MarkStage;
+import cn.com.qmth.stmms.ms.core.domain.user.Role;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
@@ -18,16 +21,22 @@ public interface ChangeLevelRepo extends JpaRepository<ChangeLevel, Long>, JpaSp
     @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.paperId = ?4 and s.auditStatus = 1 and s.isCurr = 1")
     ChangeLevel findByWorkIdAndSubjectAndPaperIdAndAuditStatusAndStageAndIsCurr(Long workId, String subject, MarkStage stage, Long paperId);
 
+    @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.role = ?4 and s.paperId = ?5 and s.auditStatus = 1 and s.isCurr = 1")
+    ChangeLevel findByWorkIdAndSubjectAndPaperIdAndAuditStatusAndStageAndRoleAndIsCurr(Long workId, String subject, MarkStage stage, Role role, Long paperId);
+
     void deleteByWorkIdAndSubjectAndStage(Long workId, String subject, MarkStage stage);
 
-    @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.paperId = ?4 and s.auditStatus = 1 and s.isCurr = 1")
-    ChangeLevel findByWorkIdAndSubjectAndStageAndPaperIdAndAuditStatusAndIsCurr(Long workId, String subject, MarkStage stage, Long paperId);
+    @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.paperId = ?4 and s.paperCheckId = ?5 and s.auditStatus = 1 and s.isCurr = 1")
+    ChangeLevel findByWorkIdAndSubjectAndStageAndPaperIdAndPaperCheckIdAndAuditStatusAndIsCurr(Long workId, String subject, MarkStage stage, Long paperId, Long paperCheckId);
 
     @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.paperId = ?4")
     List<ChangeLevel> findAllByWorkIdAndSubjectAndStageAndPaperId(Long workId, String subject, MarkStage stage, Long paperId);
 
-    @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.paperId = ?4 and s.auditStatus = 0")
-    ChangeLevel findByWorkIdAndSubjectAndStageAndPaperId(Long workId, String subject, MarkStage stage, Long paperId);
+    @Query("select s from ChangeLevel s where s.workId = ?1 and s.subject = ?2 and s.stage = ?3 and s.paperId = ?4 and s.paperCheckId = ?5 and s.auditStatus = 0")
+    ChangeLevel findByWorkIdAndSubjectAndStageAndPaperIdAndPaperCheckId(Long workId, String subject, MarkStage stage, Long paperId, Long paperCheckId);
 
     List<ChangeLevel> findByWorkIdAndSubjectAndAuditStatusAndStage(Long workId, String subject, int auditStatus, MarkStage stage);
+
+    @Query("select s from ChangeLevel s where (s.paperId, s.id) in (select cl.paperId, max(cl.id) from ChangeLevel cl where cl.paperCheckId = ?1 group by cl.paperId) order by s.id desc")
+    Page<ChangeLevel> findByPaperCheckId(Long paperCheckId, Pageable pageable);
 }

+ 20 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/ChangeLevelTaskRepo.java

@@ -0,0 +1,20 @@
+package cn.com.qmth.stmms.ms.core.repository;
+
+import cn.com.qmth.stmms.ms.core.domain.ChangeLevelTask;
+import cn.com.qmth.stmms.ms.core.domain.MarkStage;
+import cn.com.qmth.stmms.ms.core.vo.Subject;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ChangeLevelTaskRepo extends JpaRepository<ChangeLevelTask, Long>, JpaSpecificationExecutor {
+
+    @Query(value = "SELECT count(1) from change_level_task m inner join paper p on m.paper_id = p.id and p.is_missing = ?4 and p.is_shift = 1 where p.question_id = ?1 and m.marker_id = ?2 and m.stage = ?3 and m.confirm_change_stage = false", nativeQuery = true)
+    Integer countShiftByQuestionIdAndMarkerIdAndStageAndIsMissing(Long questionId, Long markerId, int stage, boolean isMissing);
+
+    int countByPaperIdAndSubjectAndStageAndConfirmChangeStage(Long paperId, String subject, MarkStage stage, boolean confirmChangeStage);
+
+    void deleteByWorkIdAndSubjectAndStage(Long workId, String subject, MarkStage stage);
+}

+ 4 - 4
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskLevelRepo.java

@@ -138,8 +138,8 @@ public interface MarkTaskLevelRepo extends JpaRepository<MarkTaskLevel, Long>, J
 
     List<MarkTaskLevel> findByWorkId(Long workId);
 
-    @Query(value = "SELECT count(1) from mark_task_level m inner join paper p on m.paper_id = p.id and p.is_missing = ?4 and p.is_shift = 1 where m.question_id = ?1 and m.marker_id = ?2 and m.stage = ?3 and m.result is null", nativeQuery = true)
-    int countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(Long questionId, Long id, int ordinal, boolean b);
+    @Query(value = "SELECT count(1) from change_level_task m inner join paper p on m.paper_id = p.id and p.is_missing = ?4 and p.is_shift = 1 where m.question_id = ?1 and m.marker_id = ?2 and m.stage = ?3 and m.confirm_change_stage = false", nativeQuery = true)
+    int countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(Long questionId, Long id, int stage, boolean b);
 
     @Query(value = "SELECT count(1) from mark_task_level m inner join paper p on m.paper_id = p.id and p.is_shift = 0 and p.is_shift_score = 1 where m.question_id = ?1 and m.marker_id = ?2 and m.stage = ?3 and m.result is null", nativeQuery = true)
     int countShiftScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(Long questionId, Long id, int ordinal);
@@ -160,8 +160,8 @@ public interface MarkTaskLevelRepo extends JpaRepository<MarkTaskLevel, Long>, J
 
     int countByWorkIdAndStageAndResultNotNull(Long id, MarkStage stage);
 
-    @Query(value = "select count(1) from mark_task_level m inner join paper p on m.paper_id = p.id where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.result is null and p.is_shift = true", nativeQuery = true)
-    int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(Long workId, String subject, Long valueOf, int stage);
+    @Query(value = "select count(1) from change_level_task m inner join paper p on m.paper_id = p.id where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.confirm_change_stage = 0 and p.is_shift = true", nativeQuery = true)
+    int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(Long workId, String subject, Long markerId, int stage);
 
     @Query(value = "select count(1) from mark_task_level m inner join paper p on m.paper_id = p.id where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.result is null and p.is_shift_score = 1", nativeQuery = true)
     int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftScoreAndResult(Long workId, String subject, Long valueOf, int stage);

+ 2 - 2
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskRoughLevelRepo.java

@@ -133,8 +133,8 @@ public interface MarkTaskRoughLevelRepo extends JpaRepository<MarkTaskRoughLevel
 
     int countByWorkIdAndSubjectAndStage(Long workId, Subject subject, MarkStage stage);
 
-    @Query(value = "select count(1) from mark_task_rough_level m inner join paper p on m.paper_id = p.id where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.result is null and p.is_shift = true", nativeQuery = true)
-    int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(Long workId, String subject, Long valueOf, int stage);
+    @Query(value = "select count(1) from change_level_task m inner join paper p on m.paper_id = p.id where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.confirm_change_stage = 0 and p.is_shift = true", nativeQuery = true)
+    int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(Long workId, String subject, Long markerId, int stage);
 
     @Query(value = "select count(1) from mark_task_rough_level m where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.is_rejected = 1", nativeQuery = true)
     int findByWorkIdAndSubjectAndMarkerIdAndStageReject(Long workId, String subject, Long valueOf, int stage);

+ 2 - 2
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskScoreRepo.java

@@ -123,12 +123,12 @@ public interface MarkTaskScoreRepo extends JpaRepository<MarkTaskScore, Long>, J
     int countShiftScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(Long questionId, Long id, int ordinal);
 
     @Query(value = "select * from mark_task_score where work_id = ?1 and subject = ?2 and marker_id = ?3 and stage = ?4 limit 1", nativeQuery = true)
-    List<MarkTaskScore> findByWorkIdAndSubjectAndMarkerIdAndStageLimit(Long workId, String subject, Long valueOf, int stage);
+    List<MarkTaskScore> findByWorkIdAndSubjectAndMarkerIdAndStageLimit(Long workId, String subject, Long markerId, int stage);
 
     int countByWorkIdAndSubjectAndStage(Long workId, Subject subject, MarkStage stage);
 
     @Query(value = "select count(1) from mark_task_score m inner join paper p on m.paper_id = p.id where m.work_id = ?1 and m.subject = ?2 and m.marker_id = ?3 and m.stage = ?4 and m.result is null and p.is_shift_score = 1", nativeQuery = true)
-    int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftScoreAndResult(Long workId, String subject, Long valueOf, int stage);
+    int countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftScoreAndResult(Long workId, String subject, Long markerId, int stage);
 
     @Query(value = "select count(1) from mark_task_score m where m.work_id = ?1", nativeQuery = true)
     int countByWorkId(Long workId);

+ 35 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperCheckRepo.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.stmms.ms.core.repository;
+
+import cn.com.qmth.stmms.ms.core.domain.MarkStage;
+import cn.com.qmth.stmms.ms.core.domain.PaperCheck;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface PaperCheckRepo extends JpaRepository<PaperCheck, Long>, JpaSpecificationExecutor {
+
+    List<PaperCheck> findByWorkIdOrderByCreatedOnDesc(Long workId);
+
+    @Query("select s from PaperCheck s where s.workId = ?1 and s.name = ?2")
+    PaperCheck selectByWorkIdAndName(Long workId, String name);
+
+    @Modifying
+    @Query("update PaperCheck p set p.selectInfo = ?1 where p.id = ?2")
+    void updateSelectInfoById(String selectInfo, Long id);
+
+    @Modifying
+    @Query("update PaperCheck p set p.studentCount = ?1 where p.id = ?2")
+    void updateStudentCountById(int studentCount, Long paperCheckId);
+
+    @Modifying
+    @Query("update PaperCheck p set p.startDeal = true where p.id = ?1 and p.startDeal = false")
+    void updateStartDealById(Long paperCheckId);
+
+    void deleteByWorkIdAndSubjectAndStage(Long workId, String subject, MarkStage stage);
+}

+ 22 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperCheckStudentRepo.java

@@ -0,0 +1,22 @@
+package cn.com.qmth.stmms.ms.core.repository;
+
+import cn.com.qmth.stmms.ms.core.domain.MarkStage;
+import cn.com.qmth.stmms.ms.core.domain.PaperCheckStudent;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface PaperCheckStudentRepo extends JpaRepository<PaperCheckStudent, Long>, JpaSpecificationExecutor {
+
+    void deleteByPaperCheckId(Long paperCheckId);
+
+    @Query(value = "select pcs.subject, p.exam_number, pcs.secret_number, p.level, t.original_level, t.suggest_level from (select * from paper_check_student where paper_check_id = :paperCheckId) pcs left join (select cl.* from change_level cl where exists (select 1 from (select paper_id, max(id) id from change_level where work_id = :workId and subject = :subject and stage = :stage and role = 'MARK_LEADER' and audit_status = 1 group by paper_id) t where cl.id = t.id)) t on pcs.paper_id = t.paper_id left join paper p on pcs.paper_id = p.id", nativeQuery = true)
+    List<Object[]> findByPaperCheckId(@Param("paperCheckId") Long paperCheckId, @Param("workId") Long workId, @Param("subject") String subject, @Param("stage") int stage);
+
+    void deleteByWorkIdAndSubjectAndStage(Long workId, String subject, MarkStage stage);
+}

+ 17 - 2
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperRepo.java

@@ -279,10 +279,10 @@ public interface PaperRepo extends JpaRepository<Paper, Long>, JpaSpecificationE
     @Query("select max(p.scoreBatchNo) from Paper p where p.workId = ?1 and p.subject = ?2")
     Long findMaxScoreBatchNoByWorkIdAndSubject(Long workId, Subject subject);
 
-    @Query(value = "select cast(p.score_batch_no as char) from paper p where p.work_id = ?1 and p.subject = ?2 order by score_batch_no desc limit 1", nativeQuery = true)
+    @Query(value = "select cast(p.score_batch_no as char) from paper p where p.work_id = ?1 and p.subject = ?2 and p.score_batch_no is not null order by score_batch_no desc limit 1", nativeQuery = true)
     List<Object> findScoreBatchNoByWorkIdAndSubject(Long workId, String subject);
 
-    List<Paper> findByWorkIdAndSubjectAndQuestionIdAndIsMissingAndTestAndLevelIsNull(Long workId, Subject valueOf, Long questionId, boolean b, int ordinal);
+    List<Paper> findByWorkIdAndSubjectAndQuestionIdAndIsMissingAndTestAndIsShiftTrue(Long workId, Subject valueOf, Long questionId, boolean b, int ordinal);
 
     List<Paper> findByWorkIdAndSubjectAndQuestionIdAndIsMissingAndTestAndRoughLevelIsNull(Long workId, Subject valueOf, Long questionId, boolean b, int ordinal);
 
@@ -324,6 +324,10 @@ public interface PaperRepo extends JpaRepository<Paper, Long>, JpaSpecificationE
     @Query("update Paper s set s.level = ?2, s.redoLevel = null, s.isShift = false , s.isShiftScore = false where s.id = ?1")
     void updateLevelById(Long paperId, String originalLevel);
 
+    @Modifying
+    @Query("update Paper s set s.level = ?2, s.isShift = false , s.isShiftScore = true where s.id = ?1")
+    void updateLevelByIdAndShift(Long paperId, String originalLevel);
+
     long countByWorkIdAndSubjectAndLevelAndTest(Long workId, Subject subject, String valueOf, int test);
 
     long countByWorkIdAndQuestionIdAndIsMissingIsFalseAndTest(Long workId, Long questionId, int test);
@@ -389,4 +393,15 @@ public interface PaperRepo extends JpaRepository<Paper, Long>, JpaSpecificationE
 
     @Query("select p.randomSeq from Paper p where p.workId = ?1")
     Set<Long> listRandomByWorkId(Long workId);
+
+    @Query("select distinct p.roughBatchNo from Paper p where p.workId = ?1 and p.subject = ?2 and p.roughBatchNo is not null")
+    List<Long> findAllRoughBatchNoByWorkIdAndSubject(Long workId, Subject subject);
+
+    @Query("select distinct p.batchNo from Paper p where p.workId = ?1 and p.subject = ?2 and p.batchNo is not null")
+    List<Long> findAllBatchNoByWorkIdAndSubject(Long workId, Subject subject);
+
+    @Query("select distinct p.scoreBatchNo from Paper p where p.workId = ?1 and p.subject = ?2 and p.scoreBatchNo is not null")
+    List<Long> findAllScoreBatchNoByWorkIdAndSubject(Long workId, Subject subject);
+
+    int countByWorkIdAndSubjectAndLevelIsNotNullAndScoreIsNull(Long workId, Subject subject);
 }

+ 1 - 1
stmms-ms-main/install/config.ini

@@ -1,5 +1,5 @@
 [app]
-version=3.1.1
+version=3.1.2
 name=ÃÀÊõÔľíÁª¿¼°æ
 portal=http://localhost:8300/
 module=api

+ 56 - 0
stmms-ms-main/install/mysql/init/stmms_ms.sql

@@ -33,15 +33,37 @@ CREATE TABLE IF NOT EXISTS `change_level`  (
     `paper_id` bigint(20) NULL DEFAULT NULL,
     `original_level` varchar(45) NULL DEFAULT NULL COMMENT '原档位',
     `audit_status` int(1) NULL DEFAULT NULL COMMENT '改档审核:0-申请,1-同意,2-不同意',
+    `paper_check_id` BIGINT(20) NULL COMMENT '试卷抽查任务ID(role=‘MARK_LEADER’时,默认为’-1’)',
     `create_id` bigint(20) NULL DEFAULT NULL COMMENT '申请改档用户id',
     `create_date` datetime(0) NULL DEFAULT NULL COMMENT '申请改档时间',
     `audit_id` bigint(20) NULL DEFAULT NULL COMMENT '审核用户id',
+    `role` VARCHAR(45) NULL DEFAULT 'MARK_LEADER' COMMENT '操作员角色,MARK_LEADER-科组长,INSPECTION-纪检',
     `audit_date` datetime(0) NULL DEFAULT NULL COMMENT '审核时间',
     `suggest_level` varchar(255) NULL DEFAULT NULL,
     `is_curr` int(11) NULL DEFAULT NULL,
     PRIMARY KEY (`id`) USING BTREE
     ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COMMENT = '改档记录表';
 
+-- ----------------------------
+-- Table structure for change_level_task
+-- ----------------------------
+CREATE TABLE `change_level_task` (
+     `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+     `work_id` BIGINT(20) NOT NULL COMMENT '工作ID',
+     `question_id` BIGINT(20) NOT NULL COMMENT '考区ID',
+     `paper_id` BIGINT(20) NOT NULL COMMENT '试卷ID',
+     `subject` VARCHAR(45) NOT NULL COMMENT '科目',
+     `stage` INT NOT NULL COMMENT '阶段',
+     `marker_id` BIGINT(20) NULL COMMENT '评卷员ID',
+     `marker_name` VARCHAR(45) NULL COMMENT '评卷员姓名',
+     `secret_number` VARCHAR(45) NULL COMMENT '密号',
+     `result` VARCHAR(3) NULL COMMENT '改档档位(纪检员同意后)',
+     `confirm_change_stage` TINYINT(1) NULL COMMENT '是否确认改档',
+     `confirm_on` DATETIME NULL COMMENT '确认时间',
+     `created_on` DATETIME NULL COMMENT '创建时间',
+     PRIMARY KEY (`id`))
+    COMMENT = '改档评卷员确认任务表';
+
 -- ----------------------------
 -- Table structure for check_data
 -- ----------------------------
@@ -539,6 +561,8 @@ CREATE TABLE IF NOT EXISTS `paper`  (
     `is_admin_mark` bit(1) NULL DEFAULT b'0' COMMENT '管理员标记',
     `first_collect_size` INT NULL COMMENT '首次采集原图大小(KB)',
     `size_abnormal` BIT(1) NULL DEFAULT 0 COMMENT '大小是否异常(1:异常)',
+    `rough_mark_leader_id` BIGINT(10) NULL COMMENT '粗分档阶段科组长操作ID',
+    `mark_leader_id` BIGINT(10) NULL COMMENT '细分档阶段科组长操作ID',
     PRIMARY KEY (`id`) USING BTREE,
     UNIQUE KEY `uq_idx` (`work_id`,`subject`,`exam_number`,`is_test`),
     INDEX `idx_paper_exam_number`(`exam_number`) USING BTREE,
@@ -548,6 +572,38 @@ CREATE TABLE IF NOT EXISTS `paper`  (
     INDEX `idx_union_5`(`work_id`, `subject`, `score_batch_no`) USING BTREE
     ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4;
 
+-- ----------------------------
+-- Table structure for paper_check
+-- ----------------------------
+CREATE TABLE `paper_check` (
+       `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+       `work_id` BIGINT(20) NOT NULL COMMENT '工作ID',
+       `subject` VARCHAR(45) NOT NULL COMMENT '科目',
+       `stage` INT NOT NULL COMMENT '阶段',
+       `name` VARCHAR(45) NOT NULL COMMENT '任务名称',
+       `remark` VARCHAR(100) NULL COMMENT '备注',
+       `student_count` INT NULL DEFAULT 0 COMMENT '学生数量',
+       `start_deal` TINYINT(1) NULL DEFAULT 0 COMMENT '是否开始批量处理',
+       `select_info` VARCHAR(150) NULL COMMENT '最后一次操作的试卷信息',
+       `created_id` BIGINT(20) NULL COMMENT '创建人',
+       `created_on` DATETIME NULL COMMENT '创建时间',
+       PRIMARY KEY (`id`))
+    COMMENT = '试卷抽查任务表';
+
+-- ----------------------------
+-- Table structure for paper_check_student
+-- ----------------------------
+CREATE TABLE `paper_check_student` (
+       `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+       `work_id` BIGINT(20) NULL COMMENT '工作ID',
+       `paper_check_id` BIGINT(20) NULL COMMENT '试卷抽查任务ID',
+       `subject` VARCHAR(45) NULL COMMENT '科目',
+       `stage` INT NULL COMMENT '阶段',
+       `paper_id` BIGINT(20) NULL COMMENT '试卷ID',
+       `secret_number` VARCHAR(45) NULL COMMENT '试卷密号',
+       PRIMARY KEY (`id`))
+    COMMENT = '试卷抽查考生表';
+
 -- ----------------------------
 -- Table structure for param_setting
 -- ----------------------------

+ 52 - 0
stmms-ms-main/install/mysql/upgrade/3.1.2.sql

@@ -0,0 +1,52 @@
+USE stmms_ms;
+
+ALTER TABLE `paper`
+    ADD COLUMN `rough_mark_leader_id` BIGINT(10) NULL COMMENT '粗分档阶段科组长操作ID' AFTER `size_abnormal`,
+ADD COLUMN `mark_leader_id` BIGINT(10) NULL COMMENT '细分档阶段科组长操作ID' AFTER `rough_mark_leader_id`;
+
+
+CREATE TABLE `change_level_task` (
+        `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+        `work_id` BIGINT(20) NOT NULL COMMENT '工作ID',
+        `question_id` BIGINT(20) NOT NULL COMMENT '考区ID',
+        `paper_id` BIGINT(20) NOT NULL COMMENT '试卷ID',
+        `subject` VARCHAR(45) NOT NULL COMMENT '科目',
+        `stage` INT NOT NULL COMMENT '阶段',
+        `marker_id` BIGINT(20) NULL COMMENT '评卷员ID',
+        `marker_name` VARCHAR(45) NULL COMMENT '评卷员姓名',
+        `secret_number` VARCHAR(45) NULL COMMENT '密号',
+        `result` VARCHAR(3) NULL COMMENT '改档档位(纪检员同意后)',
+        `confirm_change_stage` TINYINT(1) NULL COMMENT '是否确认改档',
+        `confirm_on` DATETIME NULL COMMENT '确认时间',
+        `created_on` DATETIME NULL COMMENT '创建时间',
+        PRIMARY KEY (`id`))
+    COMMENT = '改档评卷员确认任务表';
+
+ALTER TABLE `change_level` ADD COLUMN `role` VARCHAR(45) NULL DEFAULT 'MARK_LEADER' COMMENT '操作员角色,MARK_LEADER-科组长,INSPECTION-纪检' AFTER `audit_id`;
+ALTER TABLE `change_level` ADD COLUMN `paper_check_id` BIGINT(20) NULL COMMENT '试卷抽查任务ID(role=‘MARK_LEADER’时,默认为’-1’)' AFTER `audit_status`;
+
+CREATE TABLE `paper_check` (
+          `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+          `work_id` BIGINT(20) NOT NULL COMMENT '工作ID',
+          `subject` VARCHAR(45) NOT NULL COMMENT '科目',
+          `stage` INT NOT NULL COMMENT '阶段',
+          `name` VARCHAR(45) NOT NULL COMMENT '任务名称',
+          `remark` VARCHAR(100) NULL COMMENT '备注',
+          `student_count` INT NULL DEFAULT 0 COMMENT '学生数量',
+          `start_deal` TINYINT(1) NULL DEFAULT 0 COMMENT '是否开始批量处理',
+          `select_info` VARCHAR(150) NULL COMMENT '最后一次操作的试卷信息',
+          `created_id` BIGINT(20) NULL COMMENT '创建人',
+          `created_on` DATETIME NULL COMMENT '创建时间',
+          PRIMARY KEY (`id`))
+    COMMENT = '试卷抽查任务表';
+
+CREATE TABLE `paper_check_student` (
+          `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
+          `work_id` BIGINT(20) NULL COMMENT '工作ID',
+          `paper_check_id` BIGINT(20) NULL COMMENT '试卷抽查任务ID',
+          `subject` VARCHAR(45) NULL COMMENT '科目',
+          `stage` INT NULL COMMENT '阶段',
+          `paper_id` BIGINT(20) NULL COMMENT '试卷ID',
+          `secret_number` VARCHAR(45) NULL COMMENT '试卷密号',
+          PRIMARY KEY (`id`))
+    COMMENT = '试卷抽查考生表';

+ 82 - 0
stmms-ms-main/src/main/resources/application-base.properties

@@ -0,0 +1,82 @@
+server.port=9000
+
+db.host=localhost
+db.port=3306
+db.dbName=msyj-local-3.1.2
+db.userName=root
+db.password=12345678
+
+spring.datasource.url=jdbc:mysql://${db.host}:${db.port}/${db.dbName}?useUnicode=true&characterEncoding=UTF-8
+spring.datasource.username=${db.userName}
+spring.datasource.password=${db.password}
+
+spring.datasource.validation-query=SELECT 1 FROM DUAL
+spring.datasource.test-on-borrow=true
+
+server.compression.enabled=true
+server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript
+
+
+logging.file=./logs/sys.log
+#logging.level.root error
+logging.level.root=info
+logging.level.org.springframework=info
+logging.level.org.hibernate=info
+
+spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=validate
+
+spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
+spring.jackson.time-zone=GMT+8
+spring.cache.ehcache.config=classpath:ehcache.xml
+
+
+spring.http.multipart.max-file-size=10Mb
+app.config.roundUp=true
+app.config.deviation=4
+app.config.majority=true
+#?????? admin,admin1,admin2
+app.admin.loginName=admin
+#?????
+app.admin.password=87863577
+
+#????
+sys.config.localhostPath=/upload
+sys.config.imageDir=upload/images
+sys.config.thumbDir=upload/thumbs
+sys.config.sheetDir=upload/sheet
+sys.config.watermark=upload/watermark
+#??????
+sys.open.imageEnc=false
+#customSubject
+sys.open.customSubject=false
+
+sys.config.yangjuan=false
+sys.config.compression.percent=60
+sys.config.imageServer.port=9000
+sys.config.imageServer.ip=192.168.10.165
+sys.config.imageServer.aliyunOss=false
+sys.config.imageServer.dir=ms-test
+
+#????????
+web.upload-path=/Users/xiaofei/qmth/static-web/mslk/dist/
+spring.mvc.static-path-pattern=/**
+spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${sys.config.localhostPath},file:${web.upload-path}
+
+app.snapshot.initsql=/Users/yuanpan/dumps/stmms-ms-2-init.sql
+app.snapshot.fdsql=/Users/yuanpan/dumps/stmms-ms-2-fendang.sql
+app.snapshot.dfsql=/Users/yuanpan/dumps/stmms-ms-2-dafen.sql
+app.snapshot.fpsql=/Users/yuanpan/dumps/stmms-ms-2-fuping.sql
+
+#???OSS??
+aliyun.oss.endpointInner=http://oss-cn-beijing-internal.aliyuncs.com
+aliyun.oss.endpoint=https://oss-cn-beijing.aliyuncs.com
+aliyun.oss.accessKeyId=LTAIhiBoG7CsLnoy
+aliyun.oss.accessKeySecret=HqTvxO1RYiPT3SiZKv4VeoXab4AHjz
+aliyun.oss.bucket=epcc-test
+aliyun.oss.url=https://${aliyun.oss.bucket}.oss-cn-beijing.aliyuncs.com
+aliyun.oss.imageDir=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/images/ -u
+aliyun.oss.thumbDir=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/thumbs/ -u
+aliyun.oss.sheetDir=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/sheet/ -u
+aliyun.oss.watermark=oss://${aliyun.oss.bucket}/${sys.config.imageServer.dir}/watermark/ -u
+aliyun.oss.util=/Users/king/ossutilmac64 cp -r

+ 53 - 48
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/ChangeLevelApi.java

@@ -4,15 +4,14 @@ import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.*;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
-import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskRoughLevel;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskScore;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
+import cn.com.qmth.stmms.ms.core.domain.user.Role;
 import cn.com.qmth.stmms.ms.core.repository.*;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 import cn.com.qmth.stmms.ms.marking.assembler.ChangeLevelAssembler;
 import cn.com.qmth.stmms.ms.marking.dto.ChangeLevelDTO;
-import cn.com.qmth.stmms.ms.marking.service.MarkingLevelService;
-import cn.com.qmth.stmms.ms.marking.service.MarkingRoughLevelService;
+import cn.com.qmth.stmms.ms.marking.utils.RandomUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -38,39 +37,26 @@ public class ChangeLevelApi {
 
     @Autowired
     private PaperRepo paperRepo;
-
     @Autowired
     private ChangeLevelRepo changeLevelRepo;
-
-    @Resource
-    private MarkTaskRoughLevelRepo markTaskRoughLevelRepo;
-
     @Resource
     private MarkTaskLevelRepo markTaskLevelRepo;
-
     @Resource
     private MarkTaskScoreRepo markTaskScoreRepo;
-
     @Resource
     private ChangeLevelAssembler changeLevelAssembler;
-
-    @Resource
-    private MarkingRoughLevelService markingRoughLevelService;
-
-    @Resource
-    private MarkingLevelService markingLevelService;
-
     @Autowired
     private MarkLogRepo markLogRepo;
-
     @Autowired
     private WorkRepo workRepo;
-
     @Autowired
-    MarkUserRepo markUserRepo;
-
+    private MarkUserRepo markUserRepo;
+    @Resource
+    private MarkSubjectRepo markSubjectRepo;
     @Resource
-    MarkSubjectRepo markSubjectRepo;
+    private ChangeLevelTaskRepo changeLevelTaskRepo;
+    @Autowired
+    RandomUtil randomUtil;
 
     /**
      * 查询改档列表
@@ -109,7 +95,7 @@ public class ChangeLevelApi {
                     if (MarkStage.LEVEL.equals(markSubject.getStage())) {
                         papers = paperRepo.findByWorkIdAndSubjectAndQuestionIdAndIsMissingAndTestAndRoughLevelIsNull(workId, Subject.valueOf(subject), questionId, false, markSubject.getTest());
                     } else if (MarkStage.SCORE.equals(markSubject.getStage())) {
-                        papers = paperRepo.findByWorkIdAndSubjectAndQuestionIdAndIsMissingAndTestAndLevelIsNull(workId, Subject.valueOf(subject), questionId, false, markSubject.getTest());
+                        papers = paperRepo.findByWorkIdAndSubjectAndQuestionIdAndIsMissingAndTestAndIsShiftTrue(workId, Subject.valueOf(subject), questionId, false, markSubject.getTest());
                     }
                     if (papers != null && !papers.isEmpty()) {
                         CriteriaBuilder.In<Object> in = builder.in(root.get("paperId"));
@@ -153,9 +139,7 @@ public class ChangeLevelApi {
 
         Page<ChangeLevel> levels = changeLevelRepo.findAll(specification, pageable);
 
-        levels.getContent().forEach(m -> {
-            levelDTOs.add(changeLevelAssembler.toDTO(m));
-        });
+        levels.getContent().forEach(m -> levelDTOs.add(changeLevelAssembler.toDTO(m)));
         return new PageableDTO(levelDTOs, levels.getTotalElements(), levels.getTotalPages(), pageable.getPageNumber());
     }
 
@@ -171,26 +155,37 @@ public class ChangeLevelApi {
     public ResponseEntity changeLevel(@PathVariable MarkSubject markSubject,
                                       @RequestParam Long paperId,
                                       @RequestParam String level,
-                                      @RequestParam Long userId) {
+                                      @RequestParam Long userId,
+                                      @RequestParam(required = false, defaultValue = "-1") Long paperCheckId) {
         boolean roughLevelEnable = ParamCache.levelConfigMap.get(String.valueOf(markSubject.getWorkId())).getRoughLevelEnable() == 1;
-        if (!roughLevelEnable) {
-            //只有打分阶段才能改档
-            if (!Objects.equals(markSubject.getStage(), MarkStage.SCORE)) {
-                throw new RuntimeException("未开启粗分档,只有打分阶段才允许改档");
+        // -1为科组长改档
+        if (paperCheckId == -1) {
+            if (!roughLevelEnable) {
+                //只有打分阶段才能改档
+                if (!Objects.equals(markSubject.getStage(), MarkStage.SCORE)) {
+                    throw new RuntimeException("未开启粗分档,只有打分阶段才允许改档");
+                }
+            } else {
+                //只有打分阶段才能改档
+                if (!Objects.equals(markSubject.getStage(), MarkStage.LEVEL)
+                        && !Objects.equals(markSubject.getStage(), MarkStage.SCORE)) {
+                    throw new RuntimeException("已开启粗分档,只有细分档阶段或者打分阶段才允许改档");
+                }
             }
         } else {
             //只有打分阶段才能改档
-            if (!Objects.equals(markSubject.getStage(), MarkStage.LEVEL)
-                    && !Objects.equals(markSubject.getStage(), MarkStage.SCORE)) {
-                throw new RuntimeException("已开启粗分档,只有细分档阶段或者打分阶段才允许改档");
+            if (!Objects.equals(markSubject.getStage(), MarkStage.SCORE)) {
+                throw new RuntimeException("试卷抽查改档功能,只有打分阶段才允许改档");
             }
         }
 
         Paper paper = paperRepo.findOne(paperId);
         MarkUser markUser = markUserRepo.findOne(userId);
+        if (!Role.MARK_LEADER.equals(markUser.getRole()) && !Role.INSPECTION.equals(markUser.getRole())) {
+            throw new RuntimeException("用户没有此操作权限");
+        }
 
-        //
-        ChangeLevel changeLevelCurr = changeLevelRepo.findByWorkIdAndSubjectAndStageAndPaperIdAndAuditStatusAndIsCurr(markSubject.getWorkId(), markSubject.getSubject().name(), markSubject.getStage(), paperId);
+        ChangeLevel changeLevelCurr = changeLevelRepo.findByWorkIdAndSubjectAndStageAndPaperIdAndPaperCheckIdAndAuditStatusAndIsCurr(markSubject.getWorkId(), markSubject.getSubject().name(), markSubject.getStage(), paperId, paperCheckId);
         if (changeLevelCurr != null) {
             if (MarkStage.LEVEL.equals(changeLevelCurr.getStage())) {
                 if (Objects.isNull(paper.getRoughLevel())) {
@@ -216,13 +211,15 @@ public class ChangeLevelApi {
         }).collect(Collectors.toList());
         changeLevelRepo.save(list);
 
-        ChangeLevel changeLevel = changeLevelRepo.findByWorkIdAndSubjectAndStageAndPaperId(markSubject.getWorkId(), markSubject.getSubject().name(), markSubject.getStage(), paperId);
+        ChangeLevel changeLevel = changeLevelRepo.findByWorkIdAndSubjectAndStageAndPaperIdAndPaperCheckId(markSubject.getWorkId(), markSubject.getSubject().name(), markSubject.getStage(), paperId, paperCheckId);
         if (changeLevel == null) {
             changeLevel = new ChangeLevel();
             changeLevel.setWorkId(markSubject.getWorkId());
             changeLevel.setSubject(markSubject.getSubject().name());
             changeLevel.setStage(markSubject.getStage());
             changeLevel.setPaperId(paperId);
+            changeLevel.setPaperCheckId(paperCheckId);
+            changeLevel.setRole(markUser.getRole());
             if (MarkStage.LEVEL.equals(markSubject.getStage())) {
                 changeLevel.setOriginalLevel(paper.getRoughLevel());
             } else if (MarkStage.SCORE.equals(markSubject.getStage())) {
@@ -248,7 +245,8 @@ public class ChangeLevelApi {
 
         //记录日志
         Work work = workRepo.findOne(paper.getWorkId());
-        MarkLog markLog = new MarkLog(paper.getWorkId(), work.getName(), paper.getId(), markUser.getSubject(), changeLevel.getStage(), paper.getTest(), paper.getExamNumber(), paper.getStudentName(), markUser.getId(), markUser.getName(), markUser.getRole(), MarkLogOperType.CHANGE_LEVEL_APPLY.getId(),MarkLogOperType.CHANGE_LEVEL_APPLY.getName(), changeLevel.getOriginalLevel(), changeLevel.getSuggestLevel(), null, new Date());
+        MarkLogOperType markLogOperType = Role.INSPECTION.equals(markUser.getRole()) ? MarkLogOperType.INSPECTION_CHANGE_LEVEL_APPLY : MarkLogOperType.CHANGE_LEVEL_APPLY;
+        MarkLog markLog = new MarkLog(paper.getWorkId(), work.getName(), paper.getId(), markSubject.getSubject(), changeLevel.getStage(), paper.getTest(), paper.getExamNumber(), paper.getStudentName(), markUser.getId(), markUser.getName(), markUser.getRole(), markLogOperType.getId(), markLogOperType.getName(), changeLevel.getOriginalLevel(), changeLevel.getSuggestLevel(), null, new Date());
         markLogRepo.save(markLog);
 
         return new ResponseEntity(HttpStatus.OK);
@@ -267,6 +265,7 @@ public class ChangeLevelApi {
                                            @RequestParam Long userId) {
         ChangeLevel changeLevel = changeLevelRepo.findOne(id);
         changeLevel.setAuditStatus(auditStatus);
+        changeLevel.setAuditDate(new Date());
         changeLevelRepo.save(changeLevel);
         //同意
         if (auditStatus == 1) {
@@ -275,16 +274,16 @@ public class ChangeLevelApi {
             //记录日志
             MarkUser markUser = markUserRepo.findOne(userId);
             Work work = workRepo.findOne(paper.getWorkId());
-            MarkLog markLog = new MarkLog(paper.getWorkId(), work.getName(), paper.getId(), paper.getSubject(), changeLevel.getStage(), paper.getTest(), paper.getExamNumber(), paper.getStudentName(), markUser.getId(), markUser.getName(), markUser.getRole(), MarkLogOperType.CHANGE_LEVEL_AGREE.getId(),MarkLogOperType.CHANGE_LEVEL_AGREE.getName(), changeLevel.getOriginalLevel(), changeLevel.getSuggestLevel(), null, new Date());
+            MarkLog markLog = new MarkLog(paper.getWorkId(), work.getName(), paper.getId(), paper.getSubject(), changeLevel.getStage(), paper.getTest(), paper.getExamNumber(), paper.getStudentName(), markUser.getId(), markUser.getName(), markUser.getRole(), MarkLogOperType.CHANGE_LEVEL_AGREE.getId(), MarkLogOperType.CHANGE_LEVEL_AGREE.getName(), changeLevel.getOriginalLevel(), changeLevel.getSuggestLevel(), null, new Date());
             markLogRepo.save(markLog);
 
             if (MarkStage.LEVEL.equals(changeLevel.getStage())) {
                 //重置细分档档位
                 paper.setLevel(null);
 
-                List<MarkTaskRoughLevel> markTasks = markTaskRoughLevelRepo.findByPaperId(paper.getId());
-                List<String> ranges = markTasks.stream().map(m -> m.getMarkerId().toString()).collect(Collectors.toList());
-                markingRoughLevelService.reject(paper, changeLevel.getSuggestLevel(), String.join(",", ranges), true, false, changeLevel.getCreateId());
+//                List<MarkTaskRoughLevel> markTasks = markTaskRoughLevelRepo.findByPaperId(paper.getId());
+//                List<String> ranges = markTasks.stream().map(m -> m.getMarkerId().toString()).collect(Collectors.toList());
+//                markingRoughLevelService.reject(paper, changeLevel.getSuggestLevel(), String.join(",", ranges), true, false, changeLevel.getCreateId());
 
                 //重置已经打分的数据
                 List<MarkTaskLevel> markTasksLevels = markTaskLevelRepo.findByPaperId(paper.getId());
@@ -294,17 +293,21 @@ public class ChangeLevelApi {
                             o.setOriginLevel(o.getResult());
                         }
                         o.setResult(null);
-                        o.setLevel(null);
+                        o.setLevel(changeLevel.getSuggestLevel());
                     });
                     markTaskLevelRepo.save(markTasksLevels);
+
+                    // 生成确认任务
+                    List<ChangeLevelTask> changeLevelTaskList = markTasksLevels.stream().map(m -> ChangeLevelTask.toChangeLevelTask(m, changeLevel.getSuggestLevel())).collect(Collectors.toList());
+                    changeLevelTaskRepo.save(changeLevelTaskList);
                 }
             } else if (MarkStage.SCORE.equals(changeLevel.getStage())) {
                 //重置分数
                 paper.setScore(null);
 
-                List<MarkTaskLevel> markTasks = markTaskLevelRepo.findByPaperId(paper.getId());
-                List<String> ranges = markTasks.stream().map(m -> m.getMarkerId().toString()).collect(Collectors.toList());
-                markingLevelService.reject(paper, changeLevel.getSuggestLevel(), String.join(",", ranges), true, false, changeLevel.getCreateId());
+//                List<MarkTaskLevel> markTasks = markTaskLevelRepo.findByPaperId(paper.getId());
+//                List<String> ranges = markTasks.stream().map(m -> m.getMarkerId().toString()).collect(Collectors.toList());
+//                markingLevelService.reject(paper, changeLevel.getSuggestLevel(), String.join(",", ranges), true, false, changeLevel.getCreateId());
 
                 //重置已经打分的数据
                 List<MarkTaskScore> markTasksScore = markTaskScoreRepo.findByPaperId(paper.getId());
@@ -314,9 +317,12 @@ public class ChangeLevelApi {
                             o.setOriginLevel(o.getResult());
                         }
                         o.setResult(null);
-                        o.setLevel(null);
+                        o.setLevel(changeLevel.getSuggestLevel());
                     });
                     markTaskScoreRepo.save(markTasksScore);
+
+                    List<ChangeLevelTask> changeLevelTaskList = markTasksScore.stream().map(m -> ChangeLevelTask.toChangeLevelTask(m, changeLevel.getSuggestLevel(), randomUtil.randomLevel(m.getWorkId()))).collect(Collectors.toList());
+                    changeLevelTaskRepo.save(changeLevelTaskList);
                 }
             }
             //状态设置
@@ -327,5 +333,4 @@ public class ChangeLevelApi {
         }
         return new ResponseEntity(HttpStatus.OK);
     }
-
 }

+ 14 - 12
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MakrerApi.java

@@ -105,6 +105,8 @@ public class MakrerApi {
 
     @Resource
     StageControlService stageControlService;
+    @Resource
+    private ChangeLevelTaskRepo changeLevelTaskRepo;
 
     /**
      * 评卷员信息
@@ -407,7 +409,7 @@ public class MakrerApi {
         int markPaperCount;
         if (ParamCache.roughLevelConfigMap.get(String.valueOf(marker.getWorkId())).getLevelShowAllPaper() == 1) {
             // 评卷员和科组长标记的试卷
-            List<Long> markTaskPaperId = markTaskRoughLevelRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId,marker.getId(), markSubject.getStage(), true);
+            List<Long> markTaskPaperId = markTaskRoughLevelRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId, marker.getId(), markSubject.getStage(), true);
             markPaperCount = Math.toIntExact(markTaskPaperId.stream().distinct().count());
         } else {
             // 评卷员标记的试卷
@@ -533,8 +535,8 @@ public class MakrerApi {
 //            int totalCount = markTaskLevelRepo.countScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(questionId, marker.getId(), MarkStage.LEVEL.ordinal(), batchNo);
 //            nullLevelStatDto.setCount(totalCount);
             //查询改档
-            int shiftCount = markTaskRoughLevelRepo.countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(questionId, marker.getId(), MarkStage.ROUGH_LEVEL.ordinal(), false);
-            nullLevelStatDto.setShift(shiftCount);
+//            int shiftCount = markTaskRoughLevelRepo.countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(questionId, marker.getId(), MarkStage.ROUGH_LEVEL.ordinal(), false);
+            nullLevelStatDto.setShift(changeLevelTaskRepo.countShiftByQuestionIdAndMarkerIdAndStageAndIsMissing(questionId, marker.getId(), MarkStage.LEVEL.ordinal(), false));
             //查询改档打分
             int shiftScoreCount = markTaskLevelRepo.countShiftScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(questionId, marker.getId(), MarkStage.LEVEL.ordinal());
             nullLevelStatDto.setShiftScore(shiftScoreCount);
@@ -575,7 +577,7 @@ public class MakrerApi {
         int markPaperCount;
         if (ParamCache.levelConfigMap.get(String.valueOf(marker.getWorkId())).getLevelShowAllPaper() == 1) {
             // 评卷员和科组长标记的试卷
-            List<Long> markTaskPaperId = markTaskLevelRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId,marker.getId(), markSubject.getStage(), true);
+            List<Long> markTaskPaperId = markTaskLevelRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId, marker.getId(), markSubject.getStage(), true);
             markPaperCount = Math.toIntExact(markTaskPaperId.stream().distinct().count());
         } else {
             // 评卷员标记的试卷
@@ -624,8 +626,8 @@ public class MakrerApi {
         int totalCount = markTaskScoreRepo.countScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(questionId, marker.getId(), MarkStage.SCORE.ordinal(), batchNo);
         levelStatDTO.setCount(totalCount);
         //查询改档
-        int shiftCount = markTaskLevelRepo.countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(questionId, marker.getId(), MarkStage.LEVEL.ordinal(), false);
-        levelStatDTO.setShift(shiftCount);
+//        int shiftCount = markTaskLevelRepo.countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(questionId, marker.getId(), MarkStage.LEVEL.ordinal(), false);
+        levelStatDTO.setShift(changeLevelTaskRepo.countShiftByQuestionIdAndMarkerIdAndStageAndIsMissing(questionId, marker.getId(), MarkStage.SCORE.ordinal(), false));
         //查询改档打分
         int shiftScoreCount = markTaskScoreRepo.countShiftScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(questionId, marker.getId(), MarkStage.SCORE.ordinal());
         levelStatDTO.setShiftScore(shiftScoreCount);
@@ -681,7 +683,7 @@ public class MakrerApi {
         int markPaperCount;
         if (ParamCache.scoreConfigMap.get(String.valueOf(marker.getWorkId())).getScoreShowAllPaper() == 1) {
             // 评卷员和科组长标记的试卷
-            List<Long> markTaskPaperId = markTaskScoreRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId,marker.getId(), markSubject.getStage(), true);
+            List<Long> markTaskPaperId = markTaskScoreRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId, marker.getId(), markSubject.getStage(), true);
             markPaperCount = Math.toIntExact(markTaskPaperId.stream().distinct().count());
         } else {
             // 评卷员标记的试卷
@@ -723,7 +725,7 @@ public class MakrerApi {
         int totalCount = markTaskScoreRepo.countScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(questionId, marker.getId(), MarkStage.SCORE.ordinal(), batchNo);
         levelStatDTO.setCount(totalCount);
         //查询改档
-        int shiftCount = markTaskLevelRepo.countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(questionId, marker.getId(), MarkStage.LEVEL.ordinal(), false);
+        int shiftCount = markTaskLevelRepo.countShiftByQuestionIdAndMarkerIdAndStageAndResultIsNullAndIsMissing(questionId, marker.getId(), MarkStage.SCORE.ordinal(), false);
         levelStatDTO.setShift(shiftCount);
         //查询改档打分
         int shiftScoreCount = markTaskScoreRepo.countShiftScoreByQuestionIdAndMarkerIdAndStageAndResultIsNull(questionId, marker.getId(), MarkStage.SCORE.ordinal());
@@ -781,7 +783,7 @@ public class MakrerApi {
         int markPaperCount;
         if (ParamCache.scoreConfigMap.get(String.valueOf(marker.getWorkId())).getScoreShowAllPaper() == 1) {
             // 评卷员和科组长标记的试卷
-            List<Long> markTaskPaperId = markTaskScoreRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId,marker.getId(), markSubject.getStage(), true);
+            List<Long> markTaskPaperId = markTaskScoreRepo.findByWorkIdAndQuestionIdAndMarkerIdAndStageAndIsMark(markSubject.getWorkId(), questionId, marker.getId(), markSubject.getStage(), true);
             markPaperCount = Math.toIntExact(markTaskPaperId.stream().distinct().count());
         } else {
             // 评卷员标记的试卷
@@ -931,7 +933,7 @@ public class MakrerApi {
         }
 
         String loginNameStr = loginConfig.adminLoginConfig().getLoginName();
-        if(StringUtils.isBlank(loginNameStr)){
+        if (StringUtils.isBlank(loginNameStr)) {
             throw new RuntimeException("没有设置管理员账号");
         }
         List<String> loginNames = Arrays.asList(loginNameStr.split(","));
@@ -943,8 +945,8 @@ public class MakrerApi {
         }
 
         // 如果是试评,必须结束试评后再清除
-        MarkSubject markSubject = markSubjectRepo.findOne(workId+"-"+subject);
-        if(markSubject.getTest() == TrialEnum.START_TRIAL.getId()){
+        MarkSubject markSubject = markSubjectRepo.findOne(workId + "-" + subject);
+        if (markSubject.getTest() == TrialEnum.START_TRIAL.getId()) {
             throw new RuntimeException("请先结束试评");
         }
 

+ 7 - 1
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkSubjectApi.java

@@ -164,7 +164,7 @@ public class MarkSubjectApi {
     }
 
     /**
-     * 该评卷科目进入下一阶段
+     * 该评卷科目进入下一阶段(发任务)
      *
      * @param markSubject 评卷科目id
      */
@@ -701,6 +701,12 @@ public class MarkSubjectApi {
             if (count > 0) {
                 throw new RuntimeException("当前阶段已发布任务,不能编辑分组");
             }
+
+            // 分数计算方式为"去高去低加权平均时",校验各分组评卷员为3个及以上
+            boolean removeHighAndLow = Optional.ofNullable(ParamCache.scoreConfigMap.get(String.valueOf(String.valueOf(markSubject.getWorkId()))).getRemoveHighAndLow()).orElse(0) == 1;
+            if (removeHighAndLow && markerGroup.getMarkers().stream().filter(m -> Role.MARKER.equals(m.getRole())).count() < 3) {
+                throw new RuntimeException("取分规则为去高低再平均,评委数必须大于等于3");
+            }
         }
 
         markerGroup.setWorkId(markSubject.getWorkId());

+ 30 - 3
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkTaskApi.java

@@ -4,13 +4,16 @@ import cn.com.qmth.stmms.ms.commons.utils.DigitalToChineseUtil;
 import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
 import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
 import cn.com.qmth.stmms.ms.core.domain.*;
+import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkerGroupLeader;
+import cn.com.qmth.stmms.ms.core.repository.ChangeLevelTaskRepo;
 import cn.com.qmth.stmms.ms.core.repository.LevelRepo;
 import cn.com.qmth.stmms.ms.core.repository.MarkSubjectRepo;
 import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 import cn.com.qmth.stmms.ms.marking.assembler.PaperAssembler;
 import cn.com.qmth.stmms.ms.marking.dto.LevelDetailDTO;
+import cn.com.qmth.stmms.ms.marking.dto.MarkTaskBatchNoDTO;
 import cn.com.qmth.stmms.ms.marking.dto.MarkTaskDTO;
 import cn.com.qmth.stmms.ms.marking.dto.PaperDTO;
 import cn.com.qmth.stmms.ms.marking.service.*;
@@ -26,11 +29,15 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.Predicate;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.*;
@@ -71,6 +78,8 @@ public class MarkTaskApi {
 
     @Resource
     private MarkTaskSelfCheckService markTaskSelfCheckService;
+    @Resource
+    private ChangeLevelTaskService changeLevelTaskService;
 
     /**
      * 评卷员的评卷任务
@@ -152,6 +161,16 @@ public class MarkTaskApi {
         return new ResponseEntity(map, HttpStatus.OK);
     }
 
+    /**
+     * 改档-评卷任务确认
+     *
+     * @param changeLevelTaskId 改档任务ID
+     */
+    @GetMapping("/confirm/{changeLevelTaskId}")
+    public ResponseEntity confirmTask(@PathVariable Long changeLevelTaskId) {
+        return new ResponseEntity(changeLevelTaskService.confirmTask(changeLevelTaskId), HttpStatus.OK);
+    }
+
     /**
      * 批量提交评卷任务
      *
@@ -280,6 +299,13 @@ public class MarkTaskApi {
                 predicates.add(builder.and(builder.and(in)));
             }
 
+            // 科组长只查询自己操作的试卷
+            if (MarkStage.ROUGH_LEVEL.equals(markSubject.getStage())) {
+                predicates.add(builder.equal(root.get("roughMarkLeaderId"), markerId));
+            } else if (MarkStage.LEVEL.equals(markSubject.getStage())) {
+                predicates.add(builder.equal(root.get("markLeaderId"), markerId));
+            }
+
             predicates.add(builder.equal(root.get("markByLeader"), true));
             List<Predicate> list = new ArrayList<>();
             if (MarkStage.ROUGH_LEVEL.equals(markSubject.getStage())) {
@@ -472,13 +498,14 @@ public class MarkTaskApi {
                                     @RequestParam Subject subject,
                                     @RequestParam MarkStage stage,
                                     @RequestParam Long markerId,
+                                    @RequestParam Long batchNo,
                                     Pageable pageable) {
         if (stage.equals(MarkStage.ROUGH_LEVEL)) {
-            return markTaskRoughLevelService.listMarkedTaskLevel(workId, subject, markerId, pageable);
+            return markTaskRoughLevelService.listMarkedTaskLevel(workId, subject, markerId, batchNo, pageable);
         } else if (stage.equals(MarkStage.LEVEL)) {
-            return markTaskLevelService.listMarkedTaskLevel(workId, subject, markerId, pageable);
+            return markTaskLevelService.listMarkedTaskLevel(workId, subject, markerId, batchNo, pageable);
         } else if (stage.equals(MarkStage.SCORE)) {
-            return markTaskScoreService.listMarkedTaskScore(workId, subject, markerId, pageable);
+            return markTaskScoreService.listMarkedTaskScore(workId, subject, markerId, batchNo, pageable);
         }
         return null;
     }

+ 59 - 6
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/PaperApi.java

@@ -1,6 +1,7 @@
 package cn.com.qmth.stmms.ms.marking.api;
 
 import cn.com.qmth.stmms.ms.commons.config.SystemConfig;
+import cn.com.qmth.stmms.ms.commons.utils.DateUtil;
 import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
 import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
@@ -18,6 +19,7 @@ import cn.com.qmth.stmms.ms.marking.assembler.MarkTaskLevelAssembler;
 import cn.com.qmth.stmms.ms.marking.assembler.MarkTaskRoughLevelAssembler;
 import cn.com.qmth.stmms.ms.marking.assembler.MarkTaskScoreAssembler;
 import cn.com.qmth.stmms.ms.marking.assembler.PaperAssembler;
+import cn.com.qmth.stmms.ms.marking.dto.MarkTaskBatchNoDTO;
 import cn.com.qmth.stmms.ms.marking.dto.MarkTaskDTO;
 import cn.com.qmth.stmms.ms.marking.dto.PaperDTO;
 import cn.com.qmth.stmms.ms.marking.service.*;
@@ -148,11 +150,25 @@ public class PaperApi {
         Optional<Paper> paperOptional = paperRepo.findAll(specification, new PageRequest(0, 1))
                 .getContent().stream().findFirst();
         if (paperOptional.isPresent()) {
-            paperDTO = paperAssembler.toDTO(paperOptional.get());
+            Paper paper = paperOptional.get();
+            MarkSubject markSubject = markSubjectRepo.findOne(paper.getWorkId() + "-" + paper.getSubject().name());
+            if ((MarkStage.ROUGH_LEVEL.equals(markSubject.getStage()) && paper.getRoughBatchNo() == null)
+                    || (MarkStage.LEVEL.equals(markSubject.getStage()) && paper.getBatchNo() == null)
+                    || (MarkStage.SCORE.equals(markSubject.getStage()) && paper.getScoreBatchNo() == null)) {
+                throw new RuntimeException("该试卷还未发出任务");
+            }
+            paperDTO = paperAssembler.toDTO(paper);
         }
         return paperDTO;
     }
 
+    /**
+     * 科组长-筛选-任务密号查询
+     *
+     * @param questionId
+     * @param stage
+     * @param sn
+     */
     @GetMapping("search/byTaskSecretNumber")
     public PaperDTO getByTaskSecretNumber(@RequestParam Long questionId,
                                           @RequestParam MarkStage stage,
@@ -320,6 +336,7 @@ public class PaperApi {
                     //level为null时,查询待评数量
                     if (StringUtils.isEmpty(level)) {
                         predicates.add(builder.isNotNull(root.get("level")));
+                        predicates.add(builder.equal(root.get("isShift"), false));
                         predicates.add(builder.isNull(root.get("score")));
                         predicates.add(builder.isNotNull(root.get("scoreBatchNo")));
                     } else {
@@ -406,6 +423,7 @@ public class PaperApi {
     @RequestMapping(value = "{paper}", method = RequestMethod.PATCH)
     @Transactional
     public ResponseEntity marking(@PathVariable Paper paper, @RequestBody HashMap<String, String> body) {
+        Long userId = ServletUtil.getUserId();
         String action = body.get("action");
         String level = body.get("level");
         String tagged = body.get("tagged");
@@ -437,10 +455,10 @@ public class PaperApi {
                 boolean leaderConfirm = leaderConfirmStr == null || "".equals(leaderConfirmStr) || Boolean.parseBoolean(leaderConfirmStr);
                 if (MarkStage.ROUGH_LEVEL.equals(stage)) {
                     paper.setRoughOneClick(false);
-                    markingRoughLevelService.reject(paper, level, ranges, leaderConfirm, false, null);
+                    markingRoughLevelService.reject(paper, level, ranges, leaderConfirm, false, userId);
                 } else if (MarkStage.LEVEL.equals(stage)) {
                     paper.setOneClick(false);
-                    markingLevelService.reject(paper, level, ranges, leaderConfirm, false, null);
+                    markingLevelService.reject(paper, level, ranges, leaderConfirm, false, userId);
                 }
             }
         }
@@ -461,6 +479,7 @@ public class PaperApi {
     @RequestMapping(value = "batch", method = RequestMethod.PATCH)
     @Transactional
     public ResponseEntity marking(@RequestBody HashMap<String, String> body) {
+        Long userId = ServletUtil.getUserId();
         String action = body.get("action");
         String level = body.get("level");
         String tagged = body.get("tagged");
@@ -498,10 +517,10 @@ public class PaperApi {
                         boolean leaderConfirm = leaderConfirmStr == null || "".equals(leaderConfirmStr) || Boolean.parseBoolean(leaderConfirmStr);
                         if (MarkStage.ROUGH_LEVEL.equals(stage)) {
                             paper.setRoughOneClick(false);
-                            markingRoughLevelService.reject(paper, level, ranges, leaderConfirm, false, null);
+                            markingRoughLevelService.reject(paper, level, ranges, leaderConfirm, false, userId);
                         } else if (MarkStage.LEVEL.equals(stage)) {
                             paper.setOneClick(false);
-                            markingLevelService.reject(paper, level, ranges, leaderConfirm, false, null);
+                            markingLevelService.reject(paper, level, ranges, leaderConfirm, false, userId);
                         }
                     }
                 }
@@ -675,7 +694,6 @@ public class PaperApi {
                             } else {
                                 predicates.add(builder.equal(root.get("id"), markScoreTasks.get(0).getPaper().getId()));
                             }
-                            predicates.add(builder.isNull(root.get("id")));
                         } else {
                             predicates.add(builder.equal(root.get("id"), markTasks.get(0).getPaper().getId()));
                         }
@@ -918,4 +936,39 @@ public class PaperApi {
         Paper paper = paperRepo.findByWorkIdAndSubjectAndExamNumber(workId, subject, examNumber);
         return paperAssembler.toDTO(paper);
     }
+
+    /**
+     * 查询阶段批次号
+     */
+    @PostMapping("/listBatchNo")
+    public List<MarkTaskBatchNoDTO> listBatchNo(@RequestParam Long workId,
+                                                @RequestParam Subject subject,
+                                                @RequestParam MarkStage stage) {
+        if (stage == null) {
+            throw new RuntimeException("请传入当前阶段信息");
+        }
+        List<Long> batchNoList = new ArrayList<>();
+        switch (stage) {
+            case ROUGH_LEVEL:
+                batchNoList = paperRepo.findAllRoughBatchNoByWorkIdAndSubject(workId, subject);
+                break;
+            case LEVEL:
+                batchNoList = paperRepo.findAllBatchNoByWorkIdAndSubject(workId, subject);
+                break;
+            case SCORE:
+                batchNoList = paperRepo.findAllScoreBatchNoByWorkIdAndSubject(workId, subject);
+                break;
+            default:
+                break;
+        }
+        List<MarkTaskBatchNoDTO> markTaskBatchNoDTOS = batchNoList.stream().map(t -> {
+            MarkTaskBatchNoDTO markTaskBatchNoDTO = new MarkTaskBatchNoDTO();
+            markTaskBatchNoDTO.setBatchNo(t);
+            markTaskBatchNoDTO.setBatchNoDisplay(DateUtil.parseDateToStr(DateUtil.YYMMDDHHMM, t));
+            return markTaskBatchNoDTO;
+        }).collect(Collectors.toList());
+        // 倒序
+        Collections.sort(markTaskBatchNoDTOS, Collections.reverseOrder(Comparator.comparingLong(m -> m.getBatchNo())));
+        return markTaskBatchNoDTOS;
+    }
 }

+ 346 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/PaperCheckApi.java

@@ -0,0 +1,346 @@
+package cn.com.qmth.stmms.ms.marking.api;
+
+import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelError;
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelReader;
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelReaderHandle;
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExportUtils;
+import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
+import cn.com.qmth.stmms.ms.core.cache.ParamCache;
+import cn.com.qmth.stmms.ms.core.domain.*;
+import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
+import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskScore;
+import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
+import cn.com.qmth.stmms.ms.core.domain.user.Role;
+import cn.com.qmth.stmms.ms.core.repository.*;
+import cn.com.qmth.stmms.ms.core.vo.Subject;
+import cn.com.qmth.stmms.ms.marking.assembler.ChangeLevelAssembler;
+import cn.com.qmth.stmms.ms.marking.assembler.PaperAssembler;
+import cn.com.qmth.stmms.ms.marking.dto.*;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.Predicate;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/api/paperCheck")
+public class PaperCheckApi {
+
+    @Autowired
+    private PaperRepo paperRepo;
+    @Resource
+    private PaperAssembler paperAssembler;
+    @Autowired
+    private StudentRepo studentRepo;
+    @Resource
+    private MarkSubjectRepo markSubjectRepo;
+    @Resource
+    private PaperCheckRepo paperCheckRepo;
+    @Resource
+    private PaperCheckStudentRepo paperCheckStudentRepo;
+    @Resource
+    private ChangeLevelRepo changeLevelRepo;
+
+
+    /**
+     * 查询抽查任务
+     *
+     * @param workId 工作ID
+     */
+    @GetMapping("/list")
+    public List<PaperCheck> list(@RequestParam Long workId) {
+        return paperCheckRepo.findByWorkIdOrderByCreatedOnDesc(workId);
+    }
+
+    /**
+     * 新增抽查任务
+     *
+     * @param workId  工作ID
+     * @param subject 科目
+     * @param name    名称
+     * @param remark  备注
+     */
+    @PostMapping("/add")
+    @Transactional
+    public ResponseEntity add(@RequestParam Long workId,
+                              @RequestParam Subject subject,
+                              @RequestParam String name,
+                              @RequestParam String remark) {
+        PaperCheck paperCheck = paperCheckRepo.selectByWorkIdAndName(workId, name);
+        if (paperCheck != null) {
+            throw new RuntimeException("名称已存在");
+        }
+
+        MarkSubject markSubject = markSubjectRepo.findOne(workId + "-" + subject);
+        // 查询打分任务是否完成
+        int waitCount = paperRepo.countByWorkIdAndSubjectAndLevelIsNotNullAndScoreIsNull(workId, subject);
+        if (!MarkStage.SCORE.equals(markSubject.getStage()) || waitCount > 0) {
+            throw new RuntimeException("该科目打分任务还未完成,不可进行试卷抽查");
+        }
+
+        paperCheck = new PaperCheck();
+        paperCheck.setWorkId(workId);
+        paperCheck.setSubject(subject.name());
+        paperCheck.setStage(markSubject.getStage());
+        paperCheck.setName(name);
+        paperCheck.setRemark(remark);
+        paperCheck.setStudentCount(0);
+        paperCheck.setStartDeal(false);
+        paperCheck.setSelectInfo(JSON.toJSONString(new PaperCheckSelectInfoDTO(0, null)));
+        paperCheck.setCreatedId(ServletUtil.getUserId());
+        paperCheck.setCreatedOn(new Date());
+        paperCheckRepo.save(paperCheck);
+
+        return new ResponseEntity(HttpStatus.OK);
+    }
+
+    /**
+     * 导入考生名单
+     *
+     * @param paperCheckId 试卷抽查任务ID
+     * @param file         考生名单excel文件
+     */
+    @PostMapping("/importStudent")
+    @Transactional
+    public List<ExcelError> importStudent(@RequestParam Long paperCheckId,
+                                          @RequestParam MultipartFile file) throws Exception {
+        PaperCheck paperCheck = paperCheckRepo.findOne(paperCheckId);
+        if (paperCheck == null) {
+            throw new RuntimeException("任务不存在");
+        }
+        if (paperCheck.getStartDeal()) {
+            throw new RuntimeException("开始批量处理,无法执行此操作");
+        }
+
+        List<Paper> paperList = new ArrayList<>();
+        List<String> examNumberList = new ArrayList<>();
+
+        ExcelReader excelReader = new ExcelReader(PaperCheckImportStudentDTO.class);
+        List<ExcelError> excelErrors = excelReader.reader(file.getInputStream(), obj -> {
+            try {
+                PaperCheckImportStudentDTO dto = (PaperCheckImportStudentDTO) obj;
+                String examNumber = dto.getExamNumber();
+
+                // 考号是否重复
+                if (examNumberList.contains(examNumber)) {
+                    throw new RuntimeException("准考证号重复");
+                } else {
+                    examNumberList.add(examNumber);
+                }
+
+                Student student = studentRepo.findByWorkIdAndExamNumber(paperCheck.getWorkId(), examNumber);
+                if (student == null) {
+                    throw new RuntimeException("准考证号" + examNumber + "不存在此考生");
+                } else if (student.isAbsent()) {
+                    throw new RuntimeException("准考证号" + examNumber + "的考生状态为缺考");
+                }
+                Subject subject = Subject.valueOf(paperCheck.getSubject());
+                Paper paper = paperRepo.findByWorkIdAndSubjectAndExamNumber(paperCheck.getWorkId(), subject, examNumber);
+                if (paper == null) {
+                    throw new RuntimeException("准考证号" + examNumber + "考生" + subject.getName() + "试卷未上传");
+                }
+                paperList.add(paper);
+                return null;
+            } catch (RuntimeException e) {
+                //手动回滚
+                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                ExcelError excelError = new ExcelError();
+                excelError.setExcelErrorType(e.getMessage());
+                return excelError;
+            }
+        });
+        String errors = errorsString(excelErrors);
+        if (errors.length() > 0) {
+            throw new Exception(errors);
+        }
+
+        if (!CollectionUtils.isEmpty(paperList)) {
+            // 删除旧数据
+            paperCheckStudentRepo.deleteByPaperCheckId(paperCheckId);
+            List<PaperCheckStudent> data = new ArrayList<>();
+            for (Paper paper : paperList) {
+                PaperCheckStudent paperCheckStudent = new PaperCheckStudent(paperCheck.getWorkId(), paperCheck.getSubject(), paperCheck.getStage(), paperCheck.getId(), paper.getId(), paper.getSecretNumber());
+                if (data.size() == 2000) {
+                    paperCheckStudentRepo.save(paperCheckStudent);
+                    data.clear();
+                }
+                data.add(paperCheckStudent);
+            }
+            //将剩下的数据也导入
+            if (!data.isEmpty()) {
+                paperCheckStudentRepo.save(data);
+            }
+
+            // 更新抽查任务中考生数量
+            paperCheckRepo.updateStudentCountById(paperList.size(), paperCheckId);
+        }
+        return excelErrors;
+    }
+
+    /**
+     * 批量处理
+     *
+     * @param paperCheckId 试卷抽查任务ID
+     */
+    @PostMapping("/listStudent")
+    @Transactional
+    public PageableDTO listStudent(@RequestParam Long paperCheckId,
+                                   Pageable pageable) {
+        Specification<PaperCheckStudent> specification = (root, query, builder) -> {
+            List<Predicate> predicates = new ArrayList<>();
+            predicates.add(builder.equal(root.get("paperCheckId"), paperCheckId));
+            return builder.and(predicates.toArray(new Predicate[predicates.size()]));
+        };
+        Sort sort = new Sort(Sort.Direction.ASC, "secretNumber");
+        Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
+
+        Page<PaperCheckStudent> paperCheckStudents = paperCheckStudentRepo.findAll(specification, pageable1);
+        List<Paper> papers = paperRepo.findAll(paperCheckStudents.getContent().stream().map(PaperCheckStudent::getPaperId).collect(Collectors.toList()));
+
+        List<PaperDTO> paperDTOs = new ArrayList<>();
+        papers.forEach(p -> paperDTOs.add(paperAssembler.toInspectionDTO(p)));
+
+        // 更新处理标记
+        paperCheckRepo.updateStartDealById(paperCheckId);
+        return new PageableDTO(paperDTOs, paperCheckStudents.getTotalElements(), paperCheckStudents.getTotalPages(), pageable.getPageNumber());
+    }
+
+    /**
+     * 批量处理历史
+     *
+     * @param paperCheckId 试卷抽查任务ID
+     */
+    @PostMapping("/listHistory")
+    @Transactional
+    public PageableDTO listHistory(@RequestParam Long paperCheckId,
+                                   Pageable pageable) {
+        Page<ChangeLevel> changeLevelPage = changeLevelRepo.findByPaperCheckId(paperCheckId, pageable);
+        List<PaperDTO> paperDTOs = new ArrayList<>();
+        for (ChangeLevel changeLevel : changeLevelPage) {
+            PaperDTO paperDTO = paperAssembler.toInspectionDTO(paperRepo.findOne(changeLevel.getPaperId()));
+            // 新档位为改档建议档位
+            paperDTO.setLevel(changeLevel.getSuggestLevel());
+            // 旧档位为改档前档位
+            paperDTO.setOriginLevel(changeLevel.getOriginalLevel());
+            paperDTOs.add(paperDTO);
+        }
+        return new PageableDTO(paperDTOs, changeLevelPage.getTotalElements(), changeLevelPage.getTotalPages(), pageable.getPageNumber());
+    }
+
+    /**
+     * 更新选中的数据信息
+     *
+     * @param paperCheckId 试卷抽查任务ID
+     * @param pageNumber   当前页码
+     * @param secretNumber 考生任务密号
+     */
+    @PostMapping("/updateSelectInfo")
+    @Transactional
+    public ResponseEntity updateSelectInfo(@RequestParam Long paperCheckId,
+                                           @RequestParam Integer pageNumber,
+                                           @RequestParam String secretNumber) {
+        PaperCheck paperCheck = paperCheckRepo.findOne(paperCheckId);
+        if (paperCheck == null) {
+            throw new RuntimeException("抽查任务不存在");
+        }
+        PaperCheckSelectInfoDTO paperCheckSelectInfoDTO = new PaperCheckSelectInfoDTO(pageNumber, secretNumber);
+        paperCheckRepo.updateSelectInfoById(JSON.toJSONString(paperCheckSelectInfoDTO), paperCheck.getId());
+        return new ResponseEntity(HttpStatus.OK);
+    }
+
+    /**
+     * 获取选中信息
+     *
+     * @param paperCheckId 试卷抽查任务ID
+     */
+    @GetMapping("/getSelectInfo")
+    public PaperCheckSelectInfoDTO getSelectInfo(@RequestParam Long paperCheckId) {
+        PaperCheck paperCheck = paperCheckRepo.findOne(paperCheckId);
+        PaperCheckSelectInfoDTO paperCheckSelectInfoDTO = new PaperCheckSelectInfoDTO();
+        if (paperCheck == null || StringUtils.isBlank(paperCheck.getSelectInfo())) {
+            return paperCheckSelectInfoDTO;
+        }
+        return JSON.parseObject(paperCheck.getSelectInfo(), PaperCheckSelectInfoDTO.class);
+    }
+
+    /**
+     * 导出信息
+     *
+     * @param paperCheckId 试卷抽查任务ID
+     */
+    @PostMapping("/export")
+    public void export(@RequestParam Long paperCheckId, HttpServletResponse response) {
+        List<PaperCheckExportDTO> paperCheckExportDTOS = new ArrayList<>();
+        PaperCheck paperCheck = paperCheckRepo.findOne(paperCheckId);
+        List<Object[]> objects = paperCheckStudentRepo.findByPaperCheckId(paperCheckId, paperCheck.getWorkId(), paperCheck.getSubject(), paperCheck.getStage().ordinal());
+        AtomicInteger i = new AtomicInteger(1);
+        objects.forEach(o -> {
+            PaperCheckExportDTO paperCheckExportDTO = new PaperCheckExportDTO();
+            paperCheckExportDTO.setSequence(i.getAndIncrement());
+            paperCheckExportDTO.setSubjectName(Subject.valueOf(String.valueOf(o[0])).getName());
+            paperCheckExportDTO.setExamNumber(String.valueOf(o[1]));
+            paperCheckExportDTO.setSecretNumber(String.valueOf(o[2]));
+
+            Object level = o[3];
+            Object originLevel = o[4];
+            // 没有改档记录
+            if (originLevel == null) {
+                paperCheckExportDTO.setOriginLevel(String.valueOf(level));
+                paperCheckExportDTO.setLevel("-");
+                paperCheckExportDTO.setUpdateLevel("否");
+            } else {
+                paperCheckExportDTO.setOriginLevel(String.valueOf(originLevel));
+                paperCheckExportDTO.setLevel(String.valueOf(level));
+                // 有改档记录且更新前后档位未变动,说明有评卷员未确认,是否改档标记为否
+                paperCheckExportDTO.setUpdateLevel(originLevel.equals(level) ? "否" : "是");
+            }
+            paperCheckExportDTOS.add(paperCheckExportDTO);
+        });
+        String fileName = "试卷抽查数据";
+        ExportUtils.exportEXCEL(fileName, PaperCheckExportDTO.class, paperCheckExportDTOS, response);
+    }
+
+    private String errorsString(List<ExcelError> excelErrors) {
+        StringJoiner sj = new StringJoiner(";");
+        if (excelErrors != null && !excelErrors.isEmpty()) {
+            int forint = excelErrors.size() < 10 ? excelErrors.size() : 9;
+            for (int i = 0; i < forint; i++) {
+                ExcelError excelError = excelErrors.get(i);
+                StringBuffer sb = new StringBuffer();
+                sb.append("第").append(excelError.getRow()).append("行,").append(excelError.getExcelErrorType());
+                sj.add(sb.toString());
+            }
+        }
+        return sj.toString();
+    }
+
+    public static void main(String[] args) {
+        List<String> list = new ArrayList<>();
+        list.add("11");
+        list.add("22");
+        list.add("33");
+        list.add("44");
+    }
+}

+ 62 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/MarkTaskLevelAssembler.java

@@ -11,6 +11,7 @@ import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskSelfCheck;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.repository.*;
 import cn.com.qmth.stmms.ms.marking.dto.MarkTaskDTO;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -208,6 +209,67 @@ public class MarkTaskLevelAssembler {
         return markTaskDTO;
     }
 
+    /**
+     * 改档,改档打分
+     *
+     * @param changeLevelTask
+     * @return
+     */
+    public MarkTaskDTO toShiftDTO(ChangeLevelTask changeLevelTask) {
+
+        MarkTaskDTO markTaskDTO = null;
+        if (changeLevelTask != null) {
+            markTaskDTO = new MarkTaskDTO();
+            markTaskDTO.setId(changeLevelTask.getId());
+            markTaskDTO.setMarkerId(changeLevelTask.getMarkerId());
+            markTaskDTO.setMarker(changeLevelTask.getMarkerName());
+            markTaskDTO.setUpdatedOn(changeLevelTask.getCreatedOn());
+//            markTaskDTO.setResult(markTask.getResult());
+            Paper paper = changeLevelTask.getPaper();
+            if (paper.isShift()) {
+                ChangeLevel changeLevel = changeLevelRepo.findByWorkIdAndSubjectAndPaperIdAndAuditStatusAndStageAndIsCurr(changeLevelTask.getWorkId(), changeLevelTask.getSubject(), MarkStage.SCORE, paper.getId());
+                markTaskDTO.setRedoLevel(changeLevel.getSuggestLevel());
+                markTaskDTO.setOriginLevel(changeLevel != null ? changeLevel.getOriginalLevel() : "");
+            }
+            if (paper.isShiftScore()) {
+                markTaskDTO.setRoughLevel(paper.getRoughLevel());
+            }
+            markTaskDTO.setSn(changeLevelTask.getSecretNumber());
+            if(StringUtils.isBlank(markTaskDTO.getRedoLevel())) {
+                markTaskDTO.setRedoLevel(paper.getRedoLevel());
+            }
+            String imgSrc = null;
+            String thumbSrc = null;
+            String fileName = paper.getExamNumber();
+            Student student = studentRepo.findByWorkIdAndExamNumber(paper.getWorkId(), paper.getExamNumber());
+            //0:随机码 1:考号
+            if (ParamCache.collectConfigMap.get(String.valueOf(paper.getWorkId())).getNameRule() == 1) {
+                fileName = MD5Util.getImageRuleMd5(paper.getWorkId(), paper.getSubject().ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
+            }
+            if (ParamCache.collectConfigMap.get(String.valueOf(paper.getWorkId())).getImageEncrypt() == 1) {
+                imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
+                thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);
+            } else {
+                imgSrc = systemConfig.getImageUrl(changeLevelTask.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+                thumbSrc = systemConfig.getThumbUrl(changeLevelTask.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+            }
+            markTaskDTO.setThumbSrc(thumbSrc);
+            markTaskDTO.setImgSrc(imgSrc);
+            markTaskDTO.setSample(paper.isSample());
+            markTaskDTO.setMarkByLeader(paper.isMarkByLeader());
+//            markTaskDTO.setRandomSeqNew(markTask.getRandomSeqNew());
+//            markTaskDTO.setRandomSeq(markTask.getRandomSeq());
+            markTaskDTO.setPaperId(paper.getId());
+//            markTaskDTO.setSerialNumber(markTask.getSerialNumber());
+//            if (Objects.nonNull(markTask.getDisplayNumber())) {
+//                markTaskDTO.setDisplayNumber(markTask.getDisplayNumber() == 1);
+//            }
+            markTaskDTO.setShift(paper.isShift());
+            markTaskDTO.setShiftScore(paper.isShiftScore());
+        }
+        return markTaskDTO;
+    }
+
     public MarkTaskDTO toSelfCheckDTO(MarkTaskLevel markTask) {
         MarkTaskDTO markTaskDTO = null;
         if (markTask != null) {

+ 23 - 26
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/MarkTaskRoughLevelAssembler.java

@@ -150,32 +150,29 @@ public class MarkTaskRoughLevelAssembler {
 
     /**
      * 改档,改档打分
-     *
-     * @param markTask
-     * @return
      */
-    public MarkTaskDTO toShiftDTO(MarkTaskRoughLevel markTask) {
+    public MarkTaskDTO toShiftDTO(ChangeLevelTask changeLevelTask) {
 
         MarkTaskDTO markTaskDTO = null;
-        if (markTask != null) {
+        if (changeLevelTask != null) {
             markTaskDTO = new MarkTaskDTO();
-            markTaskDTO.setId(markTask.getId());
-            markTaskDTO.setRejected(markTask.isRejected());
-            markTaskDTO.setMarkerId(markTask.getMarkerId());
-            markTaskDTO.setMarker(markTask.getMarkerName());
-            markTaskDTO.setUpdatedOn(markTask.getUpdatedOn());
-            markTaskDTO.setResult(markTask.getResult());
-            Paper paper = markTask.getPaper();
+            markTaskDTO.setId(changeLevelTask.getId());
+            markTaskDTO.setMarkerId(changeLevelTask.getMarkerId());
+            markTaskDTO.setMarker(changeLevelTask.getMarkerName());
+            markTaskDTO.setUpdatedOn(changeLevelTask.getCreatedOn());
+//            markTaskDTO.setResult(markTask.getResult());
+            Paper paper = changeLevelTask.getPaper();
             if (paper.isShift()) {
-                markTaskDTO.setLevel(markTask.getResult());
-                ChangeLevel changeLevel = changeLevelRepo.findByWorkIdAndSubjectAndPaperIdAndAuditStatusAndStageAndIsCurr(markTask.getWorkId(), markTask.getSubject().name(), MarkStage.LEVEL, paper.getId());
+                ChangeLevel changeLevel = changeLevelRepo.findByWorkIdAndSubjectAndPaperIdAndAuditStatusAndStageAndIsCurr(changeLevelTask.getWorkId(), changeLevelTask.getSubject(), MarkStage.LEVEL, paper.getId());
+                markTaskDTO.setLevel(changeLevel.getSuggestLevel());
                 markTaskDTO.setOriginLevel(changeLevel != null ? changeLevel.getOriginalLevel() : "");
+                markTaskDTO.setRedoLevel(changeLevel.getSuggestLevel());
             }
             if (paper.isShiftScore()) {
                 markTaskDTO.setLevel(paper.getLevel());
             }
-            markTaskDTO.setSn(markTask.getSecretNumber());
-            markTaskDTO.setRedoLevel(paper.getRedoLevel());
+//            markTaskDTO.setSn(markTask.getSecretNumber());
+
             String imgSrc = null;
             String thumbSrc = null;
             String fileName = paper.getExamNumber();
@@ -188,23 +185,23 @@ public class MarkTaskRoughLevelAssembler {
                 imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
                 thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);
             } else {
-                imgSrc = systemConfig.getImageUrl(markTask.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
-                thumbSrc = systemConfig.getThumbUrl(markTask.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+                imgSrc = systemConfig.getImageUrl(changeLevelTask.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+                thumbSrc = systemConfig.getThumbUrl(changeLevelTask.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
             }
             markTaskDTO.setThumbSrc(thumbSrc);
             markTaskDTO.setImgSrc(imgSrc);
             markTaskDTO.setSample(paper.isSample());
             markTaskDTO.setMarkByLeader(paper.isMarkByLeader());
-            markTaskDTO.setRandomSeqNew(markTask.getRandomSeqNew());
-            markTaskDTO.setRandomSeq(markTask.getRandomSeq());
+//            markTaskDTO.setRandomSeqNew(markTask.getRandomSeqNew());
+//            markTaskDTO.setRandomSeq(markTask.getRandomSeq());
             markTaskDTO.setPaperId(paper.getId());
-            markTaskDTO.setSerialNumber(markTask.getSerialNumber());
-            if (Objects.nonNull(markTask.getDisplayNumber())) {
-                markTaskDTO.setDisplayNumber(markTask.getDisplayNumber() == 1);
-            }
-            markTaskDTO.setShift(paper.isShift());
+//            markTaskDTO.setSerialNumber(markTask.getSerialNumber());
+//            if (Objects.nonNull(markTask.getDisplayNumber())) {
+//                markTaskDTO.setDisplayNumber(markTask.getDisplayNumber() == 1);
+//            }
+            markTaskDTO.setShift(!changeLevelTask.getConfirmChangeStage() && paper.isShift());
             markTaskDTO.setShiftScore(paper.isShiftScore());
-            markTaskDTO.setMark(markTask.isMark());
+//            markTaskDTO.setMark(markTask.isMark());
         }
         return markTaskDTO;
     }

+ 77 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/PaperAssembler.java

@@ -8,6 +8,7 @@ import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.*;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskRoughLevel;
+import cn.com.qmth.stmms.ms.core.domain.user.Role;
 import cn.com.qmth.stmms.ms.core.repository.*;
 import cn.com.qmth.stmms.ms.marking.dto.PaperDTO;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -122,6 +123,82 @@ public class PaperAssembler {
         return paperDTO;
     }
 
+    public PaperDTO toInspectionDTO(Paper paper) {
+
+        String imgSrc = null;
+        String thumbSrc = null;
+        String sheetSrc = null;
+        PaperDTO paperDTO = null;
+        if (paper != null) {
+            String fileName = paper.getExamNumber();
+            Student student = studentRepo.findByWorkIdAndExamNumber(paper.getWorkId(), paper.getExamNumber());
+            //0:随机码 1:考号
+            if (ParamCache.collectConfigMap.get(String.valueOf(paper.getWorkId())).getNameRule() == 1) {
+                fileName = MD5Util.getImageRuleMd5(paper.getWorkId(), paper.getSubject().ordinal(), student.getAreaCode(), student.getExamNumber(), student.getId());
+            }
+            if (ParamCache.collectConfigMap.get(String.valueOf(paper.getWorkId())).getImageEncrypt() == 1) {
+                imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
+                thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);
+                sheetSrc = systemConfig.getSheetUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.SHEET);
+            } else {
+                imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+                thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+                sheetSrc = systemConfig.getSheetUrl(paper.getWorkId(), paper.getSubject().toString(), paper.getAreaCode(), fileName);
+            }
+            //查询阶段
+            MarkSubject markSubject = markSubjectRepo.findOne(paper.getWorkId() + "-" + paper.getSubject());
+            paperDTO = new PaperDTO();
+            paperDTO.setId(paper.getId());
+            paperDTO.setPaperId(paper.getId());
+            paperDTO.setSubjectName(paper.getSubject().getName());
+            paperDTO.setExamNumber(paper.getExamNumber());
+            paperDTO.setSn(paper.getSecretNumber());
+            paperDTO.setLevel(paper.getLevel());
+            paperDTO.setRoughLevel(paper.getRoughLevel());
+            paperDTO.setManual(paper.isManual());
+            paperDTO.setScore(Objects.isNull(paper.getScore()) ? null : paper.getScore().intValue());
+            paperDTO.setArbitrated(paper.isArbitrated());
+            paperDTO.setRejected(paper.isRejected());
+            paperDTO.setSample(paper.isSample());
+            paperDTO.setRoughSample(paper.isRoughSample());
+            paperDTO.setMarkByLeader(paper.isMarkByLeader());
+            paperDTO.setTagged(paper.isTagged());
+            paperDTO.setMarkedLogic(paper.isMarkedLogic());
+            paperDTO.setRedoLevel(paper.getRedoLevel());
+            paperDTO.setUpdatedOn(paper.getUpdatedOn());
+            paperDTO.setSecretNumber(paper.getSecretNumber());
+            paperDTO.setImgSrc(imgSrc);
+            paperDTO.setThumbSrc(thumbSrc);
+            paperDTO.setSheetSrc(sheetSrc);
+            paperDTO.setAreaCode(paper.getAreaCode());
+            paperDTO.setMissing(paper.getIsMissing());
+            if (paper.getInspectScore() != null) {
+                paperDTO.setInspectScore(paper.getInspectScore().intValue());
+            }
+            if (paper.getInspectLevel() != null) {
+                paperDTO.setInspectLevel(paper.getInspectLevel());
+            }
+            paperDTO.setStage(markSubject.getStage());
+            paperDTO.setTest(markSubject.getTest());
+            paperDTO.setPaperTest(paper.getTest());
+            paperDTO.setShift(paper.isShift());
+            paperDTO.setShiftScore(paper.isShiftScore());
+            paperDTO.setRoughOneClick(paper.isRoughOneClick());
+            paperDTO.setOneClick(paper.isOneClick());
+            paperDTO.setIsRejectedByLeader(paper.isRejectedByLeader() != null && paper.isRejectedByLeader());
+            paperDTO.setScanUserId(paper.getScanUserId());
+            paperDTO.setMark(paper.isMark());
+            paperDTO.setAdminMark(paper.isAdminMark());
+            //打回总次数
+            int rejectedCount = markLogRepo.countByWorkIdAndPaperIdAndOperType(paper.getWorkId(), paper.getId(), MarkLogOperType.CALLBACK_LEVEl.getId());
+            paperDTO.setRejectedCount(rejectedCount);
+            paperDTO.setSortSum(paper.getSortNum());
+            ChangeLevel changeLevel = changeLevelRepo.findByWorkIdAndSubjectAndPaperIdAndAuditStatusAndStageAndRoleAndIsCurr(paper.getWorkId(), paper.getSubject().name(), markSubject.getStage(), Role.INSPECTION, paper.getId());
+            paperDTO.setOriginLevel(changeLevel != null ? changeLevel.getOriginalLevel() : "");
+        }
+        return paperDTO;
+    }
+
     public PaperDTO toDTO(Paper paper, Long userId) {
 
         String imgSrc = null;

+ 2 - 2
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/QuestionStatAssembler.java

@@ -74,13 +74,13 @@ public class QuestionStatAssembler {
             rejectCount = markTaskRoughLevelRepo.findByWorkIdAndSubjectAndMarkerIdAndStageReject(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.ROUGH_LEVEL.ordinal());
         } else if (MarkStage.LEVEL.equals(stage)) {
             // 改粗档,打细档
-            shift = markTaskRoughLevelRepo.countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.ROUGH_LEVEL.ordinal());
+            shift = markTaskRoughLevelRepo.countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.LEVEL.ordinal());
             shiftScore = markTaskLevelRepo.countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftScoreAndResult(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.LEVEL.ordinal());
             //所有打回
             rejectCount = markTaskLevelRepo.findByWorkIdAndSubjectAndMarkerIdAndStageReject(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.LEVEL.ordinal());
         } else if (MarkStage.SCORE.equals(stage)) {
             // 打细档,打分
-            shift = markTaskLevelRepo.countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.LEVEL.ordinal());
+            shift = markTaskLevelRepo.countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftAndResult(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.SCORE.ordinal());
             shiftScore = markTaskScoreRepo.countByWorkIdAndSubjectAndMarkerIdAndStageAndShiftScoreAndResult(workId, subject.name(), Long.valueOf(qStats[0].toString()), MarkStage.SCORE.ordinal());
         }
 

+ 35 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/MarkTaskBatchNoDTO.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.stmms.ms.marking.dto;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 批次号
+ */
+public class MarkTaskBatchNoDTO implements Serializable{
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long batchNo;
+
+    // 显示批次号(年月日时分:2409101022)
+    private String batchNoDisplay;
+
+    public Long getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(Long batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    public String getBatchNoDisplay() {
+        return batchNoDisplay;
+    }
+
+    public void setBatchNoDisplay(String batchNoDisplay) {
+        this.batchNoDisplay = batchNoDisplay;
+    }
+}

+ 82 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/PaperCheckExportDTO.java

@@ -0,0 +1,82 @@
+package cn.com.qmth.stmms.ms.marking.dto;
+
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelProperty;
+
+/**
+ * 试卷抽查结果导出
+ */
+public class PaperCheckExportDTO {
+
+    @ExcelProperty(name = "序号", index = 0, type = 1)
+    private Integer sequence;
+    @ExcelProperty(name = "科目", index = 1, type = 1)
+    private String subjectName;
+    @ExcelProperty(name = "考号", width = 80, index = 2, type = 1)
+    private String examNumber;
+
+    @ExcelProperty(name = "试卷密号", index = 3, type = 1)
+    private String secretNumber;
+
+    @ExcelProperty(name = "原档位", index = 4, type = 1)
+    private String originLevel;
+    @ExcelProperty(name = "改后档位", index = 5, type = 1)
+    private String level;
+    @ExcelProperty(name = "是否有变更", index = 6, type = 1)
+    private String updateLevel;
+
+    public Integer getSequence() {
+        return sequence;
+    }
+
+    public void setSequence(Integer sequence) {
+        this.sequence = sequence;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public String getOriginLevel() {
+        return originLevel;
+    }
+
+    public void setOriginLevel(String originLevel) {
+        this.originLevel = originLevel;
+    }
+
+    public String getLevel() {
+        return level;
+    }
+
+    public void setLevel(String level) {
+        this.level = level;
+    }
+
+    public String getUpdateLevel() {
+        return updateLevel;
+    }
+
+    public void setUpdateLevel(String updateLevel) {
+        this.updateLevel = updateLevel;
+    }
+}

+ 21 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/PaperCheckImportStudentDTO.java

@@ -0,0 +1,21 @@
+package cn.com.qmth.stmms.ms.marking.dto;
+
+import cn.com.qmth.stmms.ms.commons.utils.excel.ExcelProperty;
+
+import java.io.Serializable;
+
+public class PaperCheckImportStudentDTO implements Serializable {
+
+    private static final long serialVersionUID = -4556126416794102992L;
+
+    @ExcelProperty(index = 1, name = "准考证号", type = 2)
+    private String examNumber;
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+}

+ 45 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/PaperCheckSelectInfoDTO.java

@@ -0,0 +1,45 @@
+package cn.com.qmth.stmms.ms.marking.dto;
+
+import java.io.Serializable;
+
+public class PaperCheckSelectInfoDTO implements Serializable {
+
+    private static final long serialVersionUID = -4556126416794102992L;
+
+    private Integer pageNumber;
+    private Integer pageSize;
+    private String secretNumber;
+
+    public PaperCheckSelectInfoDTO() {
+    }
+
+    public PaperCheckSelectInfoDTO(Integer pageNumber, String secretNumber) {
+        this.pageNumber = pageNumber;
+        this.secretNumber = secretNumber;
+        this.pageSize = 25;
+    }
+
+    public Integer getPageNumber() {
+        return pageNumber;
+    }
+
+    public void setPageNumber(Integer pageNumber) {
+        this.pageNumber = pageNumber;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+}

+ 67 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/ChangeLevelTaskService.java

@@ -0,0 +1,67 @@
+package cn.com.qmth.stmms.ms.marking.service;
+
+import cn.com.qmth.stmms.ms.commons.lock.LockService;
+import cn.com.qmth.stmms.ms.commons.lock.LockType;
+import cn.com.qmth.stmms.ms.core.domain.ChangeLevelTask;
+import cn.com.qmth.stmms.ms.core.domain.MarkStage;
+import cn.com.qmth.stmms.ms.core.repository.ChangeLevelTaskRepo;
+import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class ChangeLevelTaskService {
+
+    @Resource
+    private ChangeLevelTaskRepo changeLevelTaskRepo;
+    @Resource
+    private PaperRepo paperRepo;
+    @Resource
+    private LockService lockService;
+
+
+    @Transactional
+    public Map confirmTask(Long changeLevelTaskId) {
+        ChangeLevelTask changeLevelTask = changeLevelTaskRepo.findOne(changeLevelTaskId);
+        if (changeLevelTask == null) {
+            throw new RuntimeException("改档确认任务不存在");
+        }
+        Boolean status;
+        try {
+            lockService.waitlock(LockType.PAPER, changeLevelTask.getPaper().getId());
+            status = this.confirm(changeLevelTask);
+        } catch (Exception e) {
+            throw new RuntimeException("改档确认任务异常");
+        } finally {
+            lockService.unlock(LockType.PAPER, changeLevelTask.getPaper().getId());
+        }
+        Map map = new HashMap<>();
+        map.put("status", status);
+        map.put("hasSelfTask", false);
+        return map;
+    }
+
+    @Transactional
+    public boolean confirm(ChangeLevelTask changeLevelTask) {
+        changeLevelTask.setConfirmChangeStage(true);
+        changeLevelTask.setConfirmOn(new Date());
+        changeLevelTaskRepo.saveAndFlush(changeLevelTask);
+
+        // 确认改档,只修改试卷最终档位,不改变评卷员已评档位值
+        if (MarkStage.LEVEL.equals(changeLevelTask.getStage())) {
+            if (changeLevelTaskRepo.countByPaperIdAndSubjectAndStageAndConfirmChangeStage(changeLevelTask.getPaper().getId(), changeLevelTask.getSubject(), changeLevelTask.getStage(), false) == 0) {
+                paperRepo.updateRoughLevelById(changeLevelTask.getPaper().getId(), changeLevelTask.getResult());
+            }
+        } else if (MarkStage.SCORE.equals(changeLevelTask.getStage())) {
+            if (changeLevelTaskRepo.countByPaperIdAndSubjectAndStageAndConfirmChangeStage(changeLevelTask.getPaper().getId(), changeLevelTask.getSubject(), changeLevelTask.getStage(), false) == 0) {
+                paperRepo.updateLevelByIdAndShift(changeLevelTask.getPaper().getId(), changeLevelTask.getResult());
+            }
+        }
+        return true;
+    }
+}

+ 4 - 3
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkLogService.java

@@ -106,10 +106,12 @@ public class MarkLogService {
                     markLogOperType = MarkLogOperType.LEVEL;
                 }
             }
+            operDateBefore = markTask.getOriginLevel();
         } else {
             markLogOperType = MarkLogOperType.ONCE_LEVEl;
+            operDateBefore = markTask.getResult();
         }
-        operDateBefore = markTask.getOriginLevel();
+
         operDateAfter = levelCode;
         return new MarkLog(markTask.getWorkId(), work.getName(), paper.getId(), markTask.getSubject(), stage, markTask.getTest(), paper.getExamNumber(), paper.getStudentName(), markTask.getMarkerId(), markTask.getMarkerName(), Role.MARKER, markLogOperType.getId(),markLogOperType.getName(), Optional.ofNullable(operDateBefore).orElse("-"), Optional.ofNullable(operDateAfter).orElse("-"), null, new Date());
     }
@@ -154,9 +156,8 @@ public class MarkLogService {
      * @param level    档位
      * @param isSample 是否标准卷
      */
-    public MarkLog markingPaper(MarkStage stage, Paper paper, String level, boolean isSample) {
+    public MarkLog markingPaper(MarkStage stage, Paper paper, String level, boolean isSample, Long userId) {
         Work work = workRepo.findOne(paper.getWorkId());
-        Long userId = ServletUtil.getUserId();
         MarkUser markUser = markUserRepo.findOne(userId);
         MarkLogOperType markLogOperType;
         String operDateBefore;

+ 11 - 10
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkTaskLevelService.java

@@ -5,10 +5,7 @@ import cn.com.qmth.stmms.ms.commons.lock.LockType;
 import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
 import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
-import cn.com.qmth.stmms.ms.core.domain.ExamQuestion;
-import cn.com.qmth.stmms.ms.core.domain.MarkStage;
-import cn.com.qmth.stmms.ms.core.domain.MarkSubject;
-import cn.com.qmth.stmms.ms.core.domain.Paper;
+import cn.com.qmth.stmms.ms.core.domain.*;
 import cn.com.qmth.stmms.ms.core.domain.enums.TrialEnum;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskRoughLevel;
@@ -70,6 +67,8 @@ public class MarkTaskLevelService {
 
     @Resource
     private LockService lockService;
+    @Resource
+    private ChangeLevelTaskRepo changeLevelTaskRepo;
 
     @Resource
     private PaperAssembler paperAssembler;
@@ -243,7 +242,7 @@ public class MarkTaskLevelService {
         return markTaskDTOs;
     }
 
-    public PageableDTO listMarkedTaskLevel(Long workId, Subject subject, Long markerId, Pageable pageable) {
+    public PageableDTO listMarkedTaskLevel(Long workId, Subject subject, Long markerId, Long batchNo, Pageable pageable) {
         MarkUser markUser = markUserRepo.findOne(markerId);
         if (Role.MARKER.equals(markUser.getRole())) {
             List<PaperDTO> paperDTOS = new ArrayList<>();
@@ -253,6 +252,7 @@ public class MarkTaskLevelService {
                 predicates.add(builder.equal(root.get("subject"), subject));
                 predicates.add(builder.equal(root.get("stage"), MarkStage.LEVEL));
                 predicates.add(builder.equal(root.get("markerId"), markerId));
+                predicates.add(builder.equal(root.get("batchNo"), batchNo));
                 predicates.add(builder.equal(root.get("isMark"), true));
                 return builder.and(predicates.toArray(new Predicate[0]));
             };
@@ -266,6 +266,7 @@ public class MarkTaskLevelService {
                 List<Predicate> predicates = new ArrayList<>();
                 predicates.add(builder.equal(root.get("workId"), workId));
                 predicates.add(builder.equal(root.get("subject"), subject));
+                predicates.add(builder.equal(root.get("batchNo"), batchNo));
                 predicates.add(builder.equal(root.get("isMark"), true));
                 return builder.and(predicates.toArray(new Predicate[0]));
             };
@@ -285,19 +286,19 @@ public class MarkTaskLevelService {
     public PageableDTO shiftLevel(Long markerId, Long workId, Boolean isShift, Boolean isShiftScore, Long questionId, Pageable pageable) {
         List<MarkTaskDTO> markTaskDTOs = new ArrayList<>();
         if (isShift) {
-            Specification<MarkTaskRoughLevel> specification = (root, query, builder) -> {
+            Specification<ChangeLevelTask> specification = (root, query, builder) -> {
                 List<Predicate> predicates = new ArrayList<>();
                 predicates.add(builder.equal(root.get("questionId"), questionId));
                 predicates.add(builder.equal(root.get("markerId"), markerId));
                 //查询
                 predicates.add(builder.equal(root.get("paper").get("isShift"), isShift));
-                predicates.add(builder.equal(root.get("stage"), MarkStage.ROUGH_LEVEL));
-                predicates.add(builder.isNull(root.get("result")));
+                predicates.add(builder.equal(root.get("stage"), MarkStage.LEVEL));
+                predicates.add(builder.equal(root.get("confirmChangeStage"), false));
                 return builder.and(predicates.toArray(new Predicate[predicates.size()]));
             };
-            Sort sort = new Sort("paper.level", "serialNumber", "randomSeq");
+            Sort sort = new Sort("paper.level", "paper.secretNumber", "paper.randomSeq");
             Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
-            Page<MarkTaskRoughLevel> markTasks = markTaskRoughLevelRepo.findAll(specification, pageable1);
+            Page<ChangeLevelTask> markTasks = changeLevelTaskRepo.findAll(specification, pageable1);
 
             markTasks.getContent().forEach(m -> markTaskDTOs.add(markTaskRoughLevelAssembler.toShiftDTO(m)));
             return new PageableDTO(markTaskDTOs, markTasks.getTotalElements(), markTasks.getTotalPages(), pageable.getPageNumber());

+ 5 - 4
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkTaskRoughLevelService.java

@@ -10,7 +10,6 @@ import cn.com.qmth.stmms.ms.core.domain.MarkStage;
 import cn.com.qmth.stmms.ms.core.domain.MarkSubject;
 import cn.com.qmth.stmms.ms.core.domain.Paper;
 import cn.com.qmth.stmms.ms.core.domain.enums.TrialEnum;
-import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskRoughLevel;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.domain.user.Role;
@@ -227,9 +226,9 @@ public class MarkTaskRoughLevelService {
         return markTaskDTOs;
     }
 
-    public PageableDTO listMarkedTaskLevel(Long workId, Subject subject, Long markerId, Pageable pageable) {
+    public PageableDTO listMarkedTaskLevel(Long workId, Subject subject, Long markerId, Long batchNo, Pageable pageable) {
         MarkUser markUser = markUserRepo.findOne(markerId);
-        if(Role.MARKER.equals(markUser.getRole())) {
+        if (Role.MARKER.equals(markUser.getRole())) {
             List<PaperDTO> paperDTOS = new ArrayList<>();
             Specification<MarkTaskRoughLevel> specification = (root, query, builder) -> {
                 List<Predicate> predicates = new ArrayList<>();
@@ -237,6 +236,7 @@ public class MarkTaskRoughLevelService {
                 predicates.add(builder.equal(root.get("subject"), subject));
                 predicates.add(builder.equal(root.get("stage"), MarkStage.ROUGH_LEVEL));
                 predicates.add(builder.equal(root.get("markerId"), markerId));
+                predicates.add(builder.equal(root.get("batchNo"), batchNo));
                 predicates.add(builder.equal(root.get("isMark"), true));
                 return builder.and(predicates.toArray(new Predicate[0]));
             };
@@ -244,12 +244,13 @@ public class MarkTaskRoughLevelService {
 
             markTasks.getContent().forEach(m -> paperDTOS.add(paperAssembler.toDTO(m.getPaper())));
             return new PageableDTO(paperDTOS, markTasks.getTotalElements(), markTasks.getTotalPages(), pageable.getPageNumber());
-        } else if(Role.MARK_LEADER.equals(markUser.getRole())){
+        } else if (Role.MARK_LEADER.equals(markUser.getRole())) {
             List<PaperDTO> paperDTOS = new ArrayList<>();
             Specification<Paper> specification = (root, query, builder) -> {
                 List<Predicate> predicates = new ArrayList<>();
                 predicates.add(builder.equal(root.get("workId"), workId));
                 predicates.add(builder.equal(root.get("subject"), subject));
+                predicates.add(builder.equal(root.get("roughBatchNo"), batchNo));
                 predicates.add(builder.equal(root.get("isMark"), true));
                 return builder.and(predicates.toArray(new Predicate[0]));
             };

+ 10 - 12
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkTaskScoreService.java

@@ -5,10 +5,7 @@ import cn.com.qmth.stmms.ms.commons.lock.LockType;
 import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
 import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
-import cn.com.qmth.stmms.ms.core.domain.ExamQuestion;
-import cn.com.qmth.stmms.ms.core.domain.MarkStage;
-import cn.com.qmth.stmms.ms.core.domain.MarkSubject;
-import cn.com.qmth.stmms.ms.core.domain.Paper;
+import cn.com.qmth.stmms.ms.core.domain.*;
 import cn.com.qmth.stmms.ms.core.domain.enums.TrialEnum;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskScore;
@@ -52,7 +49,7 @@ public class MarkTaskScoreService {
     private MarkSubjectRepo markSubjectRepo;
 
     @Resource
-    private MarkTaskLevelRepo markTaskLevelRepo;
+    private ChangeLevelTaskRepo changeLevelTaskRepo;
 
     @Resource
     private MarkTaskScoreRepo markTaskScoreRepo;
@@ -211,7 +208,7 @@ public class MarkTaskScoreService {
         return markTaskDTOs;
     }
 
-    public PageableDTO listMarkedTaskScore(Long workId, Subject subject, Long markerId, Pageable pageable) {
+    public PageableDTO listMarkedTaskScore(Long workId, Subject subject, Long markerId, Long batchNo, Pageable pageable) {
         MarkUser markUser = markUserRepo.findOne(markerId);
         if (Role.MARKER.equals(markUser.getRole())) {
             List<PaperDTO> paperDTOS = new ArrayList<>();
@@ -221,6 +218,7 @@ public class MarkTaskScoreService {
                 predicates.add(builder.equal(root.get("subject"), subject));
                 predicates.add(builder.equal(root.get("stage"), MarkStage.SCORE));
                 predicates.add(builder.equal(root.get("markerId"), markerId));
+                predicates.add(builder.equal(root.get("batchNo"), batchNo));
                 predicates.add(builder.equal(root.get("isMark"), true));
                 return builder.and(predicates.toArray(new Predicate[0]));
             };
@@ -234,6 +232,7 @@ public class MarkTaskScoreService {
                 List<Predicate> predicates = new ArrayList<>();
                 predicates.add(builder.equal(root.get("workId"), workId));
                 predicates.add(builder.equal(root.get("subject"), subject));
+                predicates.add(builder.equal(root.get("scoreBatchNo"), batchNo));
                 predicates.add(builder.equal(root.get("isMark"), true));
                 return builder.and(predicates.toArray(new Predicate[0]));
             };
@@ -253,20 +252,19 @@ public class MarkTaskScoreService {
     public PageableDTO shiftScore(Long markerId, Long workId, Boolean isShift, Boolean isShiftScore, Long questionId, Pageable pageable) {
         if (isShift) {
             List<MarkTaskDTO> markTaskDTOs = new ArrayList<>();
-            Specification<MarkTaskLevel> specification = (root, query, builder) -> {
+            Specification<ChangeLevelTask> specification = (root, query, builder) -> {
                 List<Predicate> predicates = new ArrayList<>();
                 predicates.add(builder.equal(root.get("questionId"), questionId));
                 predicates.add(builder.equal(root.get("markerId"), markerId));
                 //查询
                 predicates.add(builder.equal(root.get("paper").get("isShift"), isShift));
-                predicates.add(builder.equal(root.get("stage"), MarkStage.LEVEL));
-                predicates.add(builder.isNull(root.get("result")));
+                predicates.add(builder.equal(root.get("stage"), MarkStage.SCORE));
+                predicates.add(builder.equal(root.get("confirmChangeStage"), false));
                 return builder.and(predicates.toArray(new Predicate[predicates.size()]));
             };
-            Sort sort = new Sort("paper.level", "serialNumber", "randomSeq");
+            Sort sort = new Sort("paper.level", "paper.secretNumber", "paper.randomSeq");
             Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
-            Page<MarkTaskLevel> markTasks = markTaskLevelRepo.findAll(specification, pageable1);
-
+            Page<ChangeLevelTask> markTasks = changeLevelTaskRepo.findAll(specification, pageable1);
             markTasks.getContent().forEach(m -> markTaskDTOs.add(markTaskLevelAssembler.toShiftDTO(m)));
             return new PageableDTO(markTaskDTOs, markTasks.getTotalElements(), markTasks.getTotalPages(), pageable.getPageNumber());
         } else if (isShiftScore) {

+ 6 - 3
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingLevelService.java

@@ -2,6 +2,7 @@ package cn.com.qmth.stmms.ms.marking.service;
 
 import cn.com.qmth.stmms.ms.commons.constant.ArbitrateCallback;
 import cn.com.qmth.stmms.ms.commons.constant.ArbitrateResult;
+import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
 import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.*;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskLevel;
@@ -139,7 +140,7 @@ public class MarkingLevelService {
                 paper.setRejectedByLeader(true);
                 //需要打回的评卷员
                 String ranges = String.join(",", determine.getRejectTasks());
-                markingLevelService.rejectFalse(paper, null, ranges, true, true, null);
+                markingLevelService.rejectFalse(paper, null, ranges, true, true, -1l);
             }
 
             // 若开启了粗分档,细分档改档时,对应更新粗分档档位值,与细分档的匹配
@@ -267,11 +268,12 @@ public class MarkingLevelService {
     @Transactional
     public Paper levelMarkPaper(Paper paper, String level, boolean isSample) {
         List<Level> levels = levelRepo.findByWorkId(paper.getWorkId());
-
-        MarkLog markLog = markLogService.markingPaper(MarkStage.LEVEL, paper, level, isSample);
+        Long userId = ServletUtil.getUserId();
+        MarkLog markLog = markLogService.markingPaper(MarkStage.LEVEL, paper, level, isSample, userId);
 
         paper.determineLevel(level);
         paper.setMarkByLeader(true);
+        paper.setMarkLeaderId(userId);
         paper.setSample(isSample);
 
         List<MarkTaskLevel> markTasks = markTaskLevelRepo.findByPaperId(paper.getId());
@@ -328,6 +330,7 @@ public class MarkingLevelService {
         //科组长打回标记
         paper.setRejectedByLeader(true);
         paper.setMarkByLeader(false);
+        paper.setMarkLeaderId(rejectKzzId);
         //打回后撤销标准卷
         paper.setSample(false);
         paper.setArbitrated(false);

+ 7 - 3
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingRoughLevelService.java

@@ -2,6 +2,7 @@ package cn.com.qmth.stmms.ms.marking.service;
 
 import cn.com.qmth.stmms.ms.commons.constant.ArbitrateCallback;
 import cn.com.qmth.stmms.ms.commons.constant.ArbitrateResult;
+import cn.com.qmth.stmms.ms.commons.utils.ServletUtil;
 import cn.com.qmth.stmms.ms.core.domain.*;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTaskRoughLevel;
 import cn.com.qmth.stmms.ms.core.domain.user.Role;
@@ -15,6 +16,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.security.cert.PKIXParameters;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -129,7 +131,7 @@ public class MarkingRoughLevelService {
                 paper.setRejectedByLeader(true);
                 //需要打回的评卷员
                 String ranges = String.join(",", determine.getRejectTasks());
-                markingRoughLevelService.reject(paper, null, ranges, true, true, null);
+                markingRoughLevelService.reject(paper, null, ranges, true, true, -1l);
             }
             //改档后重新分档,状态改为false
             paper.setShift(false);
@@ -232,11 +234,12 @@ public class MarkingRoughLevelService {
     @Transactional
     public Paper levelMarkPaper(Paper paper, String level, boolean isSample) {
         List<Level> levels = levelRepo.findByWorkId(paper.getWorkId());
-
-        MarkLog markLog = markLogService.markingPaper(MarkStage.ROUGH_LEVEL, paper, level, isSample);
+        Long userId = ServletUtil.getUserId();
+        MarkLog markLog = markLogService.markingPaper(MarkStage.ROUGH_LEVEL, paper, level, isSample ,userId);
 
         paper.determineRoughLevel(level);
         paper.setMarkByLeader(true);
+        paper.setRoughMarkLeaderId(userId);
         paper.setRoughSample(isSample);
 
         List<MarkTaskRoughLevel> markTasks = markTaskRoughLevelRepo.findByPaperId(paper.getId());
@@ -271,6 +274,7 @@ public class MarkingRoughLevelService {
         //科组长打回标记
         paper.setRejectedByLeader(true);
         paper.setMarkByLeader(true);
+        paper.setRoughMarkLeaderId(rejectKzzId);
         //打回后撤销标准卷
         paper.setRoughSample(false);
         paper.setArbitrated(false);

+ 4 - 1
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingScoreService.java

@@ -15,6 +15,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 
 /**
@@ -97,9 +99,10 @@ public class MarkingScoreService {
             }
 
             OptionalDouble finalScore = markTasks.stream().map(MarkTaskScore::getResult).mapToInt(Integer::valueOf).average();
+            // 分数处理方式(0:非零进一(取整),1:四舍五入(取整),2:保留两位小数)
             //湖北省,平均分非零进一
             Integer roundUp = Optional.ofNullable(ParamCache.scoreConfigMap.get(String.valueOf(markTask.getWorkId())).getRoundUp()).orElse(1);
-            double fs = roundUp == 0 ? Math.ceil(finalScore.orElse(0)) : Math.round(finalScore.orElse(0));
+            double fs = roundUp == 0 ? Math.ceil(finalScore.orElse(0)) : roundUp == 2 ? new BigDecimal(finalScore.orElse(0)).setScale(2, RoundingMode.HALF_UP).doubleValue() : Math.round(finalScore.orElse(0));
             paper.setScore(fs);
             //改档打分完成,更新状态为false
             paper.setShiftScore(false);

+ 16 - 5
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingService.java

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.ms.marking.service;
 import cn.com.qmth.stmms.ms.commons.constant.ArbitrateCallback;
 import cn.com.qmth.stmms.ms.core.cache.CacheService;
 import cn.com.qmth.stmms.ms.core.domain.ChangeLevel;
+import cn.com.qmth.stmms.ms.core.domain.ChangeLevelTask;
 import cn.com.qmth.stmms.ms.core.domain.MarkStage;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.domain.user.Role;
@@ -20,7 +21,6 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -73,12 +73,18 @@ public class MarkingService {
 
     @Resource
     private MarkTaskScoreRepo markTaskScoreRepo;
+    @Resource
+    private ChangeLevelTaskRepo changeLevelTaskRepo;
 
     @Resource
     MarkerGroupStudentRepo markerGroupStudentRepo;
 
     @Resource
     MarkTaskSelfCheckService markTaskSelfCheckService;
+    @Resource
+    private PaperCheckRepo paperCheckRepo;
+    @Resource
+    private PaperCheckStudentRepo paperCheckStudentRepo;
 
     @Transactional
     public void subjectReset(Long workId, Subject subject, MarkStage stage) {
@@ -105,9 +111,9 @@ public class MarkingService {
             Map<Long, List<ChangeLevel>> changeLevelCollects = changeLevels.stream().collect(Collectors.groupingBy(ChangeLevel::getPaperId));
             for (Map.Entry<Long, List<ChangeLevel>> entry : changeLevelCollects.entrySet()) {
                 List<ChangeLevel> changeLevelsList = entry.getValue();
-                if(!changeLevelsList.isEmpty()){
+                if (!changeLevelsList.isEmpty()) {
                     changeLevelsList.sort(Comparator.comparing(ChangeLevel::getCreateDate).reversed());
-                    ChangeLevel changeLevel =changeLevelsList.get(0);
+                    ChangeLevel changeLevel = changeLevelsList.get(0);
                     paperRepo.updateRoughLevelById(changeLevel.getPaperId(), changeLevel.getOriginalLevel());
                 }
             }
@@ -118,10 +124,15 @@ public class MarkingService {
         else if (MarkStage.SCORE.equals(stage)) {
             // 删除mark_task阶段数据
             markTaskScoreRepo.deleteByWorkIdAndSubject(workId, subject);
+            // 清除change_level_task数据
+            changeLevelTaskRepo.deleteByWorkIdAndSubjectAndStage(workId, subject.name(), stage);
             // 清除paper中的分数
             paperRepo.updateScoreByWorkIdAndSubject(workId, subject.name());
             // 删除task_publish_setting数据
             taskPublishSettingRepo.deleteByWorkIdAndSubject(workId, subject.name());
+            // 删除试卷抽查数据
+            paperCheckRepo.deleteByWorkIdAndSubjectAndStage(workId, subject.name(), stage);
+            paperCheckStudentRepo.deleteByWorkIdAndSubjectAndStage(workId, subject.name(), stage);
             //初始化打分任务数据
             assignTaskService.initTaskPublishData(workId, subject.name());
             // 还原改档审核同意前的档位(第一步)
@@ -129,9 +140,9 @@ public class MarkingService {
             Map<Long, List<ChangeLevel>> changeLevelCollects = changeLevels.stream().collect(Collectors.groupingBy(ChangeLevel::getPaperId));
             for (Map.Entry<Long, List<ChangeLevel>> entry : changeLevelCollects.entrySet()) {
                 List<ChangeLevel> changeLevelsList = entry.getValue();
-                if(!changeLevelsList.isEmpty()){
+                if (!changeLevelsList.isEmpty()) {
                     changeLevelsList.sort(Comparator.comparing(ChangeLevel::getCreateDate).reversed());
-                    ChangeLevel changeLevel =changeLevelsList.get(0);
+                    ChangeLevel changeLevel = changeLevelsList.get(0);
                     paperRepo.updateLevelById(changeLevel.getPaperId(), changeLevel.getOriginalLevel());
                 }
             }