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

评卷部分代码重构

1.TaskEntry改成公共类
2.修改领取任务查询方法,直接过滤掉多评重复的studentId任务
3.修改任务提交方法,将判断逻辑挪到service层,并修改潜在错误
4.去掉所有BACKED状态的使用,打回单个评卷任务等同于重置
5.增加已领取任务的查询接口/monitor/task,可用于跟踪任务领取现状
luoshi 6 жил өмнө
parent
commit
22e0ba10a8

+ 9 - 3
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkLibraryDao.java

@@ -30,6 +30,11 @@ public interface MarkLibraryDao extends JpaRepository<MarkLibrary, Integer>, Jpa
     List<MarkLibrary> findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(Integer examId, String subjectCode,
     List<MarkLibrary> findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(Integer examId, String subjectCode,
             Integer groupNumber, Set<LibraryStatus> statusSet, Pageable page);
             Integer groupNumber, Set<LibraryStatus> statusSet, Pageable page);
 
 
+    @Query("select l1 from MarkLibrary l1 where l1.examId=?1 and l1.subjectCode=?2 and l1.groupNumber=?3 and l1.status in (?5) "
+            + "and not exists (select l2 from MarkLibrary l2 where l2.studentId=l1.studentId and l2.id!=l1.id and l2.markerId=?4)")
+    List<MarkLibrary> findUnMarked(Integer examId, String subjectCode, Integer groupNumber, Integer markerId,
+            Set<LibraryStatus> statusSet, Pageable page);
+
     @Query("select l from MarkLibrary l where l.studentId=?1 order by l.groupNumber ")
     @Query("select l from MarkLibrary l where l.studentId=?1 order by l.groupNumber ")
     List<MarkLibrary> findByStudentId(Integer studentId);
     List<MarkLibrary> findByStudentId(Integer studentId);
 
 
@@ -60,11 +65,12 @@ public interface MarkLibraryDao extends JpaRepository<MarkLibrary, Integer>, Jpa
 
 
     @Modifying(clearAutomatically = true)
     @Modifying(clearAutomatically = true)
     @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null, m.headerId=null , m.headerTime=null , m.headerScore=null , m.headerScoreList=null  where m.markerId=?1 and m.status!=?3 and m.status!=?4 ")
     @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null, m.headerId=null , m.headerTime=null , m.headerScore=null , m.headerScoreList=null  where m.markerId=?1 and m.status!=?3 and m.status!=?4 ")
-    void resetByMarkerId(Integer markerId, LibraryStatus status,LibraryStatus libraryStatus1,LibraryStatus libraryStatus2);
+    void resetByMarkerId(Integer markerId, LibraryStatus status, LibraryStatus libraryStatus1,
+            LibraryStatus libraryStatus2);
 
 
     @Modifying(clearAutomatically = true)
     @Modifying(clearAutomatically = true)
-    @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null , m.headerId=null , m.headerTime=null , m.headerScore=null , m.headerScoreList=null where m.id=?1")
-    void resetById(Integer id, LibraryStatus status);
+    @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null , m.headerId=null , m.headerTime=null , m.headerScore=null , m.headerScoreList=null where m.id=?1 and m.status=?3")
+    int resetById(Integer id, LibraryStatus newStatus, LibraryStatus previousStatus);
 
 
     @Query("select f.markerId, count(*) as markerCount from MarkLibrary f where f.examId=?1 and f.status=?2 group by f.markerId")
     @Query("select f.markerId, count(*) as markerCount from MarkLibrary f where f.examId=?1 and f.status=?2 group by f.markerId")
     List<Object[]> countByMarkerAndStatus(Integer examId, LibraryStatus status);
     List<Object[]> countByMarkerAndStatus(Integer examId, LibraryStatus status);

+ 6 - 12
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkLibraryServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.com.qmth.stmms.biz.mark.service.Impl;
 package cn.com.qmth.stmms.biz.mark.service.Impl;
 
 
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.List;
 import java.util.Set;
 import java.util.Set;
@@ -44,23 +45,16 @@ public class MarkLibraryServiceImpl extends BaseQueryService<MarkLibrary> implem
     }
     }
 
 
     @Override
     @Override
-    public List<MarkLibrary> findByStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status,
+    public List<MarkLibrary> findUnMarked(Integer examId, String subjectCode, Integer groupNumber, Integer markerId,
             int pageNumber, int pageSize) {
             int pageNumber, int pageSize) {
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setPageNumber(pageNumber);
-        query.setPageSize(pageSize);
-        return libraryDao.findByExamIdAndSubjectCodeAndGroupNumberAndStatus(examId, subjectCode, groupNumber, status,
-                query);
-    }
+        Set<LibraryStatus> statusSet = new HashSet<>();
+        statusSet.add(LibraryStatus.WAITING);
 
 
-    @Override
-    public List<MarkLibrary> findByStatusSet(int examId, String subjectCode, int groupNumber,
-            Set<LibraryStatus> statusSet, int pageNumber, int pageSize) {
         MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
         MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
         query.setPageNumber(pageNumber);
         query.setPageNumber(pageNumber);
         query.setPageSize(pageSize);
         query.setPageSize(pageSize);
-        return libraryDao.findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(examId, subjectCode, groupNumber,
-                statusSet, query);
+
+        return libraryDao.findUnMarked(examId, subjectCode, groupNumber, markerId, statusSet, query);
     }
     }
 
 
     @Override
     @Override

+ 48 - 27
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkServiceImpl.java

@@ -210,10 +210,12 @@ public class MarkServiceImpl implements MarkService {
      */
      */
     @Override
     @Override
     public boolean applyLibrary(MarkLibrary library, Marker marker) {
     public boolean applyLibrary(MarkLibrary library, Marker marker) {
+        // 查询待领取任务时,已经做了多评同一studentId互斥处理
         // 首先判断多评情况下,同一个studentId是否已被该评卷员处理过
         // 首先判断多评情况下,同一个studentId是否已被该评卷员处理过
-        if (libraryDao.countByStudentIdAndMarkerId(library.getStudentId(), marker.getId()) > 0) {
-            return false;
-        }
+        // if (libraryDao.countByStudentIdAndMarkerId(library.getStudentId(),
+        // marker.getId()) > 0) {
+        // return false;
+        // }
         return CurrentTaskUtil.add(marker, getApplyTaskId(library));
         return CurrentTaskUtil.add(marker, getApplyTaskId(library));
     }
     }
 
 
@@ -250,10 +252,11 @@ public class MarkServiceImpl implements MarkService {
         try {
         try {
             lockService.waitUnlockGroup(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
             lockService.waitUnlockGroup(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
             lockService.lockMarker(marker.getId());
             lockService.lockMarker(marker.getId());
-            //仲裁和等待仲裁的任务不被重置
-            trackDao.deleteByMarkerId(marker.getId(),LibraryStatus.ARBITRATED,LibraryStatus.WAIT_ARBITRATE);
-            specialTagDao.deleteByMarkerId(marker.getId(),LibraryStatus.ARBITRATED,LibraryStatus.WAIT_ARBITRATE);
-            libraryDao.resetByMarkerId(marker.getId(), LibraryStatus.WAITING,LibraryStatus.ARBITRATED,LibraryStatus.WAIT_ARBITRATE);
+            // 仲裁和等待仲裁的任务不被重置
+            trackDao.deleteByMarkerId(marker.getId(), LibraryStatus.ARBITRATED, LibraryStatus.WAIT_ARBITRATE);
+            specialTagDao.deleteByMarkerId(marker.getId(), LibraryStatus.ARBITRATED, LibraryStatus.WAIT_ARBITRATE);
+            libraryDao.resetByMarkerId(marker.getId(), LibraryStatus.WAITING, LibraryStatus.ARBITRATED,
+                    LibraryStatus.WAIT_ARBITRATE);
             updateLibraryCount(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
             updateLibraryCount(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
             releaseByMarker(marker);
             releaseByMarker(marker);
         } catch (Exception e) {
         } catch (Exception e) {
@@ -294,40 +297,54 @@ public class MarkServiceImpl implements MarkService {
      */
      */
     @Override
     @Override
     @Transactional
     @Transactional
-    public void submitLibrary(MarkLibrary library, Marker marker, List<MarkTrack> trackList,
+    public boolean submitLibrary(MarkLibrary library, Marker marker, List<MarkTrack> trackList,
             List<MarkSpecialTag> tagList) {
             List<MarkSpecialTag> tagList) {
+        // 判断评卷任务记录是否存在,以及评卷员是否有权限操作
+        if (library == null || !library.getExamId().equals(marker.getExamId())
+                || !library.getSubjectCode().equals(marker.getSubjectCode())
+                || !library.getGroupNumber().equals(marker.getGroupNumber())) {
+            return false;
+        }
         // 判断大题是否存在
         // 判断大题是否存在
         MarkGroup group = groupDao.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
         MarkGroup group = groupDao.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
         if (group == null) {
         if (group == null) {
-            return;
+            return false;
         }
         }
         // 等待大题释放锁定
         // 等待大题释放锁定
         lockService.waitUnlockGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
         lockService.waitUnlockGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
         // 等待考生释放锁定
         // 等待考生释放锁定
         lockService.waitUnlockStudent(library.getStudentId());
         lockService.waitUnlockStudent(library.getStudentId());
+        // 尝试锁定评卷员
+        lockService.lockMarker(library.getMarkerId());
+        // 本人是否已领取该任务
+        boolean applied = hasApplied(library, marker);
 
 
         try {
         try {
-            Date now = new Date();
-            // 尝试锁定评卷员
-            lockService.lockMarker(library.getMarkerId());
+            // 非本人领取的待评任务
+            if (library.getStatus() == LibraryStatus.WAITING && !applied) {
+                return false;
+            }
+            // 非本人的回评任务
+            if (library.getStatus() == LibraryStatus.MARKED && !library.getMarkerId().equals(marker.getId())) {
+                return false;
+            }
             // 校验总分是否超标
             // 校验总分是否超标
             if (library.getMarkerScore() > group.getTotalScore() || StringUtils.isBlank(library.getMarkerScoreList())) {
             if (library.getMarkerScore() > group.getTotalScore() || StringUtils.isBlank(library.getMarkerScoreList())) {
-                return;
+                return false;
             }
             }
             // 是否多评情况下已处理过该考生评卷任务
             // 是否多评情况下已处理过该考生评卷任务
             if (libraryDao.countByStudentIdAndMarkerIdAndIdNotEqual(library.getStudentId(), library.getMarkerId(),
             if (libraryDao.countByStudentIdAndMarkerIdAndIdNotEqual(library.getStudentId(), library.getMarkerId(),
                     library.getId()) > 0) {
                     library.getId()) > 0) {
-                return;
+                return false;
             }
             }
             // 尝试提交评卷结果
             // 尝试提交评卷结果
+            Date now = new Date();
             if (libraryDao.updateMarkerResult(library.getId(), LibraryStatus.MARKED, library.getMarkerId(),
             if (libraryDao.updateMarkerResult(library.getId(), LibraryStatus.MARKED, library.getMarkerId(),
                     library.getMarkerScore(), library.getMarkerScoreList(), now, library.getTags(),
                     library.getMarkerScore(), library.getMarkerScoreList(), now, library.getTags(),
-                    LibraryStatus.WAITING, LibraryStatus.BACKED, LibraryStatus.MARKED) == 0) {
+                    LibraryStatus.WAITING, LibraryStatus.MARKED) == 0) {
                 // 条件不符更新失败,直接返回
                 // 条件不符更新失败,直接返回
-                return;
+                return false;
             }
             }
-            // 释放任务
-            CurrentTaskUtil.remove(marker, getApplyTaskId(library));
             // 保存阅卷轨迹
             // 保存阅卷轨迹
             if (trackList != null) {
             if (trackList != null) {
                 trackDao.deleteByLibraryId(library.getId());
                 trackDao.deleteByLibraryId(library.getId());
@@ -368,32 +385,36 @@ public class MarkServiceImpl implements MarkService {
                 // 触发仲裁后续状态更新
                 // 触发仲裁后续状态更新
                 libraryDao.updateByStudentIdAndGroupNumber(library.getStudentId(), library.getGroupNumber(),
                 libraryDao.updateByStudentIdAndGroupNumber(library.getStudentId(), library.getGroupNumber(),
                         LibraryStatus.WAIT_ARBITRATE);
                         LibraryStatus.WAIT_ARBITRATE);
-            } else {
-                // 评卷正常完成才尝试统分
-                // scoreCalculate(library.getExamId(), library.getSubjectCode(),
-                // library.getStudentId());
             }
             }
+            return true;
         } catch (Exception e) {
         } catch (Exception e) {
             throw e;
             throw e;
         } finally {
         } finally {
+            // 只有确定本人已领取该任务时,才进行释放操作
+            if (applied) {
+                CurrentTaskUtil.remove(marker, getApplyTaskId(library));
+            }
             lockService.unlockMarker(library.getMarkerId());
             lockService.unlockMarker(library.getMarkerId());
         }
         }
     }
     }
 
 
     /**
     /**
-     * 管理员/组长打回某个评卷任务
+     * 管理员/组长打回某个评卷任务<br>
+     * 暂时不用到BACKED状态,直接等同于重置该评卷任务
      * 
      * 
      * @param library
      * @param library
      */
      */
     @Override
     @Override
     @Transactional
     @Transactional
-    public void backLibrary(MarkLibrary library) {
-        if (library.getStatus() == LibraryStatus.MARKED) {
-            lockService.waitUnlockGroup(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
+    public boolean backLibrary(MarkLibrary library) {
+        lockService.waitUnlockGroup(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
+        if (libraryDao.resetById(library.getId(), LibraryStatus.WAITING, LibraryStatus.MARKED) > 0) {
             trackDao.deleteByLibraryId(library.getId());
             trackDao.deleteByLibraryId(library.getId());
             specialTagDao.deleteByLibraryId(library.getId());
             specialTagDao.deleteByLibraryId(library.getId());
-            libraryDao.resetById(library.getId(), LibraryStatus.BACKED);
             updateLibraryCount(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
             updateLibraryCount(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
+            return true;
+        } else {
+            return false;
         }
         }
     }
     }
 
 

+ 4 - 3
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/TaskServiceImpl.java

@@ -150,9 +150,10 @@ public class TaskServiceImpl implements TaskService {
         if (library.getMarkerScoreList() != null) {
         if (library.getMarkerScoreList() != null) {
             task.setScoreList(library.getMarkerScoreList());
             task.setScoreList(library.getMarkerScoreList());
         }
         }
-        if (library.getStatus() == LibraryStatus.BACKED && library.getMarkerId() != null) {
-            task.setBack(true);
-        }
+        // if (library.getStatus() == LibraryStatus.BACKED &&
+        // library.getMarkerId() != null) {
+        // task.setBack(true);
+        // }
         return task;
         return task;
     }
     }
 
 

+ 1 - 5
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkLibraryService.java

@@ -1,7 +1,6 @@
 package cn.com.qmth.stmms.biz.mark.service;
 package cn.com.qmth.stmms.biz.mark.service;
 
 
 import java.util.List;
 import java.util.List;
-import java.util.Set;
 
 
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
@@ -17,10 +16,7 @@ public interface MarkLibraryService {
 
 
     MarkLibrarySearchQuery findByQuery(MarkLibrarySearchQuery query);
     MarkLibrarySearchQuery findByQuery(MarkLibrarySearchQuery query);
 
 
-    List<MarkLibrary> findByStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status,
-            int pageNumber, int pageSize);
-
-    List<MarkLibrary> findByStatusSet(int examId, String subjectCode, int groupNumber, Set<LibraryStatus> statusSet,
+    List<MarkLibrary> findUnMarked(Integer examId, String subjectCode, Integer groupNumber, Integer markerId,
             int pageNumber, int pageSize);
             int pageNumber, int pageSize);
 
 
     long countByExamAndSubjectAndGroupAndStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status);
     long countByExamAndSubjectAndGroupAndStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status);

+ 4 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkService.java

@@ -103,8 +103,9 @@ public interface MarkService {
      * @param library
      * @param library
      * @param trackList
      * @param trackList
      * @param tagList
      * @param tagList
+     * @return
      */
      */
-    void submitLibrary(MarkLibrary library, Marker marker, List<MarkTrack> trackList, List<MarkSpecialTag> tagList);
+    boolean submitLibrary(MarkLibrary library, Marker marker, List<MarkTrack> trackList, List<MarkSpecialTag> tagList);
 
 
     /**
     /**
      * 管理员/组长直接对考生打分
      * 管理员/组长直接对考生打分
@@ -118,8 +119,9 @@ public interface MarkService {
      * 管理员/组长打回某个评卷任务
      * 管理员/组长打回某个评卷任务
      * 
      * 
      * @param library
      * @param library
+     * @return
      */
      */
-    void backLibrary(MarkLibrary library);
+    boolean backLibrary(MarkLibrary library);
 
 
     /**
     /**
      * 更新某个大题评卷任务数量
      * 更新某个大题评卷任务数量

+ 15 - 42
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/CurrentTaskUtil.java

@@ -5,8 +5,6 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 
 
-import org.apache.commons.lang.StringUtils;
-
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multiset;
 import com.google.common.collect.Multiset;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.SetMultimap;
@@ -56,7 +54,7 @@ public class CurrentTaskUtil {
         Set<TaskEntry> set = taskMap.get(key);
         Set<TaskEntry> set = taskMap.get(key);
         if (set != null) {
         if (set != null) {
             for (TaskEntry entry : set) {
             for (TaskEntry entry : set) {
-                if (entry.taskId.equals(taskId) && entry.markerId == marker.getId()) {
+                if (entry.getTaskId().equals(taskId) && entry.getMarkerId() == marker.getId()) {
                     return true;
                     return true;
                 }
                 }
             }
             }
@@ -100,7 +98,7 @@ public class CurrentTaskUtil {
         int count = 0;
         int count = 0;
         if (set != null) {
         if (set != null) {
             for (TaskEntry obj : set) {
             for (TaskEntry obj : set) {
-                if (obj.markerId == marker.getId()) {
+                if (obj.getMarkerId() == marker.getId()) {
                     count++;
                     count++;
                 }
                 }
             }
             }
@@ -131,13 +129,24 @@ public class CurrentTaskUtil {
         synchronized (CurrentTaskUtil.class) {
         synchronized (CurrentTaskUtil.class) {
             set.addAll(taskMap.get(key));
             set.addAll(taskMap.get(key));
             for (TaskEntry obj : set) {
             for (TaskEntry obj : set) {
-                if (obj.markerId == marker.getId()) {
+                if (obj.getMarkerId() == marker.getId()) {
                     taskMap.remove(key, obj);
                     taskMap.remove(key, obj);
                 }
                 }
             }
             }
         }
         }
     }
     }
 
 
+    /**
+     * 获取当前已领取的任务快照
+     * 
+     * @param examId
+     * @param subjectCode
+     * @param groupNumber
+     */
+    public static Set<TaskEntry> list(Integer examId, String subjectCode, Integer groupNumber) {
+        return taskMap.get(getKey(examId, subjectCode, groupNumber));
+    }
+
     private static String getKey(int examId, String subjectCode, int number) {
     private static String getKey(int examId, String subjectCode, int number) {
         return examId + "_" + subjectCode + "_" + number;
         return examId + "_" + subjectCode + "_" + number;
     }
     }
@@ -161,7 +170,7 @@ public class CurrentTaskUtil {
                     Set<TaskEntry> set = taskMap.get(key);
                     Set<TaskEntry> set = taskMap.get(key);
                     if (set != null) {
                     if (set != null) {
                         for (TaskEntry obj : set) {
                         for (TaskEntry obj : set) {
-                            if (getDateDifference(obj.timestamp) >= timeoutMinute) {// 如果相隔时间超过阀值,则该试卷的放入清空池中
+                            if (getDateDifference(obj.getTimestamp()) >= timeoutMinute) {// 如果相隔时间超过阀值,则该试卷的放入清空池中
                                 taskMap1.put(key, obj);
                                 taskMap1.put(key, obj);
                             }
                             }
                         }
                         }
@@ -195,39 +204,3 @@ public class CurrentTaskUtil {
         return (getDateString() - oldTime) / (1000 * 60);
         return (getDateString() - oldTime) / (1000 * 60);
     }
     }
 }
 }
-
-class TaskEntry {
-
-    int markerId;
-
-    String taskId;
-
-    public long timestamp;
-
-    public TaskEntry(int markerId, String taskId) {
-        this.markerId = markerId;
-        this.taskId = taskId;
-        this.timestamp = System.currentTimeMillis();
-    }
-
-    @Override
-    public int hashCode() {
-        return taskId.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return markerId + "-" + taskId;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj != null && obj instanceof TaskEntry) {
-            TaskEntry mt = (TaskEntry) obj;
-            return StringUtils.equals(mt.taskId, this.taskId);
-        } else {
-            return false;
-        }
-    }
-
-}

+ 50 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/TaskEntry.java

@@ -0,0 +1,50 @@
+package cn.com.qmth.stmms.biz.utils;
+
+import org.apache.commons.lang.StringUtils;
+
+public class TaskEntry {
+
+    private int markerId;
+
+    private String taskId;
+
+    private long timestamp;
+
+    public TaskEntry(int markerId, String taskId) {
+        this.markerId = markerId;
+        this.taskId = taskId;
+        this.timestamp = System.currentTimeMillis();
+    }
+
+    @Override
+    public int hashCode() {
+        return taskId.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return markerId + "-" + taskId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj != null && obj instanceof TaskEntry) {
+            TaskEntry mt = (TaskEntry) obj;
+            return StringUtils.equals(mt.taskId, this.taskId);
+        } else {
+            return false;
+        }
+    }
+
+    public int getMarkerId() {
+        return markerId;
+    }
+
+    public String getTaskId() {
+        return taskId;
+    }
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+}

+ 17 - 0
stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/LibraryStatus.java

@@ -1,5 +1,8 @@
 package cn.com.qmth.stmms.common.enums;
 package cn.com.qmth.stmms.common.enums;
 
 
+import java.util.LinkedList;
+import java.util.List;
+
 public enum LibraryStatus {
 public enum LibraryStatus {
     WAITING("未处理", 0), MARKED("已给分", 1), BACKED("已打回", 2), WAIT_ARBITRATE("等待仲裁", 3), ARBITRATED("已仲裁", 4);
     WAITING("未处理", 0), MARKED("已给分", 1), BACKED("已打回", 2), WAIT_ARBITRATE("等待仲裁", 3), ARBITRATED("已仲裁", 4);
 
 
@@ -7,6 +10,8 @@ public enum LibraryStatus {
 
 
     private int value;
     private int value;
 
 
+    private static List<LibraryStatus> options;
+
     private LibraryStatus(String name, int value) {
     private LibraryStatus(String name, int value) {
         this.name = name;
         this.name = name;
         this.value = value;
         this.value = value;
@@ -28,4 +33,16 @@ public enum LibraryStatus {
         }
         }
         return null;
         return null;
     }
     }
+
+    public static List<LibraryStatus> getOptionList() {
+        if (options == null) {
+            options = new LinkedList<>();
+            for (LibraryStatus status : LibraryStatus.values()) {
+                if (status != BACKED) {
+                    options.add(status);
+                }
+            }
+        }
+        return options;
+    }
 }
 }

+ 10 - 6
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/LibraryController.java

@@ -63,9 +63,9 @@ public class LibraryController extends BaseExamController {
         }
         }
         subjectFilter(query, wu);
         subjectFilter(query, wu);
         List<MarkGroup> groupList = groupService.findByExamAndSubject(examId, query.getSubjectCode());
         List<MarkGroup> groupList = groupService.findByExamAndSubject(examId, query.getSubjectCode());
-//        if (groupList.isEmpty()) {
-//            return "redirect:/admin/exam/mark";
-//        }
+        // if (groupList.isEmpty()) {
+        // return "redirect:/admin/exam/mark";
+        // }
         if (query.getGroupNumber() == 0 && !groupList.isEmpty()) {
         if (query.getGroupNumber() == 0 && !groupList.isEmpty()) {
             query.setGroupNumber(groupList.get(0).getNumber());
             query.setGroupNumber(groupList.get(0).getNumber());
         }
         }
@@ -82,7 +82,7 @@ public class LibraryController extends BaseExamController {
         model.addAttribute("query", query);
         model.addAttribute("query", query);
         model.addAttribute("subjectList", getExamSubject(examId, wu));
         model.addAttribute("subjectList", getExamSubject(examId, wu));
         model.addAttribute("groupList", groupList);
         model.addAttribute("groupList", groupList);
-        model.addAttribute("statusList", LibraryStatus.values());
+        model.addAttribute("statusList", LibraryStatus.getOptionList());
         model.addAttribute("status", status);
         model.addAttribute("status", status);
         model.addAttribute("markerList",
         model.addAttribute("markerList",
                 markerService.findByExamAndSubjectAndGroup(examId, query.getSubjectCode(), query.getGroupNumber()));
                 markerService.findByExamAndSubjectAndGroup(examId, query.getSubjectCode(), query.getGroupNumber()));
@@ -98,8 +98,12 @@ public class LibraryController extends BaseExamController {
         MarkLibrary library = libraryService.findById(id);
         MarkLibrary library = libraryService.findById(id);
         if (library != null) {
         if (library != null) {
             if (subjectCheck(library.getSubjectCode(), RequestUtils.getWebUser(request))) {
             if (subjectCheck(library.getSubjectCode(), RequestUtils.getWebUser(request))) {
-                markService.backLibrary(library);
-                obj.accumulate("success", true);
+                if (markService.backLibrary(library)) {
+                    obj.accumulate("success", true);
+                } else {
+                    obj.accumulate("success", false);
+                    obj.accumulate("message", "无法打回该评卷任务");
+                }
             } else {
             } else {
                 obj.accumulate("success", false);
                 obj.accumulate("success", false);
                 obj.accumulate("message", "没有操作该评卷任务的权限");
                 obj.accumulate("message", "没有操作该评卷任务的权限");

+ 17 - 46
stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java

@@ -1,9 +1,7 @@
 package cn.com.qmth.stmms.mark;
 package cn.com.qmth.stmms.mark;
 
 
 import java.util.Date;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
 import java.util.List;
-import java.util.Set;
 
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
 
 
@@ -223,12 +221,9 @@ public class MarkController extends BaseController {
     private Task getTask(Marker marker) {
     private Task getTask(Marker marker) {
         int retry = 1;
         int retry = 1;
         Task task = null;
         Task task = null;
-        Set<LibraryStatus> set = new HashSet<LibraryStatus>();
-        set.add(LibraryStatus.WAITING);
-        set.add(LibraryStatus.BACKED);
         while (retry <= 10 && task == null) {
         while (retry <= 10 && task == null) {
-            List<MarkLibrary> list = libraryService.findByStatusSet(marker.getExamId(), marker.getSubjectCode(),
-                    marker.getGroupNumber(), set, retry, 20);
+            List<MarkLibrary> list = libraryService.findUnMarked(marker.getExamId(), marker.getSubjectCode(),
+                    marker.getGroupNumber(), marker.getId(), retry, 20);
             if (list.isEmpty()) {
             if (list.isEmpty()) {
                 break;
                 break;
             }
             }
@@ -251,25 +246,25 @@ public class MarkController extends BaseController {
     public JSONObject saveTask(HttpServletRequest request, @RequestBody Task task) {
     public JSONObject saveTask(HttpServletRequest request, @RequestBody Task task) {
         Marker marker = RequestUtils.getWebUser(request).getMarker();
         Marker marker = RequestUtils.getWebUser(request).getMarker();
         JSONObject result = new JSONObject();
         JSONObject result = new JSONObject();
+        boolean success = false;
         try {
         try {
             task.setSpent((new Date().getTime() - task.getSpent()) / 1000);
             task.setSpent((new Date().getTime() - task.getSpent()) / 1000);
             MarkLibrary library = libraryService.findById(task.getLibraryId());
             MarkLibrary library = libraryService.findById(task.getLibraryId());
-            if (checkLibrary(library, marker)) {
-                library.setMarkerId(marker.getId());
-                library.setMarkerTime(new Date());
-                library.setMarkerScore(task.getTotalScore());
-                library.setMarkerScoreList(task.getScoreList());
-                library.setStatus(LibraryStatus.MARKED);
-                library.setTags(StringUtils.trimToNull(task.getTags()));
-                markService.submitLibrary(library, marker, task.getTrackList(library), task.getSpecialTagList(library));
-                result.accumulate("success", true);
-                result.accumulate("status", status(request));
-            } else {
-                result.accumulate("success", false);
-            }
+            library.setMarkerId(marker.getId());
+            library.setMarkerTime(new Date());
+            library.setMarkerScore(task.getTotalScore());
+            library.setMarkerScoreList(task.getScoreList());
+            library.setStatus(LibraryStatus.MARKED);
+            library.setTags(StringUtils.trimToNull(task.getTags()));
+            success = markService.submitLibrary(library, marker, task.getTrackList(library),
+                    task.getSpecialTagList(library));
         } catch (Exception e) {
         } catch (Exception e) {
-            log.error("MarkController-保存任务出错", e);
-            result.accumulate("success", false);
+            log.error("save task error", e);
+        }
+        result.accumulate("success", success);
+        result.accumulate("status", status(request));
+        if (!success) {
+            result.accumulate("message", "评卷任务提交失败,请刷新重试");
         }
         }
         return result;
         return result;
     }
     }
@@ -329,28 +324,4 @@ public class MarkController extends BaseController {
         return array;
         return array;
     }
     }
 
 
-    private boolean checkLibrary(MarkLibrary library, Marker marker) {
-        if (library == null) {
-            return false;
-        }
-        if (!library.getExamId().equals(marker.getExamId())) {
-            return false;
-        }
-        if (!library.getSubjectCode().equals(marker.getSubjectCode())) {
-            return false;
-        }
-        if (!library.getGroupNumber().equals(marker.getGroupNumber())) {
-            return false;
-        }
-        if (library.getStatus() != LibraryStatus.WAITING && library.getStatus() != LibraryStatus.MARKED
-                && library.getStatus() != LibraryStatus.BACKED) {
-            return false;
-        }
-        if ((library.getStatus() == LibraryStatus.WAITING || library.getStatus() == LibraryStatus.BACKED)
-                && !markService.hasApplied(library, marker)) {
-            return false;
-        }
-        return true;
-    }
-
 }
 }

+ 39 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/monitor/TaskMonitorController.java

@@ -0,0 +1,39 @@
+package cn.com.qmth.stmms.monitor;
+
+import java.util.Date;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import cn.com.qmth.stmms.biz.utils.CurrentTaskUtil;
+import cn.com.qmth.stmms.biz.utils.TaskEntry;
+import cn.com.qmth.stmms.common.utils.DateUtils;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+@Controller("taskMonitor")
+@RequestMapping("/monitor/task")
+public class TaskMonitorController {
+
+    @RequestMapping
+    @ResponseBody
+    public Object list(HttpServletRequest request, @RequestParam Integer examId, @RequestParam String subjectCode,
+            @RequestParam Integer groupNumber) {
+        Set<TaskEntry> set = CurrentTaskUtil.list(examId, subjectCode, groupNumber);
+        JSONArray array = new JSONArray();
+        for (TaskEntry entry : set) {
+            JSONObject obj = new JSONObject();
+            obj.accumulate("taskId", entry.getTaskId());
+            obj.accumulate("markerId", entry.getMarkerId());
+            obj.accumulate("time", DateUtils.formatDateTime(new Date(entry.getTimestamp())));
+            array.add(obj);
+        }
+        return array;
+    }
+
+}

+ 1 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/libraryList.jsp

@@ -106,7 +106,7 @@
                     </c:if>
                     </c:if>
 				</td>
 				</td>
 				<td>
 				<td>
-				    <c:if test="${result.status.value!=0}">
+				    <c:if test="${result.status.value==1 || result.status.value==3}">
 				    <a class="track-link" href="##" data-image-url="${ctx}/admin/exam/track/byLibrary?libraryId=${result.id}" data-title="${result.examNumber}">阅卷轨迹</a>
 				    <a class="track-link" href="##" data-image-url="${ctx}/admin/exam/track/byLibrary?libraryId=${result.id}" data-title="${result.examNumber}">阅卷轨迹</a>
 				    </c:if>
 				    </c:if>
 				    <c:if test="${result.status.value==1}">
 				    <c:if test="${result.status.value==1}">