xiaof 5 жил өмнө
parent
commit
229a180644
35 өөрчлөгдсөн 812 нэмэгдсэн , 94 устгасан
  1. 3 2
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/api/ScoreApi.java
  2. 1 1
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/service/DataUploadService.java
  3. 1 1
      stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/service/TrialService.java
  4. 7 6
      stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java
  5. 2 1
      stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/util/RotateTask.java
  6. 13 0
      stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/config/SystemConfig.java
  7. 4 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/MarkLog.java
  8. 30 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/Paper.java
  9. 20 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/TaskPublishSetting.java
  10. 19 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/task/MarkTask.java
  11. 1 1
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/user/Role.java
  12. 4 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/ExamQuestionRepo.java
  13. 2 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/LevelRepo.java
  14. 2 2
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/MarkTaskRepo.java
  15. 12 1
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperRepo.java
  16. 2 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/StudentRepo.java
  17. 17 0
      stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/TaskPublishSettingRepo.java
  18. 1 1
      stmms-ms-log/src/main/java/cn/com/qmth/stmms/ms/log/aop/MarkLogAop.java
  19. 28 5
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/ChangeLevelApi.java
  20. 14 3
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MakrerApi.java
  21. 26 6
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkSubjectApi.java
  22. 87 23
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkTaskApi.java
  23. 158 10
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/PaperApi.java
  24. 3 1
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/ChangeLevelAssembler.java
  25. 8 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/LevelStatAssembler.java
  26. 5 2
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/MarkTaskAssembler.java
  27. 3 2
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/PaperAssembler.java
  28. 12 4
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/QuestionStatAssembler.java
  29. 9 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/ChangeLevelDTO.java
  30. 116 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/LevelDetailDTO.java
  31. 18 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/LevelStatDTO.java
  32. 10 10
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/MarkQuestionStatDTO.java
  33. 18 0
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/MarkTaskDTO.java
  34. 76 7
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/AssignTaskService.java
  35. 80 5
      stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/StageControlService.java

+ 3 - 2
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/api/ScoreApi.java

@@ -9,6 +9,7 @@ import cn.com.qmth.stmms.ms.commons.config.ImageServerConfig;
 import cn.com.qmth.stmms.ms.commons.utils.MD5Util;
 import cn.com.qmth.stmms.ms.commons.utils.OssUtil;
 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.MarkStage;
 import cn.com.qmth.stmms.ms.core.domain.Paper;
 import cn.com.qmth.stmms.ms.core.domain.Student;
@@ -282,7 +283,7 @@ public class ScoreApi {
                     String watermarkFile = null;
                     String imageMd5 = null;
                     StringJoiner watermarkSj = null;
-                    if (imageConfig.isImageEnc()) {
+                    if (ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
                         Student student = studentRepo.findByWorkIdAndExamNumber(workId, examNumber);
                         imageMd5 = MD5Util.getImageRuleMd5(workId, subject.ordinal(), areaCode, examNumber, student.getId());
 
@@ -316,7 +317,7 @@ public class ScoreApi {
                     String text = new String(txt.getBytes(), Charset.forName("UTF-8"));
 //                    WaterMarkUtils.addWaterMark(imageFile, watermarkFile, text, color, font);
                     try {
-                        if (imageConfig.isImageEnc()) {
+                        if (ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
                             WaterMarkUtils.addTextWatermarkNew(imageMd5, text, "jpg", imageFile, watermarkFile);
                         } else {
                             File watermarkF = WaterMarkUtils.addTextWatermark(text, "jpg", imageFile, watermarkFile);

+ 1 - 1
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/service/DataUploadService.java

@@ -91,7 +91,7 @@ public class DataUploadService {
             if (imageConfig.isCustomSubject()) {
                 subject = Subject.CUSTOM;
             }
-            if (imageConfig.isImageEnc()) {
+            if (ParamCache.paramMap.get(student.getWorkId()).getImageEncrypt() == 1) {
                 //保存裁切原图+文件名加密
                 String imageDir = systemConfig.getImageDir() + File.separator + student.getWorkId() + File.separator + subject
                         + File.separator + student.getAreaCode();

+ 1 - 1
stmms-ms-admin/src/main/java/cn/com/qmth/stmms/ms/admin/service/TrialService.java

@@ -100,7 +100,7 @@ public class TrialService {
                 .collect(Collectors.toList());
         MarkSubject markSubject = markSubjectList.get(0);
         //分配任务
-        stageControlService.goNext(markSubject, 0);
+        stageControlService.goNext(markSubject, 0, null);
         //修改科目test
         markSubject.setTest(TrialEnum.START_TRIAL.getId());
         markSubjectRepo.save(markSubject);

+ 7 - 6
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/api/CollectApi.java

@@ -14,6 +14,7 @@ import cn.com.qmth.stmms.ms.commons.utils.CommandUtil;
 import cn.com.qmth.stmms.ms.commons.utils.FileUtil;
 import cn.com.qmth.stmms.ms.commons.utils.MD5Util;
 import cn.com.qmth.stmms.ms.commons.utils.image.ImageCompression;
+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.enums.TrialEnum;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
@@ -120,7 +121,7 @@ public class CollectApi {
             loginDTO.setUserId(markUser.getId());
             loginDTO.setExamId(activeWork.getId());
             loginDTO.setExamName(activeWork.getName());
-            loginDTO.setImageEnc(imageConfig.isImageEnc());
+            loginDTO.setImageEnc(ParamCache.paramMap.get(activeWork.getId()).getImageEncrypt()  == 1);
         }
         List<CollectSubjectDTO> collectSubjectDTOs = new ArrayList<>();
         activeWork.getSubjects().forEach(s -> {
@@ -212,7 +213,7 @@ public class CollectApi {
         List<CollectStuDTO> list = new ArrayList<>();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
 //        for (CollectStuDTO dto : uploadStudentArray) {
-            Student student = studentRepo.findByWorkIdAndExamNumberAndTest(activeWork.getId(), dto.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
+            Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(activeWork.getId(), dto.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
             if (!dto.isAbsent()) {
                 dataUploadService.savePaper(student, subject, dto.isManual());
             }
@@ -246,7 +247,7 @@ public class CollectApi {
         try {
             inputStream = file.getInputStream();
 //            inputStream = new FileInputStream(srcFile);
-            Student student = studentRepo.findByWorkIdAndExamNumberAndTest(workId, fileName, String.valueOf(TrialEnum.DEFAULT.getId()));
+            Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(workId, fileName, String.valueOf(TrialEnum.DEFAULT.getId()));
             Subject subject = Subject.values()[subjectId - 1];
 
             //保存原图
@@ -318,7 +319,7 @@ public class CollectApi {
         try {
             InputStream inputStream = file.getInputStream();
 //            inputStream = new FileInputStream(srcFile);
-            Student student = studentRepo.findByWorkIdAndExamNumberAndTest(workId, fileName, String.valueOf(TrialEnum.DEFAULT.getId()));
+            Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(workId, fileName, String.valueOf(TrialEnum.DEFAULT.getId()));
             Subject subject = Subject.values()[subjectId - 1];
             //保存裁切原图+文件名加密
             String imageDir = systemConfig.getImageDir() + File.separator + workId + File.separator + subject
@@ -495,7 +496,7 @@ public class CollectApi {
             throw new Exception("file文件格式只能为jpg,jpeg,png");
         }
         InputStream inputStream = file.getInputStream();
-        Student student = studentRepo.findByWorkIdAndExamNumberAndTest(workId, examNumber, String.valueOf(TrialEnum.DEFAULT.getId()));
+        Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(workId, examNumber, String.valueOf(TrialEnum.DEFAULT.getId()));
         if (Objects.isNull(student)) {
             throw new Exception("准考证号与学生不匹配");
         }
@@ -593,7 +594,7 @@ public class CollectApi {
         if (Objects.nonNull(format) && !(format.equalsIgnoreCase(".jpg") || format.equalsIgnoreCase(".jpeg") || format.equalsIgnoreCase(".png"))) {
             throw new Exception("file文件格式只能为jpg,jpeg,png");
         }
-        Student student = studentRepo.findByWorkIdAndExamNumberAndTest(workId, examNumber, String.valueOf(TrialEnum.DEFAULT.getId()));
+        Student student = studentRepo.findByWorkIdAndRelateExamNumberAndTest(workId, examNumber, String.valueOf(TrialEnum.DEFAULT.getId()));
         if (Objects.isNull(student)) {
             throw new Exception("准考证号与学生不匹配");
         }

+ 2 - 1
stmms-ms-collect/src/main/java/cn/com/qmth/stmms/ms/collect/util/RotateTask.java

@@ -8,6 +8,7 @@ import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
 import cn.com.qmth.stmms.ms.commons.utils.MD5Util;
 import cn.com.qmth.stmms.ms.commons.utils.OssUtil;
 import cn.com.qmth.stmms.ms.commons.utils.image.ImageCompression;
+import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.Paper;
 import cn.com.qmth.stmms.ms.core.domain.Student;
 import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
@@ -56,7 +57,7 @@ public class RotateTask implements Runnable {
             String imageNew = null;
             String sliceMD5 = null;
             LOGGER.info("准备生成缩略和裁切旋转图:{}", start);
-            if (imageConfig.isImageEnc()) {
+            if (ParamCache.paramMap.get(paper.getWorkId()).getImageEncrypt() == 1) {
                 try {
                     Student student = studentRepo.findByWorkIdAndExamNumber(paper.getWorkId(), paper.getExamNumber());
                     String imageMd5 = MD5Util.getImageRuleMd5(paper.getWorkId(), paper.getSubject().ordinal(), paper.getAreaCode(), paper.getExamNumber(), student.getId());

+ 13 - 0
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/config/SystemConfig.java

@@ -37,6 +37,11 @@ public class SystemConfig {
      */
     private String watermark;
 
+    /**
+     * 本地文件保存路径
+     */
+    private String localhostPath;
+
     private String path = "/api/file/image/download/";
 
     public String getWatermark() {
@@ -63,6 +68,14 @@ public class SystemConfig {
         this.thumbDir = thumbDir;
     }
 
+    public String getLocalhostPath() {
+        return localhostPath;
+    }
+
+    public void setLocalhostPath(String localhostPath) {
+        this.localhostPath = localhostPath;
+    }
+
     public String getThumbUrl(Long workId, String subject, String areaCode, String examNumber) {
         return imageServerConfig.getImageServer() + "/thumbs/" + String.valueOf(workId) + "/"
                 + subject + "/" + areaCode + "/" + examNumber + ".jpg?random=" + UUID.randomUUID().toString();

+ 4 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/MarkLog.java

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.ms.core.domain;
 import cn.com.qmth.stmms.ms.core.domain.user.Role;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 //import io.swagger.annotations.ApiModelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
@@ -54,6 +55,7 @@ public class MarkLog implements Serializable {
     @Temporal(value = TemporalType.DATE)
     @NotNull
 //    @ApiModelProperty(value = "操作时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
     @NotNull
     private Long workId;
@@ -68,8 +70,10 @@ public class MarkLog implements Serializable {
 //    @ApiModelProperty(value = "阶段", example = "3")
     private MarkStage stage;
 
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date loginTime;
 
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date logoutTime;
 
     public MarkLog() {

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

@@ -132,6 +132,12 @@ public class Paper implements Serializable {
 
     private Long batchNo;
 
+    private Long scoreBatchNo;
+
+    private boolean isShift;
+
+    private boolean isShiftScore;
+
     public int getTest() {
         return test;
     }
@@ -486,4 +492,28 @@ public class Paper implements Serializable {
     public void setBatchNo(Long batchNo) {
         this.batchNo = batchNo;
     }
+
+    public Long getScoreBatchNo() {
+        return scoreBatchNo;
+    }
+
+    public void setScoreBatchNo(Long scoreBatchNo) {
+        this.scoreBatchNo = scoreBatchNo;
+    }
+
+    public boolean isShift() {
+        return isShift;
+    }
+
+    public void setShift(boolean shift) {
+        isShift = shift;
+    }
+
+    public boolean isShiftScore() {
+        return isShiftScore;
+    }
+
+    public void setShiftScore(boolean shiftScore) {
+        isShiftScore = shiftScore;
+    }
 }

+ 20 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/TaskPublishSetting.java

@@ -31,6 +31,10 @@ public class TaskPublishSetting {
 
     private Integer taskCount;
 
+    private Long batchNo;
+
+    private Integer publishCount;
+
     public Long getId() {
         return id;
     }
@@ -110,4 +114,20 @@ public class TaskPublishSetting {
     public void setTaskCount(Integer taskCount) {
         this.taskCount = taskCount;
     }
+
+    public Long getBatchNo() {
+        return batchNo;
+    }
+
+    public void setBatchNo(Long batchNo) {
+        this.batchNo = batchNo;
+    }
+
+    public Integer getPublishCount() {
+        return publishCount;
+    }
+
+    public void setPublishCount(Integer publishCount) {
+        this.publishCount = publishCount;
+    }
 }

+ 19 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/task/MarkTask.java

@@ -88,6 +88,10 @@ public class MarkTask implements Serializable {
     @Column(name = "batch_no")
     private Long batchNo;
 
+    private String serialNumber;
+
+    private Integer displayNumber;
+
     public Long getBatchNo() {
         return batchNo;
     }
@@ -286,4 +290,19 @@ public class MarkTask implements Serializable {
         this.secretNumber = secretNumber;
     }
 
+    public String getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public Integer getDisplayNumber() {
+        return displayNumber;
+    }
+
+    public void setDisplayNumber(Integer displayNumber) {
+        this.displayNumber = displayNumber;
+    }
 }

+ 1 - 1
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/user/Role.java

@@ -4,7 +4,7 @@ package cn.com.qmth.stmms.ms.core.domain.user;
  * Created by zhengmin on 2016/10/9.
  */
 public enum Role {
-    MARKER("评卷员"), MARK_LEADER("科组长"), ADMIN("管理员"), INSPECTOR("复评专家"), INSPECTION("纪检员"), COLLECTOR("采集员"), UPLOAD("图片客户端");
+    MARKER("评卷员"), MARK_LEADER("科组长"), ADMIN("管理员"), INSPECTOR("复评专家"), INSPECTION("纪检员"), COLLECTOR("采集员"), UPLOAD("图片客户端"), QC("质检员");
 
     private String name;
 

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

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.ms.core.repository;
 import cn.com.qmth.stmms.ms.core.domain.ExamQuestion;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 
 import java.util.List;
 
@@ -32,4 +33,7 @@ public interface ExamQuestionRepo extends JpaRepository<ExamQuestion, Long> {
     List<ExamQuestion> findAllByAreaCodeAndSubjectAndWorkId(String areaCode, Subject subject, Long workId);
 
     List<ExamQuestion> findByWorkIdAndSubjectAndTest(Long workId, Subject subject, int test);
+
+    @Query("select distinct s.areaCode, s.areaName from ExamQuestion s where s.workId = ?1")
+    List<Object[]> findByWorkId(Long workId);
 }

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

@@ -21,4 +21,6 @@ public interface LevelRepo extends JpaRepository<Level, Long> {
     List<Level> findByWorkIdAndCodeNotIn(Long workId, List<String> levelList);
 
     long countByWorkIdAndCodeIn(Long workId, List<String> levelList);
+
+    List<Level> findByWorkIdOrderByCode(Long workId);
 }

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

@@ -91,7 +91,7 @@ public interface MarkTaskRepo extends JpaRepository<MarkTask, Long>, JpaSpecific
      * @param stageId
      * @return
      */
-    @Query(value = "SELECT q.`id`,t.`marker_name` markerName,q.`name`,SUM(IF(t.`result` IS NULL,1,0)) leftCount,COUNT(t.question_id) totalCount, SUM(t.is_rejected) rejectedCount,0 changeStage, 0 changeStageScore, q.area_code areaCode " +
+    @Query(value = "SELECT q.`id`,t.`marker_name` markerName,q.`name`,SUM(IF(t.`result` IS NULL,1,0)) leftCount,COUNT(t.question_id) totalCount, SUM(t.is_rejected) rejectedCount, q.area_code areaCode " +
             "FROM mark_task t LEFT OUTER JOIN exam_question q ON t.`question_id` = q.`id` LEFT  JOIN paper p ON t.paper_id = p.id WHERE " +
             "t.work_id = ? and t.subject = ? and t.stage = ? and p.is_missing = false and p.is_test = ?  GROUP BY t.`question_id`, t.`marker_name` ORDER BY q.`id`", nativeQuery = true)
     List<Object[]> listGroupByQuestionAndMarker(Long workId, String name, Integer stageId, int test);
@@ -138,7 +138,7 @@ public interface MarkTaskRepo extends JpaRepository<MarkTask, Long>, JpaSpecific
      *
      * @return
      */
-    @Query(value = "SELECT q.`id`,t.`marker_name` markerName,q.`name`,SUM(IF(t.`result` IS NULL,1,0)) leftCount,COUNT(t.question_id) totalCount,SUM(t.is_rejected) rejectedCount,0 changeStage, 0 changeStageScore, q.area_code areaCode " +
+    @Query(value = "SELECT q.`id`,t.`marker_name` markerName,q.`name`,SUM(IF(t.`result` IS NULL,1,0)) leftCount,COUNT(t.question_id) totalCount,SUM(t.is_rejected) rejectedCount, q.area_code areaCode " +
             "FROM mark_task t LEFT OUTER JOIN exam_question q ON t.`question_id` = q.`id` LEFT  JOIN paper p ON t.paper_id = p.id WHERE " +
             "t.work_id = ? and t.subject = ? and t.stage = ? and p.is_missing = false GROUP BY t.`question_id` ORDER BY q.`id`, t.`marker_name`", nativeQuery = true)
     List<Object[]> listGroupByQuestionAndMarker(Long workId, String name, Integer stageId);

+ 12 - 1
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/PaperRepo.java

@@ -12,6 +12,7 @@ import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * Created by zhengmin on 2016/9/23.
@@ -90,7 +91,9 @@ public interface PaperRepo extends JpaRepository<Paper, Long>, JpaSpecificationE
      */
     @Query(value = "SELECT p.`level`,COUNT(*)," +
             "SUM(IF(p.`is_rejected` = 1, 1, 0))," +
-            "SUM(IF(p.`is_arbitrated` = 1, 1, 0))" +
+            "SUM(IF(p.`is_arbitrated` = 1, 1, 0))," +
+            "SUM(IF(p.`is_shift` = 1, 1, 0))," +
+            "SUM(IF(p.`is_shift_score` = 1, 1, 0))" +
             "FROM paper p " +
             "WHERE p.`question_id` = ? and p.is_missing = false and p.is_test = ? " +
             "GROUP BY p.`level` ORDER BY p.`level`", nativeQuery = true)
@@ -278,5 +281,13 @@ public interface PaperRepo extends JpaRepository<Paper, Long>, JpaSpecificationE
 
     int countByWorkIdAndSubjectAndIsMissingFalseAndTestAndQuestionId(Long workId, Subject subject, int test, Long questionId);
 
+    List<Paper> findByworkIdAndSubjectAndQuestionIdAndTest(Long workId, Subject subject, Long questionId, int test);
+
+    List<Paper> findByWorkIdAndSubjectAndIsMissingFalseAndActiveTrueAndScoreBatchNoIsNull(Long workId, Subject subject, Sort sort);
+
+    int countByWorkIdAndSubjectAndIsArbitratedTrue(Long workId, Subject subject);
+
+    int countByWorkIdAndSubjectAndScoreBatchNoIsNotNullAndScoreIsNull(Long workId, Subject subject);
+
 //    List<Paper> findByWorkIdAndSubjectAndInspectRange(Long workId, Subject subject, Long inspectRange);
 }

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

@@ -17,6 +17,8 @@ public interface StudentRepo extends JpaRepository<Student, Long>, JpaSpecificat
 
     Student findByWorkIdAndExamNumberAndTest(Long workId, String examNumber, String test);
 
+    Student findByWorkIdAndRelateExamNumberAndTest(Long workId, String examNumber, String test);
+
     void deleteByWorkId(Long workId);
 
     List<Student> findByWorkIdAndTest(Long workId, String test);

+ 17 - 0
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/repository/TaskPublishSettingRepo.java

@@ -1,9 +1,26 @@
 package cn.com.qmth.stmms.ms.core.repository;
 
 import cn.com.qmth.stmms.ms.core.domain.TaskPublishSetting;
+import cn.com.qmth.stmms.ms.core.vo.Subject;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+import java.util.Map;
+
 @Repository
 public interface TaskPublishSettingRepo extends JpaRepository<TaskPublishSetting, Long> {
+    List<TaskPublishSetting> findByWorkIdAndSubject(Long workId, String subject);
+
+    @Query(value = "select b.workId, b.subject, a.code,ifnull(b.totalCount,0) totalCount, ifnull(b.successCount,0) successCount, ifnull(b.waitCount,0) waitCount from level a " +
+            "left join (select p.work_id workId, p.subject, p.level, count(1) as totalCount,SUM(IF(p.score is not null, 1, 0)) successCount,SUM(if(p.score is null, 1, 0)) waitCount from paper p " +
+            "where p.work_id = ?1 and p.subject = ?2 and p.is_test = ?3 and p.level is not null and p.is_missing = false and p.is_active = true group by p.work_id, p.subject, p.level) b on a.work_id = b.workId and a.code = b.level  " +
+            "where a.work_id = 32 order by a.code", nativeQuery = true)
+    List<Map> findByWorkIdAndSubjectAndTest(Long workId, String subject, int ordinal);
+
+    @Query("select max(t.publishCount) from TaskPublishSetting t where t.workId = ?1 and t.subject = ?2")
+    int maxPublishCount(Long workId, String subject);
+
+    List<TaskPublishSetting> findByWorkIdAndSubjectAndPublishCount(Long workId, String subject, int maxCount);
 }

+ 1 - 1
stmms-ms-log/src/main/java/cn/com/qmth/stmms/ms/log/aop/MarkLogAop.java

@@ -231,7 +231,7 @@ public class MarkLogAop {
         markLogRepo.save(markLog);
         //20191107wangliang加入仲裁自动打回算法 start
         if (markStage.ordinal() == 1 && paper.isArbitrated()) {
-            if (levelConfig.isAutoCallback()) {//为true则自动打回
+            if (ParamCache.paramMap.get(work.getId()).getAutoCallback() == 1) {//为true则自动打回
                 List<MarkTask> markTasks = markTaskRepo.findByPaperIdAndStage(paper.getId(), markStage);
                 JSONObject js = new JSONObject();
                 js.put("paperId", paper.getId());

+ 28 - 5
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/ChangeLevelApi.java

@@ -6,17 +6,22 @@ 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.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.MarkTask;
 import cn.com.qmth.stmms.ms.core.repository.ChangeLevelRepo;
+import cn.com.qmth.stmms.ms.core.repository.MarkTaskRepo;
 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.ChangeLevelAssembler;
 import cn.com.qmth.stmms.ms.marking.dto.ChangeLevelDTO;
+import cn.com.qmth.stmms.ms.marking.service.MarkingService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 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.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
 
@@ -26,6 +31,7 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/api/changelevel")
@@ -37,9 +43,15 @@ public class ChangeLevelApi {
     @Autowired
     private ChangeLevelRepo changeLevelRepo;
 
+    @Autowired
+    private MarkTaskRepo markTaskRepo;
+
     @Autowired
     private ChangeLevelAssembler changeLevelAssembler;
 
+    @Autowired
+    private MarkingService markingService;
+
     @Autowired
     private SqlUtil sqlUtil;
 
@@ -47,14 +59,14 @@ public class ChangeLevelApi {
      * 查询改档列表
      *
      * @param workId
-     * @param areaCode
+     * @param questionId
      * @param subject
      * @param status
      * @return
      */
     @RequestMapping(value = "/list", method = RequestMethod.GET)
     public PageableDTO changeLevel(@RequestParam(required = false) Long workId,
-                                   @RequestParam(required = false) String areaCode,
+                                   @RequestParam(required = false) Long questionId,
                                    @RequestParam(required = false) String subject,
                                    @RequestParam(required = false) String status,
                                    Pageable pageable) {
@@ -104,8 +116,8 @@ public class ChangeLevelApi {
             if (!StringUtils.isEmpty(workId)) {
                 predicates.add(builder.equal(root.get("workId"), workId));
             }
-            if (!StringUtils.isEmpty(areaCode)) {
-                List<Paper> papers = paperRepo.findByworkIdAndSubjectAndAreaCode(workId, Subject.valueOf(subject), areaCode);
+            if (!StringUtils.isEmpty(questionId)) {
+                List<Paper> papers = paperRepo.findByworkIdAndSubjectAndQuestionIdAndTest(workId, Subject.valueOf(subject), questionId, TrialEnum.DEFAULT.ordinal());
 //                predicates.add(builder.equal(root.get("areaCode"), areaCode));
                 CriteriaBuilder.In<Object> in = builder.in(root.get("paperId"));
                 for (Paper paper : papers) {
@@ -187,12 +199,23 @@ public class ChangeLevelApi {
      * @return
      */
     @RequestMapping(value = "/changeLevelAudit", method = RequestMethod.POST)
+    @Transactional
     public ResponseEntity changeLevelAudit(@RequestParam Long id,
                                            @RequestParam Integer auditStatus) {
         ChangeLevel changeLevel = changeLevelRepo.findOne(id);
         changeLevel.setAuditStatus(auditStatus);
         changeLevelRepo.save(changeLevel);
-
+        //同意
+        if(auditStatus == 1) {
+            Paper paper = paperRepo.findOne(changeLevel.getPaperId());
+            //状态设置
+            paper.setShift(true);
+            paper.setShiftScore(Objects.nonNull(paper.getScore()));
+            List<MarkTask> markTasks = markTaskRepo.findByPaperIdAndStage(paper.getId(), MarkStage.LEVEL);
+            List<String> ranges = markTasks.stream().map(m->m.getMarkerId().toString()).collect(Collectors.toList());
+            markingService.reject(paper, changeLevel.getSuggestLevel(), String.join(",", ranges));
+        }
         return new ResponseEntity(HttpStatus.OK);
     }
+
 }

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

@@ -296,7 +296,7 @@ public class MakrerApi {
 
 
         //考区进度
-        List<Object[]> areas = null;
+        List<Object[]> areas;
         if (markSubject.getStage() == MarkStage.SCORE) {
             areas = markTaskRepo.listGroupByAreaName(workId, markSubject.getSubject().name(), markSubject.getStage().ordinal());
         } else {
@@ -311,8 +311,19 @@ public class MakrerApi {
             objectMap.put("areaProgress", questionStatDTOs);
         }
 
+        //科组长
+        List<MarkUser> markUser = markUserRepo.findByWorkIdAndSubjectAndRole(workId, subject, Role.MARK_LEADER);
+        //仲裁数量
+        int arbitrate = paperRepo.countByWorkIdAndSubjectAndIsArbitratedTrue(workId, subject);
+        if(markUser != null && markUser.size() >0){
+            Map map = new HashMap();
+            map.put("name", markUser.get(0).getName());
+            map.put("arbitrated", arbitrate);
+            objectMap.put("kzz", map);
+        }
+
         //各评卷员评卷进度
-        List<Object[]> qStats = null;
+        List<Object[]> qStats;
         if (markSubject.getStage() == MarkStage.SCORE) {
             qStats = markTaskRepo.listGroupByQuestionAndMarker(workId, markSubject.getSubject().name(), markSubject.getStage().ordinal());
         } else {
@@ -321,7 +332,7 @@ public class MakrerApi {
         if (qStats != null) {
             List<MarkQuestionStatDTO> questionStatDTOs = new ArrayList<>();
             for (Object[] objects : qStats) {
-                MarkQuestionStatDTO dto = questionStatAssembler.toMarkProgressDTO(objects);
+                MarkQuestionStatDTO dto = questionStatAssembler.toMarkProgressDTO(objects, workId, subject);
                 questionStatDTOs.add(dto);
             }
             objectMap.put("markerProgress", questionStatDTOs);

+ 26 - 6
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkSubjectApi.java

@@ -1,9 +1,6 @@
 package cn.com.qmth.stmms.ms.marking.api;
 
-import cn.com.qmth.stmms.ms.core.domain.Level;
-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.user.MarkRight;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkerGroup;
@@ -239,6 +236,19 @@ public class MarkSubjectApi {
         markerGroupRepo.save(domain);
     }
 
+    /**
+     * 是否可以进行打分任务投放
+     *
+     * @param markSubject
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "{markSubject}/canScore", method = RequestMethod.GET)
+    public Boolean canScore(@PathVariable MarkSubject markSubject) {
+        int count = paperRepo.countByWorkIdAndSubjectAndScoreBatchNoIsNotNullAndScoreIsNull(markSubject.getWorkId(), markSubject.getSubject());
+        return count > 0 ? false : true;
+    }
+
     /**
      * 该评卷科目进入下一阶段
      *
@@ -246,8 +256,8 @@ public class MarkSubjectApi {
      * @param taskCount   分配任务数量
      */
     @RequestMapping(value = "{markSubject}", method = RequestMethod.PATCH)
-    public void goNext(@PathVariable MarkSubject markSubject, @RequestParam(value = "taskCount", defaultValue = "0") int taskCount) throws Exception {
-        stageControlService.goNext(markSubject, taskCount);
+    public void goNext(@PathVariable MarkSubject markSubject, @RequestParam(value = "taskCount", defaultValue = "0") int taskCount, List<TaskPublishSetting> taskList) throws Exception {
+        stageControlService.goNext(markSubject, taskCount, taskList);
     }
 
     /**
@@ -260,6 +270,16 @@ public class MarkSubjectApi {
         return stageControlService.progress(markSubject);
     }
 
+    /**
+     * 查询打分进度
+     *
+     * @param markSubject 评卷科目id
+     */
+    @RequestMapping(value = "{markSubject}/scoreProgress", method = RequestMethod.GET)
+    public List scoreProgress(@PathVariable MarkSubject markSubject) {
+        return stageControlService.scoreProgress(markSubject);
+    }
+
     /**
      * 分考区查询分档进度
      *

+ 87 - 23
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/MarkTaskApi.java

@@ -3,15 +3,14 @@ package cn.com.qmth.stmms.ms.marking.api;
 import cn.com.qmth.stmms.ms.commons.config.ScoreConfig;
 import cn.com.qmth.stmms.ms.commons.utils.SqlUtil;
 import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
-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.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.MarkTask;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 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.MarkTaskAssembler;
+import cn.com.qmth.stmms.ms.marking.dto.LevelDetailDTO;
 import cn.com.qmth.stmms.ms.marking.dto.MarkTaskDTO;
 import cn.com.qmth.stmms.ms.marking.service.MarkingService;
 import org.slf4j.Logger;
@@ -24,9 +23,11 @@ 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.orm.jpa.vendor.OpenJpaDialect;
 import org.springframework.web.bind.annotation.*;
 
 import javax.persistence.criteria.Predicate;
+import java.math.BigDecimal;
 import java.util.*;
 
 /**
@@ -62,6 +63,9 @@ public class MarkTaskApi {
     @Autowired
     LevelRepo levelRepo;
 
+    @Autowired
+    MarkSubjectRepo markSubjectRepo;
+
     @Autowired
     SqlUtil sqlUtil;
 
@@ -108,14 +112,15 @@ public class MarkTaskApi {
             predicates.add(builder.equal(root.get("paper").get("isMissing"), false));
             predicates.add(builder.equal(root.get("paper").get("active"), true));
             //过滤考区
-            if(Objects.nonNull(areaCode)){
+            if (Objects.nonNull(areaCode)) {
                 predicates.add(builder.equal(root.get("paper").get("areaCode"), areaCode));
             }
 //            predicates.add(builder.equal(root.get("isActive"), false));
             return builder.and(predicates.toArray(new Predicate[predicates.size()]));
         };
-
-        Page<MarkTask> markTasks = markTaskRepo.findAll(specification, pageable);
+        Sort sort = new Sort("paper.level", "serialNumber", "randomSeq");
+        Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
+        Page<MarkTask> markTasks = markTaskRepo.findAll(specification, pageable1);
 
 
         if (Objects.isNull(markTasks) || markTasks.getContent().size() == 0) {
@@ -137,11 +142,11 @@ public class MarkTaskApi {
             markTaskDTOs.add(markTaskAssembler.toDTO(m));
         });
         if (stage == MarkStage.SCORE && Objects.isNull(level)) {
-            if (Objects.nonNull(scoreConfig) && Objects.nonNull(scoreConfig.getTaskSort()) && Objects.equals("paper", scoreConfig.getTaskSort())) {
-                Collections.sort(markTaskDTOs, Comparator.comparing(MarkTaskDTO::getPaperId));
-            } else {
-                randomSeqNewSort(markTaskDTOs);
-            }
+//            if (Objects.nonNull(scoreConfig) && Objects.nonNull(scoreConfig.getTaskSort()) && Objects.equals("paper", scoreConfig.getTaskSort())) {
+//                Collections.sort(markTaskDTOs, Comparator.comparing(MarkTaskDTO::getPaperId));
+//            } else {
+//                randomSeqNewSort(markTaskDTOs);
+//            }
         } else if (stage == MarkStage.LEVEL && Objects.isNull(level)) {
             randomSeqNewSort(markTaskDTOs);
         }
@@ -211,25 +216,26 @@ public class MarkTaskApi {
 
     /**
      * 已评试卷回显
+     *
      * @param markerId
      * @param stage
      * @param questionId
      * @param areaCode
-     * @param pageable
      * @return
      */
-    @RequestMapping(value = "/reviewPaper",method = RequestMethod.GET)
-    public PageableDTO reviewPaper(@RequestParam Long markerId,
-                            @RequestParam MarkStage stage,
-                            @RequestParam Long questionId,
-                            @RequestParam(required = false) String areaCode,
-                            Pageable pageable) {
+    @RequestMapping(value = "/reviewPaper", method = RequestMethod.GET)
+    public List<MarkTaskDTO> reviewPaper(@RequestParam Long markerId,
+                                   @RequestParam MarkStage stage,
+                                   @RequestParam Long questionId,
+                                   @RequestParam(required = false) String areaCode) {
         List<MarkTaskDTO> markTaskDTOs = new ArrayList<>();
         Sort sort = new Sort(Sort.Direction.DESC, "updatedOn");
-        Pageable pageable1 = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
+        Pageable pageable = new PageRequest(0, 5, sort);
         Specification<MarkTask> specification = (root, query, builder) -> {
             List<Predicate> predicates = new ArrayList<>();
-            predicates.add(builder.equal(root.get("questionId"), questionId));
+            if(Objects.nonNull(questionId)) {
+                predicates.add(builder.equal(root.get("questionId"), questionId));
+            }
             predicates.add(builder.equal(root.get("markerId"), markerId));
             predicates.add(builder.equal(root.get("stage"), stage));
             if (stage == MarkStage.LEVEL) {
@@ -242,17 +248,75 @@ public class MarkTaskApi {
                 predicates.add(builder.isNotNull(root.get("result")));
             }
             //过滤考区
-            if(Objects.nonNull(areaCode)){
+            if (Objects.nonNull(areaCode)) {
                 predicates.add(builder.equal(root.get("paper").get("areaCode"), areaCode));
             }
             return builder.and(predicates.toArray(new Predicate[predicates.size()]));
         };
 
-        Page<MarkTask> markTasks = markTaskRepo.findAll(specification, pageable1);
+        Page<MarkTask> markTasks = markTaskRepo.findAll(specification, pageable);
         markTasks.getContent().forEach(m -> {
             markTaskDTOs.add(markTaskAssembler.toDTO(m));
         });
-        return new PageableDTO(markTaskDTOs, markTasks.getTotalElements(), markTasks.getTotalPages(), pageable.getPageNumber());
+        return markTaskDTOs;
     }
 
+
+    /**
+     * 分档详情
+     *
+     * @param workId
+     * @param subject
+     * @param questionId
+     * @return
+     */
+    @RequestMapping(value = "/levelStatDetail", method = RequestMethod.GET)
+    public List<LevelDetailDTO> levelStatDetail(@RequestParam Long workId,
+                                            @RequestParam Subject subject,
+                                            @RequestParam(required = false) Long questionId) {
+
+        List<Level> levels = levelRepo.findByWorkIdOrderByCode(workId);
+        List<Paper> papers;
+        if (questionId == null) {
+            papers = paperRepo.findByWorkIdAndSubjectAndTest(workId, subject, TrialEnum.DEFAULT.getId());
+        } else {
+            papers = paperRepo.findByworkIdAndSubjectAndQuestionIdAndTest(workId, subject, questionId, TrialEnum.DEFAULT.getId());
+        }
+        MarkSubject markSubject = markSubjectRepo.findOne(workId+"-"+subject.name());
+
+        List<LevelDetailDTO> list = new ArrayList<>();
+        for (Level level : levels) {
+            LevelDetailDTO levelDetailDTO = new LevelDetailDTO();
+            levelDetailDTO.setWorkId(workId);
+            levelDetailDTO.setSubjectName(markSubject.getName());
+            //档位
+            levelDetailDTO.setCode(level.getCode());
+            levelDetailDTO.setMinScore(level.getMinScore());
+            levelDetailDTO.setMaxScore(level.getMaxScore());
+            //数量
+            long count = papers.stream().filter(m-> Objects.nonNull(m.getLevel()) && Objects.equals(level.getCode(), m.getLevel())).count();
+            levelDetailDTO.setLevelCount((int) count);
+            BigDecimal prop = new BigDecimal(String.valueOf(count*100)).divide(new BigDecimal(String.valueOf(papers.size())),2, BigDecimal.ROUND_HALF_UP);
+            //占比
+            levelDetailDTO.setLevelProp(prop.doubleValue());
+            //预设占比
+            levelDetailDTO.setExamLevelProp(level.getPt());
+            //差值
+            BigDecimal diff = prop.subtract(new BigDecimal(String.valueOf(level.getPt())));
+            levelDetailDTO.setDiffProp(diff.doubleValue());
+            //累计数量
+            int sumCount = list.stream().mapToInt(LevelDetailDTO::getLevelCount).sum();
+            levelDetailDTO.setCumulateCount(sumCount + (int) count);
+            //累计占比
+            double sumProp = list.stream().mapToDouble(LevelDetailDTO::getLevelProp).sum();
+            levelDetailDTO.setCumulateProp(sumProp + prop.doubleValue());
+
+            //调整
+            int adjustment = new BigDecimal(String.valueOf(papers.size())).multiply(diff).intValue();
+            levelDetailDTO.setAdjustmentCount(adjustment);
+
+            list.add(levelDetailDTO);
+        }
+        return list;
+    }
 }

+ 158 - 10
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/api/PaperApi.java

@@ -1,10 +1,14 @@
 package cn.com.qmth.stmms.ms.marking.api;
 
+import cn.com.qmth.stmms.ms.commons.config.SystemConfig;
 import cn.com.qmth.stmms.ms.commons.web.PageableDTO;
+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.task.MarkTask;
 import cn.com.qmth.stmms.ms.core.repository.ExamQuestionRepo;
+import cn.com.qmth.stmms.ms.core.repository.MarkSubjectRepo;
 import cn.com.qmth.stmms.ms.core.repository.MarkTaskRepo;
 import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
 import cn.com.qmth.stmms.ms.core.vo.Subject;
@@ -13,6 +17,7 @@ import cn.com.qmth.stmms.ms.marking.assembler.PaperAssembler;
 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.MarkingService;
+import org.apache.commons.codec.digest.DigestUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
@@ -24,8 +29,12 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.persistence.criteria.Predicate;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -46,6 +55,9 @@ public class PaperApi {
     @Autowired
     private MarkTaskRepo markTaskRepo;
 
+    @Autowired
+    private MarkSubjectRepo markSubjectRepo;
+
     @Autowired
     private MarkTaskAssembler markTaskAssembler;
 
@@ -55,6 +67,9 @@ public class PaperApi {
     @Autowired
     ExamQuestionRepo examQuestionRepo;
 
+    @Autowired
+    SystemConfig systemConfig;
+
     /**
      * 单个试卷信息
      *
@@ -292,7 +307,7 @@ public class PaperApi {
      * 考生成绩查询
      *
      * @param workId
-     * @param areaCode
+     * @param questionId
      * @param subject
      * @param number
      * @param studentName
@@ -300,18 +315,18 @@ public class PaperApi {
      */
     @RequestMapping(value = "/studentScore", method = RequestMethod.GET)
     public List<Map> markTasks(@RequestParam Long workId,
-                                 @RequestParam(required = false) String areaCode,
-                                 @RequestParam(required = false) Subject subject,
-                                 @RequestParam(required = false) String type,
-                                 @RequestParam(required = false) String number,
-                                 @RequestParam(required = false) String studentName) {
+                               @RequestParam(required = false) Long questionId,
+                               @RequestParam(required = false) Subject subject,
+                               @RequestParam(required = false) String type,
+                               @RequestParam(required = false) String number,
+                               @RequestParam(required = false) String studentName) {
         Specification<Paper> specification = (root, query, builder) -> {
             List<Predicate> predicates = new ArrayList<>();
             if (!StringUtils.isEmpty(workId)) {
                 predicates.add(builder.equal(root.get("workId"), workId));
             }
-            if (!StringUtils.isEmpty(areaCode)) {
-                predicates.add(builder.equal(root.get("areaCode"), areaCode));
+            if (!StringUtils.isEmpty(questionId)) {
+                predicates.add(builder.equal(root.get("questionId"), questionId));
             }
             if (!StringUtils.isEmpty(subject)) {
                 predicates.add(builder.equal(root.get("subject"), subject));
@@ -341,13 +356,13 @@ public class PaperApi {
         //根据考生分组
         Map<String, List<Paper>> groupPaper = papers.stream().collect(Collectors.groupingBy(p -> p.getExamNumber() + ":" + p.getStudentName()));
         List<Map> mapList = new ArrayList<>();
-        for (Map.Entry<String, List<Paper>> entry :groupPaper.entrySet()) {
+        for (Map.Entry<String, List<Paper>> entry : groupPaper.entrySet()) {
             Map map = new HashMap();
             String key = entry.getKey();
             List<Paper> paperList = entry.getValue();
             map.put("examNumber", key.split(":")[0]);
             map.put("name", key.split(":")[1]);
-            double sumScore = paperList.stream().filter(m->Objects.nonNull(m.getScore())).mapToDouble(Paper::getScore).sum();
+            double sumScore = paperList.stream().filter(m -> Objects.nonNull(m.getScore())).mapToDouble(Paper::getScore).sum();
             map.put("sumScore", Optional.ofNullable(sumScore).orElse(0D).intValue());
             List<PaperDTO> paperDTOs = new ArrayList<>();
             paperList.forEach(p -> paperDTOs.add(paperAssembler.toDTO(p)));
@@ -357,4 +372,137 @@ public class PaperApi {
         return mapList;
     }
 
+    /**
+     * 上传试题列表
+     *
+     * @param workId
+     * @throws Exception
+     */
+    @RequestMapping(value = "/{workId}/listUploadPaper", method = {RequestMethod.GET})
+    public List<Map> uploadPaperFile(@PathVariable Long workId) {
+        List<Object[]> questions = examQuestionRepo.findByWorkId(workId);
+        List<MarkSubject> subjects = markSubjectRepo.findAllByWorkId(workId);
+        List<Map> mapList = new ArrayList<>();
+        for (Object[] question : questions) {
+            Map map = new HashMap();
+            map.put("questionId", question[0]);
+            map.put("questionName", question[1]);
+            List<Map> subjectList = new ArrayList<>();
+            for (MarkSubject subject : subjects) {
+                //科目信息
+                Map subjectMap = new HashMap();
+                subjectMap.put("subject", subject.getSubject().name());
+                subjectMap.put("subjectName", subject.getName());
+                subjectMap.put("enable", subject.isEnable());
+                //上传路径,已有上传,取文件路径,没有为null
+                String subjectUrl = null;
+                String url = systemConfig.getLocalhostPath() + File.separator + workId + File.separator + question[0] + File.separator + subject.getSubject().name();
+                File path = new File(url);
+                if (path.exists()) {
+                    File[] file = path.listFiles();
+                    if (file.length > 0) {
+                        subjectUrl = file[0].getAbsolutePath();
+                    }
+                }
+                subjectMap.put("url", subjectUrl);
+                subjectList.add(subjectMap);
+            }
+            map.put("subjects", subjectList);
+            mapList.add(map);
+        }
+        return mapList;
+    }
+
+
+    /**
+     * 上传试卷
+     *
+     * @param workId
+     * @param questionId
+     * @param subject
+     * @param file
+     * @param request
+     * @param response
+     * @throws Exception
+     */
+    @RequestMapping(value = "/{workId}/{questionId}/{subject}/uploadPaperFile", method = {RequestMethod.POST})
+    public void uploadPaperFile(@PathVariable Long workId,
+                                @PathVariable Long questionId,
+                                @PathVariable Subject subject,
+                                @RequestParam MultipartFile file,
+                                HttpServletRequest request, HttpServletResponse response) throws Exception {
+        if (Objects.isNull(file)) {
+            throw new Exception("file文件不能为空");
+        }
+        int temp = file.getOriginalFilename().indexOf(".");
+        String format = file.getOriginalFilename().substring(temp);
+        if (Objects.nonNull(format) && !(format.equalsIgnoreCase(".jpg")
+                || format.equalsIgnoreCase(".jpeg")
+                || format.equalsIgnoreCase(".png")
+                || format.equalsIgnoreCase(".pdf"))) {
+            throw new Exception("file文件格式只能为jpg,jpeg,png,pdf");
+        }
+        InputStream inputStream = file.getInputStream();
+        //保存原图
+        String savePath = systemConfig.getLocalhostPath() + File.separator + workId + File.separator + questionId + File.separator + subject.name();
+        File fileSave = new File(savePath);
+        if (!fileSave.exists()) {
+            fileSave.mkdirs();
+        }
+        File outSheetFile = new File(savePath + File.separator + DigestUtils.md5Hex(workId + "-" + questionId + "-" + subject.name()) + format);
+        OutputStream outputSheetStream = new FileOutputStream(outSheetFile);
+        int index = 0;
+        byte[] bytes = new byte[1024 * 8];
+        while ((index = inputStream.read(bytes)) != -1) {
+            outputSheetStream.write(bytes, 0, index);
+        }
+        inputStream.close();
+        outputSheetStream.flush();
+        outputSheetStream.close();
+
+        String md5 = request.getHeader("md5");
+        if (Objects.isNull(md5)) {
+            throw new Exception("request的md5为空");
+        }
+        FileInputStream in = new FileInputStream(outSheetFile);
+        String sliceMD5 = DigestUtils.md5Hex(in);
+        if (!md5.equalsIgnoreCase(sliceMD5)) {
+            throw new Exception("图片md5值不一致");
+        }
+        in.close();
+    }
+
+    /**
+     * 查看试题
+     *
+     * @param workId
+     * @throws Exception
+     */
+    @RequestMapping(value = "/{workId}/{subject}/viewUploadPaper", method = {RequestMethod.GET})
+    public List<Map> viewPaperFile(@PathVariable Long workId, @PathVariable Subject subject) {
+        List<ExamQuestion> questions = examQuestionRepo.findByWorkIdAndSubject(workId, subject);
+        List<Map> mapList = new ArrayList<>();
+        for (ExamQuestion question : questions) {
+            Map map = new HashMap();
+            map.put("questionId", question.getAreaCode());
+            map.put("questionName", question.getAreaName());
+            //科目信息
+            MarkSubject markSubject = markSubjectRepo.findOne(workId + "-" + subject.name());
+            map.put("subject", markSubject.getSubject().name());
+            map.put("subjectName", markSubject.getName());
+            //上传路径,已有上传,取文件路径,没有为null
+            String subjectUrl = null;
+            String url = systemConfig.getLocalhostPath() + File.separator + workId + File.separator + question.getAreaCode() + File.separator + markSubject.getSubject().name();
+            File path = new File(url);
+            if (path.exists()) {
+                File[] file = path.listFiles();
+                if (file.length > 0) {
+                    subjectUrl = file[0].getAbsolutePath();
+                }
+            }
+            map.put("url", subjectUrl);
+            mapList.add(map);
+        }
+        return mapList;
+    }
 }

+ 3 - 1
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/ChangeLevelAssembler.java

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.ms.marking.assembler;
 import cn.com.qmth.stmms.ms.commons.config.ImageConfig;
 import cn.com.qmth.stmms.ms.commons.config.SystemConfig;
 import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
+import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.ChangeLevel;
 import cn.com.qmth.stmms.ms.core.domain.Paper;
 import cn.com.qmth.stmms.ms.core.domain.Student;
@@ -50,7 +51,7 @@ public class ChangeLevelAssembler {
             String examNumber = paper.getExamNumber();
             String areaCode = paper.getAreaCode();
             Subject subject = paper.getSubject();
-            if (imageConfig.isImageEnc()) {
+            if (ParamCache.paramMap.get(workId).getImageEncrypt() == 1) {
                 Student student = studentRepo.findByWorkIdAndExamNumberAndTest(workId, examNumber, String.valueOf(TrialEnum.DEFAULT.getId()));
                 imgSrc = systemConfig.getImageUrl(workId, subject.ordinal(), student.getId(), SystemConstant.IMAGE);
                 thumbSrc = systemConfig.getThumbUrl(workId, subject.ordinal(), student.getId(), SystemConstant.THUMB);
@@ -63,6 +64,7 @@ public class ChangeLevelAssembler {
             changeLevelDTO.setSample(paper.isSample());
             changeLevelDTO.setMarkByLeader(paper.isMarkByLeader());
             changeLevelDTO.setPaperId(changeLevel.getPaperId());
+            changeLevelDTO.setAuditStatus(changeLevel.getAuditStatus());
         }
         return changeLevelDTO;
     }

+ 8 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/assembler/LevelStatAssembler.java

@@ -28,6 +28,14 @@ public class LevelStatAssembler {
             	BigDecimal arbitrated =(BigDecimal) levelStats[3];
             	levelStatDTO.setArbitrated(arbitrated.intValue());
             }
+            if(levelStats.length>4){
+                BigDecimal shift =(BigDecimal) levelStats[4];
+                levelStatDTO.setShift(shift.intValue());
+            }
+            if(levelStats.length>5){
+                BigDecimal shiftScore =(BigDecimal) levelStats[5];
+                levelStatDTO.setShiftScore(shiftScore.intValue());
+            }
         }
         return levelStatDTO;
     }

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

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.ms.marking.assembler;
 import cn.com.qmth.stmms.ms.commons.config.ImageConfig;
 import cn.com.qmth.stmms.ms.commons.config.SystemConfig;
 import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
+import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 import cn.com.qmth.stmms.ms.core.domain.MarkStage;
 import cn.com.qmth.stmms.ms.core.domain.Paper;
 import cn.com.qmth.stmms.ms.core.domain.Student;
@@ -50,7 +51,7 @@ public class MarkTaskAssembler {
             markTaskDTO.setRedoLevel(paper.getRedoLevel());
             String imgSrc = null;
             String thumbSrc = null;
-            if (imageConfig.isImageEnc()) {
+            if (ParamCache.paramMap.get(paper.getWorkId()).getImageEncrypt() == 1) {
                 Student student = studentRepo.findByWorkIdAndExamNumberAndTest(paper.getWorkId(), paper.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
                 imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
                 thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);
@@ -67,6 +68,8 @@ public class MarkTaskAssembler {
             markTaskDTO.setRandomSeqNew(markTask.getRandomSeqNew());
             markTaskDTO.setRandomSeq(markTask.getRandomSeq());
             markTaskDTO.setPaperId(paper.getId());
+            markTaskDTO.setSerialNumber(markTask.getSerialNumber());
+            markTaskDTO.setDisplayNumber(markTask.getDisplayNumber());
         }
         return markTaskDTO;
     }
@@ -92,7 +95,7 @@ public class MarkTaskAssembler {
             markTaskDTO.setRedoLevel(paper.getRedoLevel());
             String imgSrc = null;
             String thumbSrc = null;
-            if (imageConfig.isImageEnc()) {
+            if (ParamCache.paramMap.get(paper.getWorkId()).getImageEncrypt() == 1) {
                 Student student = studentRepo.findByWorkIdAndExamNumberAndTest(paper.getWorkId(), paper.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
                 imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
                 thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);

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

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.ms.marking.assembler;
 import cn.com.qmth.stmms.ms.commons.config.ImageConfig;
 import cn.com.qmth.stmms.ms.commons.config.SystemConfig;
 import cn.com.qmth.stmms.ms.commons.constant.SystemConstant;
+import cn.com.qmth.stmms.ms.core.cache.ParamCache;
 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.Student;
@@ -44,7 +45,7 @@ public class PaperAssembler {
     public PaperDTO toDTO(Paper paper) {
         String imgSrc = null;
         String thumbSrc = null;
-        if (imageConfig.isImageEnc()) {
+        if (ParamCache.paramMap.get(paper.getWorkId()).getImageEncrypt() == 1) {
             Student student = studentRepo.findByWorkIdAndExamNumberAndTest(paper.getWorkId(), paper.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
             imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
             thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);
@@ -95,7 +96,7 @@ public class PaperAssembler {
         String imgSrc = null;
         String thumbSrc = null;
         String sheetSrc = null;
-        if (imageConfig.isImageEnc()) {
+        if (ParamCache.paramMap.get(paper.getWorkId()).getImageEncrypt() == 1) {
             Student student = studentRepo.findByWorkIdAndExamNumberAndTest(paper.getWorkId(), paper.getExamNumber(), String.valueOf(TrialEnum.DEFAULT.getId()));
             imgSrc = systemConfig.getImageUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.IMAGE);
             thumbSrc = systemConfig.getThumbUrl(paper.getWorkId(), paper.getSubject().ordinal(), student.getId(), SystemConstant.THUMB);

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

@@ -1,5 +1,7 @@
 package cn.com.qmth.stmms.ms.marking.assembler;
 
+import cn.com.qmth.stmms.ms.core.domain.Paper;
+import cn.com.qmth.stmms.ms.core.vo.Subject;
 import cn.com.qmth.stmms.ms.marking.dto.MarkQuestionStatDTO;
 import cn.com.qmth.stmms.ms.marking.dto.QuestionStatDTO;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -8,6 +10,9 @@ import org.springframework.stereotype.Component;
 import cn.com.qmth.stmms.ms.core.repository.LevelRepo;
 import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * Created by zhengmin on 2016/10/14.
  */
@@ -59,7 +64,10 @@ public class QuestionStatAssembler {
     }
 
 
-    public MarkQuestionStatDTO toMarkProgressDTO(Object[] qStats){
+    public MarkQuestionStatDTO toMarkProgressDTO(Object[] qStats, Long workId, Subject subject){
+        List<Paper> papers = paperRepo.findByWorkIdAndSubject(workId, subject);
+        long shift = papers.stream().filter(m->m.isShift()).count();
+        long shiftScore = papers.stream().filter(m->m.isShiftScore()).count();
         MarkQuestionStatDTO qpDTO = null;
         if(qStats != null){
             qpDTO = new MarkQuestionStatDTO();
@@ -69,9 +77,9 @@ public class QuestionStatAssembler {
             qpDTO.setLeftCount(qStats[3]);
             qpDTO.setTotalCount(qStats[4]);
             qpDTO.setRejectedCount(qStats[5]);
-            qpDTO.setChangeStage(qStats[6]);
-            qpDTO.setChangeStageScore(qStats[7]);
-            qpDTO.setAreaCode(qStats[8]);
+            qpDTO.setShiftCount(shift);
+            qpDTO.setShiftScoreCount(shiftScore);
+            qpDTO.setAreaCode(qStats[6]);
         }
         return qpDTO;
     }

+ 9 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/ChangeLevelDTO.java

@@ -29,6 +29,7 @@ public class ChangeLevelDTO implements Serializable{
     private Long paperId;
     private Long randomSeqNew;
     private Integer randomSeq;
+    private Integer auditStatus;
 
     public Integer getRandomSeq() {
         return randomSeq;
@@ -185,4 +186,12 @@ public class ChangeLevelDTO implements Serializable{
     public void setRandomSeqNew(Long randomSeqNew) {
         this.randomSeqNew = randomSeqNew;
     }
+
+    public Integer getAuditStatus() {
+        return auditStatus;
+    }
+
+    public void setAuditStatus(Integer auditStatus) {
+        this.auditStatus = auditStatus;
+    }
 }

+ 116 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/LevelDetailDTO.java

@@ -0,0 +1,116 @@
+package cn.com.qmth.stmms.ms.marking.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class LevelDetailDTO implements Serializable{
+
+    private Long workId;
+    private String subjectName;
+    private String code;
+    private Integer minScore;
+    private Integer maxScore;
+    private Integer levelCount;
+    private double levelProp;
+    private double examLevelProp;
+    private double diffProp;
+    private Integer cumulateCount;
+    private double cumulateProp;
+    private Integer adjustmentCount;
+
+    public Long getWorkId() {
+        return workId;
+    }
+
+    public void setWorkId(Long workId) {
+        this.workId = workId;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public Integer getMinScore() {
+        return minScore;
+    }
+
+    public void setMinScore(Integer minScore) {
+        this.minScore = minScore;
+    }
+
+    public Integer getMaxScore() {
+        return maxScore;
+    }
+
+    public void setMaxScore(Integer maxScore) {
+        this.maxScore = maxScore;
+    }
+
+    public Integer getLevelCount() {
+        return levelCount;
+    }
+
+    public void setLevelCount(Integer levelCount) {
+        this.levelCount = levelCount;
+    }
+
+    public double getLevelProp() {
+        return levelProp;
+    }
+
+    public void setLevelProp(double levelProp) {
+        this.levelProp = levelProp;
+    }
+
+    public double getExamLevelProp() {
+        return examLevelProp;
+    }
+
+    public void setExamLevelProp(double examLevelProp) {
+        this.examLevelProp = examLevelProp;
+    }
+
+    public double getDiffProp() {
+        return diffProp;
+    }
+
+    public void setDiffProp(double diffProp) {
+        this.diffProp = diffProp;
+    }
+
+    public Integer getCumulateCount() {
+        return cumulateCount;
+    }
+
+    public void setCumulateCount(Integer cumulateCount) {
+        this.cumulateCount = cumulateCount;
+    }
+
+    public double getCumulateProp() {
+        return cumulateProp;
+    }
+
+    public void setCumulateProp(double cumulateProp) {
+        this.cumulateProp = cumulateProp;
+    }
+
+    public Integer getAdjustmentCount() {
+        return adjustmentCount;
+    }
+
+    public void setAdjustmentCount(Integer adjustmentCount) {
+        this.adjustmentCount = adjustmentCount;
+    }
+}

+ 18 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/LevelStatDTO.java

@@ -14,6 +14,8 @@ public class LevelStatDTO implements Serializable {
     private Integer count;//paper总数
     private Integer rejected;
     private Integer arbitrated;
+    private Integer shift;
+    private Integer shiftScore;
     private Double percent;
     /**
      * 占比阈值。percent thredhold,0-100
@@ -111,4 +113,20 @@ public class LevelStatDTO implements Serializable {
     public void setGcount(Integer gcount) {
         this.gcount = gcount;
     }
+
+    public Integer getShift() {
+        return shift;
+    }
+
+    public void setShift(Integer shift) {
+        this.shift = shift;
+    }
+
+    public Integer getShiftScore() {
+        return shiftScore;
+    }
+
+    public void setShiftScore(Integer shiftScore) {
+        this.shiftScore = shiftScore;
+    }
 }

+ 10 - 10
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/MarkQuestionStatDTO.java

@@ -13,8 +13,8 @@ public class MarkQuestionStatDTO implements Serializable {
     private Object leftCount;
     private Object totalCount;
     private Object rejectedCount;
-    private Object changeStage;
-    private Object changeStageScore;
+    private Object shiftCount;
+    private Object shiftScoreCount;
     private Object areaCode;
 
     public Object getId() {
@@ -65,20 +65,20 @@ public class MarkQuestionStatDTO implements Serializable {
         this.rejectedCount = rejectedCount;
     }
 
-    public Object getChangeStage() {
-        return changeStage;
+    public Object getShiftCount() {
+        return shiftCount;
     }
 
-    public void setChangeStage(Object changeStage) {
-        this.changeStage = changeStage;
+    public void setShiftCount(Object shiftCount) {
+        this.shiftCount = shiftCount;
     }
 
-    public Object getChangeStageScore() {
-        return changeStageScore;
+    public Object getShiftScoreCount() {
+        return shiftScoreCount;
     }
 
-    public void setChangeStageScore(Object changeStageScore) {
-        this.changeStageScore = changeStageScore;
+    public void setShiftScoreCount(Object shiftScoreCount) {
+        this.shiftScoreCount = shiftScoreCount;
     }
 
     public Object getAreaCode() {

+ 18 - 0
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/dto/MarkTaskDTO.java

@@ -29,6 +29,8 @@ public class MarkTaskDTO implements Serializable{
     private Long paperId;
     private Long randomSeqNew;
     private Integer randomSeq;
+    private String serialNumber;
+    private Integer displayNumber;
 
     public Integer getRandomSeq() {
         return randomSeq;
@@ -185,4 +187,20 @@ public class MarkTaskDTO implements Serializable{
     public void setRandomSeqNew(Long randomSeqNew) {
         this.randomSeqNew = randomSeqNew;
     }
+
+    public String getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public Integer isDisplayNumber() {
+        return displayNumber;
+    }
+
+    public void setDisplayNumber(Integer displayNumber) {
+        this.displayNumber = displayNumber;
+    }
 }

+ 76 - 7
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/AssignTaskService.java

@@ -1,18 +1,18 @@
 package cn.com.qmth.stmms.ms.marking.service;
 
 import cn.com.qmth.stmms.ms.commons.utils.RandomUtil;
+import cn.com.qmth.stmms.ms.commons.utils.SqlUtil;
 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.TaskPublishSetting;
 import cn.com.qmth.stmms.ms.core.domain.task.MarkTask;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
 import cn.com.qmth.stmms.ms.core.domain.user.MarkerGroup;
-import cn.com.qmth.stmms.ms.core.repository.MarkSubjectRepo;
-import cn.com.qmth.stmms.ms.core.repository.MarkTaskRepo;
-import cn.com.qmth.stmms.ms.core.repository.MarkerGroupRepo;
-import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
+import cn.com.qmth.stmms.ms.core.repository.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -39,11 +39,17 @@ public class AssignTaskService {
     @Autowired
     private MarkerGroupRepo markerGroupRepo;
 
+    @Autowired
+    private TaskPublishSettingRepo taskPublishSettingRepo;
+
     @Value("${sys.config.random-bundle-size}")
     private int randomBundleSize;
 
     @Autowired
     RandomUtil randomUtil;
+    
+    @Autowired
+    SqlUtil sqlUtil;
 
     /**
      * 单评任务模式,每个科目评卷员都需要对该科目每份试卷进行评卷
@@ -103,12 +109,12 @@ public class AssignTaskService {
     /**
      * 分组任务模式,将该科目的评卷员分成N组,将该科目试卷平均分给这些组,每组内的评卷员每人将这些试卷打分
      * 比如:6个评卷员分2组,有1000份试卷,每组评500份,每个评卷员评500份
-     *
-     * @param papers
+     *  @param papers
      * @param markerGroups
+     * @param taskList
      */
     @Transactional
-    public void assignForGrouping(List<Paper> papers, List<MarkerGroup> markerGroups, MarkSubject markSubject) throws Exception {
+    public void assignForGrouping(List<Paper> papers, List<MarkerGroup> markerGroups, MarkSubject markSubject, List<TaskPublishSetting> taskList) throws Exception {
         markerGroups = markerGroups.stream().filter(m -> m.getMarkers().size() > 0).collect(Collectors.toList());
         int sum = markerGroups.stream().mapToInt(m -> m.getMarkers().size()).sum();
         int groupSize = markerGroups.size();
@@ -130,6 +136,10 @@ public class AssignTaskService {
                 if (Objects.equals(MarkStage.SCORE, markSubject.getStage())) {
                     markTask = new MarkTask(marker, paper, markSubject.getStage(), random, markSubject.getTest());
                     markTask.setBatchNo(currentTime);
+                    //是否显示序号
+                    long display = taskList.stream().filter(m->Objects.equals(m.getCode(), paper.getLevel())&& m.getDisplayNumber() == 1).count();
+                    markTask.setSerialNumber(paper.getLevel() + (idx+1));
+                    markTask.setDisplayNumber((int) display);
                 } else {
                     markTask = new MarkTask(marker, paper, markSubject.getStage(), random, markSubject.getTest());
                 }
@@ -148,6 +158,10 @@ public class AssignTaskService {
 //                    markSubject.setFormal(true);
 //                    markSubjectRepo.saveAndFlush(markSubject);
                 }
+                if (MarkStage.SCORE.equals(markSubject.getStage())) {
+                    paper.setScoreBatchNo(currentTime);
+                    paperList.add(paper);
+                }
             }
             idx++;
         }
@@ -167,6 +181,61 @@ public class AssignTaskService {
             }
             markerGroupRepo.delete(markerGroups);
         }
+        if (MarkStage.SCORE.equals(markSubject.getStage()) && count == 0) {
+            //初始化打分任务数据
+            initTaskPublishData(markSubject);
+
+        }
+    }
+
+    private void initTaskPublishData(MarkSubject markSubject) {
+        StringBuffer sql = new StringBuffer();
+        sql.append("  SELECT                                                                         ");
+        sql.append("      a.work_id workId,                                                          ");
+        sql.append("      b.subject,                                                                 ");
+        sql.append("      a.code level,                                                              ");
+        sql.append("      IFNULL(b.totalCount, 0) totalCount                                        ");
+//        sql.append("      IFNULL(b.successCount, 0) successCount,                                    ");
+//        sql.append("      IFNULL(b.waitCount, 0) waitCount                                           ");
+        sql.append("  FROM                                                                           ");
+        sql.append("      level a                                                                    ");
+        sql.append("          LEFT JOIN                                                              ");
+        sql.append("      (SELECT                                                                    ");
+        sql.append("          p.work_id workId,                                                      ");
+        sql.append("              p.subject,                                                         ");
+        sql.append("              p.level,                                                           ");
+        sql.append("              COUNT(1) AS totalCount                                            ");
+//        sql.append("              SUM(IF(p.score IS NOT NULL, 1, 0)) successCount,                   ");
+//        sql.append("              SUM(IF(p.score IS NULL, 1, 0)) waitCount                           ");
+        sql.append("      FROM                                                                       ");
+        sql.append("          paper p                                                                ");
+        sql.append("      WHERE                                                                      ");
+        sql.append("          p.work_id = '"+markSubject.getWorkId()+"' AND p.subject = '"+markSubject.getSubject().name()+"'                                    ");
+        sql.append("              AND p.is_test = 0                                                  ");
+        sql.append("              AND p.level IS NOT NULL                                            ");
+        sql.append("              AND p.is_missing = FALSE                                           ");
+        sql.append("              AND p.is_active = TRUE                                             ");
+        sql.append("      GROUP BY p.work_id , p.subject , p.level) b ON a.work_id = b.workId        ");
+        sql.append("          AND a.code = b.level                                                   ");
+        sql.append("  WHERE                                                                          ");
+        sql.append("      a.work_id = '"+markSubject.getWorkId()+"'                                  ");
+        sql.append("  ORDER BY a.code                                                                ");
+        List list =  sqlUtil.execSqlForMap(sql.toString());
+        List<TaskPublishSetting> taskPublishSettings = new ArrayList<>(list.size());
+        for (Object o : list) {
+            Map map = (Map) o;
+            TaskPublishSetting taskPublishSetting = new TaskPublishSetting();
+            taskPublishSetting.setWorkId((Long) map.get("workId"));
+            taskPublishSetting.setSubject((String) map.get("subject"));
+            taskPublishSetting.setCode((String) map.get("code"));
+            taskPublishSetting.setTotalCount((Integer) map.get("totalCount"));
+            taskPublishSetting.setSuccessCount(0);
+            taskPublishSetting.setWaitCount((Integer) map.get("totalCount"));
+            taskPublishSetting.setSortRule(0);
+            taskPublishSetting.setPublishCount(0);
+            taskPublishSettings.add(taskPublishSetting);
+        }
+        taskPublishSettingRepo.save(taskPublishSettings);
     }
 
     /**

+ 80 - 5
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/StageControlService.java

@@ -51,6 +51,9 @@ public class StageControlService {
     @Autowired
     private MarkerGroupRepo markerGroupRepo;
 
+    @Autowired
+    private TaskPublishSettingRepo taskPublishSettingRepo;
+
     @Autowired
     ScoreConfig scoreConfig;
 
@@ -63,9 +66,10 @@ public class StageControlService {
      * 进入下一阶段
      *
      * @param markSubject
+     * @param taskList
      */
     @Transactional
-    public void goNext(MarkSubject markSubject, int taskCount) throws Exception {
+    public void goNext(MarkSubject markSubject, int taskCount, List<TaskPublishSetting> taskList) throws Exception {
         if (statusMap.get(markSubject.getId()) != null && statusMap.get(markSubject.getId())) {
             return;
         }
@@ -83,7 +87,8 @@ public class StageControlService {
                 break;
             case LEVEL:
                 markSubject.setStage(MarkStage.SCORE);
-                enterScoreStage(markSubject);
+//                enterScoreStage(markSubject);
+                enterScoreStage(markSubject, taskList);
                 break;
             case SCORE:
                 //TODO 进入抽查阶段
@@ -165,7 +170,7 @@ public class StageControlService {
             List<Paper> papersList = paperRepo.findByWorkIdAndSubjectAndIsMissingFalseAndActiveFalseAndTest(workId, subject, TrialEnum.DEFAULT.getId());
             papers = papersList.subList(0, taskCount);
         }
-        assignTaskService.assignForGrouping(papers, markerGroups, markSubject);
+        assignTaskService.assignForGrouping(papers, markerGroups, markSubject, null);
     }
 
     /**
@@ -286,7 +291,62 @@ public class StageControlService {
             Sort sort = new Sort("questionId");
             papers = paperRepo.findByWorkIdAndSubjectAndIsMissingFalseAndActiveTrue(workId, subject, sort);
         }
-        assignTaskService.assignForGrouping(papers, markerGroups, markSubject);
+        assignTaskService.assignForGrouping(papers, markerGroups, markSubject, null);
+    }
+
+    private void enterScoreStage(MarkSubject markSubject, List<TaskPublishSetting> taskList) throws Exception {
+        Long workId = markSubject.getWorkId();
+        Subject subject = markSubject.getSubject();
+        List<MarkUser> markers = markUserRepo.findByWorkIdAndSubjectAndRole(workId, subject, Role.MARKER);
+        List<MarkUser> levelMarkers = markers.stream().filter(m -> m.getMarkRight() == MarkRight.ALLOW_ALL || m.getMarkRight() == MarkRight.ALLOW_SCORING).collect(Collectors.toList());
+        if (levelMarkers.size() == 0) {
+            statusMap.put(markSubject.getId(), false);
+            throw new RuntimeException("没有设定评卷员");
+        }
+        int count = paperRepo.countByWorkIdAndSubjectAndLevelIsNullAndIsMissingFalseAndActiveTrueAndBatchNoNotNullAndTest(workId, subject, 0);
+        if (count > 0) {
+            statusMap.put(markSubject.getId(), false);
+            throw new RuntimeException("没有分档完成");
+        }
+        this.isPtFull(workId, markSubject);
+        List<MarkerGroup> markerGroups = markerGroupRepo.findByWorkIdAndSubject(workId, subject);
+        if (markerGroups.size() == 0) {
+            statusMap.put(markSubject.getId(), false);
+            throw new RuntimeException("评卷员没有进行分组");
+        }
+
+        //校验发布任务数量
+        for (TaskPublishSetting taskPublishSetting : taskList) {
+            if (Objects.nonNull(taskPublishSetting.getTaskCount()) && taskPublishSetting.getTaskCount() > 0 && taskPublishSetting.getWaitCount() < taskPublishSetting.getTaskCount()) {
+                statusMap.put(markSubject.getId(), false);
+                throw new RuntimeException(taskPublishSetting.getCode()+"档位本次任务数量必须小于等于未评数量");
+            }
+        }
+
+        //总的发布任务数
+        int totalTaskCount = taskList.stream().mapToInt(TaskPublishSetting::getTaskCount).sum();
+
+        markSubject.setAllLevel(true);
+        Sort sort = new Sort("questionId");
+        List<Paper> papers = null;
+        Map<String, TaskPublishSetting> map = new HashMap<>();
+        papers = paperRepo.findByWorkIdAndSubjectAndIsMissingFalseAndActiveTrueAndScoreBatchNoIsNull(workId, subject, sort);
+        papers = papers.subList(0, totalTaskCount);
+
+        assignTaskService.assignForGrouping(papers, markerGroups, markSubject, taskList);
+
+        //保存发布数据
+        int max = taskList.get(0).getPublishCount() + 1;
+        long scoreBatchNo = papers.get(0).getScoreBatchNo();
+        taskList.stream().map(m->{
+            m.setSuccessCount(m.getSuccessCount() + m.getTaskCount());
+            m.setWaitCount(m.getTotalCount() - m.getSuccessCount());
+            m.setTaskCount(0);
+            m.setBatchNo(scoreBatchNo);
+            m.setPublishCount(max);
+            return m;
+        }).collect(Collectors.toList());
+        taskPublishSettingRepo.save(taskList);
     }
 
     /**
@@ -378,6 +438,21 @@ public class StageControlService {
         return progressDTO;
     }
 
+    /**
+     * 分档进度查询
+     *
+     * @param markSubject
+     */
+    public List scoreProgress(MarkSubject markSubject) {
+        List<TaskPublishSetting> publishSettings = taskPublishSettingRepo.findByWorkIdAndSubject(markSubject.getWorkId(), markSubject.getSubject().name());
+        if (publishSettings != null && publishSettings.size() > 0) {
+            int maxCount = taskPublishSettingRepo.maxPublishCount(markSubject.getWorkId(), markSubject.getSubject().name());
+            return taskPublishSettingRepo.findByWorkIdAndSubjectAndPublishCount(markSubject.getWorkId(), markSubject.getSubject().name(), maxCount);
+        }
+
+        return null;
+    }
+
 
     /**
      * 分档进度查询
@@ -410,7 +485,7 @@ public class StageControlService {
             list.add(areaProgressDTO);
         }
 
-        if(examQuestions!= null && examQuestions.size() > 1) {
+        if (examQuestions != null && examQuestions.size() > 1) {
             //已评任务数
             int successCount = paperRepo.countByWorkIdAndSubjectAndLevelNotNullAndIsMissingFalseAndActiveTrueAndTest(workId, subject, 0);
             //所有任务数(查询所有有效试卷)