浏览代码

美术阅卷10月新增需求-打回算法优化

wangliang 5 年之前
父节点
当前提交
37a82baf22

+ 37 - 47
stmms-ms-commons/src/main/java/cn/com/qmth/stmms/ms/commons/constant/ArbitrateCallback.java

@@ -5,8 +5,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
@@ -20,67 +20,45 @@ import java.util.stream.Collectors;
 public class ArbitrateCallback {
     private static Logger LOGGER = LoggerFactory.getLogger(ArbitrateCallback.class);
 
-    public static char[] LEVELS = null;//各评卷员评选的档位数组
-
     public static int MAX_DISTANCE = 2 //仲裁档位
             , SUM_DISTANCE = 2 * 2 + 1;//最大落差档位和
 
     /**
      * 自动打回算法
      *
-     * @param levelList
+     * @param levelsMap
      * @param maxDistance
      * @return
      */
-    public static List<String> judge(List<String> levelList, int maxDistance) {
+    public static List<Distance> judge(Map<Long, String> levelsMap, int maxDistance) {
         MAX_DISTANCE = maxDistance;
         SUM_DISTANCE = MAX_DISTANCE * 2 + 1;
-        List<String> resultList = null;
-        Collections.sort(levelList);
-        LEVELS = new char[levelList.size()];
-        for (int i = 0; i < levelList.size(); i++) {
-            LEVELS[i] = levelList.get(i).charAt(0);
-        }
-        List<Distance> result = judge(LEVELS);
+        List<Distance> result = judge(levelsMap);
         if (Objects.nonNull(result)) {
-            resultList = result.stream().map(o -> String.valueOf(o.c)).collect(Collectors.toList());
-            LOGGER.info("LEVELS:{},设置的隔档档位为:{},设置的最大落差值和为:{},需要打回的档位为:{}", LEVELS, MAX_DISTANCE, SUM_DISTANCE, JSONObject.toJSONString(result));
-        }
-        return resultList;
-    }
-
-    /**
-     * 计算每个档位和试卷档位的落差
-     *
-     * @param levelList
-     * @param paperLevel
-     * @return
-     */
-    public static List<Distance> judge(List<String> levelList, String paperLevel) {
-        List<Distance> result = null;
-        Collections.sort(levelList);
-        LEVELS = new char[levelList.size()];
-        for (int i = 0; i < levelList.size(); i++) {
-            LEVELS[i] = levelList.get(i).charAt(0);
+            LOGGER.info("LEVELS:{},设置的隔档档位为:{},设置的最大落差值和为:{},需要打回的档位为:{}", levelsMap.values().stream().collect(Collectors.toList()), MAX_DISTANCE, SUM_DISTANCE, JSONObject.toJSONString(result));
         }
-        result = judge(LEVELS, paperLevel);
-        LOGGER.info("LEVELS:{},paperLevel为:{},档位落差为:{}", LEVELS, paperLevel, JSONObject.toJSONString(result));
         return result;
     }
 
     /**
      * 计算档位偏差值
      *
-     * @param levels
+     * @param levelsMap
+     * @param paperLevel
      * @return
      */
-    public static List<Distance> judge(char[] levels, String paperLevel) {
+    public static List<Distance> judge(Map<Long, String> levelsMap, String paperLevel) {
         List<Distance> result = new ArrayList<>();
         char p = paperLevel.charAt(0);
-        for (char c : levels) {
-            Distance d = new Distance(c);
+        levelsMap.forEach((k, v) -> {
+            char c = v.charAt(0);
+            Distance d = new Distance(c, k);
             d.distance = Math.abs(c - p);
             result.add(d);
+            LOGGER.info("计算档位偏差值:{}", JSONObject.toJSONString(d));
+        });
+        if (Objects.nonNull(result)) {
+            LOGGER.info("LEVELS:{},paperLevel为:{},档位落差为:{}", levelsMap.values().stream().collect(Collectors.toList()), paperLevel, JSONObject.toJSONString(result));
         }
         return result;
     }
@@ -88,40 +66,44 @@ public class ArbitrateCallback {
     /**
      * 计算档位最大落差档位和档位和
      *
-     * @param levels
+     * @param levelsMap
      * @return
      */
-    public static List<Distance> judge(char[] levels) {
+    public static List<Distance> judge(Map<Long, String> levelsMap) {
         List<Distance> result = new ArrayList<>();
-        for (char c : levels) {
-            Distance d = new Distance(c);
-            for (char other : levels) {
+        levelsMap.forEach((k, v) -> {
+            char c = v.charAt(0);
+            Distance d = new Distance(c, k);
+            levelsMap.forEach((k1, v1) -> {
+                char other = v1.charAt(0);
                 int distance = Math.abs(c - other);
                 d.max = Math.max(d.max, distance);
                 d.sum += distance;
-            }
+            });
             if (d.max >= MAX_DISTANCE && d.sum >= SUM_DISTANCE) {
                 result.add(d);
             }
-            LOGGER.info("档位:{}", JSONObject.toJSONString(d));
-        }
+            LOGGER.info("计算档位最大落差档位和档位和:{}", JSONObject.toJSONString(d));
+        });
         return result;
     }
 
     /**
      * 档位计算类[档位,最大档位落差,最大档位落差和,档位偏差值]
      */
-    static class Distance {
+    public static class Distance {
         char c;
         int max;
         int sum;
         int distance;
+        Long markId;
 
-        public Distance(char c) {
+        public Distance(char c, Long markId) {
             this.c = c;
             this.max = 0;
             this.sum = 0;
             this.distance = 0;
+            this.markId = markId;
         }
 
         public char getC() {
@@ -155,5 +137,13 @@ public class ArbitrateCallback {
         public void setDistance(int distance) {
             this.distance = distance;
         }
+
+        public Long getMarkId() {
+            return markId;
+        }
+
+        public void setMarkId(Long markId) {
+            this.markId = markId;
+        }
     }
 }

+ 10 - 1
stmms-ms-core/src/main/java/cn/com/qmth/stmms/ms/core/domain/MarkLogOperType.java

@@ -67,7 +67,12 @@ public enum MarkLogOperType {
     /**
      * 手动打回
      */
-    HANDLE_LEVEl(12, "手动打回");
+    HANDLE_LEVEl(12, "手动打回"),
+
+    /**
+     * 档位落差
+     */
+    LEVEl_DIFFERENCE(13, "档位落差");
 
     private int id;
 
@@ -123,6 +128,8 @@ public enum MarkLogOperType {
             return REEVALUATION_LEVEl.getId();
         } else if (value.trim().equals(HANDLE_LEVEl.name)) {
             return HANDLE_LEVEl.getId();
+        } else if (value.trim().equals(LEVEl_DIFFERENCE.name)) {
+            return LEVEl_DIFFERENCE.getId();
         } else {
             return CRITERION_PAPER_SET.getId();
         }
@@ -157,6 +164,8 @@ public enum MarkLogOperType {
             return REEVALUATION_LEVEl.name;
         } else if (id == HANDLE_LEVEl.getId()) {
             return HANDLE_LEVEl.name;
+        } else if (id == LEVEl_DIFFERENCE.getId()) {
+            return LEVEl_DIFFERENCE.name;
         } else {
             return CRITERION_PAPER_SET.name;
         }

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

@@ -1,12 +1,20 @@
 package cn.com.qmth.stmms.ms.log.aop;
 
+import cn.com.qmth.stmms.ms.commons.config.LevelConfig;
+import cn.com.qmth.stmms.ms.commons.constant.ArbitrateCallback;
 import cn.com.qmth.stmms.ms.commons.utils.SqlUtil;
-import cn.com.qmth.stmms.ms.core.domain.*;
+import cn.com.qmth.stmms.ms.core.domain.MarkLog;
+import cn.com.qmth.stmms.ms.core.domain.MarkLogOperType;
+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.task.MarkTask;
 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.MarkLogRepo;
+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.repository.StudentRepo;
-import cn.com.qmth.stmms.ms.core.vo.Subject;
+import cn.com.qmth.stmms.ms.marking.config.MarkingConfig;
 import cn.com.qmth.stmms.ms.marking.dto.MarkTaskDTO;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -24,6 +32,7 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 纪检审查aop
@@ -66,6 +75,15 @@ public class MarkLogAop {
     @Autowired
     SqlUtil sqlUtil;
 
+    @Autowired
+    LevelConfig levelConfig;
+
+    @Autowired
+    MarkTaskRepo markTaskRepo;
+
+    @Autowired
+    MarkingConfig markingConfig;
+
     /**
      * 标准卷、定档、档位打回切入点
      */
@@ -201,6 +219,38 @@ public class MarkLogAop {
         LOGGER.info("markLog:{}", JSONObject.toJSONString(markLog));
         //分档、打分、回评档位、回评分数、档位打回、档位打回回评end
         markLogRepo.save(markLog);
+        //20191107wangliang加入仲裁自动打回算法 start
+        if (markStage.ordinal() == 1 && paper.isArbitrated()) {
+            if (levelConfig.isAutoCallback()) {//为true则自动打回
+                List<MarkTask> markTasks = markTaskRepo.findByPaperIdAndStage(paper.getId(), markStage);
+                Map<Long, String> levelsMap = markTasks.stream().collect(Collectors.toMap(MarkTask::getMarkerId, o -> o.getResult().toUpperCase()));
+                List<ArbitrateCallback.Distance> list = ArbitrateCallback.judge(levelsMap, markingConfig.getDeviation());
+                if (Objects.nonNull(list) && list.size() > 0) {
+                    paper.reject(null);
+                    List<MarkLog> markLogList = new ArrayList<>();
+                    for (ArbitrateCallback.Distance d : list) {
+                        for (MarkTask m : markTasks) {
+                            if (Objects.equals(String.valueOf(d.getC()), m.getResult()) && d.getMarkId().longValue() == m.getMarkerId().longValue()) {
+                                m.setRejected(true);
+                                m.setOriginLevel(m.getResult());
+                                m.setResult(null);
+                                MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(m.getMarkerId(), MarkLogOperType.SYSTEM_CALLBACK_LEVEl.getId(), m.getSubject().toString(), paper.getExamNumber());
+                                if (Objects.nonNull(markLogPrev)) {
+                                    operResult = Optional.ofNullable(markLogPrev.getOperDataAfter()).orElse("-");
+                                }
+                                //加入打回日志
+                                markLog = new MarkLog(m.getMarkerId(), m.getMarkerName(), Role.MARKER, m.getSubject(), paper.getExamNumber(), paper.getStudentName(), MarkLogOperType.SYSTEM_CALLBACK_LEVEl.getId(), paper.getWorkId(), paper.getId(), m.getStage(), operResult, String.valueOf(d.getC()), MarkLogOperType.SYSTEM_CALLBACK_LEVEl.getName());
+                                markLogList.add(markLog);
+                            }
+                        }
+                    }
+                    markTaskRepo.save(markTasks);
+                    paperRepo.save(paper);
+                    markLogRepo.save(markLogList);
+                }
+            }
+        }
+        //20191107wangliang加入仲裁自动打回算法 end
     }
 
 //    /**

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

@@ -119,7 +119,7 @@ public class TaskApi {
 
         //加入重评日志
         String operResult = null;
-        MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(-1L, MarkLogOperType.REEVALUATION_LEVEl.getId(), markTask.getSubject().toString(), paper.getExamNumber());
+        MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(markTask.getMarkerId(), MarkLogOperType.REEVALUATION_LEVEl.getId(), markTask.getSubject().toString(), paper.getExamNumber());
         if (Objects.nonNull(markLogPrev)) {
             operResult = Optional.ofNullable(markLogPrev.getOperDataAfter()).orElse("-");
         }

+ 27 - 30
stmms-ms-marking/src/main/java/cn/com/qmth/stmms/ms/marking/service/MarkingService.java

@@ -9,6 +9,7 @@ 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.config.MarkingConfig;
 import cn.com.qmth.stmms.ms.marking.service.arbitration.ArbitrationService;
+import com.alibaba.fastjson.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -121,35 +122,6 @@ public class MarkingService {
             if (result) {
                 //仲裁
                 paper.arbitrate();
-                if (levelConfig.isAutoCallback()) {//为true则自动打回
-                    //20191107wangliang加入仲裁自动打回算法
-                    List<String> levels = markTasks.stream().map(o -> o.getResult()).collect(Collectors.toList());
-                    List<String> list = ArbitrateCallback.judge(levels, markingConfig.getDeviation());
-                    if (Objects.nonNull(list) && list.size() > 0) {
-                        paper.reject(null);
-                        String operResult = null;
-                        List<MarkLog> markLogList = new ArrayList<>();
-                        for (String s : list) {
-                            for (MarkTask m : markTasks) {
-                                if (Objects.equals(s, m.getResult())) {
-                                    m.setRejected(true);
-                                    m.setOriginLevel(markTask.getResult());
-                                    m.setResult(null);
-                                    MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(-1L, MarkLogOperType.SYSTEM_CALLBACK_LEVEl.getId(), markTask.getSubject().toString(), paper.getExamNumber());
-                                    if (Objects.nonNull(markLogPrev)) {
-                                        operResult = Optional.ofNullable(markLogPrev.getOperDataAfter()).orElse("-");
-                                    }
-                                    //加入打回日志
-                                    MarkLog markLog = new MarkLog(m.getMarkerId(), m.getMarkerName(), Role.MARKER, m.getSubject(), paper.getExamNumber(), paper.getStudentName(), MarkLogOperType.SYSTEM_CALLBACK_LEVEl.getId(), paper.getWorkId(), paper.getId(), m.getStage(), operResult, s, MarkLogOperType.SYSTEM_CALLBACK_LEVEl.getName());
-                                    markLogList.add(markLog);
-                                }
-                            }
-                        }
-                        markTaskRepo.save(markTasks);
-                        paperRepo.save(paper);
-                        markLogRepo.save(markLogList);
-                    }
-                }
             } else {
                 //定档
                 DeterResult determine = determineLevelService.determine(markingConfig.isMajority(), markTasks.toArray(sources));
@@ -159,6 +131,31 @@ public class MarkingService {
                 } else {
                     paper.setMarkedLogic(false);
                 }
+                //20191108wangliang加入档位落差值计算
+                Map<Long, String> levelsMap = markTasks.stream().collect(Collectors.toMap(MarkTask::getMarkerId, o -> o.getResult().toUpperCase()));
+                List<ArbitrateCallback.Distance> list = ArbitrateCallback.judge(levelsMap, paper.getLevel());
+                String operResult = "-";
+                for (ArbitrateCallback.Distance d : list) {
+                    for (MarkTask m : markTasks) {
+                        if (Objects.equals(String.valueOf(d.getC()), m.getResult()) && d.getMarkId().longValue() == m.getMarkerId().longValue()) {
+                            MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(m.getMarkerId(), MarkLogOperType.LEVEl_DIFFERENCE.getId(), m.getSubject().toString(), paper.getExamNumber());
+                            JSONObject jsonObject = new JSONObject();
+                            jsonObject.put("task", m.getResult());
+                            jsonObject.put("paper", paper.getLevel());
+                            if (Objects.isNull(markLogPrev)) {
+                                //加入档位落差值日志
+                                MarkLog markLog = new MarkLog(m.getMarkerId(), m.getMarkerName(), Role.MARKER, m.getSubject(), paper.getExamNumber(), paper.getStudentName(), MarkLogOperType.LEVEl_DIFFERENCE.getId(), paper.getWorkId(), paper.getId(), m.getStage(), operResult, String.valueOf(d.getDistance()), jsonObject.toJSONString());
+                                markLogRepo.save(markLog);
+                            } else {
+                                operResult = Optional.ofNullable(markLogPrev.getOperDataAfter()).orElse("-");
+                                markLogPrev.setOperDataBefore(operResult);
+                                markLogPrev.setOperDataAfter(String.valueOf(d.getDistance()));
+                                markLogPrev.setRemark(jsonObject.toJSONString());
+                                markLogRepo.save(markLogPrev);
+                            }
+                        }
+                    }
+                }
             }
             paperRepo.save(paper);
         }
@@ -225,7 +222,7 @@ public class MarkingService {
                         markTask.setRejected(true);
                         markTask.setOriginLevel(markTask.getResult());
                         markTask.setResult(null);
-                        MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(-1L, MarkLogOperType.HANDLE_LEVEl.getId(), markTask.getSubject().toString(), paper.getExamNumber());
+                        MarkLog markLogPrev = markLogRepo.findTopByCreateUserIdAndOperTypeAndSubjectAndExamNumberOrderByCreateTimeDesc(markTask.getMarkerId(), MarkLogOperType.HANDLE_LEVEl.getId(), markTask.getSubject().toString(), paper.getExamNumber());
                         if (Objects.nonNull(markLogPrev)) {
                             operResult = Optional.ofNullable(markLogPrev.getOperDataAfter()).orElse("-");
                         }