Sfoglia il codice sorgente

增加双评功能

1.MarkGroup增加双评相关配置
2.构造评卷任务时根据比例自动生成多评任务
3.评卷员领取多评任务时避免studentId重复
4.评卷提交判断是否仲裁
5.管理员/组长查看仲裁记录
luoshi 6 anni fa
parent
commit
b4118df64c
36 ha cambiato i file con 4655 aggiunte e 3255 eliminazioni
  1. 101 97
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/MarkGroupDao.java
  2. 239 206
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamQuestion.java
  3. 75 3
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/MarkGroup.java
  4. 2 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/MarkGroupService.java
  5. 13 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/MarkGroupServiceImpl.java
  6. 35 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/ArbitrateHistoryDao.java
  7. 98 87
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkLibraryDao.java
  8. 208 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/ArbitrateHistory.java
  9. 44 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/ArbitrationDTO.java
  10. 314 300
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkLibrary.java
  11. 13 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/SpecialTagDTO.java
  12. 11 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/Task.java
  13. 86 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/ArbitrateHistorySearchQuery.java
  14. 23 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/ArbitrateHistoryService.java
  15. 108 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/ArbitrateHistoryServiceImpl.java
  16. 298 265
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkLibraryServiceImpl.java
  17. 13 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkServiceImpl.java
  18. 204 104
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/TaskServiceImpl.java
  19. 65 56
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkLibraryService.java
  20. 6 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkService.java
  21. 8 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/TaskService.java
  22. 32 31
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/HistoryStatus.java
  23. 31 31
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/LibraryStatus.java
  24. 37 0
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/ScorePolicy.java
  25. 2 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectQuestionDTO.java
  26. 41 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectiveQuestionDTO.java
  27. 283 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ArbitrateController.java
  28. 275 252
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkController.java
  29. 9 4
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkGroupController.java
  30. 491 488
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkerController.java
  31. 403 409
      stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ExamStudentController.java
  32. 370 360
      stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java
  33. 159 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/arbitrateList.jsp
  34. 1 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/groupList.jsp
  35. 193 192
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/libraryList.jsp
  36. 364 363
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/markerList.jsp

+ 101 - 97
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/MarkGroupDao.java

@@ -1,97 +1,101 @@
-package cn.com.qmth.stmms.biz.exam.dao;
-
-import java.util.Date;
-import java.util.List;
-
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.PagingAndSortingRepository;
-
-import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
-import cn.com.qmth.stmms.biz.exam.model.MarkGroupPK;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-public interface MarkGroupDao
-        extends PagingAndSortingRepository<MarkGroup, MarkGroupPK>, JpaSpecificationExecutor<MarkGroup> {
-
-    @Modifying
-    @Query("delete from MarkGroup q where q.pk.examId=?1")
-    void deleteByExamId(int examId);
-
-    @Modifying
-    @Query("delete from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2")
-    void deleteByExamIdAndSubjectCode(int examId, String subjectCode);
-
-    @Query("select count(q) from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2")
-    long countByExamIdAndSubjectCode(int examId, String subjectCode);
-
-    @Query("select q from MarkGroup q where q.pk.examId=?1 order by q.pk.number")
-    List<MarkGroup> findByExamId(int examId);
-
-    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 order by q.pk.number")
-    List<MarkGroup> findByExamIdAndSubjectCode(int examId, String code);
-
-    @Query("select count(q) from MarkGroup q where q.pk.examId=?1")
-    long countByExamId(int examId);
-
-    @Modifying
-    @Query("update MarkGroup g set g.libraryCount=(select count(l) from MarkLibrary l "
-            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number) "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
-    void updateLibraryCount(int examId, String subjectCode);
-
-    @Modifying
-    @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
-            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number and l.status=?3) "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
-    void updateMarkedCount(int examId, String subjectCode, LibraryStatus status);
-
-    @Modifying
-    @Query("update MarkGroup g set g.leftCount = g.libraryCount - g.markedCount "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
-    void updateLeftCount(int examId, String subjectCode);
-
-    @Modifying
-    @Query("update MarkGroup g set g.libraryCount=(select count(l) from MarkLibrary l "
-            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3) "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updateLibraryCount(int examId, String subjectCode, int number);
-
-    @Modifying
-    @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
-            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3 and l.status=?4 ) "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updateMarkedCount(int examId, String subjectCode, int number, LibraryStatus status);
-
-    @Modifying
-    @Query("update MarkGroup g set g.leftCount = g.libraryCount - g.markedCount "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updateLeftCount(int examId, String subjectCode, int number);
-
-    @Modifying
-    @Query("update MarkGroup g set g.leftCount = g.libraryCount, g.markedCount = 0 "
-            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void resetCount(int examId, String subjectCode, int number);
-
-    @Modifying
-    @Query("update MarkGroup g set g.picList=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updatePicList(int examId, String subjectCode, int number, String picList);
-
-    @Modifying
-    @Query("update MarkGroup g set g.title=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updateTitle(int examId, String subjectCode, int number, String title);
-
-    @Modifying
-    @Query("update MarkGroup g set g.totalScore=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updateTotalScore(int examId, String subjectCode, int number, Double score);
-
-    @Modifying
-    @Query("update MarkGroup g set g.buildTime=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
-    void updateBuildTime(int examId, String subjectCode, int number, Date time);
-
-    @Modifying
-    @Query("update MarkGroup g set g.buildTime=?3 where g.pk.examId=?1 and g.pk.subjectCode=?2")
-    void updateBuildTime(int examId, String subjectCode, Date time);
-
-}
+package cn.com.qmth.stmms.biz.exam.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroupPK;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+public interface MarkGroupDao
+        extends PagingAndSortingRepository<MarkGroup, MarkGroupPK>, JpaSpecificationExecutor<MarkGroup> {
+
+    @Modifying
+    @Query("delete from MarkGroup q where q.pk.examId=?1")
+    void deleteByExamId(int examId);
+
+    @Modifying
+    @Query("delete from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2")
+    void deleteByExamIdAndSubjectCode(int examId, String subjectCode);
+
+    @Query("select count(q) from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2")
+    long countByExamIdAndSubjectCode(int examId, String subjectCode);
+
+    @Query("select q from MarkGroup q where q.pk.examId=?1 order by q.pk.number")
+    List<MarkGroup> findByExamId(int examId);
+
+    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 order by q.pk.number")
+    List<MarkGroup> findByExamIdAndSubjectCode(int examId, String code);
+
+    @Query("select q from MarkGroup q where q.pk.examId=?1 and q.pk.subjectCode=?2 "
+            + "and q.doubleRate!=null and q.doubleRate>0 order by q.pk.number")
+    List<MarkGroup> findByExamIdAndSubjectCodeWithDouble(int examId, String code);
+
+    @Query("select count(q) from MarkGroup q where q.pk.examId=?1")
+    long countByExamId(int examId);
+
+    @Modifying
+    @Query("update MarkGroup g set g.libraryCount=(select count(l) from MarkLibrary l "
+            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number) "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
+    void updateLibraryCount(int examId, String subjectCode);
+
+    @Modifying
+    @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
+            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number and l.status in ?3) "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
+    void updateMarkedCount(int examId, String subjectCode, LibraryStatus... status);
+
+    @Modifying
+    @Query("update MarkGroup g set g.leftCount = g.libraryCount - g.markedCount "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
+    void updateLeftCount(int examId, String subjectCode);
+
+    @Modifying
+    @Query("update MarkGroup g set g.libraryCount=(select count(l) from MarkLibrary l "
+            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3) "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updateLibraryCount(int examId, String subjectCode, int number);
+
+    @Modifying
+    @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
+            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3 and l.status in ?4 ) "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updateMarkedCount(int examId, String subjectCode, int number, LibraryStatus... status);
+
+    @Modifying
+    @Query("update MarkGroup g set g.leftCount = g.libraryCount - g.markedCount "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updateLeftCount(int examId, String subjectCode, int number);
+
+    @Modifying
+    @Query("update MarkGroup g set g.leftCount = g.libraryCount, g.markedCount = 0 "
+            + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void resetCount(int examId, String subjectCode, int number);
+
+    @Modifying
+    @Query("update MarkGroup g set g.picList=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updatePicList(int examId, String subjectCode, int number, String picList);
+
+    @Modifying
+    @Query("update MarkGroup g set g.title=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updateTitle(int examId, String subjectCode, int number, String title);
+
+    @Modifying
+    @Query("update MarkGroup g set g.totalScore=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updateTotalScore(int examId, String subjectCode, int number, Double score);
+
+    @Modifying
+    @Query("update MarkGroup g set g.buildTime=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
+    void updateBuildTime(int examId, String subjectCode, int number, Date time);
+
+    @Modifying
+    @Query("update MarkGroup g set g.buildTime=?3 where g.pk.examId=?1 and g.pk.subjectCode=?2")
+    void updateBuildTime(int examId, String subjectCode, Date time);
+
+}

+ 239 - 206
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamQuestion.java

@@ -1,206 +1,239 @@
-package cn.com.qmth.stmms.biz.exam.model;
-
-import java.io.Serializable;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.persistence.Column;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-@Entity
-@Table(name = "eb_exam_question")
-public class ExamQuestion implements Serializable {
-
-    private static final long serialVersionUID = -6614640229855098561L;
-
-    @EmbeddedId
-    private QuestionPK pk;
-
-    @Column(name = "main_title", length = 128)
-    private String mainTitle;
-
-    @Column(name = "answer")
-    private String answer;
-
-    @Column(name = "total_score")
-    private Double totalScore;
-
-    @Column(name = "interval_score")
-    private Double intervalScore;
-
-    /**
-     * 考生人数
-     */
-    @Column(name = "total_count")
-    private Integer totalCount;
-
-    /**
-     * 零分人数
-     */
-    @Column(name = "zero_count")
-    private Integer zeroCount;
-
-    /**
-     * 满分人数
-     */
-    @Column(name = "full_count")
-    private Integer fullCount;
-
-    @Transient
-    private ExamSubject subject;
-
-    @Transient
-    private String picList;
-
-    public ExamQuestion() {
-        this.pk = new QuestionPK();
-    }
-
-    public Integer getExamId() {
-        return pk.getExamId();
-    }
-
-    public void setExamId(Integer examId) {
-        pk.setExamId(examId);
-    }
-
-    public String getSubjectCode() {
-        return pk.getSubjectCode();
-    }
-
-    public void setSubjectCode(String subjectCode) {
-        pk.setSubjectCode(subjectCode);
-    }
-
-    public Integer getMainNumber() {
-        return pk.getMainNumber();
-    }
-
-    public void setMainNumber(Integer mainNumber) {
-        pk.setMainNumber(mainNumber);
-    }
-
-    public Integer getSubNumber() {
-        return pk.getSubNumber();
-    }
-
-    public void setSubNumber(Integer subNumber) {
-        pk.setSubNumber(subNumber);
-    }
-
-    public String getMainTitle() {
-        return mainTitle;
-    }
-
-    public void setObjective(boolean objective) {
-        pk.setObjective(objective);
-    }
-
-    public boolean isObjective() {
-        return pk.isObjective();
-    }
-
-    public void setMainTitle(String mainTitle) {
-        this.mainTitle = mainTitle;
-    }
-
-    public Double getTotalScore() {
-        return totalScore;
-    }
-
-    public void setTotalScore(Double totalScore) {
-        this.totalScore = totalScore;
-    }
-
-    public String getName() {
-        if (mainTitle != null && getSubNumber() != null) {
-            return mainTitle + "-" + getSubNumber();
-        } else {
-            return "";
-        }
-    }
-
-    public List<Double> getScoreList() {
-        List<Double> list = new LinkedList<Double>();
-        if (totalScore != null && intervalScore != null) {
-            for (double score = 0; score <= totalScore; score += intervalScore) {
-                list.add(score);
-            }
-        }
-        return list;
-    }
-
-    public double[] getScoreListArray() {
-        List<Double> list = getScoreList();
-        int length = list.size();
-        double[] array = new double[length];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    public String getAnswer() {
-        return answer;
-    }
-
-    public void setAnswer(String answer) {
-        this.answer = answer;
-    }
-
-    public Double getIntervalScore() {
-        return intervalScore;
-    }
-
-    public void setIntervalScore(Double intervalScore) {
-        this.intervalScore = intervalScore;
-    }
-
-    public Integer getZeroCount() {
-        return zeroCount;
-    }
-
-    public void setZeroCount(Integer zeroCount) {
-        this.zeroCount = zeroCount;
-    }
-
-    public Integer getFullCount() {
-        return fullCount;
-    }
-
-    public void setFullCount(Integer fullCount) {
-        this.fullCount = fullCount;
-    }
-
-    public Integer getTotalCount() {
-        return totalCount;
-    }
-
-    public void setTotalCount(Integer totalCount) {
-        this.totalCount = totalCount;
-    }
-
-    public ExamSubject getSubject() {
-        return subject;
-    }
-
-    public void setSubject(ExamSubject subject) {
-        this.subject = subject;
-    }
-
-    public String getQuestionNumber() {
-        return getMainNumber() + "." + getSubNumber();
-    }
-
-    public String getPicList() {
-        return picList;
-    }
-
-    public void setPicList(String picList) {
-        this.picList = picList;
-    }
-
-}
+package cn.com.qmth.stmms.biz.exam.model;
+
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+@Entity
+@Table(name = "eb_exam_question")
+public class ExamQuestion implements Serializable {
+
+    private static final long serialVersionUID = -6614640229855098561L;
+
+    @EmbeddedId
+    private QuestionPK pk;
+
+    @Column(name = "main_title", length = 128)
+    private String mainTitle;
+
+    @Column(name = "answer")
+    private String answer;
+
+    @Column(name = "total_score")
+    private Double totalScore;
+
+    @Column(name = "interval_score")
+    private Double intervalScore;
+
+    /**
+     * 考生人数
+     */
+    @Column(name = "total_count")
+    private Integer totalCount;
+
+    /**
+     * 零分人数
+     */
+    @Column(name = "zero_count")
+    private Integer zeroCount;
+
+    /**
+     * 满分人数
+     */
+    @Column(name = "full_count")
+    private Integer fullCount;
+
+    @Transient
+    private ExamSubject subject;
+
+    @Transient
+    private String picList;
+
+    @Transient
+    private Double doubleRate;
+
+    @Transient
+    private Double arbitrateThreshold;
+
+    @Transient
+    private Integer scorePolicy;
+
+    public ExamQuestion() {
+        this.pk = new QuestionPK();
+    }
+
+    public Integer getExamId() {
+        return pk.getExamId();
+    }
+
+    public void setExamId(Integer examId) {
+        pk.setExamId(examId);
+    }
+
+    public String getSubjectCode() {
+        return pk.getSubjectCode();
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        pk.setSubjectCode(subjectCode);
+    }
+
+    public Integer getMainNumber() {
+        return pk.getMainNumber();
+    }
+
+    public void setMainNumber(Integer mainNumber) {
+        pk.setMainNumber(mainNumber);
+    }
+
+    public Integer getSubNumber() {
+        return pk.getSubNumber();
+    }
+
+    public void setSubNumber(Integer subNumber) {
+        pk.setSubNumber(subNumber);
+    }
+
+    public String getMainTitle() {
+        return mainTitle;
+    }
+
+    public void setObjective(boolean objective) {
+        pk.setObjective(objective);
+    }
+
+    public boolean isObjective() {
+        return pk.isObjective();
+    }
+
+    public void setMainTitle(String mainTitle) {
+        this.mainTitle = mainTitle;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public String getName() {
+        if (mainTitle != null && getSubNumber() != null) {
+            return mainTitle + "-" + getSubNumber();
+        } else {
+            return "";
+        }
+    }
+
+    public List<Double> getScoreList() {
+        List<Double> list = new LinkedList<Double>();
+        if (totalScore != null && intervalScore != null) {
+            for (double score = 0; score <= totalScore; score += intervalScore) {
+                list.add(score);
+            }
+        }
+        return list;
+    }
+
+    public double[] getScoreListArray() {
+        List<Double> list = getScoreList();
+        int length = list.size();
+        double[] array = new double[length];
+        for (int i = 0; i < list.size(); i++) {
+            array[i] = list.get(i);
+        }
+        return array;
+    }
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public Double getIntervalScore() {
+        return intervalScore;
+    }
+
+    public void setIntervalScore(Double intervalScore) {
+        this.intervalScore = intervalScore;
+    }
+
+    public Integer getZeroCount() {
+        return zeroCount;
+    }
+
+    public void setZeroCount(Integer zeroCount) {
+        this.zeroCount = zeroCount;
+    }
+
+    public Integer getFullCount() {
+        return fullCount;
+    }
+
+    public void setFullCount(Integer fullCount) {
+        this.fullCount = fullCount;
+    }
+
+    public Integer getTotalCount() {
+        return totalCount;
+    }
+
+    public void setTotalCount(Integer totalCount) {
+        this.totalCount = totalCount;
+    }
+
+    public ExamSubject getSubject() {
+        return subject;
+    }
+
+    public void setSubject(ExamSubject subject) {
+        this.subject = subject;
+    }
+
+    public String getQuestionNumber() {
+        return getMainNumber() + "." + getSubNumber();
+    }
+
+    public String getPicList() {
+        return picList;
+    }
+
+    public void setPicList(String picList) {
+        this.picList = picList;
+    }
+
+    public Double getDoubleRate() {
+        return doubleRate;
+    }
+
+    public void setDoubleRate(Double doubleRate) {
+        this.doubleRate = doubleRate;
+    }
+
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
+
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
+
+    public Integer getScorePolicy() {
+        return scorePolicy;
+    }
+
+    public void setScorePolicy(Integer scorePolicy) {
+        this.scorePolicy = scorePolicy;
+    }
+
+}

+ 75 - 3
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/MarkGroup.java

@@ -8,6 +8,8 @@ import java.util.List;
 import javax.persistence.Column;
 import javax.persistence.EmbeddedId;
 import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
@@ -16,6 +18,8 @@ import javax.persistence.Transient;
 import org.apache.commons.lang.StringUtils;
 
 import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
+import cn.com.qmth.stmms.biz.utils.ScoreItem;
+import cn.com.qmth.stmms.common.enums.ScorePolicy;
 
 @Entity
 @Table(name = "eb_mark_group")
@@ -35,6 +39,16 @@ public class MarkGroup implements Serializable {
     @Column(name = "total_score", nullable = false)
     private Double totalScore;
 
+    @Column(name = "double_rate", nullable = true)
+    private Double doubleRate;
+
+    @Column(name = "arbitrate_threshold", nullable = true)
+    private Double arbitrateThreshold;
+
+    @Column(name = "score_policy", nullable = true)
+    @Enumerated(EnumType.STRING)
+    private ScorePolicy scorePolicy;
+
     @Temporal(TemporalType.TIMESTAMP)
     @Column(name = "build_time", nullable = true)
     private Date buildTime;
@@ -63,12 +77,19 @@ public class MarkGroup implements Serializable {
     @Transient
     private int percent;
 
+    @Transient
+    private double markScore;
+
+    @Transient
+    private List<ScoreItem> markScoreDetail;
+
     public MarkGroup() {
         this.pk = new MarkGroupPK();
     }
 
     public MarkGroup(Integer examId, String subjectCode, Integer number, String title,
-            List<PictureConfigItem> configList, Double totalScore) {
+            List<PictureConfigItem> configList, Double totalScore, Double doubleRate, Double arbitrateThreshold,
+            Integer scorePolicy) {
         this.pk = new MarkGroupPK();
         this.pk.setExamId(examId);
         this.pk.setNumber(number);
@@ -76,11 +97,21 @@ public class MarkGroup implements Serializable {
         this.title = title;
         this.picList = configList != null && configList.size() > 0
                 ? StringUtils.join(configList, PictureConfigItem.DB_ITEM_JOINER)
-                : null;
+                : "";
         this.totalScore = totalScore;
         this.libraryCount = 0;
         this.markedCount = 0;
         this.leftCount = 0;
+
+        if (doubleRate != null && doubleRate >= 0 && doubleRate <= 1) {
+            this.doubleRate = doubleRate;
+        }
+        if (arbitrateThreshold != null && arbitrateThreshold > 0) {
+            this.arbitrateThreshold = arbitrateThreshold;
+        }
+        if (scorePolicy != null) {
+            this.scorePolicy = ScorePolicy.findByValue(scorePolicy);
+        }
     }
 
     public Integer getExamId() {
@@ -118,7 +149,7 @@ public class MarkGroup implements Serializable {
     public void setPicList(List<PictureConfigItem> configList) {
         this.picList = configList != null && configList.size() > 0
                 ? StringUtils.join(configList, PictureConfigItem.DB_ITEM_JOINER)
-                : null;
+                : "";
     }
 
     public List<PictureConfigItem> getPictureConfigList() {
@@ -224,4 +255,45 @@ public class MarkGroup implements Serializable {
     public void setPercent(int percent) {
         this.percent = percent;
     }
+
+    public Double getDoubleRate() {
+        return doubleRate;
+    }
+
+    public void setDoubleRate(Double doubleRate) {
+        this.doubleRate = doubleRate;
+    }
+
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
+
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
+
+    public ScorePolicy getScorePolicy() {
+        return scorePolicy;
+    }
+
+    public void setScorePolicy(ScorePolicy scorePolicy) {
+        this.scorePolicy = scorePolicy;
+    }
+
+    public double getMarkScore() {
+        return markScore;
+    }
+
+    public void setMarkScore(double markScore) {
+        this.markScore = markScore;
+    }
+
+    public List<ScoreItem> getMarkScoreDetail() {
+        return markScoreDetail;
+    }
+
+    public void setMarkScoreDetail(List<ScoreItem> markScoreDetail) {
+        this.markScoreDetail = markScoreDetail;
+    }
+
 }

+ 2 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/MarkGroupService.java

@@ -22,6 +22,8 @@ public interface MarkGroupService {
 
     List<MarkGroup> findByExamAndSubject(int examId, String code);
 
+    List<MarkGroup> findByExamAndSubjectWithDouble(int examId, String code);
+
     long countByExam(int examId);
 
     void updatePicList(int examId, String subjectCode, int number, List<PictureConfigItem> picList);

+ 13 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/MarkGroupServiceImpl.java

@@ -18,6 +18,7 @@ import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
 import cn.com.qmth.stmms.biz.exam.service.MarkerService;
 import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
+import cn.com.qmth.stmms.biz.mark.service.ArbitrateHistoryService;
 import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
 import cn.com.qmth.stmms.biz.mark.service.TaskService;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
@@ -40,6 +41,9 @@ public class MarkGroupServiceImpl extends BaseQueryService<MarkGroup> implements
     @Autowired
     private MarkLibraryService libraryService;
 
+    @Autowired
+    private ArbitrateHistoryService arbitrateService;
+
     @Autowired
     private TaskService taskService;
 
@@ -62,6 +66,7 @@ public class MarkGroupServiceImpl extends BaseQueryService<MarkGroup> implements
         groupDao.resetCount(group.getExamId(), group.getSubjectCode(), group.getNumber());
 
         libraryService.resetByGroup(group);
+        arbitrateService.deleteByGroup(group);
         taskService.clearCurrent(group.getExamId(), group.getSubjectCode(), group.getNumber());
     }
 
@@ -80,6 +85,7 @@ public class MarkGroupServiceImpl extends BaseQueryService<MarkGroup> implements
         questionService.deleteByExamAndSubjectAndObjectiveAndMainNumber(group.getExamId(), group.getSubjectCode(),
                 false, group.getNumber());
         libraryService.deleteByGroup(group);
+        arbitrateService.deleteByGroup(group);
         markerService.deleteByGroup(group);
         subjectService.updateScore(group.getExamId(), group.getSubjectCode());
     }
@@ -88,7 +94,7 @@ public class MarkGroupServiceImpl extends BaseQueryService<MarkGroup> implements
     @Override
     public void updateLibraryCount(int examId, String subjectCode, int number) {
         groupDao.updateLibraryCount(examId, subjectCode, number);
-        groupDao.updateMarkedCount(examId, subjectCode, number, LibraryStatus.MARKED);
+        groupDao.updateMarkedCount(examId, subjectCode, number, LibraryStatus.MARKED, LibraryStatus.ARBITRATED);
         groupDao.updateLeftCount(examId, subjectCode, number);
     }
 
@@ -96,7 +102,7 @@ public class MarkGroupServiceImpl extends BaseQueryService<MarkGroup> implements
     @Override
     public void updateLibraryCount(int examId, String subjectCode) {
         groupDao.updateLibraryCount(examId, subjectCode);
-        groupDao.updateMarkedCount(examId, subjectCode, LibraryStatus.MARKED);
+        groupDao.updateMarkedCount(examId, subjectCode, LibraryStatus.MARKED, LibraryStatus.ARBITRATED);
         groupDao.updateLeftCount(examId, subjectCode);
     }
 
@@ -164,6 +170,11 @@ public class MarkGroupServiceImpl extends BaseQueryService<MarkGroup> implements
         return groupDao.findByExamIdAndSubjectCode(examId, code);
     }
 
+    @Override
+    public List<MarkGroup> findByExamAndSubjectWithDouble(int examId, String code) {
+        return groupDao.findByExamIdAndSubjectCodeWithDouble(examId, code);
+    }
+
     @Override
     public long countByExam(int examId) {
         return groupDao.countByExamId(examId);

+ 35 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/ArbitrateHistoryDao.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.stmms.biz.mark.dao;
+
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+public interface ArbitrateHistoryDao
+        extends PagingAndSortingRepository<ArbitrateHistory, Integer>, JpaSpecificationExecutor<ArbitrateHistory> {
+
+    List<ArbitrateHistory> findByExamIdAndSubjectCodeAndGroupNumber(Integer examId, String subjectCode,
+            Integer groupNumber, Pageable page);
+
+    List<ArbitrateHistory> findByExamIdAndSubjectCodeAndGroupNumberAndStatus(Integer examId, String subjectCode,
+            Integer groupNumber, LibraryStatus status, Pageable page);
+
+    List<ArbitrateHistory> findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(Integer examId, String subjectCode,
+            Integer groupNumber, Set<LibraryStatus> statusSet, Pageable page);
+
+    @Modifying
+    @Query("delete ArbitrateHistory m where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3")
+    void deleteByExamIdAndSubjectCodeAndGroupNumber(Integer examId, String subjectCode, Integer groupNumber);
+
+    @Modifying
+    @Query("delete ArbitrateHistory m where m.studentId=?1")
+    void deleteByStudentId(Integer studentId);
+
+}

+ 98 - 87
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkLibraryDao.java

@@ -1,87 +1,98 @@
-package cn.com.qmth.stmms.biz.mark.dao;
-
-import java.util.List;
-import java.util.Set;
-
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.PagingAndSortingRepository;
-
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-public interface MarkLibraryDao
-        extends PagingAndSortingRepository<MarkLibrary, Integer>, JpaSpecificationExecutor<MarkLibrary> {
-
-    List<MarkLibrary> findByExamId(int examId, Pageable page);
-
-    List<MarkLibrary> findByExamIdAndSubjectCode(int examId, String subjectCode, Pageable page);
-
-    List<MarkLibrary> findByExamIdAndStatus(int examId, LibraryStatus status, Pageable page);
-
-    List<MarkLibrary> findByExamIdAndSubjectCodeAndGroupNumberAndStatus(int examId, String subjectCode, int groupNumber,
-            LibraryStatus status, Pageable page);
-
-    List<MarkLibrary> findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(int examId, String subjectCode,
-            int groupNumber, Set<LibraryStatus> statusSet, Pageable page);
-
-    List<MarkLibrary> findByExamIdAndMarkerId(int examId, int markerId, Pageable page);
-
-    List<MarkLibrary> findByExamIdAndExamNumber(int examId, String examNumber);
-
-    @Query("select l from MarkLibrary l where l.studentId=?1 order by l.groupNumber ")
-    List<MarkLibrary> findByStudentId(int studentId);
-
-    List<MarkLibrary> findByStudentIdAndGroupNumber(int studentId, int groupNumber);
-
-    @Query("select distinct l.campusId from MarkLibrary l where l.examId=?1 and l.tags is not null")
-    List<Integer> findTagCampusId(int examId);
-
-    @Query("select distinct l.subjectCode from MarkLibrary l where l.examId=?1 and l.tags is not null")
-    List<String> findTagSubjectCode(int examId);
-
-    @Modifying
-    @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null where m.examId=?1")
-    void resetByExamId(int examId, LibraryStatus status);
-
-    @Modifying
-    @Query("update MarkLibrary m set m.status=?4, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3")
-    void resetByExamIdAndSubjectCodeAndNumber(int examId, String subjectCode, int number, LibraryStatus status);
-
-    @Modifying
-    @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null where m.markerId=?1")
-    void resetByMarkerId(int markerId, LibraryStatus status);
-
-    @Modifying
-    @Query("update MarkLibrary m set m.status=?2, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null where m.id=?1")
-    void resetById(int id, LibraryStatus status);
-
-    @Query("select count(*) from MarkLibrary f where f.examId=?1")
-    long countByExamId(int examId);
-
-    @Query("select count(*) from MarkLibrary f where f.examId=?1 and f.subjectCode=?2")
-    long countByExamIdAndSubjectCode(int examId, String subjectCode);
-
-    @Query("select count(*) from MarkLibrary f where f.examId=?1 and f.subjectCode=?2 and f.status=?3")
-    long countByExamIdAndSubjectCodeAndStatus(int examId, String subjectCode, LibraryStatus status);
-
-    @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(int examId, LibraryStatus status);
-
-    @Query("select f.markerId, count(*) as markerCount from MarkLibrary f where f.examId=?1 and f.subjectCode=?2 and f.status=?3 group by f.markerId")
-    List<Object[]> countByMarkerAndStatus(int examId, String subjectCode, LibraryStatus status);
-
-    @Modifying
-    @Query("delete MarkLibrary m where m.examId=?1")
-    void deleteByExamId(int examId);
-
-    @Modifying
-    @Query("delete MarkLibrary m where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3")
-    void deleteByExamIdAndSubjectCodeAndGroupNumber(int examId, String subjectCode, int groupNumber);
-
-    @Query("select l from MarkLibrary l where l.studentId=?1 and l.status=?2 order by l.groupNumber ")
-    List<MarkLibrary> findByStudentIdAndStatus(int studentId, LibraryStatus status);
-
-}
+package cn.com.qmth.stmms.biz.mark.dao;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+public interface MarkLibraryDao
+        extends PagingAndSortingRepository<MarkLibrary, Integer>, JpaSpecificationExecutor<MarkLibrary> {
+
+    List<MarkLibrary> findByExamId(int examId, Pageable page);
+
+    List<MarkLibrary> findByExamIdAndSubjectCode(int examId, String subjectCode, Pageable page);
+
+    List<MarkLibrary> findByExamIdAndStatus(int examId, LibraryStatus status, Pageable page);
+
+    List<MarkLibrary> findByExamIdAndSubjectCodeAndGroupNumberAndStatus(int examId, String subjectCode, int groupNumber,
+            LibraryStatus status, Pageable page);
+
+    List<MarkLibrary> findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(int examId, String subjectCode,
+            int groupNumber, Set<LibraryStatus> statusSet, Pageable page);
+
+    List<MarkLibrary> findByExamIdAndMarkerId(int examId, int markerId, Pageable page);
+
+    List<MarkLibrary> findByExamIdAndExamNumber(int examId, String examNumber);
+
+    @Query("select l from MarkLibrary l where l.studentId=?1 order by l.groupNumber ")
+    List<MarkLibrary> findByStudentId(int studentId);
+
+    List<MarkLibrary> findByStudentIdAndGroupNumber(int studentId, int groupNumber);
+
+    @Query("select distinct l.campusId from MarkLibrary l where l.examId=?1 and l.tags is not null")
+    List<Integer> findTagCampusId(int examId);
+
+    @Query("select distinct l.subjectCode from MarkLibrary l where l.examId=?1 and l.tags is not null")
+    List<String> findTagSubjectCode(int examId);
+
+    @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 where m.examId=?1")
+    void resetByExamId(int examId, LibraryStatus status);
+
+    @Modifying(clearAutomatically = true)
+    @Query("update MarkLibrary m set m.status=?4, m.tags=null, m.markerId=null, m.markerTime=null, m.markerScore=null, m.markerScoreList=null where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3")
+    void resetByExamIdAndSubjectCodeAndNumber(int examId, String subjectCode, int number, LibraryStatus status);
+
+    @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 where m.markerId=?1")
+    void resetByMarkerId(int markerId, LibraryStatus status);
+
+    @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 where m.id=?1")
+    void resetById(int id, LibraryStatus status);
+
+    @Query("select count(*) from MarkLibrary f where f.examId=?1")
+    long countByExamId(int examId);
+
+    @Query("select count(*) from MarkLibrary f where f.examId=?1 and f.subjectCode=?2")
+    long countByExamIdAndSubjectCode(int examId, String subjectCode);
+
+    @Query("select count(*) from MarkLibrary f where f.examId=?1 and f.subjectCode=?2 and f.status=?3")
+    long countByExamIdAndSubjectCodeAndStatus(int examId, String subjectCode, LibraryStatus status);
+
+    @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(int examId, LibraryStatus status);
+
+    @Query("select f.markerId, count(*) as markerCount from MarkLibrary f where f.examId=?1 and f.subjectCode=?2 and f.status=?3 group by f.markerId")
+    List<Object[]> countByMarkerAndStatus(int examId, String subjectCode, LibraryStatus status);
+
+    @Modifying
+    @Query("delete MarkLibrary m where m.examId=?1")
+    void deleteByExamId(int examId);
+
+    @Modifying
+    @Query("delete MarkLibrary m where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3")
+    void deleteByExamIdAndSubjectCodeAndGroupNumber(int examId, String subjectCode, int groupNumber);
+
+    @Query("select l from MarkLibrary l where l.studentId=?1 and l.status=?2 order by l.groupNumber ")
+    List<MarkLibrary> findByStudentIdAndStatus(int studentId, LibraryStatus status);
+
+    @Modifying(clearAutomatically = true)
+    @Query("update MarkLibrary m set m.headerId=?3, m.headerScore=?4, m.headerScoreList=?5, m.headerTime=?6, "
+            + "m.status=?7 where m.studentId=?1 and m.groupNumber=?2")
+    void updateHeaderResult(Integer studentId, Integer groupNumber, Integer userId, Double totalScore, String scoreList,
+            Date updateTime, LibraryStatus arbitrated);
+
+    @Modifying(clearAutomatically = true)
+    @Query("update MarkLibrary m set m.status=?3 where m.studentId=?1 and m.groupNumber=?2")
+    void updateByStudentIdAndGroupNumber(Integer studentId, Integer groupNumber, LibraryStatus status);
+
+}

+ 208 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/ArbitrateHistory.java

@@ -0,0 +1,208 @@
+package cn.com.qmth.stmms.biz.mark.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import cn.com.qmth.stmms.biz.user.model.User;
+import cn.com.qmth.stmms.common.enums.HistoryStatus;
+
+/**
+ * 多评仲裁记录表
+ * 
+ * @author luoshi
+ *
+ */
+@Entity
+@Table(name = "m_arbitrate_history")
+public class ArbitrateHistory implements Serializable {
+
+    private static final long serialVersionUID = -6778980854289204628L;
+
+    @Id
+    @GeneratedValue
+    private Integer id;
+
+    /**
+     * 考试ID
+     */
+    @Column(name = "exam_id")
+    private Integer examId;
+
+    /**
+     * 科目CODE
+     */
+    @Column(name = "subject_code")
+    private String subjectCode;
+
+    /**
+     * 大题序号
+     */
+    @Column(name = "group_number")
+    private Integer groupNumber;
+
+    /**
+     * 考生编号
+     */
+    @Column(name = "student_id")
+    private Integer studentId;
+
+    /**
+     * 准考证号
+     */
+    @Column(name = "exam_number")
+    private String examNumber;
+
+    /**
+     * 仲裁处理用户ID
+     */
+    @Column(name = "user_id", nullable = true)
+    private Integer userId;
+
+    /**
+     * 仲裁给分总分
+     */
+    @Column(name = "total_score", nullable = true)
+    private Double totalScore;
+
+    /**
+     * 仲裁给分明细
+     */
+    @Column(name = "score_list", nullable = true, length = 255)
+    private String scoreList;
+
+    /**
+     * 状态
+     */
+    @Column(name = "status")
+    @Enumerated(EnumType.ORDINAL)
+    private HistoryStatus status;
+
+    /**
+     * 处理时间
+     */
+    @Column(name = "update_time", nullable = true)
+    private Date updateTime;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_time", nullable = false)
+    private Date createTime;
+
+    @Transient
+    private User user;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public Integer getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(Integer groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+
+    public Integer getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Integer studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public String getScoreList() {
+        return scoreList;
+    }
+
+    public void setScoreList(String scoreList) {
+        this.scoreList = scoreList;
+    }
+
+    public HistoryStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(HistoryStatus status) {
+        this.status = status;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public User getUser() {
+        return user;
+    }
+
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+}

+ 44 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/ArbitrationDTO.java

@@ -0,0 +1,44 @@
+package cn.com.qmth.stmms.biz.mark.model;
+
+import java.util.Date;
+
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+
+public class ArbitrationDTO {
+
+    private String markerName;
+
+    private Date markTime;
+
+    private Double totalScore;
+
+    public ArbitrationDTO(MarkLibrary library, Marker marker) {
+        markerName = marker.getName();
+        markTime = library.getMarkerTime();
+        totalScore = library.getMarkerScore();
+    }
+
+    public String getMarkerName() {
+        return markerName;
+    }
+
+    public void setMarkerName(String markerName) {
+        this.markerName = markerName;
+    }
+
+    public Date getMarkTime() {
+        return markTime;
+    }
+
+    public void setMarkTime(Date markTime) {
+        this.markTime = markTime;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+}

+ 314 - 300
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkLibrary.java

@@ -1,300 +1,314 @@
-package cn.com.qmth.stmms.biz.mark.model;
-
-import java.io.Serializable;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-
-import org.apache.commons.lang.StringUtils;
-
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.utils.ScoreItem;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-@Entity
-@Table(name = "m_library")
-public class MarkLibrary implements Serializable {
-
-    private static final long serialVersionUID = 7121951721670633060L;
-
-    @Id
-    @GeneratedValue
-    private Integer id;
-
-    /**
-     * 考试ID
-     */
-    @Column(name = "exam_id")
-    private Integer examId;
-
-    /**
-     * 科目CODE
-     */
-    @Column(name = "subject_code")
-    private String subjectCode;
-
-    /**
-     * 大题序号
-     */
-    @Column(name = "group_number")
-    private Integer groupNumber;
-
-    /**
-     * 学习中心
-     */
-    @Column(name = "campus_id")
-    private Integer campusId;
-
-    /**
-     * 考生编号
-     */
-    @Column(name = "student_id")
-    private Integer studentId;
-
-    /**
-     * 准考证号
-     */
-    @Column(name = "exam_number")
-    private String examNumber;
-
-    /**
-     * 评卷员
-     */
-    @Column(name = "marker_id")
-    private Integer markerId;
-
-    /**
-     * 评卷时间
-     */
-    @Column(name = "marker_time")
-    private Date markerTime;
-
-    /**
-     * 评卷员给分总分
-     */
-    @Column(name = "marker_score")
-    private Double markerScore;
-
-    /**
-     * 评卷员给分明细
-     */
-    @Column(name = "marker_score_list")
-    private String markerScoreList;
-
-    /**
-     * 试卷标记信息
-     */
-    @Column(name = "tags")
-    private String tags;
-
-    /**
-     * 任务状态
-     */
-    @Column(name = "status")
-    @Enumerated(EnumType.ORDINAL)
-    private LibraryStatus status;
-
-    @Transient
-    private Marker marker;
-    
-    /**
-     * 科组长
-     */
-    @Column(name = "header_id")
-    private Integer headerId;
-
-    /**
-     * 科组长评卷时间
-     */
-    @Column(name = "header_time")
-    private Date headerTime;
-
-    /**
-     * 科组长给分总分
-     */
-    @Column(name = "header_score")
-    private Double headerScore;
-
-    /**
-     * 科组长给分明细
-     */
-    @Column(name = "header_score_list")
-    private String headerScoreList;
-
-    public Integer getId() {
-        return id;
-    }
-
-    public void setId(Integer id) {
-        this.id = id;
-    }
-
-    public Integer getExamId() {
-        return examId;
-    }
-
-    public void setExamId(Integer examId) {
-        this.examId = examId;
-    }
-
-    public String getSubjectCode() {
-        return subjectCode;
-    }
-
-    public void setSubjectCode(String subjectCode) {
-        this.subjectCode = subjectCode;
-    }
-
-    public Integer getStudentId() {
-        return studentId;
-    }
-
-    public void setStudentId(Integer studentId) {
-        this.studentId = studentId;
-    }
-
-    public String getExamNumber() {
-        return examNumber;
-    }
-
-    public void setExamNumber(String examNumber) {
-        this.examNumber = examNumber;
-    }
-
-    public Integer getMarkerId() {
-        return markerId;
-    }
-
-    public void setMarkerId(Integer markerId) {
-        this.markerId = markerId;
-    }
-
-    public Date getMarkerTime() {
-        return markerTime;
-    }
-
-    public void setMarkerTime(Date markerTime) {
-        this.markerTime = markerTime;
-    }
-
-    public Double getMarkerScore() {
-        return markerScore;
-    }
-
-    public void setMarkerScore(Double markerScore) {
-        this.markerScore = markerScore;
-    }
-
-    public String getMarkerScoreList() {
-        return markerScoreList;
-    }
-
-    public void setMarkerScoreList(String markerScoreList) {
-        this.markerScoreList = markerScoreList;
-    }
-
-    public LibraryStatus getStatus() {
-        return status;
-    }
-
-    public void setStatus(LibraryStatus status) {
-        this.status = status;
-    }
-
-    public List<ScoreItem> getScoreList() {
-        List<ScoreItem> list = new LinkedList<ScoreItem>();
-        String scoreList = null;
-        if (StringUtils.isNotBlank(headerScoreList)){
-        	scoreList = headerScoreList;
-        }else if(StringUtils.isNotBlank(markerScoreList)){
-        	scoreList = markerScoreList;
-        }
-        if (StringUtils.isNotBlank(scoreList)) {
-            try {
-                String[] values = scoreList.split(",");
-                for (String value : values) {
-                    ScoreItem item = ScoreItem.parse(value, false);
-                    if (item != null) {
-                        list.add(item);
-                    }
-                }
-            } catch (Exception e) {
-            }
-        }
-        return list;
-    }
-
-    public Integer getCampusId() {
-        return campusId;
-    }
-
-    public void setCampusId(Integer campusId) {
-        this.campusId = campusId;
-    }
-
-    public String getTags() {
-        return tags;
-    }
-
-    public void setTags(String tags) {
-        this.tags = tags;
-    }
-
-    public Integer getGroupNumber() {
-        return groupNumber;
-    }
-
-    public void setGroupNumber(Integer groupNumber) {
-        this.groupNumber = groupNumber;
-    }
-
-    public Marker getMarker() {
-        return marker;
-    }
-
-    public void setMarker(Marker marker) {
-        this.marker = marker;
-    }
-
-	public Integer getHeaderId() {
-		return headerId;
-	}
-
-	public void setHeaderId(Integer headerId) {
-		this.headerId = headerId;
-	}
-
-	public Date getHeaderTime() {
-		return headerTime;
-	}
-
-	public void setHeaderTime(Date headerTime) {
-		this.headerTime = headerTime;
-	}
-
-	public Double getHeaderScore() {
-		return headerScore;
-	}
-
-	public void setHeaderScore(Double headerScore) {
-		this.headerScore = headerScore;
-	}
-
-	public String getHeaderScoreList() {
-		return headerScoreList;
-	}
-
-	public void setHeaderScoreList(String headerScoreList) {
-		this.headerScoreList = headerScoreList;
-	}
-
-}
+package cn.com.qmth.stmms.biz.mark.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.commons.lang.StringUtils;
+
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.utils.ScoreItem;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+@Entity
+@Table(name = "m_library")
+public class MarkLibrary implements Serializable {
+
+    private static final long serialVersionUID = 7121951721670633060L;
+
+    @Id
+    @GeneratedValue
+    private Integer id;
+
+    /**
+     * 考试ID
+     */
+    @Column(name = "exam_id")
+    private Integer examId;
+
+    /**
+     * 科目CODE
+     */
+    @Column(name = "subject_code")
+    private String subjectCode;
+
+    /**
+     * 大题序号
+     */
+    @Column(name = "group_number")
+    private Integer groupNumber;
+
+    /**
+     * 学习中心
+     */
+    @Column(name = "campus_id")
+    private Integer campusId;
+
+    /**
+     * 考生编号
+     */
+    @Column(name = "student_id")
+    private Integer studentId;
+
+    /**
+     * 准考证号
+     */
+    @Column(name = "exam_number")
+    private String examNumber;
+
+    /**
+     * 多评任务编号,单评时为1
+     */
+    @Column(name = "task_number")
+    private Integer taskNumber;
+
+    /**
+     * 评卷员
+     */
+    @Column(name = "marker_id")
+    private Integer markerId;
+
+    /**
+     * 评卷时间
+     */
+    @Column(name = "marker_time")
+    private Date markerTime;
+
+    /**
+     * 评卷员给分总分
+     */
+    @Column(name = "marker_score")
+    private Double markerScore;
+
+    /**
+     * 评卷员给分明细
+     */
+    @Column(name = "marker_score_list")
+    private String markerScoreList;
+
+    /**
+     * 试卷标记信息
+     */
+    @Column(name = "tags")
+    private String tags;
+
+    /**
+     * 任务状态
+     */
+    @Column(name = "status")
+    @Enumerated(EnumType.ORDINAL)
+    private LibraryStatus status;
+
+    /**
+     * 科组长
+     */
+    @Column(name = "header_id")
+    private Integer headerId;
+
+    /**
+     * 科组长评卷时间
+     */
+    @Column(name = "header_time")
+    private Date headerTime;
+
+    /**
+     * 科组长给分总分
+     */
+    @Column(name = "header_score")
+    private Double headerScore;
+
+    /**
+     * 科组长给分明细
+     */
+    @Column(name = "header_score_list")
+    private String headerScoreList;
+
+    @Transient
+    private Marker marker;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public Integer getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Integer studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public Integer getMarkerId() {
+        return markerId;
+    }
+
+    public void setMarkerId(Integer markerId) {
+        this.markerId = markerId;
+    }
+
+    public Date getMarkerTime() {
+        return markerTime;
+    }
+
+    public void setMarkerTime(Date markerTime) {
+        this.markerTime = markerTime;
+    }
+
+    public Double getMarkerScore() {
+        return markerScore;
+    }
+
+    public void setMarkerScore(Double markerScore) {
+        this.markerScore = markerScore;
+    }
+
+    public String getMarkerScoreList() {
+        return markerScoreList;
+    }
+
+    public void setMarkerScoreList(String markerScoreList) {
+        this.markerScoreList = markerScoreList;
+    }
+
+    public LibraryStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(LibraryStatus status) {
+        this.status = status;
+    }
+
+    public List<ScoreItem> getScoreList() {
+        List<ScoreItem> list = new LinkedList<ScoreItem>();
+        String scoreList = null;
+        if (StringUtils.isNotBlank(headerScoreList)) {
+            scoreList = headerScoreList;
+        } else if (StringUtils.isNotBlank(markerScoreList)) {
+            scoreList = markerScoreList;
+        }
+        if (StringUtils.isNotBlank(scoreList)) {
+            try {
+                String[] values = scoreList.split(",");
+                for (String value : values) {
+                    ScoreItem item = ScoreItem.parse(value, false);
+                    if (item != null) {
+                        list.add(item);
+                    }
+                }
+            } catch (Exception e) {
+            }
+        }
+        return list;
+    }
+
+    public Integer getCampusId() {
+        return campusId;
+    }
+
+    public void setCampusId(Integer campusId) {
+        this.campusId = campusId;
+    }
+
+    public String getTags() {
+        return tags;
+    }
+
+    public void setTags(String tags) {
+        this.tags = tags;
+    }
+
+    public Integer getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(Integer groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+
+    public Marker getMarker() {
+        return marker;
+    }
+
+    public void setMarker(Marker marker) {
+        this.marker = marker;
+    }
+
+    public Integer getHeaderId() {
+        return headerId;
+    }
+
+    public void setHeaderId(Integer headerId) {
+        this.headerId = headerId;
+    }
+
+    public Date getHeaderTime() {
+        return headerTime;
+    }
+
+    public void setHeaderTime(Date headerTime) {
+        this.headerTime = headerTime;
+    }
+
+    public Double getHeaderScore() {
+        return headerScore;
+    }
+
+    public void setHeaderScore(Double headerScore) {
+        this.headerScore = headerScore;
+    }
+
+    public String getHeaderScoreList() {
+        return headerScoreList;
+    }
+
+    public void setHeaderScoreList(String headerScoreList) {
+        this.headerScoreList = headerScoreList;
+    }
+
+    public Integer getTaskNumber() {
+        return taskNumber;
+    }
+
+    public void setTaskNumber(Integer taskNumber) {
+        this.taskNumber = taskNumber;
+    }
+
+}

+ 13 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/SpecialTagDTO.java

@@ -3,14 +3,27 @@ package cn.com.qmth.stmms.biz.mark.model;
 import java.io.Serializable;
 
 public class SpecialTagDTO implements Serializable {
+
     private static final long serialVersionUID = -5424015292124065736L;
+
     private String tagName;
+
     private Double positionX;
+
     private Double positionY;
 
     public SpecialTagDTO() {
     }
 
+    public MarkSpecialTag transform(MarkLibrary library) {
+        MarkSpecialTag markSpecialTag = new MarkSpecialTag();
+        markSpecialTag.setLibraryId(library.getId());
+        markSpecialTag.setTagName(tagName);
+        markSpecialTag.setPositionX(positionX);
+        markSpecialTag.setPositionY(positionY);
+        return markSpecialTag;
+    }
+
     public String getTagName() {
         return tagName;
     }

+ 11 - 1
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/Task.java

@@ -134,8 +134,10 @@ public class Task implements Serializable {
     // 特殊标识:√ 或 ❌ 或 乄
     private SpecialTagDTO[] tagList;
 
-    public Task() {
+    // 仲裁记录集合
+    private List<ArbitrationDTO> arbitrationList;
 
+    public Task() {
     }
 
     public String getStudentId() {
@@ -378,4 +380,12 @@ public class Task implements Serializable {
         this.pictureConfig = pictureConfig;
     }
 
+    public List<ArbitrationDTO> getArbitrationList() {
+        return arbitrationList;
+    }
+
+    public void setArbitrationList(List<ArbitrationDTO> arbitrationList) {
+        this.arbitrationList = arbitrationList;
+    }
+
 }

+ 86 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/ArbitrateHistorySearchQuery.java

@@ -0,0 +1,86 @@
+package cn.com.qmth.stmms.biz.mark.query;
+
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+
+import cn.com.qmth.stmms.biz.common.BaseQuery;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.common.enums.HistoryStatus;
+
+public class ArbitrateHistorySearchQuery extends BaseQuery<ArbitrateHistory> {
+
+    private Integer examId;
+
+    private String subjectCode;
+
+    private Integer groupNumber;
+
+    private Integer studentId;
+
+    private String examNumber;
+
+    private HistoryStatus status;
+
+    private Integer userId;
+
+    public void orderByIdDesc() {
+        setSort(new Sort(Direction.DESC, "id"));
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public Integer getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(Integer groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+
+    public Integer getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Integer studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public HistoryStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(HistoryStatus status) {
+        this.status = status;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+}

+ 23 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/ArbitrateHistoryService.java

@@ -0,0 +1,23 @@
+package cn.com.qmth.stmms.biz.mark.service;
+
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.biz.mark.query.ArbitrateHistorySearchQuery;
+
+public interface ArbitrateHistoryService {
+
+    void delete(ArbitrateHistory history);
+
+    void deleteByStudent(Integer studentId);
+
+    void deleteByGroup(MarkGroup group);
+
+    ArbitrateHistory save(ArbitrateHistory history);
+
+    ArbitrateHistory findById(Integer id);
+
+    long countByQuery(ArbitrateHistorySearchQuery query);
+
+    ArbitrateHistorySearchQuery findByQuery(ArbitrateHistorySearchQuery query);
+
+}

+ 108 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/ArbitrateHistoryServiceImpl.java

@@ -0,0 +1,108 @@
+package cn.com.qmth.stmms.biz.mark.service.Impl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import cn.com.qmth.stmms.biz.common.BaseQueryService;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.mark.dao.ArbitrateHistoryDao;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.biz.mark.query.ArbitrateHistorySearchQuery;
+import cn.com.qmth.stmms.biz.mark.service.ArbitrateHistoryService;
+import cn.com.qmth.stmms.common.enums.HistoryStatus;
+
+@Service
+public class ArbitrateHistoryServiceImpl extends BaseQueryService<ArbitrateHistory> implements ArbitrateHistoryService {
+
+    @Autowired
+    private ArbitrateHistoryDao historyDao;
+
+    @Transactional
+    @Override
+    public void delete(ArbitrateHistory history) {
+        historyDao.delete(history);
+    }
+
+    @Transactional
+    @Override
+    public void deleteByStudent(Integer studentId) {
+        historyDao.deleteByStudentId(studentId);
+    }
+
+    @Transactional
+    @Override
+    public void deleteByGroup(MarkGroup group) {
+        historyDao.deleteByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
+                group.getNumber());
+    }
+
+    @Transactional
+    @Override
+    public ArbitrateHistory save(ArbitrateHistory history) {
+        return historyDao.save(history);
+    }
+
+    @Override
+    public ArbitrateHistory findById(Integer id) {
+        return historyDao.findOne(id);
+    }
+
+    @Override
+    public long countByQuery(final ArbitrateHistorySearchQuery query) {
+        return historyDao.count(buildSpecification(query));
+    }
+
+    @Override
+    public ArbitrateHistorySearchQuery findByQuery(final ArbitrateHistorySearchQuery query) {
+        checkQuery(query);
+        Page<ArbitrateHistory> result = historyDao.findAll(buildSpecification(query), query);
+        fillResult(result, query);
+        return query;
+    }
+
+    private Specification<ArbitrateHistory> buildSpecification(final ArbitrateHistorySearchQuery query) {
+        return new Specification<ArbitrateHistory>() {
+
+            @Override
+            public Predicate toPredicate(Root<ArbitrateHistory> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
+                List<Predicate> predicates = new LinkedList<Predicate>();
+                if (query.getExamId() != null) {
+                    predicates.add(cb.equal(root.get("examId"), query.getExamId()));
+                }
+                if (StringUtils.isNotBlank(query.getSubjectCode())) {
+                    predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
+                }
+                if (query.getGroupNumber() != null) {
+                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
+                }
+                if (StringUtils.isNotBlank(query.getExamNumber())) {
+                    predicates.add(cb.equal(root.get("examNumber"), query.getExamNumber()));
+                }
+                if (query.getStudentId() != null) {
+                    predicates.add(cb.equal(root.get("studentId"), query.getStudentId()));
+                }
+                if (query.getUserId() != null) {
+                    predicates.add(cb.equal(root.get("userId"), query.getUserId()));
+                }
+                if (query.getStatus() != null) {
+                    predicates.add(cb.equal(root.get("status").as(HistoryStatus.class), query.getStatus()));
+                }
+                return predicates.isEmpty() ? cb.conjunction()
+                        : cb.and(predicates.toArray(new Predicate[predicates.size()]));
+            }
+        };
+    }
+
+}

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

@@ -1,265 +1,298 @@
-package cn.com.qmth.stmms.biz.mark.service.Impl;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
-import javax.persistence.criteria.Root;
-
-import org.apache.commons.lang.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import cn.com.qmth.stmms.biz.common.BaseQueryService;
-import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
-import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
-import cn.com.qmth.stmms.biz.mark.dao.MarkLibraryDao;
-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.service.MarkLibraryService;
-import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
-import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-@Service
-public class MarkLibraryServiceImpl extends BaseQueryService<MarkLibrary> implements MarkLibraryService {
-
-    @Autowired
-    private MarkLibraryDao libraryDao;
-
-    @Autowired
-    private MarkTrackService trackService;
-
-    @Autowired
-    private ExamQuestionService questionService;
-    
-    @Autowired
-    private MarkSpecialTagService markSpecialTagService;
-
-    @Transactional
-    @Override
-    public void delete(MarkLibrary library) {
-    	markSpecialTagService.deleteByLibraryId(library.getId());
-        libraryDao.delete(library);
-        if (library != null) {
-            List<ExamQuestion> examQuestions = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(
-                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
-            for (ExamQuestion examQuestion : examQuestions) {
-                trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(),
-                        examQuestion.getQuestionNumber());
-            }
-        }
-    }
-
-    @Transactional
-    @Override
-    public void deleteByStudent(int studentId) {
-        List<MarkLibrary> library = findByStudentId(studentId);
-        if (library != null) {
-            for (MarkLibrary markLibrary : library) {
-            	markSpecialTagService.deleteByLibraryId(markLibrary.getId());
-                this.delete(markLibrary);
-            }
-        }
-        trackService.deleteByStudentId(studentId);
-    }
-
-    @Transactional
-    @Override
-    public void deleteByGroup(MarkGroup group) {
-    	markSpecialTagService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
-        libraryDao.deleteByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
-                group.getNumber());
-        trackService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
-    }
-
-    @Transactional
-    @Override
-    public MarkLibrary save(MarkLibrary library) {
-        return libraryDao.save(library);
-    }
-
-    @Override
-    public MarkLibrary findById(int id) {
-        return libraryDao.findOne(id);
-    }
-
-    @Override
-    public MarkLibrary findByStudentAndGroup(int studentId, int groupNumber) {
-        List<MarkLibrary> list = libraryDao.findByStudentIdAndGroupNumber(studentId, groupNumber);
-        return list != null && list.size() > 0 ? list.get(0) : null;
-    }
-
-    @Override
-    public List<MarkLibrary> findByStudentId(int studentId) {
-        List<MarkLibrary> list = libraryDao.findByStudentId(studentId);
-        // return list != null && list.size() > 0 ? list.get(0) : null;
-        return list;
-    }
-
-    @Override
-    public List<MarkLibrary> findByStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status,
-            int pageNumber, int pageSize) {
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setPageNumber(pageNumber);
-        query.setPageSize(pageSize);
-        return libraryDao.findByExamIdAndSubjectCodeAndGroupNumberAndStatus(examId, subjectCode, groupNumber, status,
-                query);
-    }
-
-    @Override
-    public List<MarkLibrary> findByStatusSet(int examId, String subjectCode, int groupNumber,
-            Set<LibraryStatus> statusSet, int pageNumber, int pageSize) {
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setPageNumber(pageNumber);
-        query.setPageSize(pageSize);
-        return libraryDao.findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(examId, subjectCode, groupNumber,
-                statusSet, query);
-    }
-
-    @Override
-    @Transactional
-    public void resetByGroup(MarkGroup group) {
-    	markSpecialTagService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
-        libraryDao.resetByExamIdAndSubjectCodeAndNumber(group.getExamId(), group.getSubjectCode(), group.getNumber(),
-                LibraryStatus.WAITING);
-        trackService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
-    }
-
-    @Override
-    @Transactional
-    public void resetByMarker(Marker marker) {
-    	markSpecialTagService.deleteByMarkerId(marker.getId());
-        libraryDao.resetByMarkerId(marker.getId(), LibraryStatus.WAITING);
-        trackService.deleteByMarkerId(marker.getId());
-    }
-
-    @Override
-    @Transactional
-    public void resetById(int id) {
-        libraryDao.resetById(id, LibraryStatus.WAITING);
-        MarkLibrary library = findById(id);
-        if (library != null) {
-            List<ExamQuestion> examQuestions = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(
-                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
-            for (ExamQuestion examQuestion : examQuestions) {
-                trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(),
-                        examQuestion.getQuestionNumber());
-            }
-            markSpecialTagService.deleteByLibraryId(id);
-        }
-    }
-
-    @Override
-    @Transactional
-    public void backById(int id) {
-        libraryDao.resetById(id, LibraryStatus.BACKED);
-        MarkLibrary library = findById(id);
-        if (library != null) {
-            List<ExamQuestion> examQuestions = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(
-                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
-            for (ExamQuestion examQuestion : examQuestions) {
-                trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(),
-                        examQuestion.getQuestionNumber());
-            }
-            markSpecialTagService.deleteByLibraryId(id);
-        }
-    }
-
-    @Override
-    public List<Integer> findTagCampusId(int examId) {
-        return libraryDao.findTagCampusId(examId);
-    }
-
-    @Override
-    public List<String> findTagSubjectCode(int examId) {
-        return libraryDao.findTagSubjectCode(examId);
-    }
-
-    @Override
-    public long countByExamAndSubjectAndGroupAndStatus(int examId, String subjectCode, int groupNumber,
-            LibraryStatus status) {
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setExamId(examId);
-        query.setSubjectCode(subjectCode);
-        query.setGroupNumber(groupNumber);
-        query.setStatus(status);
-        return countByQuery(query);
-    }
-
-    @Override
-    public long countByMarker(int markerId) {
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setMarkerId(markerId);
-        query.setStatus(LibraryStatus.MARKED);
-        return countByQuery(query);
-    }
-
-    @Override
-    public long countByQuery(final MarkLibrarySearchQuery query) {
-        return libraryDao.count(buildSpecification(query));
-    }
-
-    @Override
-    public MarkLibrarySearchQuery findByQuery(final MarkLibrarySearchQuery query) {
-        checkQuery(query);
-        Page<MarkLibrary> result = libraryDao.findAll(buildSpecification(query), query);
-        fillResult(result, query);
-        return query;
-    }
-
-    private Specification<MarkLibrary> buildSpecification(final MarkLibrarySearchQuery query) {
-        return new Specification<MarkLibrary>() {
-
-            @Override
-            public Predicate toPredicate(Root<MarkLibrary> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
-                List<Predicate> predicates = new LinkedList<Predicate>();
-                if (query.getExamId() > 0) {
-                    predicates.add(cb.equal(root.get("examId"), query.getExamId()));
-                }
-                if (StringUtils.isNotBlank(query.getSubjectCode())) {
-                    predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
-                }
-                if (query.getCampusId() > 0) {
-                    predicates.add(cb.equal(root.get("campusId"), query.getCampusId()));
-                }
-                if (query.getGroupNumber() > 0) {
-                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
-                }
-                if (StringUtils.isNotBlank(query.getExamNumber())) {
-                    predicates.add(cb.equal(root.get("examNumber"), query.getExamNumber()));
-                }
-                if (query.getStudentId() > 0) {
-                    predicates.add(cb.equal(root.get("studentId"), query.getStudentId()));
-                }
-                if (query.getMarkerId() > 0) {
-                    predicates.add(cb.equal(root.get("markerId"), query.getMarkerId()));
-                }
-                if (query.getStatus() != null) {
-                    predicates.add(cb.equal(root.get("status").as(LibraryStatus.class), query.getStatus()));
-                }
-                if (query.getTagNotNull() != null && query.getTagNotNull().booleanValue()) {
-                    predicates.add(cb.isNotNull(root.get("tags")));
-                }
-                if (query.getTagId() > 0) {
-                    predicates.add(cb.like(root.get("tags").as(String.class), "%" + query.getTagId() + "%"));
-                }
-                return predicates.isEmpty() ? cb.conjunction()
-                        : cb.and(predicates.toArray(new Predicate[predicates.size()]));
-            }
-        };
-    }
-
-    @Override
-    public List<MarkLibrary> findByStudentIdAndStatus(int studentId, LibraryStatus status) {
-        return libraryDao.findByStudentIdAndStatus(studentId, status);
-    }
-}
+package cn.com.qmth.stmms.biz.mark.service.Impl;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import cn.com.qmth.stmms.biz.common.BaseQueryService;
+import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
+import cn.com.qmth.stmms.biz.mark.dao.MarkLibraryDao;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+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.service.MarkLibraryService;
+import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
+import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+@Service
+public class MarkLibraryServiceImpl extends BaseQueryService<MarkLibrary> implements MarkLibraryService {
+
+    @Autowired
+    private MarkLibraryDao libraryDao;
+
+    @Autowired
+    private MarkTrackService trackService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @Autowired
+    private MarkSpecialTagService markSpecialTagService;
+
+    @Transactional
+    @Override
+    public void delete(MarkLibrary library) {
+        markSpecialTagService.deleteByLibraryId(library.getId());
+        libraryDao.delete(library);
+        if (library != null) {
+            List<ExamQuestion> examQuestions = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(
+                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
+            for (ExamQuestion examQuestion : examQuestions) {
+                trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(),
+                        examQuestion.getQuestionNumber());
+            }
+        }
+    }
+
+    @Transactional
+    @Override
+    public void deleteByStudent(int studentId) {
+        List<MarkLibrary> library = findByStudentId(studentId);
+        if (library != null) {
+            for (MarkLibrary markLibrary : library) {
+                markSpecialTagService.deleteByLibraryId(markLibrary.getId());
+                this.delete(markLibrary);
+            }
+        }
+        trackService.deleteByStudentId(studentId);
+    }
+
+    @Transactional
+    @Override
+    public void deleteByGroup(MarkGroup group) {
+        markSpecialTagService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(),
+                group.getNumber());
+        libraryDao.deleteByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
+                group.getNumber());
+        trackService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
+    }
+
+    @Transactional
+    @Override
+    public MarkLibrary save(MarkLibrary library) {
+        return libraryDao.save(library);
+    }
+
+    @Override
+    public MarkLibrary findById(int id) {
+        return libraryDao.findOne(id);
+    }
+
+    @Override
+    public List<MarkLibrary> findByStudentAndGroup(int studentId, int groupNumber) {
+        return libraryDao.findByStudentIdAndGroupNumber(studentId, groupNumber);
+    }
+
+    @Override
+    public List<MarkLibrary> findByStudentId(int studentId) {
+        return libraryDao.findByStudentId(studentId);
+    }
+
+    @Override
+    public List<MarkLibrary> findByStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status,
+            int pageNumber, int pageSize) {
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setPageNumber(pageNumber);
+        query.setPageSize(pageSize);
+        return libraryDao.findByExamIdAndSubjectCodeAndGroupNumberAndStatus(examId, subjectCode, groupNumber, status,
+                query);
+    }
+
+    @Override
+    public List<MarkLibrary> findByStatusSet(int examId, String subjectCode, int groupNumber,
+            Set<LibraryStatus> statusSet, int pageNumber, int pageSize) {
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setPageNumber(pageNumber);
+        query.setPageSize(pageSize);
+        return libraryDao.findByExamIdAndSubjectCodeAndGroupNumberAndStatusIn(examId, subjectCode, groupNumber,
+                statusSet, query);
+    }
+
+    @Override
+    @Transactional
+    public void resetByGroup(MarkGroup group) {
+        libraryDao.resetByExamIdAndSubjectCodeAndNumber(group.getExamId(), group.getSubjectCode(), group.getNumber(),
+                LibraryStatus.WAITING);
+        trackService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
+        markSpecialTagService.deleteByExamAndSubjectAndGroup(group.getExamId(), group.getSubjectCode(),
+                group.getNumber());
+    }
+
+    @Override
+    @Transactional
+    public void resetByMarker(Marker marker) {
+        libraryDao.resetByMarkerId(marker.getId(), LibraryStatus.WAITING);
+        trackService.deleteByMarkerId(marker.getId());
+        markSpecialTagService.deleteByMarkerId(marker.getId());
+    }
+
+    @Override
+    @Transactional
+    public void resetById(int id) {
+        MarkLibrary library = findById(id);
+        if (library != null) {
+            libraryDao.resetById(id, LibraryStatus.WAITING);
+            List<ExamQuestion> examQuestions = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(
+                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
+            for (ExamQuestion examQuestion : examQuestions) {
+                trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(),
+                        examQuestion.getQuestionNumber());
+            }
+            markSpecialTagService.deleteByLibraryId(id);
+        }
+    }
+
+    @Override
+    @Transactional
+    public void backById(int id) {
+        back(findById(id));
+    }
+
+    @Override
+    @Transactional
+    public void back(MarkLibrary library) {
+        if (library != null) {
+            List<ExamQuestion> examQuestions = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(
+                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
+            for (ExamQuestion examQuestion : examQuestions) {
+                trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(),
+                        examQuestion.getQuestionNumber());
+            }
+            markSpecialTagService.deleteByLibraryId(library.getId());
+
+            libraryDao.resetById(library.getId(), LibraryStatus.BACKED);
+        }
+    }
+
+    @Override
+    @Transactional
+    public void backWaitArbitrate(Integer studentId, Integer groupNumber) {
+        List<MarkLibrary> list = findByStudentAndGroup(studentId, groupNumber);
+        if (list != null) {
+            for (MarkLibrary library : list) {
+                if (library.getStatus() == LibraryStatus.WAIT_ARBITRATE) {
+                    back(library);
+                }
+            }
+        }
+    }
+
+    @Override
+    @Transactional
+    public void setArbitrate(Integer studentId, Integer groupNumber) {
+        libraryDao.updateByStudentIdAndGroupNumber(studentId, groupNumber, LibraryStatus.WAIT_ARBITRATE);
+    }
+
+    @Override
+    @Transactional
+    public void arbitrated(ArbitrateHistory history) {
+        libraryDao.updateHeaderResult(history.getStudentId(), history.getGroupNumber(), history.getUserId(),
+                history.getTotalScore(), history.getScoreList(), history.getUpdateTime(), LibraryStatus.ARBITRATED);
+    }
+
+    @Override
+    public List<Integer> findTagCampusId(int examId) {
+        return libraryDao.findTagCampusId(examId);
+    }
+
+    @Override
+    public List<String> findTagSubjectCode(int examId) {
+        return libraryDao.findTagSubjectCode(examId);
+    }
+
+    @Override
+    public long countByExamAndSubjectAndGroupAndStatus(int examId, String subjectCode, int groupNumber,
+            LibraryStatus status) {
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setExamId(examId);
+        query.setSubjectCode(subjectCode);
+        query.setGroupNumber(groupNumber);
+        query.setStatus(status);
+        return countByQuery(query);
+    }
+
+    @Override
+    public long countByMarker(int markerId) {
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setMarkerId(markerId);
+        query.setStatus(LibraryStatus.MARKED);
+        return countByQuery(query);
+    }
+
+    @Override
+    public long countByQuery(final MarkLibrarySearchQuery query) {
+        return libraryDao.count(buildSpecification(query));
+    }
+
+    @Override
+    public MarkLibrarySearchQuery findByQuery(final MarkLibrarySearchQuery query) {
+        checkQuery(query);
+        Page<MarkLibrary> result = libraryDao.findAll(buildSpecification(query), query);
+        fillResult(result, query);
+        return query;
+    }
+
+    private Specification<MarkLibrary> buildSpecification(final MarkLibrarySearchQuery query) {
+        return new Specification<MarkLibrary>() {
+
+            @Override
+            public Predicate toPredicate(Root<MarkLibrary> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
+                List<Predicate> predicates = new LinkedList<Predicate>();
+                if (query.getExamId() > 0) {
+                    predicates.add(cb.equal(root.get("examId"), query.getExamId()));
+                }
+                if (StringUtils.isNotBlank(query.getSubjectCode())) {
+                    predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
+                }
+                if (query.getCampusId() > 0) {
+                    predicates.add(cb.equal(root.get("campusId"), query.getCampusId()));
+                }
+                if (query.getGroupNumber() > 0) {
+                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
+                }
+                if (StringUtils.isNotBlank(query.getExamNumber())) {
+                    predicates.add(cb.equal(root.get("examNumber"), query.getExamNumber()));
+                }
+                if (query.getStudentId() > 0) {
+                    predicates.add(cb.equal(root.get("studentId"), query.getStudentId()));
+                }
+                if (query.getMarkerId() > 0) {
+                    predicates.add(cb.equal(root.get("markerId"), query.getMarkerId()));
+                }
+                if (query.getStatus() != null) {
+                    predicates.add(cb.equal(root.get("status").as(LibraryStatus.class), query.getStatus()));
+                }
+                if (query.getTagNotNull() != null && query.getTagNotNull().booleanValue()) {
+                    predicates.add(cb.isNotNull(root.get("tags")));
+                }
+                if (query.getTagId() > 0) {
+                    predicates.add(cb.like(root.get("tags").as(String.class), "%" + query.getTagId() + "%"));
+                }
+                return predicates.isEmpty() ? cb.conjunction()
+                        : cb.and(predicates.toArray(new Predicate[predicates.size()]));
+            }
+        };
+    }
+
+    @Override
+    public List<MarkLibrary> findByStudentIdAndStatus(int studentId, LibraryStatus status) {
+        return libraryDao.findByStudentIdAndStatus(studentId, status);
+    }
+
+}

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

@@ -0,0 +1,13 @@
+package cn.com.qmth.stmms.biz.mark.service.Impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import cn.com.qmth.stmms.biz.exam.dao.MarkGroupDao;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
+
+public class MarkServiceImpl implements MarkService {
+
+    @Autowired
+    private MarkGroupDao groupDao;
+
+}

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

@@ -22,6 +22,9 @@ import cn.com.qmth.stmms.biz.exam.model.Marker;
 import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrationDTO;
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
 import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
 import cn.com.qmth.stmms.biz.mark.model.MarkStepDTO;
@@ -31,13 +34,16 @@ import cn.com.qmth.stmms.biz.mark.model.SpecialTagDTO;
 import cn.com.qmth.stmms.biz.mark.model.Task;
 import cn.com.qmth.stmms.biz.mark.model.TrackDTO;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
+import cn.com.qmth.stmms.biz.mark.service.ArbitrateHistoryService;
 import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
 import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
 import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
 import cn.com.qmth.stmms.biz.mark.service.TaskService;
 import cn.com.qmth.stmms.biz.utils.CurrentTaskUtil;
 import cn.com.qmth.stmms.biz.utils.ScoreItem;
+import cn.com.qmth.stmms.common.enums.HistoryStatus;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import cn.com.qmth.stmms.common.enums.ScorePolicy;
 import cn.com.qmth.stmms.common.utils.PictureUrlBuilder;
 
 /**
@@ -72,6 +78,12 @@ public class TaskServiceImpl implements TaskService {
     @Autowired
     private CampusService campusService;
 
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private ArbitrateHistoryService arbitrateService;
+
     @Override
     public List<Task> findByQuery(MarkLibrarySearchQuery query) {
         List<Task> list = new LinkedList<Task>();
@@ -84,6 +96,36 @@ public class TaskServiceImpl implements TaskService {
         return list;
     }
 
+    @Override
+    public Task build(ArbitrateHistory history, MarkGroup group) {
+        ExamStudent student = studentService.findByExamIdAndExamNumber(history.getExamId(), history.getExamNumber());
+        List<MarkLibrary> libraryList = libraryService.findByStudentAndGroup(student.getId(), group.getNumber());
+        Integer campusId = libraryList.get(0).getCampusId();
+
+        Task task = new Task();
+        task.setExist(true);
+        task.setStudentId(student.getExamNumber());
+        task.setLibraryId(history.getId());
+        task.setMarkStepList(buildMarkStep(group, null));
+        task.setPictureUrls(PictureUrlBuilder.getSliceUrls(student.getExamId(), campusId, student.getSubjectCode(),
+                student.getExamNumber(), student.getSliceCount()));
+        task.setPictureConfig(group.getPictureConfigList());
+        task.setSheetUrls(PictureUrlBuilder.getSheetUrls(student.getExamId(), campusId, student.getSubjectCode(),
+                student.getExamNumber(), student.getSheetCount()));
+        task.setAnswerUrl(PictureUrlBuilder.getAnswerUrl(student.getExamId(), student.getSubjectCode()));
+        task.setPaperUrl(PictureUrlBuilder.getPaperUrl(student.getExamId(), student.getSubjectCode()));
+        task.setObjectiveScore(student.getObjectiveScore() != null ? student.getObjectiveScore() : 0);
+        // 构造仲裁信息
+        List<ArbitrationDTO> list = new ArrayList<ArbitrationDTO>();
+        for (MarkLibrary library : libraryList) {
+            if (library.getStatus() == LibraryStatus.WAIT_ARBITRATE) {
+                list.add(new ArbitrationDTO(library, markerService.findById(library.getMarkerId())));
+            }
+        }
+        task.setArbitrationList(list);
+        return task;
+    }
+
     @Override
     public Task build(MarkLibrary library) {
         ExamStudent student = studentService.findByExamIdAndExamNumber(library.getExamId(), library.getExamNumber());
@@ -93,7 +135,7 @@ public class TaskServiceImpl implements TaskService {
         task.setExist(true);
         task.setStudentId(library.getExamNumber());
         task.setLibraryId(library.getId());
-        task.setMarkStepList(buildMarkStep(library));
+        task.setMarkStepList(buildMarkStep(group, student.getId()));
         task.setPictureUrls(PictureUrlBuilder.getSliceUrls(library.getExamId(), library.getCampusId(),
                 library.getSubjectCode(), library.getExamNumber(), student.getSliceCount()));
         task.setPictureConfig(group.getPictureConfigList());
@@ -119,10 +161,10 @@ public class TaskServiceImpl implements TaskService {
         return task;
     }
 
-    private List<MarkStepDTO> buildMarkStep(MarkLibrary library) {
+    private List<MarkStepDTO> buildMarkStep(MarkGroup group, Integer studentId) {
         List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
-        List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(library.getExamId(),
-                library.getSubjectCode(), false, library.getGroupNumber());
+        List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjectiveAndMainNumber(group.getExamId(),
+                group.getSubjectCode(), false, group.getNumber());
         int number = 0;
         for (ExamQuestion question : sList) {
             number++;
@@ -139,8 +181,10 @@ public class TaskServiceImpl implements TaskService {
             step.setMin(0d);
             step.setInterval(question.getIntervalScore());
             step.setScoreList(question.getScoreListArray());
-            // 增加阅卷轨迹列表获取
-            addTrack(step, question, trackService.findByStudentId(library.getStudentId()));
+            if (studentId != null) {
+                // 增加阅卷轨迹列表获取
+                addTrack(step, question, trackService.findByStudentId(studentId));
+            }
             list.add(step);
         }
         return list;
@@ -162,7 +206,7 @@ public class TaskServiceImpl implements TaskService {
             return false;
         }
         try {
-            submitLibrary(task);
+            submitTask(task);
             return true;
         } catch (Exception e) {
             log.error("task submit faile", e);
@@ -170,81 +214,115 @@ public class TaskServiceImpl implements TaskService {
         }
     }
 
-    private void submitLibrary(Task task) {
+    private void submitTask(Task task) {
         MarkLibrary library = updateLibrary(task);
-        if (library == null) {
-            return;
+        // 正常完成评卷后尝试算分
+        if (library != null && library.getStatus() == LibraryStatus.MARKED) {
+            scoreCalculate(library.getExamId(), library.getSubjectCode(), library.getGroupNumber(),
+                    library.getStudentId());
         }
-        // 同步操作
-        if (task.isProblem()) {
-            // ProblemLibrary library = new ProblemLibrary();
-            // library.setExamId(formallyLibrary.getExamId());
-            // library.setCampusCode(formallyLibrary.getCampusCode());
-            // library.setSubjectCode(formallyLibrary.getSubjectCode());
-            // library.setLibraryId(formallyLibrary.getId());
-            // library.setType(LibraryType.FORMALLY);
-            // library.setBlockId(formallyLibrary.getBlockId());
-            // library.setSecretNo(formallyLibrary.getSecretNo());
-            // library.setReason(task.getReason());
-            // library.setSubmitTime(new Date());
-            // library.setSubmitter(task.getMarkId());
-            // library.setStage(formallyLibrary.getMarkerCount());
-            // library.setStatus(LibraryStatus.WAITING);
-            // problemLibraryService.save(library);
-        } else {
-            // FormallyHistory history = new FormallyHistory();
-            // history.setLibraryId(task.getLibraryId());
-            // history.setScoreList(task.getScoreList());
-            // history.setScorer(task.getMarkId());
-            // history.setScoreTime(new Date());
-            // history.setSpent(task.getSpent());
-            // history.setStage(task.getMarkerCount());
-            // history.setTotalScore(task.getTotalScore());
-            // if (task.isSelf()) {
-            // history.setType(HistoryType.SELF);
-            // } else if (task.isBack()) {
-            // history.setType(HistoryType.BACK);
-            // } else {
-            // history.setType(HistoryType.COMMON);
-            // BlockTaskCountUtil.addBlockMarkedTask(stringRedisTemplate,
-            // task.getBlockId(), task.getLibraryId());
-            // }
-            // formallyHistoryService.save(history);
-
-            onTaskSubmit(library, task);
+    }
+
+    @Override
+    public void scoreCalculate(Integer examId, String subjectCode, Integer groupNumber, Integer studentId) {
+        List<MarkGroup> groups = groupService.findByExamAndSubject(examId, subjectCode);
+        List<ScoreItem> scoreList = new ArrayList<ScoreItem>();
+        double totalScore = 0.0;
+        // 循环所有大题
+        for (MarkGroup group : groups) {
+            if (calculateGroup(group, studentId)) {
+                totalScore += group.getMarkScore();
+                scoreList.addAll(group.getMarkScoreDetail());
+            } else {
+                // 未评完直接返回
+                return;
+            }
         }
+        // 全部评完,更新考生主观题得分
+        studentService.updateSubjectiveScore(studentId, totalScore, ExamStudent.buildScoreList(scoreList));
     }
 
-    private void onTaskSubmit(MarkLibrary library, Task task) {
-        if (library.getStatus() == LibraryStatus.MARKED) {
-            // ExamStudent student =
-            // studentService.findById(library.getStudentId());
-            // if (student != null) {
-            // student.setSubjectiveScore(library.getMarkerScore());
-            // student.setScoreList(library.getScoreList(), false);
-            // studentService.save(student);
-            // }
-            List<MarkGroup> groups = groupService.findByExamAndSubject(library.getExamId(), library.getSubjectCode());
-            List<MarkLibrary> libraries = libraryService.findByStudentIdAndStatus(library.getStudentId(),
-                    LibraryStatus.MARKED);
-            if (libraries.size() == groups.size()) {
-                List<ScoreItem> scoreList = new ArrayList<ScoreItem>();
-                Double markerScore = 0.0;
-                for (MarkLibrary librarie : libraries) {
-                    if (librarie.getHeaderId() != null) {
-                        scoreList.addAll(librarie.getScoreList());
-                        markerScore = markerScore + librarie.getHeaderScore();
-                    } else {
-                        scoreList.addAll(librarie.getScoreList());
-                        markerScore = markerScore + librarie.getMarkerScore();
+    private boolean calculateGroup(MarkGroup group, Integer studentId) {
+        double score = 0;
+        List<ScoreItem> detail = null;
+        int count = 0;
+        // 未设置算分策略的情况下,默认取平均分
+        ScorePolicy policy = group.getScorePolicy() != null ? group.getScorePolicy() : ScorePolicy.AVG;
+        List<MarkLibrary> list = libraryService.findByStudentAndGroup(studentId, group.getNumber());
+        for (MarkLibrary library : list) {
+            if (library.getStatus() == LibraryStatus.MARKED || library.getStatus() == LibraryStatus.ARBITRATED) {
+                count++;
+                Double current = (library.getHeaderScore() != null ? library.getHeaderScore()
+                        : library.getMarkerScore());
+                List<ScoreItem> scores = library.getScoreList();
+                if (count == 1) {
+                    // 首份评卷任务,直接取总分与明细
+                    score = current;
+                    detail = scores;
+                } else {
+                    switch (policy) {
+                    case AVG:
+                        // 直接累加
+                        score += current;
+                        for (int i = 0; i < detail.size(); i++) {
+                            try {
+                                ScoreItem item = detail.get(i);
+                                ScoreItem other = scores.get(i);
+                                item.setScore(item.getScore() + other.getScore());
+                            } catch (Exception e) {
+                                continue;
+                            }
+                        }
+                        break;
+                    case MAX:
+                        if (current > score) {
+                            score = current;
+                            detail = scores;
+                        }
+                        break;
+                    case MIN:
+                        if (current < score) {
+                            score = current;
+                            detail = scores;
+                        }
+                        break;
+                    default:
+                        break;
                     }
                 }
-                studentService.updateSubjectiveScore(library.getStudentId(), markerScore,
-                        ExamStudent.buildScoreList(scoreList));
+            } else {
+                return false;
             }
+        }
+        // 取平均分策略下,累计分数需要重新计算一次
+        if (policy == ScorePolicy.AVG && count > 1) {
+            score = score / count;
+            for (int i = 0; i < detail.size(); i++) {
+                ScoreItem item = detail.get(i);
+                item.setScore(item.getScore() / count);
+            }
+        }
+        group.setMarkScore(score);
+        group.setMarkScoreDetail(detail);
+        return true;
+    }
 
-            groupService.updateLibraryCount(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
-
+    /**
+     * 保存评卷任务
+     * 
+     * @param task
+     * @return
+     */
+    private MarkLibrary updateLibrary(Task task) {
+        MarkLibrary library = libraryService.findById(task.getLibraryId());
+        if (library != null) {
+            // 判断大题是否存在
+            MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(),
+                    library.getGroupNumber());
+            if (group == null) {
+                return null;
+            }
+            // 保存阅卷轨迹
             Map<String, List<TrackDTO>> trackMap = task.getTrackMap();
             for (String questionNumber : trackMap.keySet()) {
                 trackService.deleteByStudentIdAndQuestionNumber(library.getStudentId(), questionNumber);
@@ -253,49 +331,71 @@ public class TaskServiceImpl implements TaskService {
                     trackService.save(dto.transform(library));
                 }
             }
-
+            // 保存特殊标记
             SpecialTagDTO[] tagList = task.getTagList();
-            markSpecialTagService.deleteByLibraryId(library.getId());
             if (tagList != null && tagList.length > 0) {
+                markSpecialTagService.deleteByLibraryId(library.getId());
                 for (SpecialTagDTO s : tagList) {
-                    MarkSpecialTag markSpecialTag = new MarkSpecialTag();
-                    markSpecialTag.setLibraryId(library.getId());
-                    markSpecialTag.setTagName(s.getTagName());
-                    markSpecialTag.setPositionX(s.getPositionX());
-                    markSpecialTag.setPositionY(s.getPositionY());
-                    markSpecialTagService.save(markSpecialTag);
+                    markSpecialTagService.save(s.transform(library));
                 }
             }
-        }
-    }
 
-    /**
-     * 保存评卷任务
-     * 
-     * @param task
-     * @return
-     */
-    private MarkLibrary updateLibrary(Task task) {
-        MarkLibrary library = libraryService.findById(task.getLibraryId());
-        if (library != null) {
-            library.setMarkerId(task.getMarkId());
-            library.setMarkerTime(new Date());
-            library.setTags(StringUtils.trimToNull(task.getTags()));
-            library.setStatus(LibraryStatus.MARKED);
-            if (!task.isProblem()) {
-                library.setMarkerScore(task.getTotalScore());
-                library.setMarkerScoreList(task.getScoreList());
-            }
             if (task.getHeaderId() != null) {
+                // 组长或管理员打分模式
                 library.setHeaderId(task.getHeaderId());
                 library.setHeaderTime(new Date());
                 library.setHeaderScore(task.getHeaderScore());
                 library.setHeaderScoreList(task.getHeaderScoreList());
+                library.setStatus(LibraryStatus.MARKED);
+                library.setTags(StringUtils.trimToNull(task.getTags()));
+            } else {
+                // 评卷员打分模式
+                library.setMarkerId(task.getMarkId());
+                library.setMarkerTime(new Date());
+                library.setMarkerScore(task.getTotalScore());
+                library.setMarkerScoreList(task.getScoreList());
+                library.setStatus(LibraryStatus.MARKED);
+                library.setTags(StringUtils.trimToNull(task.getTags()));
+
+                List<MarkLibrary> list = libraryService.findByStudentAndGroup(library.getStudentId(),
+                        library.getGroupNumber());
+                ArbitrateHistory history = null;
+                if (group.getArbitrateThreshold() != null && group.getArbitrateThreshold() > 0) {
+                    // 多评模式
+                    for (MarkLibrary other : list) {
+                        if (other.getId().equals(library.getId()) || other.getStatus() != LibraryStatus.MARKED
+                                || other.getMarkerScore() == null || other.getHeaderScore() != null) {
+                            // 未评卷或组长已打分,则跳过该任务
+                            continue;
+                        }
+                        if (Math.abs(other.getMarkerScore() - library.getMarkerScore()) > group
+                                .getArbitrateThreshold()) {
+                            // 分差超过阀值,触发仲裁
+                            history = new ArbitrateHistory();
+                            history.setExamId(library.getExamId());
+                            history.setSubjectCode(library.getSubjectCode());
+                            history.setGroupNumber(library.getGroupNumber());
+                            history.setStudentId(library.getStudentId());
+                            history.setExamNumber(library.getExamNumber());
+                            history.setStatus(HistoryStatus.WAITING);
+                            history.setCreateTime(new Date());
+                            arbitrateService.save(history);
+
+                            library.setStatus(LibraryStatus.WAIT_ARBITRATE);
+                            break;
+                        }
+                    }
+                }
+                library = libraryService.save(library);
+                // 触发仲裁后续处理
+                if (history != null) {
+                    libraryService.setArbitrate(history.getStudentId(), history.getGroupNumber());
+                }
             }
-            return libraryService.save(library);
-        } else {
-            return null;
+            // 更新评卷任务数量
+            groupService.updateLibraryCount(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
         }
+        return library;
     }
 
     @Override
@@ -435,7 +535,7 @@ public class TaskServiceImpl implements TaskService {
                     totalScore = totalScore + Double.parseDouble(score);
                 }
                 stepTask.setHeaderScore(totalScore);
-                submitLibrary(stepTask);
+                submitTask(stepTask);
             }
             return true;
         } catch (Exception e) {

+ 65 - 56
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkLibraryService.java

@@ -1,56 +1,65 @@
-package cn.com.qmth.stmms.biz.mark.service;
-
-import java.util.List;
-import java.util.Set;
-
-import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-public interface MarkLibraryService {
-
-    MarkLibrary save(MarkLibrary library);
-
-    MarkLibrary findById(int id);
-
-    List<MarkLibrary> findByStudentId(int studentId);
-
-    long countByQuery(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,
-            int pageNumber, int pageSize);
-
-    void resetByMarker(Marker marker);
-
-    void resetById(int id);
-
-    void backById(int id);
-
-    void delete(MarkLibrary library);
-
-    void deleteByStudent(int studentId);
-
-    long countByExamAndSubjectAndGroupAndStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status);
-
-    long countByMarker(int markerId);
-
-    List<Integer> findTagCampusId(int examId);
-
-    List<String> findTagSubjectCode(int examId);
-
-    MarkLibrary findByStudentAndGroup(int studentId, int groupNumber);
-
-    List<MarkLibrary> findByStudentIdAndStatus(int studentId, LibraryStatus status);
-
-    void resetByGroup(MarkGroup group);
-
-    void deleteByGroup(MarkGroup group);
-
-}
+package cn.com.qmth.stmms.biz.mark.service;
+
+import java.util.List;
+import java.util.Set;
+
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+public interface MarkLibraryService {
+
+    MarkLibrary save(MarkLibrary library);
+
+    MarkLibrary findById(int id);
+
+    List<MarkLibrary> findByStudentId(int studentId);
+
+    long countByQuery(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,
+            int pageNumber, int pageSize);
+
+    void resetByMarker(Marker marker);
+
+    void resetById(int id);
+
+    void backById(int id);
+
+    void back(MarkLibrary library);
+
+    void backWaitArbitrate(Integer studentId, Integer groupNumber);
+
+    void delete(MarkLibrary library);
+
+    void deleteByStudent(int studentId);
+
+    long countByExamAndSubjectAndGroupAndStatus(int examId, String subjectCode, int groupNumber, LibraryStatus status);
+
+    long countByMarker(int markerId);
+
+    List<Integer> findTagCampusId(int examId);
+
+    List<String> findTagSubjectCode(int examId);
+
+    List<MarkLibrary> findByStudentAndGroup(int studentId, int groupNumber);
+
+    List<MarkLibrary> findByStudentIdAndStatus(int studentId, LibraryStatus status);
+
+    void resetByGroup(MarkGroup group);
+
+    void deleteByGroup(MarkGroup group);
+
+    void arbitrated(ArbitrateHistory history);
+
+    void setArbitrate(Integer studentId, Integer groupNumber);
+
+}

+ 6 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkService.java

@@ -0,0 +1,6 @@
+package cn.com.qmth.stmms.biz.mark.service;
+
+
+public interface MarkService {
+
+}

+ 8 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/TaskService.java

@@ -2,7 +2,9 @@ package cn.com.qmth.stmms.biz.mark.service;
 
 import java.util.List;
 
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
 import cn.com.qmth.stmms.biz.mark.model.Task;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
@@ -13,6 +15,8 @@ public interface TaskService {
 
     List<Task> findByQuery(MarkLibrarySearchQuery query);
 
+    Task build(ArbitrateHistory history, MarkGroup group);
+
     Task build(MarkLibrary library);
 
     boolean setCurrent(Marker marker, int libraryId);
@@ -27,10 +31,12 @@ public interface TaskService {
 
     void clearCurrent(Marker marker);
 
-	Task build(Integer studentId);
+    Task build(Integer studentId);
 
-	boolean submitByStudent(Task task);
+    boolean submitByStudent(Task task);
 
     void clearTaskMap(long cleanMapinterval) throws Exception;
 
+    void scoreCalculate(Integer examId, String subjectCode, Integer groupNumber, Integer studentId);
+
 }

+ 32 - 31
stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/HistoryType.java → stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/HistoryStatus.java

@@ -1,31 +1,32 @@
-package cn.com.qmth.stmms.common.enums;
-
-public enum HistoryType {
-    COMMON("正常给分", 0), SELF("自评给分", 1), BACK("打回给分", 2);
-
-    private String name;
-
-    private int value;
-
-    private HistoryType(String name, int value) {
-        this.name = name;
-        this.value = value;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public static HistoryType findByValue(int value) {
-        for (HistoryType c : HistoryType.values()) {
-            if (c.getValue() == value) {
-                return c;
-            }
-        }
-        return null;
-    }
-}
+package cn.com.qmth.stmms.common.enums;
+
+public enum HistoryStatus {
+
+    WAITING("待处理", 0), MARKED("已给分", 1), BACK("已打回", 2);
+
+    private String name;
+
+    private int value;
+
+    private HistoryStatus(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static HistoryStatus findByValue(int value) {
+        for (HistoryStatus c : HistoryStatus.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

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

@@ -1,31 +1,31 @@
-package cn.com.qmth.stmms.common.enums;
-
-public enum LibraryStatus {
-    WAITING("未处理", 0), MARKED("已给分", 1), BACKED("已打回", 2);
-
-    private String name;
-
-    private int value;
-
-    private LibraryStatus(String name, int value) {
-        this.name = name;
-        this.value = value;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public int getValue() {
-        return value;
-    }
-
-    public static LibraryStatus findByValue(int value) {
-        for (LibraryStatus c : LibraryStatus.values()) {
-            if (c.getValue() == value) {
-                return c;
-            }
-        }
-        return null;
-    }
-}
+package cn.com.qmth.stmms.common.enums;
+
+public enum LibraryStatus {
+    WAITING("未处理", 0), MARKED("已给分", 1), BACKED("已打回", 2), WAIT_ARBITRATE("等待仲裁", 3), ARBITRATED("已仲裁", 4);
+
+    private String name;
+
+    private int value;
+
+    private LibraryStatus(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static LibraryStatus findByValue(int value) {
+        for (LibraryStatus c : LibraryStatus.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

+ 37 - 0
stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/ScorePolicy.java

@@ -0,0 +1,37 @@
+package cn.com.qmth.stmms.common.enums;
+
+/**
+ * 多评情况下的合分策略
+ * 
+ * @author luoshi
+ *
+ */
+public enum ScorePolicy {
+    AVG("平均分", 1), MAX("最高分", 2), MIN("最低分", 3);
+
+    private String name;
+
+    private int value;
+
+    private ScorePolicy(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ScorePolicy findByValue(int value) {
+        for (ScorePolicy c : ScorePolicy.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

+ 2 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectQuestionDTO.java

@@ -46,7 +46,8 @@ public class SubjectQuestionDTO {
                 MarkGroup group = groups.get(question.getMainNumber());
                 if (group == null) {
                     group = new MarkGroup(examId, subjectCode, question.getMainNumber(), question.getMainTitle(),
-                            PictureConfigItem.parse(question.getPicList()), 0d);
+                            PictureConfigItem.parse(question.getPicList()), 0d, question.getDoubleRate(),
+                            question.getArbitrateThreshold(), question.getScorePolicy());
                     group.setQuestionList(new LinkedList<ExamQuestion>());
                     groups.put(question.getMainNumber(), group);
                 }

+ 41 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectiveQuestionDTO.java

@@ -6,6 +6,7 @@ import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.common.annotation.ExcelField;
+import cn.com.qmth.stmms.common.enums.ScorePolicy;
 
 public class SubjectiveQuestionDTO implements QuestionDTO {
 
@@ -30,9 +31,18 @@ public class SubjectiveQuestionDTO implements QuestionDTO {
     @ExcelField(title = "间隔分", align = 2, sort = 70)
     private Double intervalScore;
 
-    @ExcelField(title = "图片序号(用英文逗号分割)", align = 2, sort = 90)
+    @ExcelField(title = "图片序号(用英文逗号分割)", align = 2, sort = 80)
     private String picList;
 
+    @ExcelField(title = "双评比例(0~1)", align = 2, sort = 90)
+    private Double doubleRate;
+
+    @ExcelField(title = "仲裁阀值", align = 2, sort = 100)
+    private Double arbitrateThreshold;
+
+    @ExcelField(title = "合分策略(1-平均,2-最高,3-最低)", align = 2, sort = 110)
+    private Integer scorePolicy;
+
     public SubjectiveQuestionDTO() {
 
     }
@@ -46,6 +56,10 @@ public class SubjectiveQuestionDTO implements QuestionDTO {
         setTotalScore(question.getTotalScore());
         setIntervalScore(question.getIntervalScore());
         setPicList(group != null ? group.getPicList() : "");
+        setDoubleRate(group != null ? group.getDoubleRate() : 0d);
+        setArbitrateThreshold(group != null ? group.getArbitrateThreshold() : 0d);
+        setScorePolicy(group != null && group.getScorePolicy() != null ? group.getScorePolicy().getValue()
+                : ScorePolicy.AVG.getValue());
     }
 
     public ExamQuestion transform() {
@@ -61,6 +75,8 @@ public class SubjectiveQuestionDTO implements QuestionDTO {
         question.setZeroCount(0);
         question.setFullCount(0);
         question.setPicList(picList);
+        question.setDoubleRate(doubleRate);
+        question.setArbitrateThreshold(arbitrateThreshold);
         return question;
     }
 
@@ -158,4 +174,28 @@ public class SubjectiveQuestionDTO implements QuestionDTO {
         this.picList = picList;
     }
 
+    public Double getDoubleRate() {
+        return doubleRate;
+    }
+
+    public void setDoubleRate(Double doubleRate) {
+        this.doubleRate = doubleRate;
+    }
+
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
+
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
+
+    public Integer getScorePolicy() {
+        return scorePolicy;
+    }
+
+    public void setScorePolicy(Integer scorePolicy) {
+        this.scorePolicy = scorePolicy;
+    }
+
 }

+ 283 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ArbitrateController.java

@@ -0,0 +1,283 @@
+package cn.com.qmth.stmms.admin.exam;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
+import cn.com.qmth.stmms.biz.mark.model.Task;
+import cn.com.qmth.stmms.biz.mark.query.ArbitrateHistorySearchQuery;
+import cn.com.qmth.stmms.biz.mark.service.ArbitrateHistoryService;
+import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
+import cn.com.qmth.stmms.biz.mark.service.TaskService;
+import cn.com.qmth.stmms.biz.user.service.UserService;
+import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
+import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.HistoryStatus;
+import cn.com.qmth.stmms.common.enums.Role;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+import net.sf.json.JSONObject;
+
+@Controller("libraryController")
+@RequestMapping("/admin/exam/arbitrate")
+public class ArbitrateController extends BaseExamController {
+
+    protected static Logger log = LoggerFactory.getLogger(ArbitrateController.class);
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private ArbitrateHistoryService arbitrateService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Autowired
+    private TaskService taskService;
+
+    // 并发处理互斥锁
+    private Map<Integer, Integer> currentTaskMap = new HashMap<Integer, Integer>();
+
+    @RequestMapping
+    public String list(Model model, HttpServletRequest request, ArbitrateHistorySearchQuery query) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        List<ExamSubject> subjectList = getExamSubject(examId, wu);
+        if (subjectList.isEmpty()) {
+            return "redirect:/admin/exam/mark";
+        }
+        query.setExamId(examId);
+        if (query.getSubjectCode() == null && !subjectList.isEmpty()) {
+            query.setSubjectCode(subjectList.get(0).getCode());
+        }
+        subjectFilter(query, wu);
+        List<MarkGroup> groupList = groupService.findByExamAndSubjectWithDouble(examId, query.getSubjectCode());
+        if (groupList.isEmpty()) {
+            return "redirect:/admin/exam/mark";
+        }
+        if (query.getGroupNumber() == 0) {
+            query.setGroupNumber(groupList.get(0).getNumber());
+        }
+        query.orderByIdDesc();
+        query = arbitrateService.findByQuery(query);
+        for (ArbitrateHistory history : query.getResult()) {
+            if (history.getUserId() != null) {
+                history.setUser(userService.findById(history.getUserId()));
+            }
+        }
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", subjectList);
+        model.addAttribute("groupList", groupList);
+        model.addAttribute("statusList", HistoryStatus.values());
+        return "modules/exam/arbitrateList";
+    }
+
+    @RequestMapping("/process")
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    public String process(Model model, HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer groupNumber) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        if (!subjectCheck(subjectCode, wu)) {
+            return "redirect:/admin/exam/arbitrate";
+        }
+        MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
+        if (group == null) {
+            return "redirect:/admin/exam/arbitrate";
+        }
+        releaseByUser(wu.getUser().getId());
+        model.addAttribute("subjectCode", subjectCode);
+        model.addAttribute("groupNumber", groupNumber);
+        return "modules/exam/arbitrateProcess";
+    }
+
+    @RequestMapping(value = "/back", method = RequestMethod.POST)
+    @ResponseBody
+    @Transactional
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    public JSONObject back(HttpServletRequest request, @RequestParam Integer id) {
+        JSONObject obj = new JSONObject();
+        ArbitrateHistory history = arbitrateService.findById(id);
+        if (history != null) {
+            if (history.getStatus() != HistoryStatus.WAITING) {
+                obj.accumulate("success", false);
+                obj.accumulate("message", "该仲裁卷已被处理");
+            } else {
+                if (subjectCheck(history.getSubjectCode(), RequestUtils.getWebUser(request))) {
+                    libraryService.backWaitArbitrate(history.getStudentId(), history.getGroupNumber());
+                    obj.accumulate("success", true);
+                } else {
+                    obj.accumulate("success", false);
+                    obj.accumulate("message", "没有操作该仲裁卷的权限");
+                }
+            }
+        } else {
+            obj.accumulate("success", false);
+            obj.accumulate("message", "该仲裁记录不存在");
+        }
+        return obj;
+    }
+
+    @RequestMapping(value = "/getTask", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    public Task getTask(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer groupNumber) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
+        if (subjectCheck(subjectCode, wu) && group != null) {
+            ArbitrateHistorySearchQuery query = new ArbitrateHistorySearchQuery();
+            query.setExamId(examId);
+            query.setSubjectCode(subjectCode);
+            query.setGroupNumber(groupNumber);
+            query.setStatus(HistoryStatus.WAITING);
+            query.setPageNumber(1);
+            query.setPageSize(10);
+            while (true) {
+                query = arbitrateService.findByQuery(query);
+                if (query.getCurrentCount() == 0) {
+                    break;
+                }
+                for (ArbitrateHistory history : query.getResult()) {
+                    // 尝试领取该任务并上锁
+                    if (setCurrent(history.getId(), wu.getUser().getId())) {
+                        return taskService.build(history, group);
+                    } else {
+                        continue;
+                    }
+                }
+                // 查询下一页
+                query.setPageNumber(query.getPageNumber() + 1);
+                continue;
+            }
+        }
+        Task task = new Task();
+        task.setExist(false);
+        return task;
+    }
+
+    @RequestMapping(value = "/saveTask", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    public JSONObject saveTask(HttpServletRequest request, @RequestBody Task task) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        ArbitrateHistory history = arbitrateService.findById(task.getLibraryId());
+        JSONObject result = new JSONObject();
+        if (history != null && subjectCheck(history.getSubjectCode(), wu)) {
+            try {
+                history.setUserId(wu.getUser().getId());
+                history.setTotalScore(task.getTotalScore());
+                history.setScoreList(task.getScoreList());
+                history.setStatus(HistoryStatus.MARKED);
+                history.setUpdateTime(new Date());
+                arbitrateService.save(history);
+                libraryService.arbitrated(history);
+                taskService.scoreCalculate(history.getExamId(), history.getSubjectCode(), history.getGroupNumber(),
+                        history.getStudentId());
+                groupService.updateLibraryCount(history.getExamId(), history.getSubjectCode(),
+                        history.getGroupNumber());
+                releaseTask(history.getId());
+                result.accumulate("success", true);
+                result.accumulate("status", status(request, history.getSubjectCode(), history.getGroupNumber()));
+            } catch (Exception e) {
+                log.error("ArbitrateController-处理仲裁卷出错", e);
+                result.accumulate("success", false);
+            }
+        } else {
+            result.accumulate("success", false);
+        }
+        return result;
+    }
+
+    @RequestMapping("/status")
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    public JSONObject status(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer groupNumber) {
+        JSONObject status = new JSONObject();
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
+        if (subjectCheck(subjectCode, wu) && group != null) {
+            ArbitrateHistorySearchQuery query = new ArbitrateHistorySearchQuery();
+            query.setExamId(examId);
+            query.setSubjectCode(subjectCode);
+            query.setGroupNumber(groupNumber);
+            query.setStatus(HistoryStatus.WAITING);
+            long totalCount = arbitrateService.countByQuery(query);
+
+            query.setUserId(wu.getUser().getId());
+            query.setStatus(HistoryStatus.MARKED);
+            long markedCount = arbitrateService.countByQuery(query);
+
+            status.accumulate("totalCount", totalCount);
+            status.accumulate("markedCount", markedCount);
+            status.accumulate("valid", totalCount > 0);
+        } else {
+            status.accumulate("valid", false);
+        }
+        return status;
+    }
+
+    private void releaseByUser(Integer userId) {
+        Set<Integer> taskIds = new HashSet<>();
+        taskIds.addAll(currentTaskMap.keySet());
+        synchronized (currentTaskMap) {
+            for (Integer taskId : taskIds) {
+                Integer value = currentTaskMap.get(taskId);
+                if (value != null && value.equals(userId)) {
+                    currentTaskMap.remove(taskId);
+                }
+            }
+        }
+    }
+
+    private void releaseTask(Integer taskId) {
+        synchronized (currentTaskMap) {
+            currentTaskMap.remove(taskId);
+        }
+    }
+
+    private boolean setCurrent(Integer taskId, Integer userId) {
+        Integer value = currentTaskMap.get(taskId);
+        if (value != null) {
+            synchronized (currentTaskMap) {
+                value = currentTaskMap.get(taskId);
+                if (value == null) {
+                    currentTaskMap.put(taskId, userId);
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        } else {
+            return false;
+        }
+    }
+
+}

+ 275 - 252
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkController.java

@@ -1,252 +1,275 @@
-package cn.com.qmth.stmms.admin.exam;
-
-import java.text.DecimalFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.domain.Sort.Direction;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.servlet.mvc.support.RedirectAttributes;
-
-import cn.com.qmth.stmms.admin.dto.MarkGroupDTO;
-import cn.com.qmth.stmms.admin.dto.MarkerInfoDTO;
-import cn.com.qmth.stmms.admin.vo.SubjectLibraryVO;
-import cn.com.qmth.stmms.biz.campus.model.Campus;
-import cn.com.qmth.stmms.biz.campus.service.CampusService;
-import cn.com.qmth.stmms.biz.exam.model.Exam;
-import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
-import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
-import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.exam.query.ExamSearchQuery;
-import cn.com.qmth.stmms.biz.exam.service.ExamService;
-import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
-import cn.com.qmth.stmms.biz.exam.service.MarkerService;
-import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
-import cn.com.qmth.stmms.common.domain.WebUser;
-import cn.com.qmth.stmms.common.enums.ExamStatus;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-import cn.com.qmth.stmms.common.utils.ExportExcel;
-import cn.com.qmth.stmms.common.utils.RequestUtils;
-
-@Controller("markInfoController")
-@RequestMapping("/admin/exam/mark")
-public class MarkController extends BaseExamController {
-
-    protected static Logger log = LoggerFactory.getLogger(MarkController.class);
-
-    @Autowired
-    private ExamService examService;
-
-    @Autowired
-    private CampusService campusService;
-
-    @Autowired
-    private ExamSubjectService subjectService;
-
-    @Autowired
-    private ExamStudentService studentService;
-
-    @Autowired
-    private MarkLibraryService libraryService;
-
-    @Autowired
-    private MarkerService markerService;
-
-    @Autowired
-    private MarkGroupService groupService;
-
-    /**
-     * 评卷进度
-     * 
-     * @param request
-     * @param model
-     * @param query
-     * @return
-     */
-    @RequestMapping(value = { "", "/subject" })
-    public String subjectList(HttpServletRequest request, Model model, ExamSubjectSearchQuery query) {
-        WebUser wu = RequestUtils.getWebUser(request);
-        int examId = getSessionExamId(request);
-        query.setExamId(examId);
-        // query.setUploadCountGt(0);
-        subjectFilter(query, wu);
-        query = subjectService.findByQuery(query);
-
-        List<SubjectLibraryVO> list = new LinkedList<SubjectLibraryVO>();
-        for (ExamSubject subject : query.getResult()) {
-            SubjectLibraryVO vo = new SubjectLibraryVO();
-            vo.setSubject(subject);
-            vo.setStudentCount(subject.getUploadCount());
-            vo.setGroupCount(groupService.countByExamAndSubject(examId, subject.getCode()));
-            list.add(vo);
-        }
-
-        double total = libraryService.countByExamAndSubjectAndGroupAndStatus(examId, null, 0, null);
-        double finish = libraryService.countByExamAndSubjectAndGroupAndStatus(examId, null, 0, LibraryStatus.MARKED);
-        double percent = total > 0 ? (finish * 100 / total) : 0;
-        model.addAttribute("percent", new DecimalFormat("###.#").format(percent));
-        model.addAttribute("resultList", list);
-        model.addAttribute("query", query);
-        model.addAttribute("subjectList", getExamSubject(examId, wu));
-        model.addAttribute("levelList", subjectService.listLevel(examId));
-        model.addAttribute("categoryList", subjectService.listCategory(examId));
-        return "modules/exam/markInfo";
-    }
-
-    @RequestMapping(value = "/export-progress", method = RequestMethod.POST)
-    public String exportProgress(HttpServletRequest request, HttpServletResponse response,
-            RedirectAttributes redirectAttributes) {
-        WebUser wu = RequestUtils.getWebUser(request);
-        int examId = getSessionExamId(request);
-        List<MarkGroupDTO> result = new LinkedList<MarkGroupDTO>();
-        List<MarkGroup> list = wu.isSubjectHeader()
-                ? groupService.findByExamAndSubject(examId, wu.getUser().getSubjectCode())
-                : groupService.findByExam(examId);
-        for (MarkGroup group : list) {
-            group.setMarkerCount(
-                    markerService.countByExamAndSubjectAndGroup(examId, group.getSubjectCode(), group.getNumber()));
-            MarkGroupDTO dto = new MarkGroupDTO(subjectService.find(examId, group.getSubjectCode()), group);
-            result.add(dto);
-        }
-
-        try {
-            String fileName = "整体评卷进度.xlsx";
-            new ExportExcel("整体评卷进度", MarkGroupDTO.class).setDataList(result).write(response, fileName).dispose();
-            return null;
-        } catch (Exception e) {
-            addMessage(redirectAttributes, "导出整体评卷进度失败!" + e.getMessage());
-            return "redirect:/admin/exam/mark";
-        }
-    }
-
-    @RequestMapping(value = "/export-marker", method = RequestMethod.POST)
-    public String exportMarker(HttpServletRequest request, HttpServletResponse response,
-            RedirectAttributes redirectAttributes) {
-        WebUser wu = RequestUtils.getWebUser(request);
-        int examId = getSessionExamId(request);
-        List<MarkerInfoDTO> result = new LinkedList<MarkerInfoDTO>();
-        List<Marker> list = wu.isSubjectHeader() ? markerService.getMarkCount(examId, wu.getUser().getSubjectCode())
-                : markerService.getMarkCount(examId);
-        for (Marker marker : list) {
-            MarkerInfoDTO dto = new MarkerInfoDTO(marker,
-                    subjectService.find(marker.getExamId(), marker.getSubjectCode()),
-                    groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber()));
-            result.add(dto);
-        }
-
-        try {
-            String fileName = "评卷员工作量.xlsx";
-            new ExportExcel("评卷员工作量", MarkerInfoDTO.class).setDataList(result).write(response, fileName).dispose();
-            return null;
-        } catch (Exception e) {
-            addMessage(redirectAttributes, "导出评卷员工作量失败!" + e.getMessage());
-            return "redirect:/admin/exam/mark";
-        }
-    }
-
-    /**
-     * 定时生成评卷任务
-     */
-    @Scheduled(fixedDelay = 2 * 60 * 1000, initialDelay = 60 * 1000)
-    public void createLibrary() {
-        log.debug("start auto-create library");
-        try {
-            Map<String, Campus> campusMap = new HashMap<String, Campus>();
-
-            ExamSearchQuery query = new ExamSearchQuery();
-            query.addStatus(ExamStatus.START);
-            query.setSort(new Sort(Direction.DESC, "id"));
-            query.setPageNumber(1);
-            query.setPageSize(10);
-            query = examService.findByQuery(query);
-            while (query.getCurrentCount() > 0) {
-                for (Exam exam : query.getResult()) {
-                    createLibraryByExam(exam, campusMap);
-                }
-                query.setPageNumber(query.getPageNumber() + 1);
-                query = examService.findByQuery(query);
-            }
-        } catch (Exception e) {
-        } finally {
-            log.debug("finish auto-create library");
-        }
-    }
-
-    private void createLibraryByExam(Exam exam, Map<String, Campus> campusMap) {
-        List<ExamSubject> subjects = subjectService.list(exam.getId(), 0);
-        for (ExamSubject subject : subjects) {
-            // 清除缺考考生和违纪考生
-            List<Integer> idList = studentService.findAbsentOrBreachLibraryStudent(subject.getExamId(), subject.getCode());
-            if (idList != null) {
-                for (Integer studentId : idList) {
-                    libraryService.deleteByStudent(studentId);
-                }
-                groupService.updateLibraryCount(subject.getExamId(), subject.getCode());
-            }
-            // 处理正常考生
-            List<MarkGroup> groups = groupService.findByExamAndSubject(exam.getId(), subject.getCode());
-            for (MarkGroup group : groups) {
-                Date lastBuildTime = group.getBuildTime();
-                ExamStudent student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(),
-                        group.getNumber(), lastBuildTime);
-                while (student != null) {
-                    MarkGroup current = groupService.findOne(group.getExamId(), group.getSubjectCode(),
-                            group.getNumber());
-                    if (current == null || (current.getBuildTime() == null && lastBuildTime != null)) {
-                        // 大题已被删除,或者已被重置,直接退出循环
-                        break;
-                    }
-                    Campus campus = campusMap.get(student.getSchoolId() + "_" + student.getCampusName());
-                    if (campus == null) {
-                        campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
-                        if (campus == null) {
-                            log.error("campus unexist for student id=" + student.getId());
-                            continue;
-                        } else {
-                            campusMap.put(student.getSchoolId() + "_" + student.getCampusName(), campus);
-                        }
-                    }
-                    MarkLibrary library = libraryService.findByStudentAndGroup(student.getId(), group.getNumber());
-                    if (library == null) {
-                        library = new MarkLibrary();
-                        library.setExamId(student.getExamId());
-                        library.setSubjectCode(student.getSubjectCode());
-                        library.setGroupNumber(group.getNumber());
-                        library.setCampusId(campus.getId());
-                        library.setStudentId(student.getId());
-                        library.setExamNumber(student.getExamNumber());
-                        library.setStatus(LibraryStatus.WAITING);
-                        libraryService.save(library);
-                    }
-                    lastBuildTime = student.getUploadTime();
-                    groupService.updateBuildTime(group.getExamId(), group.getSubjectCode(), group.getNumber(),
-                            lastBuildTime);
-                    groupService.updateLibraryCount(exam.getId(), subject.getCode(), group.getNumber());
-                    // 取下一个考生
-                    student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(), group.getNumber(),
-                            lastBuildTime);
-                }
-            }
-        }
-    }
-
-}
+package cn.com.qmth.stmms.admin.exam;
+
+import java.text.DecimalFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import cn.com.qmth.stmms.admin.dto.MarkGroupDTO;
+import cn.com.qmth.stmms.admin.dto.MarkerInfoDTO;
+import cn.com.qmth.stmms.admin.vo.SubjectLibraryVO;
+import cn.com.qmth.stmms.biz.campus.model.Campus;
+import cn.com.qmth.stmms.biz.campus.service.CampusService;
+import cn.com.qmth.stmms.biz.exam.model.Exam;
+import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.exam.query.ExamSearchQuery;
+import cn.com.qmth.stmms.biz.exam.service.ExamService;
+import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
+import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.biz.mark.service.ArbitrateHistoryService;
+import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
+import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.ExamStatus;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import cn.com.qmth.stmms.common.utils.ExportExcel;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+
+@Controller("markInfoController")
+@RequestMapping("/admin/exam/mark")
+public class MarkController extends BaseExamController {
+
+    protected static Logger log = LoggerFactory.getLogger(MarkController.class);
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private CampusService campusService;
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private ExamStudentService studentService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private ArbitrateHistoryService arbitrateService;
+
+    /**
+     * 评卷进度
+     * 
+     * @param request
+     * @param model
+     * @param query
+     * @return
+     */
+    @RequestMapping(value = { "", "/subject" })
+    public String subjectList(HttpServletRequest request, Model model, ExamSubjectSearchQuery query) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        int examId = getSessionExamId(request);
+        query.setExamId(examId);
+        // query.setUploadCountGt(0);
+        subjectFilter(query, wu);
+        query = subjectService.findByQuery(query);
+
+        List<SubjectLibraryVO> list = new LinkedList<SubjectLibraryVO>();
+        for (ExamSubject subject : query.getResult()) {
+            SubjectLibraryVO vo = new SubjectLibraryVO();
+            vo.setSubject(subject);
+            vo.setStudentCount(subject.getUploadCount());
+            vo.setGroupCount(groupService.countByExamAndSubject(examId, subject.getCode()));
+            list.add(vo);
+        }
+
+        double total = libraryService.countByExamAndSubjectAndGroupAndStatus(examId, null, 0, null);
+        double finish = libraryService.countByExamAndSubjectAndGroupAndStatus(examId, null, 0, LibraryStatus.MARKED);
+        double percent = total > 0 ? (finish * 100 / total) : 0;
+        model.addAttribute("percent", new DecimalFormat("###.#").format(percent));
+        model.addAttribute("resultList", list);
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", getExamSubject(examId, wu));
+        model.addAttribute("levelList", subjectService.listLevel(examId));
+        model.addAttribute("categoryList", subjectService.listCategory(examId));
+        return "modules/exam/markInfo";
+    }
+
+    @RequestMapping(value = "/export-progress", method = RequestMethod.POST)
+    public String exportProgress(HttpServletRequest request, HttpServletResponse response,
+            RedirectAttributes redirectAttributes) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        int examId = getSessionExamId(request);
+        List<MarkGroupDTO> result = new LinkedList<MarkGroupDTO>();
+        List<MarkGroup> list = wu.isSubjectHeader()
+                ? groupService.findByExamAndSubject(examId, wu.getUser().getSubjectCode())
+                : groupService.findByExam(examId);
+        for (MarkGroup group : list) {
+            group.setMarkerCount(
+                    markerService.countByExamAndSubjectAndGroup(examId, group.getSubjectCode(), group.getNumber()));
+            MarkGroupDTO dto = new MarkGroupDTO(subjectService.find(examId, group.getSubjectCode()), group);
+            result.add(dto);
+        }
+
+        try {
+            String fileName = "整体评卷进度.xlsx";
+            new ExportExcel("整体评卷进度", MarkGroupDTO.class).setDataList(result).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导出整体评卷进度失败!" + e.getMessage());
+            return "redirect:/admin/exam/mark";
+        }
+    }
+
+    @RequestMapping(value = "/export-marker", method = RequestMethod.POST)
+    public String exportMarker(HttpServletRequest request, HttpServletResponse response,
+            RedirectAttributes redirectAttributes) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        int examId = getSessionExamId(request);
+        List<MarkerInfoDTO> result = new LinkedList<MarkerInfoDTO>();
+        List<Marker> list = wu.isSubjectHeader() ? markerService.getMarkCount(examId, wu.getUser().getSubjectCode())
+                : markerService.getMarkCount(examId);
+        for (Marker marker : list) {
+            MarkerInfoDTO dto = new MarkerInfoDTO(marker,
+                    subjectService.find(marker.getExamId(), marker.getSubjectCode()),
+                    groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber()));
+            result.add(dto);
+        }
+
+        try {
+            String fileName = "评卷员工作量.xlsx";
+            new ExportExcel("评卷员工作量", MarkerInfoDTO.class).setDataList(result).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导出评卷员工作量失败!" + e.getMessage());
+            return "redirect:/admin/exam/mark";
+        }
+    }
+
+    /**
+     * 定时生成评卷任务
+     */
+    @Scheduled(fixedDelay = 2 * 60 * 1000, initialDelay = 60 * 1000)
+    public void createLibrary() {
+        log.debug("start auto-create library");
+        try {
+            Map<String, Campus> campusMap = new HashMap<String, Campus>();
+
+            ExamSearchQuery query = new ExamSearchQuery();
+            query.addStatus(ExamStatus.START);
+            query.setSort(new Sort(Direction.DESC, "id"));
+            query.setPageNumber(1);
+            query.setPageSize(10);
+            query = examService.findByQuery(query);
+            while (query.getCurrentCount() > 0) {
+                for (Exam exam : query.getResult()) {
+                    createLibraryByExam(exam, campusMap);
+                }
+                query.setPageNumber(query.getPageNumber() + 1);
+                query = examService.findByQuery(query);
+            }
+        } catch (Exception e) {
+        } finally {
+            log.debug("finish auto-create library");
+        }
+    }
+
+    private void createLibraryByExam(Exam exam, Map<String, Campus> campusMap) {
+        List<ExamSubject> subjects = subjectService.list(exam.getId(), 0);
+        for (ExamSubject subject : subjects) {
+            // 清除缺考考生和违纪考生
+            List<Integer> idList = studentService.findAbsentOrBreachLibraryStudent(subject.getExamId(),
+                    subject.getCode());
+            if (idList != null) {
+                for (Integer studentId : idList) {
+                    libraryService.deleteByStudent(studentId);
+                    arbitrateService.deleteByStudent(studentId);
+                }
+                groupService.updateLibraryCount(subject.getExamId(), subject.getCode());
+            }
+            // 处理正常考生
+            List<MarkGroup> groups = groupService.findByExamAndSubject(exam.getId(), subject.getCode());
+            for (MarkGroup group : groups) {
+                Date lastBuildTime = group.getBuildTime();
+                ExamStudent student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(),
+                        group.getNumber(), lastBuildTime);
+                while (student != null) {
+                    // 重复检测大题状态
+                    MarkGroup current = groupService.findOne(group.getExamId(), group.getSubjectCode(),
+                            group.getNumber());
+                    if (current == null || (current.getBuildTime() == null && lastBuildTime != null)) {
+                        // 大题已被删除,或者已被重置,直接退出循环
+                        break;
+                    }
+                    // 补充学习中心集合
+                    Campus campus = campusMap.get(student.getSchoolId() + "_" + student.getCampusName());
+                    if (campus == null) {
+                        campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
+                        if (campus == null) {
+                            log.error("campus unexist for student id=" + student.getId());
+                            continue;
+                        } else {
+                            campusMap.put(student.getSchoolId() + "_" + student.getCampusName(), campus);
+                        }
+                    }
+                    // 查询是否已创建评卷任务
+                    List<MarkLibrary> list = libraryService.findByStudentAndGroup(student.getId(), group.getNumber());
+                    if (list == null || list.isEmpty()) {
+                        MarkLibrary library = new MarkLibrary();
+                        library.setExamId(student.getExamId());
+                        library.setSubjectCode(student.getSubjectCode());
+                        library.setGroupNumber(group.getNumber());
+                        library.setCampusId(campus.getId());
+                        library.setStudentId(student.getId());
+                        library.setExamNumber(student.getExamNumber());
+                        library.setTaskNumber(1);
+                        library.setStatus(LibraryStatus.WAITING);
+                        libraryService.save(library);
+                        // 开启双评,且随机数超过双评比例,生成第二份评卷任务
+                        if (group.getDoubleRate() != null && group.getDoubleRate() > Math.random()) {
+                            library = new MarkLibrary();
+                            library.setExamId(student.getExamId());
+                            library.setSubjectCode(student.getSubjectCode());
+                            library.setGroupNumber(group.getNumber());
+                            library.setCampusId(campus.getId());
+                            library.setStudentId(student.getId());
+                            library.setExamNumber(student.getExamNumber());
+                            library.setTaskNumber(2);
+                            library.setStatus(LibraryStatus.WAITING);
+                            libraryService.save(library);
+                        }
+                    }
+                    lastBuildTime = student.getUploadTime();
+                    groupService.updateBuildTime(group.getExamId(), group.getSubjectCode(), group.getNumber(),
+                            lastBuildTime);
+                    groupService.updateLibraryCount(exam.getId(), subject.getCode(), group.getNumber());
+                    // 取下一个考生
+                    student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(), group.getNumber(),
+                            lastBuildTime);
+                }
+            }
+        }
+    }
+
+}

+ 9 - 4
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkGroupController.java

@@ -84,10 +84,13 @@ public class MarkGroupController extends BaseExamController {
 
     @RequestMapping("/query")
     @ResponseBody
-    public JSONArray query(HttpServletRequest request, @RequestParam String subjectCode) {
+    public JSONArray query(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam(required = false) Boolean withDouble) {
         int examId = getSessionExamId(request);
         JSONArray array = new JSONArray();
-        List<MarkGroup> list = groupService.findByExamAndSubject(examId, subjectCode);
+        List<MarkGroup> list = withDouble != null && withDouble
+                ? groupService.findByExamAndSubjectWithDouble(examId, subjectCode)
+                : groupService.findByExamAndSubject(examId, subjectCode);
         for (MarkGroup group : list) {
             JSONObject obj = new JSONObject();
             obj.accumulate("number", group.getNumber());
@@ -279,7 +282,9 @@ public class MarkGroupController extends BaseExamController {
     public String insert(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number,
             @RequestParam(required = false) String title, @RequestParam(required = false) String picList,
-            @RequestParam(required = false) String scoreList) {
+            @RequestParam(required = false) String scoreList, @RequestParam(required = false) Double doubleRate,
+            @RequestParam(required = false) Double arbitrateThreshold,
+            @RequestParam(required = false) Integer scorePolicy) {
         int examId = getSessionExamId(request);
         MarkGroup group = groupService.findOne(examId, subjectCode, number);
         if (group != null) {
@@ -289,7 +294,7 @@ public class MarkGroupController extends BaseExamController {
         } else {
             // create group
             group = new MarkGroup(examId, subjectCode, number, StringUtils.trimToNull(title),
-                    PictureConfigItem.parse(picList), 0d);
+                    PictureConfigItem.parse(picList), 0d, doubleRate, arbitrateThreshold, scorePolicy);
             List<Double> scores = buildDoubleList(scoreList);
             if (group.getTitle() != null && group.getPicList() != null && scores.size() > 0) {
                 // clear and replace exam_question

+ 491 - 488
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkerController.java

@@ -1,488 +1,491 @@
-package cn.com.qmth.stmms.admin.exam;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Controller;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.multipart.MultipartFile;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.support.RedirectAttributes;
-
-import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
-import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.exam.model.MarkerDTO;
-import cn.com.qmth.stmms.biz.exam.query.MarkerSearchQuery;
-import cn.com.qmth.stmms.biz.exam.service.ExamService;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
-import cn.com.qmth.stmms.biz.exam.service.MarkerService;
-import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
-import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
-import cn.com.qmth.stmms.biz.mark.service.TaskService;
-import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
-import cn.com.qmth.stmms.common.domain.WebUser;
-import cn.com.qmth.stmms.common.enums.MarkerExcelError;
-import cn.com.qmth.stmms.common.enums.Role;
-import cn.com.qmth.stmms.common.utils.ExportExcel;
-import cn.com.qmth.stmms.common.utils.ImportExcel;
-import cn.com.qmth.stmms.common.utils.RequestUtils;
-
-import com.google.common.collect.Lists;
-
-@Controller("examMarkerController")
-@RequestMapping("/admin/exam/marker")
-public class MarkerController extends BaseExamController {
-
-    protected static Logger log = LoggerFactory.getLogger(MarkerController.class);
-
-    public static final String USER_PASSWORD = "123456";
-
-    @Autowired
-    private MarkerService markerService;
-
-    @Autowired
-    private ExamSubjectService subjectService;
-
-    @Autowired
-    private MarkGroupService groupService;
-
-    @Autowired
-    private MarkLibraryService libraryService;
-
-    @Autowired
-    private MarkTrackService trackService;
-
-    @Autowired
-    private TaskService taskService;
-    
-    @Autowired
-    private ExamService examService;
-    
-    @Value("${marker.showBtnImportAndBtnUpdateImport}")
-    private String showBtnImport;
-
-    @RequestMapping
-    public String list(Model model, HttpServletRequest request, MarkerSearchQuery query) {
-        WebUser wu = RequestUtils.getWebUser(request);
-        int examId = getSessionExamId(request);
-        query.setExamId(examId);
-        query.orderById();
-        subjectFilter(query, wu);
-        query = markerService.findByQuery(query);
-        for (Marker marker : query.getResult()) {
-            marker.setSubject(subjectService.find(marker.getExamId(), marker.getSubjectCode()));
-            marker.setGroup(groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber()));
-            marker.setMarkedCount(libraryService.countByMarker(marker.getId()));
-            marker.setCurrentCount(taskService.countCurrent(marker));
-        }
-        model.addAttribute("query", query);
-        model.addAttribute("subjectList", getExamSubject(examId, wu));
-        model.addAttribute("showBtnImport",showBtnImport);
-        return "modules/exam/markerList";
-    }
-
-    @RequestMapping("/query")
-    @ResponseBody
-    public JSONArray query(HttpServletRequest request, @RequestParam String subjectCode,
-            @RequestParam Integer groupNumber) {
-        int examId = getSessionExamId(request);
-        JSONArray array = new JSONArray();
-        List<Marker> list = markerService.findByExamAndSubjectAndGroup(examId, subjectCode, groupNumber);
-        for (Marker marker : list) {
-            JSONObject obj = new JSONObject();
-            obj.accumulate("id", marker.getId());
-            obj.accumulate("loginName", marker.getLoginName());
-            obj.accumulate("name", marker.getName());
-            array.add(obj);
-        }
-        return array;
-    }
-
-    @RequestMapping("/release")
-    @ResponseBody
-    @RoleRequire(Role.SCHOOL_ADMIN)
-    public JSONObject release(@RequestParam Integer id) {
-        JSONObject result = new JSONObject();
-        Marker marker = markerService.findById(id);
-        if (marker != null) {
-            taskService.clearCurrent(marker);
-            result.accumulate("success", true);
-        } else {
-            result.accumulate("success", false);
-            result.accumulate("message", "评卷员不存在");
-        }
-        return result;
-    }
-
-    @RequestMapping("/batch-create")
-    @RoleRequire(Role.SCHOOL_ADMIN)
-    public String createInit(Model model, HttpServletRequest request,
-            @RequestParam(required = false) String subjectCode, @RequestParam(required = false) Integer groupNumber) {
-        int examId = getSessionExamId(request);
-        model.addAttribute("subjectList", getExamSubject(examId, RequestUtils.getWebUser(request)));
-        if (subjectCode != null) {
-            model.addAttribute("subjectCode", subjectCode);
-            model.addAttribute("groupList", groupService.findByExamAndSubject(examId, subjectCode));
-            if (groupNumber != null) {
-                model.addAttribute("groupNumber", groupNumber);
-            }
-        } else {
-            model.addAttribute("groupList", new ArrayList<MarkGroup>());
-        }
-        return "modules/exam/markerCreate";
-    }
-
-    @RequestMapping(value = "/batch-create", method = RequestMethod.POST)
-    @RoleRequire(Role.SCHOOL_ADMIN)
-    public ModelAndView create(HttpServletRequest request, @RequestParam String subjectCode,
-            @RequestParam Integer groupNumber, @RequestParam Integer count, @RequestParam(required = false) String password) {
-        int examId = getSessionExamId(request);
-        ExamSubject subject = subjectService.find(examId, subjectCode);
-        ModelAndView view = new ModelAndView("redirect:/admin/exam/marker");
-        if (subject != null && count > 0 ) {
-            markerService.batchCreate(subject, groupNumber, count, password);
-        }
-        view.addObject("subjectCode", subjectCode);
-        if (groupNumber > 0) {
-            view.addObject("groupNumber", groupNumber);
-        }
-        return view;
-    }
-
-    @RequestMapping(value = "/delete")
-    @Transactional
-    @RoleRequire(Role.SCHOOL_ADMIN)
-    public String delete(@RequestParam Integer id, Model model, RedirectAttributes redirectAttributes) {
-        Marker marker = markerService.findById(id);
-        if (marker != null && !isMarking(marker.getExamId(), marker.getSubjectCode())) {
-            libraryService.resetByMarker(marker);
-            taskService.clearCurrent(marker);
-            groupService.updateLibraryCount(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
-            trackService.deleteByMarkerId(id);
-            markerService.deleteById(id);
-        }
-        redirectAttributes.addAttribute("subjectCode", marker.getSubjectCode());
-        redirectAttributes.addAttribute("groupNumber", marker.getGroupNumber());
-        return "redirect:/admin/exam/marker";
-    }
-
-    @RequestMapping(value = "/delete", method = RequestMethod.POST)
-    @ResponseBody
-    @Transactional
-    @RoleRequire(Role.SCHOOL_ADMIN)
-    public JSONObject deleteMarker(@RequestParam Integer id) {
-        Marker marker = markerService.findById(id);
-        JSONObject obj = new JSONObject();
-        if (marker != null) {
-            libraryService.resetByMarker(marker);
-            taskService.clearCurrent(marker);
-            groupService.updateLibraryCount(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
-            trackService.deleteByMarkerId(id);
-            markerService.deleteById(id);
-            obj.accumulate("success", true);
-        } else {
-            obj.accumulate("success", false);
-            obj.accumulate("message", "该评卷员不存在");
-        }
-        return obj;
-    }
-
-    @RequestMapping(value = "/toggle", method = RequestMethod.POST)
-    @ResponseBody
-    @RoleRequire(Role.SCHOOL_ADMIN)
-    public JSONObject toggle(@RequestParam Integer id, @RequestParam Boolean enable) {
-        Marker marker = markerService.findById(id);
-        JSONObject obj = new JSONObject();
-        if (marker != null) {
-            marker.setEnable(enable);
-            markerService.save(marker);
-            obj.accumulate("success", true);
-        } else {
-            obj.accumulate("success", false);
-            obj.accumulate("message", "该评卷员不存在");
-        }
-        return obj;
-    }
-
-    @RequestMapping(value = "/export", method = RequestMethod.POST)
-    public String exportFile(MarkerSearchQuery query, HttpServletRequest request, HttpServletResponse response,
-            RedirectAttributes redirectAttributes) {
-        WebUser wu = RequestUtils.getWebUser(request);
-        int examId = getSessionExamId(request);
-        query.setExamId(examId);
-        try {
-            query.setPageNumber(1);
-            query.setPageSize(Integer.MAX_VALUE);
-            query.setExamId(examId);
-            query.orderById();
-            subjectFilter(query, wu);
-            String fileName = "评卷员账号.xlsx";
-            query = markerService.findByQuery(query);
-            for (Marker marker : query.getResult()) {
-                ExamSubject subject = subjectService.find(examId, marker.getSubjectCode());
-                if (subject != null) {
-                    marker.setSubjectName(subject.getCode() + "-" + subject.getName());
-                } else {
-                    marker.setSubjectName("");
-                }
-                MarkGroup group = groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber());
-                if (group != null) {
-                    marker.setGroupName(group.getNumber() + "-" + group.getTitle());
-                } else {
-                    marker.setGroupName("");
-                }
-            }
-            new ExportExcel("评卷员数据", Marker.class).setDataList(query.getResult()).write(response, fileName).dispose();
-            return null;
-        } catch (Exception e) {
-            addMessage(redirectAttributes, "导出评卷员失败!" + e.getMessage());
-        }
-        return "redirect:/admin/exam/marker?repage";
-    }
-    
-    @RequestMapping(value = "/reSetPassword", method = RequestMethod.POST)
-    @ResponseBody
-    public JSONObject reSetPassword(@RequestParam Integer id,@RequestParam String password) {
-        Marker marker = markerService.findById(id);
-        JSONObject obj = new JSONObject();
-        if (marker != null) {
-            marker.setPassword(password);
-            marker = markerService.save(marker);
-            obj.accumulate("success", true);
-        } else {
-            obj.accumulate("success", false);
-            obj.accumulate("message", "该评卷员不存在");
-        }
-        return obj;
-    }
-    
-    @RequestMapping(value = "/setTaskCount", method = RequestMethod.POST)
-    @ResponseBody
-    public JSONObject setTaskCount(@RequestParam Integer id,@RequestParam Integer taskCount) {
-        Marker marker = markerService.findById(id);
-        JSONObject obj = new JSONObject();
-        if (marker != null) {
-            marker.setTopCount(taskCount.toString());
-            marker = markerService.save(marker);
-            obj.accumulate("success", true);
-        } else {
-            obj.accumulate("success", false);
-            obj.accumulate("message", "该评卷员不存在");
-        }
-        return obj;
-    }
-    
-    @RequestMapping(value = "/template")
-    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
-        try {
-            String fileName = "评卷员数据导入模板.xlsx";
-            List<Marker> list = Lists.newArrayList();
-            list.add(new Marker());
-            new ExportExcel("评卷员数据", Marker.class, 2).setDataList(list).write(response, fileName).dispose();
-            return null;
-        } catch (Exception e) {
-            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
-        }
-        return "redirect:" + "/admin/exam/marker";
-    }
-    
-    @RequestMapping(value = "/updateLoginNameTemplate")
-    public String updateLoginNameTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
-        try {
-            String fileName = "评卷员账号修改导入模板.xlsx";
-            List<MarkerDTO> list = Lists.newArrayList();
-            list.add(new MarkerDTO());
-            new ExportExcel("评卷员账号修改数据", MarkerDTO.class, 2).setDataList(list).write(response, fileName).dispose();
-            return null;
-        } catch (Exception e) {
-            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
-        }
-        return "redirect:" + "/admin/exam/marker";
-    }
-    @RequestMapping(value = "/import", method = RequestMethod.POST)
-    public String importFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
-        int examId = getSessionExamId(request);
-        try {
-            int successNum = 0;
-            int failureNum = 0;
-            StringBuilder failureMsg = new StringBuilder();
-            ImportExcel ei = new ImportExcel(file, 1, 0);
-            List<Marker> list = ei.getDataList(Marker.class);
-            List<Marker> saveList = new LinkedList<Marker>();
-            Map<String, Marker> saveMap = new HashMap<String, Marker>();
-            Map<String, ExamSubject> current = null;
-            current = new HashMap<String, ExamSubject>();
-            List<ExamSubject> list2 = subjectService.list(examId);
-            for (ExamSubject s : list2) {
-                current.put(s.getCode(), s);
-            }
-            for (Marker marker : list) {
-                String password = "";
-                if (StringUtils.isBlank(marker.getSubjectCode()) || StringUtils.isBlank(marker.getLoginName())) {
-                    continue;
-                }
-                marker.setExamId(examId);
-                marker.setName(marker.getLoginName());
-                marker.setEnable(true);
-                if(StringUtils.isBlank(marker.getPassword())){
-                    Random random = new Random();
-                    for (int i=0;i<6;i++)
-                    {
-                        password+=random.nextInt(10);
-                    }
-                    marker.setPassword(password);
-                }
-                MarkerExcelError markerExcelError = checkLongNameAndPassword(marker,current,saveMap);
-                if (markerExcelError.equals(MarkerExcelError.MARKER)) {
-                    saveList.add(marker);
-                    saveMap.put(marker.getLoginName(), marker);
-                } else {
-                    failureMsg.append("<br/>评卷员 " + marker.getLoginName() + ","+markerExcelError.getName());
-                    failureNum++;
-                }
-            }
-            successNum = markerService.batchSave(saveList);
-            if (failureNum > 0) {
-                failureMsg.insert(0, ",失败 " + failureNum + " 条记录!");
-            }
-            addMessage(redirectAttributes, "已成功导入 " + successNum + " 条评卷员" + failureMsg);
-        } catch (Exception e) {
-            log.error("Batch import marker error!", e);
-            addMessage(redirectAttributes, "导入评卷员失败!失败信息:" + e.getMessage());
-        }
-        return "redirect:" + "/admin/exam/marker";
-    }
-    @RequestMapping(value = "/importUpdate", method = RequestMethod.POST)
-    public String importUpdateFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
-        try {
-            int successNum = 0;
-            int failureNum = 0;
-            StringBuilder failureMsg = new StringBuilder();
-            ImportExcel ei = new ImportExcel(file, 1, 0);
-            List<MarkerDTO> list = ei.getDataList(MarkerDTO.class);
-            List<Marker> saveList = new LinkedList<Marker>();
-            Map<String, Marker> current = null;
-            List<Marker> list2 = markerService.findMode("common");
-            if(list2.size()<10000){
-                current = new HashMap<String, Marker>();
-                for (Marker s : list2) {
-                    current.put(s.getLoginName(), s);
-                }
-            }
-            for (MarkerDTO markerDTO : list) {
-                if (StringUtils.isBlank(markerDTO.getSubjectCode()) || StringUtils.isBlank(markerDTO.getLoginName())
-                        || StringUtils.isBlank(markerDTO.getNewLoginName()) || StringUtils.isBlank(markerDTO.getPassword())) {
-                    continue;
-                }
-                MarkerExcelError markerExcelError = checkExcelData(markerDTO,current);
-                if (markerExcelError.equals(MarkerExcelError.MARKER)) {
-                    Marker marker = null;
-                    if(current != null){
-                         marker = current.get(markerDTO.getLoginName());
-                    }else {
-                        marker = markerService.findByLoginName(markerDTO.getLoginName());
-                    }
-                    marker.setLoginName(markerDTO.getNewLoginName());
-                    marker.setPassword(markerDTO.getPassword());
-                    saveList.add(marker);
-                } else {
-                    failureMsg.append("<br/>科目代码(" + markerDTO.getSubjectCode()+")原评卷员("+markerDTO.getLoginName() +")更换新评卷员为("+markerDTO.getNewLoginName()+ ")失败!");
-                    failureMsg.append("---->失败原因:("+markerExcelError.getName()+")");
-                    failureNum++;
-                }
-            }
-            successNum = markerService.batchSave(saveList);
-            if (failureNum > 0) {
-                failureMsg.insert(0, ",失败 " + failureNum + " 条记录!");
-            }
-            addMessage(redirectAttributes, "已成功导入 " + successNum + " 条" + failureMsg);
-        } catch (Exception e) {
-            log.error("Batch import marker error!", e);
-            addMessage(redirectAttributes, "导入修改评卷员账号失败!失败信息:" + e.getMessage());
-        }
-        return "redirect:" + "/admin/exam/marker";
-    }
-    private MarkerExcelError checkLongNameAndPassword(Marker marker, Map<String, ExamSubject> current,Map<String, Marker> saveMap) {
-        Marker previous = null;
-
-        if(current != null && current.get(marker.getSubjectCode()) == null){
-            return MarkerExcelError.MARKERNOTCODE;
-        }
-        MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), Integer.valueOf(marker.getGroupName()));
-        if(group==null){
-        	return MarkerExcelError.MARKERNOTGROUP;
-        }else{
-        	marker.setGroupNumber(Integer.valueOf(marker.getGroupName()));
-        }
-        if (saveMap != null) {
-            previous = saveMap.get(marker.getLoginName());
-        }
-
-        if (previous != null) {
-            return MarkerExcelError.MARKERED;
-        }
-
-        previous = markerService.findByLoginName(marker.getLoginName());
-
-        if(marker.getPassword().length()>0 && marker.getPassword().length()<4){
-            return MarkerExcelError.MARKERPWERROR;
-        }
-
-        if (previous == null) {
-            return MarkerExcelError.MARKER;
-        }
-        return MarkerExcelError.MARKERED;
-    }
-
-    //校验excel中数据
-    public MarkerExcelError checkExcelData(MarkerDTO markerDTO,Map<String, Marker> current ){
-        if(markerDTO != null){
-            Marker marker = null;
-            if(current == null){
-                marker = markerService.findByLoginName(markerDTO.getLoginName());
-            }else {
-                marker = current.get(markerDTO.getLoginName());
-            }
-            if(markerDTO.getPassword().length() < 4){
-                return MarkerExcelError.MARKERPWERROR;
-            }
-            if(marker != null){
-                if(marker.getSubjectCode().equals(markerDTO.getSubjectCode())){
-                    if(markerService.countByLoginName(markerDTO.getNewLoginName()) > 0){
-                        return MarkerExcelError.MARKERNEWMISS;
-                    }else {
-                        return MarkerExcelError.MARKER;
-                    }
-                }else{
-                    return  MarkerExcelError.MARKERCODEMISS;
-                }
-            }else {
-                return MarkerExcelError.MARKERMISS;
-            }
-        }else {
-          return   MarkerExcelError.MARKERNOTINFO;
-        }
-    }
-}
+package cn.com.qmth.stmms.admin.exam;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import com.google.common.collect.Lists;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.exam.model.MarkerDTO;
+import cn.com.qmth.stmms.biz.exam.query.MarkerSearchQuery;
+import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
+import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
+import cn.com.qmth.stmms.biz.mark.service.TaskService;
+import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
+import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.MarkerExcelError;
+import cn.com.qmth.stmms.common.enums.Role;
+import cn.com.qmth.stmms.common.utils.ExportExcel;
+import cn.com.qmth.stmms.common.utils.ImportExcel;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+@Controller("examMarkerController")
+@RequestMapping("/admin/exam/marker")
+public class MarkerController extends BaseExamController {
+
+    protected static Logger log = LoggerFactory.getLogger(MarkerController.class);
+
+    public static final String USER_PASSWORD = "123456";
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Autowired
+    private MarkTrackService trackService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Value("${marker.showBtnImportAndBtnUpdateImport}")
+    private String showBtnImport;
+
+    @RequestMapping
+    public String list(Model model, HttpServletRequest request, MarkerSearchQuery query) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        int examId = getSessionExamId(request);
+        query.setExamId(examId);
+        query.orderById();
+        subjectFilter(query, wu);
+        query = markerService.findByQuery(query);
+        for (Marker marker : query.getResult()) {
+            marker.setSubject(subjectService.find(marker.getExamId(), marker.getSubjectCode()));
+            marker.setGroup(groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber()));
+            marker.setMarkedCount(libraryService.countByMarker(marker.getId()));
+            marker.setCurrentCount(taskService.countCurrent(marker));
+        }
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", getExamSubject(examId, wu));
+        model.addAttribute("showBtnImport", showBtnImport);
+        return "modules/exam/markerList";
+    }
+
+    @RequestMapping("/query")
+    @ResponseBody
+    public JSONArray query(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer groupNumber) {
+        int examId = getSessionExamId(request);
+        JSONArray array = new JSONArray();
+        List<Marker> list = markerService.findByExamAndSubjectAndGroup(examId, subjectCode, groupNumber);
+        for (Marker marker : list) {
+            JSONObject obj = new JSONObject();
+            obj.accumulate("id", marker.getId());
+            obj.accumulate("loginName", marker.getLoginName());
+            obj.accumulate("name", marker.getName());
+            array.add(obj);
+        }
+        return array;
+    }
+
+    @RequestMapping("/release")
+    @ResponseBody
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public JSONObject release(@RequestParam Integer id) {
+        JSONObject result = new JSONObject();
+        Marker marker = markerService.findById(id);
+        if (marker != null) {
+            taskService.clearCurrent(marker);
+            result.accumulate("success", true);
+        } else {
+            result.accumulate("success", false);
+            result.accumulate("message", "评卷员不存在");
+        }
+        return result;
+    }
+
+    @RequestMapping("/batch-create")
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public String createInit(Model model, HttpServletRequest request,
+            @RequestParam(required = false) String subjectCode, @RequestParam(required = false) Integer groupNumber) {
+        int examId = getSessionExamId(request);
+        model.addAttribute("subjectList", getExamSubject(examId, RequestUtils.getWebUser(request)));
+        if (subjectCode != null) {
+            model.addAttribute("subjectCode", subjectCode);
+            model.addAttribute("groupList", groupService.findByExamAndSubject(examId, subjectCode));
+            if (groupNumber != null) {
+                model.addAttribute("groupNumber", groupNumber);
+            }
+        } else {
+            model.addAttribute("groupList", new ArrayList<MarkGroup>());
+        }
+        return "modules/exam/markerCreate";
+    }
+
+    @RequestMapping(value = "/batch-create", method = RequestMethod.POST)
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public ModelAndView create(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer groupNumber, @RequestParam Integer count,
+            @RequestParam(required = false) String password) {
+        int examId = getSessionExamId(request);
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        ModelAndView view = new ModelAndView("redirect:/admin/exam/marker");
+        if (subject != null && count > 0) {
+            markerService.batchCreate(subject, groupNumber, count, password);
+        }
+        view.addObject("subjectCode", subjectCode);
+        if (groupNumber > 0) {
+            view.addObject("groupNumber", groupNumber);
+        }
+        return view;
+    }
+
+    @RequestMapping(value = "/delete")
+    @Transactional
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public String delete(@RequestParam Integer id, Model model, RedirectAttributes redirectAttributes) {
+        Marker marker = markerService.findById(id);
+        if (marker != null && !isMarking(marker.getExamId(), marker.getSubjectCode())) {
+            libraryService.resetByMarker(marker);
+            taskService.clearCurrent(marker);
+            groupService.updateLibraryCount(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
+            trackService.deleteByMarkerId(id);
+            markerService.deleteById(id);
+        }
+        redirectAttributes.addAttribute("subjectCode", marker.getSubjectCode());
+        redirectAttributes.addAttribute("groupNumber", marker.getGroupNumber());
+        return "redirect:/admin/exam/marker";
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    @ResponseBody
+    @Transactional
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public JSONObject deleteMarker(@RequestParam Integer id) {
+        Marker marker = markerService.findById(id);
+        JSONObject obj = new JSONObject();
+        if (marker != null) {
+            libraryService.resetByMarker(marker);
+            taskService.clearCurrent(marker);
+            groupService.updateLibraryCount(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
+            trackService.deleteByMarkerId(id);
+            markerService.deleteById(id);
+            obj.accumulate("success", true);
+        } else {
+            obj.accumulate("success", false);
+            obj.accumulate("message", "该评卷员不存在");
+        }
+        return obj;
+    }
+
+    @RequestMapping(value = "/toggle", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public JSONObject toggle(@RequestParam Integer id, @RequestParam Boolean enable) {
+        Marker marker = markerService.findById(id);
+        JSONObject obj = new JSONObject();
+        if (marker != null) {
+            marker.setEnable(enable);
+            markerService.save(marker);
+            obj.accumulate("success", true);
+        } else {
+            obj.accumulate("success", false);
+            obj.accumulate("message", "该评卷员不存在");
+        }
+        return obj;
+    }
+
+    @RequestMapping(value = "/export", method = RequestMethod.POST)
+    public String exportFile(MarkerSearchQuery query, HttpServletRequest request, HttpServletResponse response,
+            RedirectAttributes redirectAttributes) {
+        WebUser wu = RequestUtils.getWebUser(request);
+        int examId = getSessionExamId(request);
+        query.setExamId(examId);
+        try {
+            query.setPageNumber(1);
+            query.setPageSize(Integer.MAX_VALUE);
+            query.setExamId(examId);
+            query.orderById();
+            subjectFilter(query, wu);
+            String fileName = "评卷员账号.xlsx";
+            query = markerService.findByQuery(query);
+            for (Marker marker : query.getResult()) {
+                ExamSubject subject = subjectService.find(examId, marker.getSubjectCode());
+                if (subject != null) {
+                    marker.setSubjectName(subject.getCode() + "-" + subject.getName());
+                } else {
+                    marker.setSubjectName("");
+                }
+                MarkGroup group = groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber());
+                if (group != null) {
+                    marker.setGroupName(group.getNumber() + "-" + group.getTitle());
+                } else {
+                    marker.setGroupName("");
+                }
+            }
+            new ExportExcel("评卷员数据", Marker.class).setDataList(query.getResult()).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导出评卷员失败!" + e.getMessage());
+        }
+        return "redirect:/admin/exam/marker?repage";
+    }
+
+    @RequestMapping(value = "/reSetPassword", method = RequestMethod.POST)
+    @ResponseBody
+    public JSONObject reSetPassword(@RequestParam Integer id, @RequestParam String password) {
+        Marker marker = markerService.findById(id);
+        JSONObject obj = new JSONObject();
+        if (marker != null) {
+            marker.setPassword(password);
+            marker = markerService.save(marker);
+            obj.accumulate("success", true);
+        } else {
+            obj.accumulate("success", false);
+            obj.accumulate("message", "该评卷员不存在");
+        }
+        return obj;
+    }
+
+    @RequestMapping(value = "/setTaskCount", method = RequestMethod.POST)
+    @ResponseBody
+    public JSONObject setTaskCount(@RequestParam Integer id, @RequestParam Integer taskCount) {
+        Marker marker = markerService.findById(id);
+        JSONObject obj = new JSONObject();
+        if (marker != null) {
+            marker.setTopCount(taskCount.toString());
+            marker = markerService.save(marker);
+            obj.accumulate("success", true);
+        } else {
+            obj.accumulate("success", false);
+            obj.accumulate("message", "该评卷员不存在");
+        }
+        return obj;
+    }
+
+    @RequestMapping(value = "/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "评卷员数据导入模板.xlsx";
+            List<Marker> list = Lists.newArrayList();
+            list.add(new Marker());
+            new ExportExcel("评卷员数据", Marker.class, 2).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam/marker";
+    }
+
+    @RequestMapping(value = "/updateLoginNameTemplate")
+    public String updateLoginNameTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "评卷员账号修改导入模板.xlsx";
+            List<MarkerDTO> list = Lists.newArrayList();
+            list.add(new MarkerDTO());
+            new ExportExcel("评卷员账号修改数据", MarkerDTO.class, 2).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam/marker";
+    }
+
+    @RequestMapping(value = "/import", method = RequestMethod.POST)
+    public String importFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+        int examId = getSessionExamId(request);
+        try {
+            int successNum = 0;
+            int failureNum = 0;
+            StringBuilder failureMsg = new StringBuilder();
+            ImportExcel ei = new ImportExcel(file, 1, 0);
+            List<Marker> list = ei.getDataList(Marker.class);
+            List<Marker> saveList = new LinkedList<Marker>();
+            Map<String, Marker> saveMap = new HashMap<String, Marker>();
+            Map<String, ExamSubject> current = null;
+            current = new HashMap<String, ExamSubject>();
+            List<ExamSubject> list2 = subjectService.list(examId);
+            for (ExamSubject s : list2) {
+                current.put(s.getCode(), s);
+            }
+            for (Marker marker : list) {
+                String password = "";
+                if (StringUtils.isBlank(marker.getSubjectCode()) || StringUtils.isBlank(marker.getLoginName())) {
+                    continue;
+                }
+                marker.setExamId(examId);
+                marker.setName(marker.getLoginName());
+                marker.setEnable(true);
+                if (StringUtils.isBlank(marker.getPassword())) {
+                    Random random = new Random();
+                    for (int i = 0; i < 6; i++) {
+                        password += random.nextInt(10);
+                    }
+                    marker.setPassword(password);
+                }
+                MarkerExcelError markerExcelError = checkLongNameAndPassword(marker, current, saveMap);
+                if (markerExcelError.equals(MarkerExcelError.MARKER)) {
+                    saveList.add(marker);
+                    saveMap.put(marker.getLoginName(), marker);
+                } else {
+                    failureMsg.append("<br/>评卷员 " + marker.getLoginName() + "," + markerExcelError.getName());
+                    failureNum++;
+                }
+            }
+            successNum = markerService.batchSave(saveList);
+            if (failureNum > 0) {
+                failureMsg.insert(0, ",失败 " + failureNum + " 条记录!");
+            }
+            addMessage(redirectAttributes, "已成功导入 " + successNum + " 条评卷员" + failureMsg);
+        } catch (Exception e) {
+            log.error("Batch import marker error!", e);
+            addMessage(redirectAttributes, "导入评卷员失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam/marker";
+    }
+
+    @RequestMapping(value = "/importUpdate", method = RequestMethod.POST)
+    public String importUpdateFile(HttpServletRequest request, MultipartFile file,
+            RedirectAttributes redirectAttributes) {
+        try {
+            int successNum = 0;
+            int failureNum = 0;
+            StringBuilder failureMsg = new StringBuilder();
+            ImportExcel ei = new ImportExcel(file, 1, 0);
+            List<MarkerDTO> list = ei.getDataList(MarkerDTO.class);
+            List<Marker> saveList = new LinkedList<Marker>();
+            Map<String, Marker> current = null;
+            List<Marker> list2 = markerService.findMode("common");
+            if (list2.size() < 10000) {
+                current = new HashMap<String, Marker>();
+                for (Marker s : list2) {
+                    current.put(s.getLoginName(), s);
+                }
+            }
+            for (MarkerDTO markerDTO : list) {
+                if (StringUtils.isBlank(markerDTO.getSubjectCode()) || StringUtils.isBlank(markerDTO.getLoginName())
+                        || StringUtils.isBlank(markerDTO.getNewLoginName())
+                        || StringUtils.isBlank(markerDTO.getPassword())) {
+                    continue;
+                }
+                MarkerExcelError markerExcelError = checkExcelData(markerDTO, current);
+                if (markerExcelError.equals(MarkerExcelError.MARKER)) {
+                    Marker marker = null;
+                    if (current != null) {
+                        marker = current.get(markerDTO.getLoginName());
+                    } else {
+                        marker = markerService.findByLoginName(markerDTO.getLoginName());
+                    }
+                    marker.setLoginName(markerDTO.getNewLoginName());
+                    marker.setPassword(markerDTO.getPassword());
+                    saveList.add(marker);
+                } else {
+                    failureMsg.append("<br/>科目代码(" + markerDTO.getSubjectCode() + ")原评卷员(" + markerDTO.getLoginName()
+                            + ")更换新评卷员为(" + markerDTO.getNewLoginName() + ")失败!");
+                    failureMsg.append("---->失败原因:(" + markerExcelError.getName() + ")");
+                    failureNum++;
+                }
+            }
+            successNum = markerService.batchSave(saveList);
+            if (failureNum > 0) {
+                failureMsg.insert(0, ",失败 " + failureNum + " 条记录!");
+            }
+            addMessage(redirectAttributes, "已成功导入 " + successNum + " 条" + failureMsg);
+        } catch (Exception e) {
+            log.error("Batch import marker error!", e);
+            addMessage(redirectAttributes, "导入修改评卷员账号失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam/marker";
+    }
+
+    private MarkerExcelError checkLongNameAndPassword(Marker marker, Map<String, ExamSubject> current,
+            Map<String, Marker> saveMap) {
+        Marker previous = null;
+
+        if (current != null && current.get(marker.getSubjectCode()) == null) {
+            return MarkerExcelError.MARKERNOTCODE;
+        }
+        MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(),
+                Integer.valueOf(marker.getGroupName()));
+        if (group == null) {
+            return MarkerExcelError.MARKERNOTGROUP;
+        } else {
+            marker.setGroupNumber(Integer.valueOf(marker.getGroupName()));
+        }
+        if (saveMap != null) {
+            previous = saveMap.get(marker.getLoginName());
+        }
+
+        if (previous != null) {
+            return MarkerExcelError.MARKERED;
+        }
+
+        previous = markerService.findByLoginName(marker.getLoginName());
+
+        if (marker.getPassword().length() > 0 && marker.getPassword().length() < 4) {
+            return MarkerExcelError.MARKERPWERROR;
+        }
+
+        if (previous == null) {
+            return MarkerExcelError.MARKER;
+        }
+        return MarkerExcelError.MARKERED;
+    }
+
+    // 校验excel中数据
+    public MarkerExcelError checkExcelData(MarkerDTO markerDTO, Map<String, Marker> current) {
+        if (markerDTO != null) {
+            Marker marker = null;
+            if (current == null) {
+                marker = markerService.findByLoginName(markerDTO.getLoginName());
+            } else {
+                marker = current.get(markerDTO.getLoginName());
+            }
+            if (markerDTO.getPassword().length() < 4) {
+                return MarkerExcelError.MARKERPWERROR;
+            }
+            if (marker != null) {
+                if (marker.getSubjectCode().equals(markerDTO.getSubjectCode())) {
+                    if (markerService.countByLoginName(markerDTO.getNewLoginName()) > 0) {
+                        return MarkerExcelError.MARKERNEWMISS;
+                    } else {
+                        return MarkerExcelError.MARKER;
+                    }
+                } else {
+                    return MarkerExcelError.MARKERCODEMISS;
+                }
+            } else {
+                return MarkerExcelError.MARKERMISS;
+            }
+        } else {
+            return MarkerExcelError.MARKERNOTINFO;
+        }
+    }
+}

+ 403 - 409
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ExamStudentController.java

@@ -1,409 +1,403 @@
-package cn.com.qmth.stmms.api.controller;
-
-import java.text.DecimalFormat;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-
-import cn.com.qmth.stmms.api.utils.AESUtil;
-import cn.com.qmth.stmms.api.utils.MenualAbsentDTO;
-import cn.com.qmth.stmms.biz.api.auth.annotation.AuthValidate;
-import cn.com.qmth.stmms.biz.api.auth.exception.ApiException;
-import cn.com.qmth.stmms.biz.campus.model.Campus;
-import cn.com.qmth.stmms.biz.campus.service.CampusService;
-import cn.com.qmth.stmms.biz.exam.model.Exam;
-import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
-import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
-import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
-import cn.com.qmth.stmms.biz.exam.service.ExamPackageService;
-import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
-import cn.com.qmth.stmms.biz.exam.service.ExamService;
-import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
-import cn.com.qmth.stmms.biz.user.model.User;
-import cn.com.qmth.stmms.biz.utils.ScoreItem;
-import cn.com.qmth.stmms.common.utils.RequestUtils;
-
-import com.google.common.base.Strings;
-
-@Controller("examStudentApiController")
-@RequestMapping("/api")
-public class ExamStudentController extends BaseApiController {
-
-    protected static Logger logger = LoggerFactory.getLogger(ExamStudentController.class);
-
-    @Autowired
-    private ExamStudentService examStudentService;
-
-    @Autowired
-    private ExamService examService;
-
-    @Autowired
-    private CampusService campusService;
-
-    @Autowired
-    private ExamPackageService packageService;
-    
-    @Autowired
-    private ExamQuestionService questionService;
-    
-    @AuthValidate("adminUser")
-    @RequestMapping(value = "/student/manualAbsent/{examId}", method = RequestMethod.POST)
-    @ResponseBody
-    public Object updateManualAbsent(HttpServletRequest request, @PathVariable Integer examId,
-            @RequestBody MenualAbsentDTO[] datas) {
-        User user = RequestUtils.getApiUser(request);
-        Exam exam = examService.findById(examId);
-        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
-            for (MenualAbsentDTO dto : datas) {
-                examStudentService.updateManualAbsent(examId, dto.getExamNumber(), dto.isAbsent());
-            }
-            return true;
-        } else {
-            throw ApiException.EXAM_NOT_ACCESSIBLED;
-        }
-    }
-
-    @AuthValidate("adminUser")
-    @RequestMapping(value = "/student/manualAbsent/clear", method = RequestMethod.POST)
-    @ResponseBody
-    public Object clearManualAbsent(HttpServletRequest request, @RequestParam Integer examId) {
-        User user = RequestUtils.getApiUser(request);
-        Exam exam = examService.findById(examId);
-        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
-            examStudentService.clearManualAbsent(examId);
-            return true;
-        } else {
-            throw ApiException.EXAM_NOT_ACCESSIBLED;
-        }
-    }
-
-    @AuthValidate({ "adminUser", "scanner" })
-    @RequestMapping(value = "/exam/students/{examId}", method = RequestMethod.GET)
-    @ResponseBody
-    public JSONArray getExamStudents(HttpServletRequest request, @PathVariable Integer examId) {
-        JSONArray array = new JSONArray();
-        List<ExamStudent> esList = new LinkedList<ExamStudent>();
-        Exam exam = examService.findById(examId);
-        if (exam != null) {
-            esList = examStudentService.findByExamId(examId);
-        }
-        for (ExamStudent student : esList) {
-            JSONObject obj = new JSONObject();
-            obj.accumulate("examNumber", student.getExamNumber());
-            obj.accumulate("campusName", student.getCampusName());
-            obj.accumulate("subjectCode", student.getSubjectCode());
-            obj.accumulate("subjectName", student.getSubjectName());
-            obj.accumulate("name", student.getName());
-            obj.accumulate("studentId", String.valueOf(student.getId()));
-            obj.accumulate("barcode", student.getExamNumber());
-
-            Campus campus = campusService.findBySchoolAndName(exam.getSchoolId(), student.getCampusName());
-            obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
-            array.add(obj);
-        }
-        return array;
-    }
-
-    @AuthValidate({ "adminUser", "scanner" })
-    @RequestMapping(value = "/students/{examId}", method = RequestMethod.GET)
-    @ResponseBody
-    public JSONArray getStudent(HttpServletRequest request, @PathVariable Integer examId,
-            @RequestParam(required = false) Boolean upload, @RequestParam(required = false) Boolean absent,
-            @RequestParam(required = false) Integer pageNumber, @RequestParam(required = false) Integer pageSize) {
-        JSONArray array = new JSONArray();
-        Exam exam = examService.findById(examId);
-        if (exam == null) {
-            return array;
-        }
-
-        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
-        query.setExamId(examId);
-        query.setUpload(upload);
-        query.setAbsent(absent);
-        if (pageNumber != null && pageSize != null) {
-            query.setPageNumber(pageNumber);
-            query.setPageSize(pageSize);
-        } else {
-            query.setPageNumber(1);
-            query.setPageSize(Integer.MAX_VALUE);
-        }
-        examStudentService.findByQuery(query);
-        for (ExamStudent student : query.getResult()) {
-            JSONObject obj = new JSONObject();
-            obj.accumulate("id", student.getId());
-            obj.accumulate("examNumber", student.getExamNumber());
-            obj.accumulate("campusName", student.getCampusName());
-            obj.accumulate("subjectCode", student.getSubjectCode());
-            obj.accumulate("subjectName", student.getSubjectName());
-            obj.accumulate("name", student.getName());
-            obj.accumulate("studentCode", student.getStudentCode());
-
-            Campus campus = campusService.findBySchoolAndName(exam.getSchoolId(), student.getCampusName());
-            obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
-            array.add(obj);
-        }
-        return array;
-    }
-
-    @AuthValidate({ "adminUser", "scanner" })
-    @RequestMapping(value = "/student/check", method = RequestMethod.POST)
-    @ResponseBody
-    public JSONObject checkStudent(HttpServletRequest request, @RequestBody ExamStudent examStudent) {
-        JSONObject obj = new JSONObject();
-        Exam exam = examService.findById(examStudent.getExamId());
-        ExamStudent student = examStudentService.findByExamIdAndExamNumber(examStudent.getExamId(),
-                examStudent.getExamNumber());
-        if (student != null) {
-            obj.accumulate("examId", examStudent.getExamId());
-            obj.accumulate("campusName", student.getCampusName());
-            obj.accumulate("examNumber", student.getExamNumber());
-            obj.accumulate("name", student.getName());
-            obj.accumulate("studentId", String.valueOf(student.getId()));
-            obj.accumulate("subjectCode", student.getSubjectCode());
-            obj.accumulate("subjectName", student.getSubjectName());
-
-            Campus campus = campusService.findBySchoolAndName(exam.getSchoolId(), student.getCampusName());
-            obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
-        } else {
-            obj.accumulate("examId", examStudent.getExamId());
-            obj.accumulate("campusCode", "");
-            obj.accumulate("campusName", "");
-            obj.accumulate("examNumber", examStudent.getExamNumber());
-            obj.accumulate("name", "");
-            obj.accumulate("studentId", "");
-            obj.accumulate("subjectCode", "");
-            obj.accumulate("subjectName", "");
-        }
-        return obj;
-    }
-    
-    @AuthValidate("adminUser")
-    @RequestMapping("/students/count/{examId}")
-    @ResponseBody
-    public long getStudentCount(HttpServletRequest request, @PathVariable Integer examId,
-            @RequestParam(required = false) Boolean upload, @RequestParam(required = false) Boolean absent) {
-        User user = RequestUtils.getApiUser(request);
-        Exam exam = examService.findById(examId);
-        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
-            ExamStudentSearchQuery query = new ExamStudentSearchQuery();
-            query.setExamId(examId);
-            query.setUpload(upload);
-            query.setAbsent(absent);
-            return examStudentService.countByQuery(query);
-        }
-        return 0;
-    }
-    
-    @AuthValidate("adminUser")
-    @RequestMapping("/exam/students")
-    @ResponseBody
-    public JSONArray getStudent(HttpServletRequest request, ExamStudentSearchQuery query,
-            @RequestParam(required = false) Boolean withScoreDetail) {
-        User user = RequestUtils.getApiUser(request);
-        JSONArray array = new JSONArray();
-        if (query.getExamId() == null) {
-            return array;
-        }
-        Exam exam = examService.findById(query.getExamId());
-        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
-            DecimalFormat format = new DecimalFormat("####.##");
-            examStudentService.findByQuery(query);
-            for (ExamStudent student : query.getResult()) {
-                JSONObject obj = new JSONObject();
-                obj.accumulate("id", student.getId());
-                obj.accumulate("schoolId", student.getSchoolId());
-                obj.accumulate("examNumber", student.getExamNumber());
-                obj.accumulate("campusName", student.getCampusName());
-                obj.accumulate("subjectCode", student.getSubjectCode());
-                obj.accumulate("subjectName", student.getSubjectName());
-                obj.accumulate("name", student.getName());
-                obj.accumulate("studentCode", student.getStudentCode());
-                obj.accumulate("packageCode", student.getPackageCode());
-                obj.accumulate("batchCode", student.getBatchCode() == null ? "" : student.getBatchCode());
-                obj.accumulate("sheetCount", student.getSheetCount() != null ? student.getSheetCount() : 0);
-                obj.accumulate("sliceCount", student.getSliceCount() != null ? student.getSliceCount() : 0);
-                obj.accumulate("answers", StringUtils.trimToEmpty(student.getAnswers()));
-                obj.accumulate("upload", student.isUpload());
-                obj.accumulate("absent", student.isAbsent());
-                obj.accumulate("manualAbsent", student.isManualAbsent());
-                obj.accumulate("breach", student.isBreach());
-                obj.accumulate("objectiveScore",
-                        student.getObjectiveScore() == null ? "" : format.format(student.getObjectiveScore()));
-                obj.accumulate("subjectiveScore",
-                        student.getSubjectiveScore() == null ? "" : format.format(student.getSubjectiveScore()));
-                obj.accumulate("examSite", StringUtils.trimToEmpty(student.getExamSite()));
-                obj.accumulate("examRoom", StringUtils.trimToEmpty(student.getExamRoom()));
-                obj.accumulate("remark", StringUtils.trimToEmpty(student.getRemark()));
-                Campus campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
-                obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
-
-                try {
-                    if (withScoreDetail != null && withScoreDetail.booleanValue()) {
-                        // 构造客观题得分明细
-                        JSONArray objective = new JSONArray();
-                        List<ScoreItem> scoreList = student.getScoreList(true);
-                        List<ExamQuestion> questionList = questionService
-                                .findByExamAndSubjectAndObjective(student.getExamId(), student.getSubjectCode(), true);
-                        int i = 0;
-                        for (ScoreItem item : scoreList) {
-                            i++;
-                            if (questionList.size() < i) {
-                                break;
-                            }
-                            ExamQuestion question = questionList.get(i - 1);
-                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
-                                continue;
-                            }
-                            JSONObject detail = new JSONObject();
-                            detail.accumulate("mainNumber", question.getMainNumber());
-                            detail.accumulate("subNumber", question.getSubNumber());
-                            detail.accumulate("score", item.getScore());
-                            detail.accumulate("answer", item.getAnswer());
-                            objective.add(detail);
-                        }
-                        obj.accumulate("objectiveScoreDetail", objective);
-
-                        // 构造主观题得分明细
-                        JSONArray subjective = new JSONArray();
-                        scoreList = student.getScoreList(false);
-                        questionList = questionService.findByExamAndSubjectAndObjective(student.getExamId(),
-                                student.getSubjectCode(), false);
-                        i = 0;
-                        for (ScoreItem item : scoreList) {
-                            i++;
-                            if (questionList.size() < i) {
-                                break;
-                            }
-                            ExamQuestion question = questionList.get(i - 1);
-                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
-                                continue;
-                            }
-                            JSONObject detail = new JSONObject();
-                            detail.accumulate("mainNumber", question.getMainNumber());
-                            detail.accumulate("subNumber", question.getSubNumber());
-                            detail.accumulate("score", item.getScore());
-                            subjective.add(detail);
-                        }
-                        obj.accumulate("subjectiveScoreDetail", subjective);
-                    }
-                    array.add(obj);
-                } catch (Exception e) {
-                    logger.error("student api error", e);
-                }
-            }
-        }
-        return array;
-    }
-
-    /**
-     * 
-     * @param s
-     *            需要转换的字符串
-     * @param convert
-     *            是否正向转换
-     * @return
-     */
-    @SuppressWarnings("unused")
-    private String convert(String s, String[] diploma, String[] bachelorDegree, boolean convert) {
-        if (diploma == null || bachelorDegree == null) {
-            return s;
-        }
-
-        char[] ss = s.toCharArray();
-        String[] str = new String[ss.length];
-        for (int i = 0; i < str.length; i++) {
-            str[i] = String.valueOf(ss[i]);
-        }
-
-        if (convert) {
-            if (str[Integer.parseInt(diploma[2]) - 1].equals(diploma[1])) {
-                str[Integer.parseInt(diploma[2]) - 1] = diploma[0];
-            }
-            if (str[Integer.parseInt(diploma[3]) - 1].equals(diploma[1])) {
-                str[Integer.parseInt(diploma[3]) - 1] = diploma[0];
-            }
-            if (str[Integer.parseInt(bachelorDegree[2]) - 1].equals(bachelorDegree[1])) {
-                str[Integer.parseInt(bachelorDegree[2]) - 1] = bachelorDegree[0];
-            }
-            if (str[Integer.parseInt(bachelorDegree[3]) - 1].equals(bachelorDegree[1])) {
-                str[Integer.parseInt(bachelorDegree[3]) - 1] = bachelorDegree[0];
-            }
-        } else {
-            if (str[Integer.parseInt(diploma[2]) - 1].equals(diploma[0])) {
-                str[Integer.parseInt(diploma[2]) - 1] = diploma[1];
-            }
-            if (str[Integer.parseInt(diploma[3]) - 1].equals(diploma[0])) {
-                str[Integer.parseInt(diploma[3]) - 1] = diploma[1];
-            }
-            if (str[Integer.parseInt(bachelorDegree[2]) - 1].equals(bachelorDegree[0])) {
-                str[Integer.parseInt(bachelorDegree[2]) - 1] = bachelorDegree[1];
-            }
-            if (str[Integer.parseInt(bachelorDegree[3]) - 1].equals(bachelorDegree[0])) {
-                str[Integer.parseInt(bachelorDegree[3]) - 1] = bachelorDegree[1];
-            }
-        }
-        StringBuffer sb = new StringBuffer();
-        for (String i : str) {
-            sb.append(i);
-        }
-        return sb.toString();
-    }
-
-    @RequestMapping(value = "/score/school/{schoolId}", method = RequestMethod.POST)
-    @ResponseBody
-    public String getScore(@PathVariable Integer schoolId, @RequestParam String studentCode,
-            @RequestParam String subjectCode, @RequestParam(required = false, defaultValue = "true") boolean encrypt,
-            @RequestParam(required = false) String examSeqCode) {
-        JSONObject obj = new JSONObject();
-        ExamStudent student = null;
-        try {
-            if (Strings.isNullOrEmpty(examSeqCode)) {
-                student = examStudentService.findBySchoolIdAndSubjectCodeAndStudentCode(schoolId, subjectCode,
-                        studentCode);
-            } else {
-                student = examStudentService.findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(schoolId, subjectCode,
-                        studentCode, examSeqCode);
-            }
-            if (student != null) {
-                DecimalFormat df = new DecimalFormat("###.#");
-                obj.accumulate("exist", true);
-                obj.accumulate("objectiveScore", df.format(student.getObjectiveScore()));
-                obj.accumulate("subjectiveScore", df.format(student.getSubjectiveScore()));
-                obj.accumulate("totalScore", df.format(student.getTotalScore()));
-            } else {
-                obj.accumulate("exist", false);
-                obj.accumulate("objectiveScore", 0);
-                obj.accumulate("subjectiveScore", 0);
-                obj.accumulate("totalScore", 0);
-            }
-            if (!Strings.isNullOrEmpty(examSeqCode)) {
-                obj.accumulate("examSeqCode", examSeqCode);
-            }
-            obj.accumulate("studentCode", studentCode);
-            obj.accumulate("subjectCode", subjectCode);
-        } catch (Exception e) {
-            e.printStackTrace();
-            obj.accumulate("exception", "500");
-        }
-        String result = obj.toString();
-        return encrypt ? AESUtil.encrypt(result) : result;
-    }
-    
-    
-}
+package cn.com.qmth.stmms.api.controller;
+
+import java.text.DecimalFormat;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.google.common.base.Strings;
+
+import cn.com.qmth.stmms.api.utils.AESUtil;
+import cn.com.qmth.stmms.api.utils.MenualAbsentDTO;
+import cn.com.qmth.stmms.biz.api.auth.annotation.AuthValidate;
+import cn.com.qmth.stmms.biz.api.auth.exception.ApiException;
+import cn.com.qmth.stmms.biz.campus.model.Campus;
+import cn.com.qmth.stmms.biz.campus.service.CampusService;
+import cn.com.qmth.stmms.biz.exam.model.Exam;
+import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
+import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
+import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
+import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
+import cn.com.qmth.stmms.biz.exam.service.ExamService;
+import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
+import cn.com.qmth.stmms.biz.user.model.User;
+import cn.com.qmth.stmms.biz.utils.ScoreItem;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+@Controller("examStudentApiController")
+@RequestMapping("/api")
+public class ExamStudentController extends BaseApiController {
+
+    protected static Logger logger = LoggerFactory.getLogger(ExamStudentController.class);
+
+    @Autowired
+    private ExamStudentService examStudentService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private CampusService campusService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @AuthValidate("adminUser")
+    @RequestMapping(value = "/student/manualAbsent/{examId}", method = RequestMethod.POST)
+    @ResponseBody
+    public Object updateManualAbsent(HttpServletRequest request, @PathVariable Integer examId,
+            @RequestBody MenualAbsentDTO[] datas) {
+        User user = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(examId);
+        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
+            for (MenualAbsentDTO dto : datas) {
+                examStudentService.updateManualAbsent(examId, dto.getExamNumber(), dto.isAbsent());
+            }
+            return true;
+        } else {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+    }
+
+    @AuthValidate("adminUser")
+    @RequestMapping(value = "/student/manualAbsent/clear", method = RequestMethod.POST)
+    @ResponseBody
+    public Object clearManualAbsent(HttpServletRequest request, @RequestParam Integer examId) {
+        User user = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(examId);
+        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
+            examStudentService.clearManualAbsent(examId);
+            return true;
+        } else {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+    }
+
+    @AuthValidate({ "adminUser", "scanner" })
+    @RequestMapping(value = "/exam/students/{examId}", method = RequestMethod.GET)
+    @ResponseBody
+    public JSONArray getExamStudents(HttpServletRequest request, @PathVariable Integer examId) {
+        JSONArray array = new JSONArray();
+        List<ExamStudent> esList = new LinkedList<ExamStudent>();
+        Exam exam = examService.findById(examId);
+        if (exam != null) {
+            esList = examStudentService.findByExamId(examId);
+        }
+        for (ExamStudent student : esList) {
+            JSONObject obj = new JSONObject();
+            obj.accumulate("examNumber", student.getExamNumber());
+            obj.accumulate("campusName", student.getCampusName());
+            obj.accumulate("subjectCode", student.getSubjectCode());
+            obj.accumulate("subjectName", student.getSubjectName());
+            obj.accumulate("name", student.getName());
+            obj.accumulate("studentId", String.valueOf(student.getId()));
+            obj.accumulate("barcode", student.getExamNumber());
+
+            Campus campus = campusService.findBySchoolAndName(exam.getSchoolId(), student.getCampusName());
+            obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
+            array.add(obj);
+        }
+        return array;
+    }
+
+    @AuthValidate({ "adminUser", "scanner" })
+    @RequestMapping(value = "/students/{examId}", method = RequestMethod.GET)
+    @ResponseBody
+    public JSONArray getStudent(HttpServletRequest request, @PathVariable Integer examId,
+            @RequestParam(required = false) Boolean upload, @RequestParam(required = false) Boolean absent,
+            @RequestParam(required = false) Integer pageNumber, @RequestParam(required = false) Integer pageSize) {
+        JSONArray array = new JSONArray();
+        Exam exam = examService.findById(examId);
+        if (exam == null) {
+            return array;
+        }
+
+        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
+        query.setExamId(examId);
+        query.setUpload(upload);
+        query.setAbsent(absent);
+        if (pageNumber != null && pageSize != null) {
+            query.setPageNumber(pageNumber);
+            query.setPageSize(pageSize);
+        } else {
+            query.setPageNumber(1);
+            query.setPageSize(Integer.MAX_VALUE);
+        }
+        examStudentService.findByQuery(query);
+        for (ExamStudent student : query.getResult()) {
+            JSONObject obj = new JSONObject();
+            obj.accumulate("id", student.getId());
+            obj.accumulate("examNumber", student.getExamNumber());
+            obj.accumulate("campusName", student.getCampusName());
+            obj.accumulate("subjectCode", student.getSubjectCode());
+            obj.accumulate("subjectName", student.getSubjectName());
+            obj.accumulate("name", student.getName());
+            obj.accumulate("studentCode", student.getStudentCode());
+
+            Campus campus = campusService.findBySchoolAndName(exam.getSchoolId(), student.getCampusName());
+            obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
+            array.add(obj);
+        }
+        return array;
+    }
+
+    @AuthValidate({ "adminUser", "scanner" })
+    @RequestMapping(value = "/student/check", method = RequestMethod.POST)
+    @ResponseBody
+    public JSONObject checkStudent(HttpServletRequest request, @RequestBody ExamStudent examStudent) {
+        JSONObject obj = new JSONObject();
+        Exam exam = examService.findById(examStudent.getExamId());
+        ExamStudent student = examStudentService.findByExamIdAndExamNumber(examStudent.getExamId(),
+                examStudent.getExamNumber());
+        if (student != null) {
+            obj.accumulate("examId", examStudent.getExamId());
+            obj.accumulate("campusName", student.getCampusName());
+            obj.accumulate("examNumber", student.getExamNumber());
+            obj.accumulate("name", student.getName());
+            obj.accumulate("studentId", String.valueOf(student.getId()));
+            obj.accumulate("subjectCode", student.getSubjectCode());
+            obj.accumulate("subjectName", student.getSubjectName());
+
+            Campus campus = campusService.findBySchoolAndName(exam.getSchoolId(), student.getCampusName());
+            obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
+        } else {
+            obj.accumulate("examId", examStudent.getExamId());
+            obj.accumulate("campusCode", "");
+            obj.accumulate("campusName", "");
+            obj.accumulate("examNumber", examStudent.getExamNumber());
+            obj.accumulate("name", "");
+            obj.accumulate("studentId", "");
+            obj.accumulate("subjectCode", "");
+            obj.accumulate("subjectName", "");
+        }
+        return obj;
+    }
+
+    @AuthValidate("adminUser")
+    @RequestMapping("/students/count/{examId}")
+    @ResponseBody
+    public long getStudentCount(HttpServletRequest request, @PathVariable Integer examId,
+            @RequestParam(required = false) Boolean upload, @RequestParam(required = false) Boolean absent) {
+        User user = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(examId);
+        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
+            ExamStudentSearchQuery query = new ExamStudentSearchQuery();
+            query.setExamId(examId);
+            query.setUpload(upload);
+            query.setAbsent(absent);
+            return examStudentService.countByQuery(query);
+        }
+        return 0;
+    }
+
+    @AuthValidate("adminUser")
+    @RequestMapping("/exam/students")
+    @ResponseBody
+    public JSONArray getStudent(HttpServletRequest request, ExamStudentSearchQuery query,
+            @RequestParam(required = false) Boolean withScoreDetail) {
+        User user = RequestUtils.getApiUser(request);
+        JSONArray array = new JSONArray();
+        if (query.getExamId() == null) {
+            return array;
+        }
+        Exam exam = examService.findById(query.getExamId());
+        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
+            DecimalFormat format = new DecimalFormat("####.##");
+            examStudentService.findByQuery(query);
+            for (ExamStudent student : query.getResult()) {
+                JSONObject obj = new JSONObject();
+                obj.accumulate("id", student.getId());
+                obj.accumulate("schoolId", student.getSchoolId());
+                obj.accumulate("examNumber", student.getExamNumber());
+                obj.accumulate("campusName", student.getCampusName());
+                obj.accumulate("subjectCode", student.getSubjectCode());
+                obj.accumulate("subjectName", student.getSubjectName());
+                obj.accumulate("name", student.getName());
+                obj.accumulate("studentCode", student.getStudentCode());
+                obj.accumulate("packageCode", student.getPackageCode());
+                obj.accumulate("batchCode", student.getBatchCode() == null ? "" : student.getBatchCode());
+                obj.accumulate("sheetCount", student.getSheetCount() != null ? student.getSheetCount() : 0);
+                obj.accumulate("sliceCount", student.getSliceCount() != null ? student.getSliceCount() : 0);
+                obj.accumulate("answers", StringUtils.trimToEmpty(student.getAnswers()));
+                obj.accumulate("upload", student.isUpload());
+                obj.accumulate("absent", student.isAbsent());
+                obj.accumulate("manualAbsent", student.isManualAbsent());
+                obj.accumulate("breach", student.isBreach());
+                obj.accumulate("objectiveScore",
+                        student.getObjectiveScore() == null ? "" : format.format(student.getObjectiveScore()));
+                obj.accumulate("subjectiveScore",
+                        student.getSubjectiveScore() == null ? "" : format.format(student.getSubjectiveScore()));
+                obj.accumulate("examSite", StringUtils.trimToEmpty(student.getExamSite()));
+                obj.accumulate("examRoom", StringUtils.trimToEmpty(student.getExamRoom()));
+                obj.accumulate("remark", StringUtils.trimToEmpty(student.getRemark()));
+                Campus campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
+                obj.accumulate("campusCode", campus != null ? campus.getId().toString() : "");
+
+                try {
+                    if (withScoreDetail != null && withScoreDetail.booleanValue()) {
+                        // 构造客观题得分明细
+                        JSONArray objective = new JSONArray();
+                        List<ScoreItem> scoreList = student.getScoreList(true);
+                        List<ExamQuestion> questionList = questionService
+                                .findByExamAndSubjectAndObjective(student.getExamId(), student.getSubjectCode(), true);
+                        int i = 0;
+                        for (ScoreItem item : scoreList) {
+                            i++;
+                            if (questionList.size() < i) {
+                                break;
+                            }
+                            ExamQuestion question = questionList.get(i - 1);
+                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
+                                continue;
+                            }
+                            JSONObject detail = new JSONObject();
+                            detail.accumulate("mainNumber", question.getMainNumber());
+                            detail.accumulate("subNumber", question.getSubNumber());
+                            detail.accumulate("score", item.getScore());
+                            detail.accumulate("answer", item.getAnswer());
+                            objective.add(detail);
+                        }
+                        obj.accumulate("objectiveScoreDetail", objective);
+
+                        // 构造主观题得分明细
+                        JSONArray subjective = new JSONArray();
+                        scoreList = student.getScoreList(false);
+                        questionList = questionService.findByExamAndSubjectAndObjective(student.getExamId(),
+                                student.getSubjectCode(), false);
+                        i = 0;
+                        for (ScoreItem item : scoreList) {
+                            i++;
+                            if (questionList.size() < i) {
+                                break;
+                            }
+                            ExamQuestion question = questionList.get(i - 1);
+                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
+                                continue;
+                            }
+                            JSONObject detail = new JSONObject();
+                            detail.accumulate("mainNumber", question.getMainNumber());
+                            detail.accumulate("subNumber", question.getSubNumber());
+                            detail.accumulate("score", item.getScore());
+                            subjective.add(detail);
+                        }
+                        obj.accumulate("subjectiveScoreDetail", subjective);
+                    }
+                    array.add(obj);
+                } catch (Exception e) {
+                    logger.error("student api error", e);
+                }
+            }
+        }
+        return array;
+    }
+
+    /**
+     * 
+     * @param s
+     *            需要转换的字符串
+     * @param convert
+     *            是否正向转换
+     * @return
+     */
+    @SuppressWarnings("unused")
+    private String convert(String s, String[] diploma, String[] bachelorDegree, boolean convert) {
+        if (diploma == null || bachelorDegree == null) {
+            return s;
+        }
+
+        char[] ss = s.toCharArray();
+        String[] str = new String[ss.length];
+        for (int i = 0; i < str.length; i++) {
+            str[i] = String.valueOf(ss[i]);
+        }
+
+        if (convert) {
+            if (str[Integer.parseInt(diploma[2]) - 1].equals(diploma[1])) {
+                str[Integer.parseInt(diploma[2]) - 1] = diploma[0];
+            }
+            if (str[Integer.parseInt(diploma[3]) - 1].equals(diploma[1])) {
+                str[Integer.parseInt(diploma[3]) - 1] = diploma[0];
+            }
+            if (str[Integer.parseInt(bachelorDegree[2]) - 1].equals(bachelorDegree[1])) {
+                str[Integer.parseInt(bachelorDegree[2]) - 1] = bachelorDegree[0];
+            }
+            if (str[Integer.parseInt(bachelorDegree[3]) - 1].equals(bachelorDegree[1])) {
+                str[Integer.parseInt(bachelorDegree[3]) - 1] = bachelorDegree[0];
+            }
+        } else {
+            if (str[Integer.parseInt(diploma[2]) - 1].equals(diploma[0])) {
+                str[Integer.parseInt(diploma[2]) - 1] = diploma[1];
+            }
+            if (str[Integer.parseInt(diploma[3]) - 1].equals(diploma[0])) {
+                str[Integer.parseInt(diploma[3]) - 1] = diploma[1];
+            }
+            if (str[Integer.parseInt(bachelorDegree[2]) - 1].equals(bachelorDegree[0])) {
+                str[Integer.parseInt(bachelorDegree[2]) - 1] = bachelorDegree[1];
+            }
+            if (str[Integer.parseInt(bachelorDegree[3]) - 1].equals(bachelorDegree[0])) {
+                str[Integer.parseInt(bachelorDegree[3]) - 1] = bachelorDegree[1];
+            }
+        }
+        StringBuffer sb = new StringBuffer();
+        for (String i : str) {
+            sb.append(i);
+        }
+        return sb.toString();
+    }
+
+    @RequestMapping(value = "/score/school/{schoolId}", method = RequestMethod.POST)
+    @ResponseBody
+    public String getScore(@PathVariable Integer schoolId, @RequestParam String studentCode,
+            @RequestParam String subjectCode, @RequestParam(required = false, defaultValue = "true") boolean encrypt,
+            @RequestParam(required = false) String examSeqCode) {
+        JSONObject obj = new JSONObject();
+        ExamStudent student = null;
+        try {
+            if (Strings.isNullOrEmpty(examSeqCode)) {
+                student = examStudentService.findBySchoolIdAndSubjectCodeAndStudentCode(schoolId, subjectCode,
+                        studentCode);
+            } else {
+                student = examStudentService.findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(schoolId, subjectCode,
+                        studentCode, examSeqCode);
+            }
+            if (student != null) {
+                DecimalFormat df = new DecimalFormat("###.#");
+                obj.accumulate("exist", true);
+                obj.accumulate("objectiveScore", df.format(student.getObjectiveScore()));
+                obj.accumulate("subjectiveScore", df.format(student.getSubjectiveScore()));
+                obj.accumulate("totalScore", df.format(student.getTotalScore()));
+            } else {
+                obj.accumulate("exist", false);
+                obj.accumulate("objectiveScore", 0);
+                obj.accumulate("subjectiveScore", 0);
+                obj.accumulate("totalScore", 0);
+            }
+            if (!Strings.isNullOrEmpty(examSeqCode)) {
+                obj.accumulate("examSeqCode", examSeqCode);
+            }
+            obj.accumulate("studentCode", studentCode);
+            obj.accumulate("subjectCode", subjectCode);
+        } catch (Exception e) {
+            e.printStackTrace();
+            obj.accumulate("exception", "500");
+        }
+        String result = obj.toString();
+        return encrypt ? AESUtil.encrypt(result) : result;
+    }
+
+}

+ 370 - 360
stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java

@@ -1,360 +1,370 @@
-package cn.com.qmth.stmms.mark;
-
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.servlet.ModelAndView;
-
-import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.exam.model.Tag;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.exam.service.MarkerService;
-import cn.com.qmth.stmms.biz.exam.service.TagService;
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.biz.mark.model.Task;
-import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
-import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
-import cn.com.qmth.stmms.biz.mark.service.TaskService;
-import cn.com.qmth.stmms.common.controller.BaseController;
-import cn.com.qmth.stmms.common.enums.ExamSubjectStatus;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-import cn.com.qmth.stmms.common.session.model.StmmsSession;
-import cn.com.qmth.stmms.common.utils.RequestUtils;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-
-@Controller
-@RequestMapping("/mark")
-public class MarkController extends BaseController {
-
-    private static Logger log = LoggerFactory.getLogger(MarkController.class);
-
-    @Autowired
-    private ExamSubjectService subjectService;
-
-    @Autowired
-    private MarkerService markerService;
-
-    @Autowired
-    private MarkLibraryService libraryService;
-
-    @Autowired
-    private TaskService taskService;
-
-    @Autowired
-    private TagService tagService;
-
-    @Value("${slice.image.server}")
-    private String sliceServer;
-
-    @Value("${sheet.image.server}")
-    private String sheetServer;
-
-    @Value("${card.server}")
-    private String cardServer;
-
-    @RequestMapping(value = "/reset", method = RequestMethod.GET)
-    public ModelAndView reset(HttpServletRequest request) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        ModelAndView modelAndView = new ModelAndView("modules/mark/reset");
-        modelAndView.addObject("marker", marker);
-        return modelAndView;
-    }
-
-    @RequestMapping(value = "/reset", method = RequestMethod.POST)
-    public ModelAndView reset(HttpServletRequest request, Marker marker) {
-        Marker current = RequestUtils.getWebUser(request).getMarker();
-        current.setName(marker.getName());
-        current.setPassword(marker.getPassword());
-        current.setLastLoginIp(request.getRemoteAddr());
-        current.setLastLoginTime(new Date());
-        markerService.save(current);
-        return new ModelAndView("redirect:/mark/index");
-    }
-
-    @RequestMapping(value = "/subject-select", method = RequestMethod.GET)
-    public ModelAndView select(HttpServletRequest request) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        ModelAndView modelAndView = new ModelAndView("modules/mark/subjectSelect");
-        modelAndView.addObject("marker", marker);
-        modelAndView.addObject("subjectList", subjectService.list(marker.getExamId(), ExamSubjectStatus.MARKING, 0));
-
-        if (StringUtils.isNotBlank(marker.getSubjectCode())) {
-            clearCurrentTask(marker);
-        }
-        return modelAndView;
-    }
-
-    @RequestMapping(value = "/subject-select", method = RequestMethod.POST)
-    public ModelAndView select(HttpServletRequest request, @RequestParam String subjectCode) {
-        Marker current = RequestUtils.getWebUser(request).getMarker();
-        current.setSubjectCode(subjectCode);
-        markerService.save(current);
-        return new ModelAndView("redirect:/mark/index");
-    }
-
-    @RequestMapping("/index")
-    public ModelAndView index(HttpServletRequest request, @RequestParam(value = "mode", required = false) String mode) {
-        StmmsSession session = RequestUtils.getSession(request);
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        ModelAndView modelAndView = getMarkModeView(marker, mode);
-        preProcess(marker, session, modelAndView);
-        return modelAndView;
-    }
-
-    private ModelAndView getMarkModeView(Marker marker, String mode) {
-        if (StringUtils.isNotBlank(mode)) {
-            marker.setMode(mode);
-        }
-        String view = null;
-        if ("track".equals(marker.getMode())) {
-            view = "modules/mark/markTrack";
-        } else {
-            marker.setMode("common");
-            view = "modules/mark/markNew";
-        }
-        markerService.save(marker);
-        return new ModelAndView(view);
-    }
-
-    @RequestMapping("/logout")
-    public ModelAndView logout(HttpServletRequest request) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        clearCurrentTask(marker);
-        return new ModelAndView("redirect:/mark-logout");
-    }
-
-    /**
-     * 进入评卷界面后的通用预处理
-     * 
-     * @param marker
-     * @param session
-     * @param modelAndView
-     * @param modelAndView
-     */
-    private void preProcess(Marker marker, StmmsSession session, ModelAndView modelAndView) {
-        modelAndView.addObject("sliceServer", sliceServer);
-        modelAndView.addObject("sheetServer", sheetServer);
-        modelAndView.addObject("cardServer", cardServer);
-        modelAndView.addObject("marker", marker);
-        modelAndView.addObject("subject", subjectService.find(marker.getExamId(), marker.getSubjectCode()));
-        clearCurrentTask(marker);
-    }
-
-    @RequestMapping("/clear")
-    @ResponseBody
-    public void clear(HttpServletRequest request) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        if (marker != null) {
-            // 清除该评卷员当前正在评卷的指定任务
-            clearCurrentTask(marker);
-        }
-    }
-
-    @RequestMapping("/status")
-    @ResponseBody
-    public JSONObject status(HttpServletRequest request) {
-        JSONObject status = new JSONObject();
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
-        if (subject == null || subject.getStatus() != ExamSubjectStatus.MARKING) {
-            status.accumulate("valid", false);
-            return status;
-        }
-
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setExamId(marker.getExamId());
-        query.setSubjectCode(marker.getSubjectCode());
-        query.setGroupNumber(marker.getGroupNumber());
-        long totalCount = libraryService.countByQuery(query);
-
-        query.setStatus(LibraryStatus.MARKED);
-        long markedCount = libraryService.countByQuery(query);
-
-        query.setMarkerId(marker.getId());
-        long personCount = libraryService.countByQuery(query);
-
-        status.accumulate("personCount", personCount);
-        status.accumulate("totalCount", totalCount);
-        status.accumulate("markedCount", markedCount);
-        status.accumulate("exceptionCount", 0);
-        status.accumulate("valid", totalCount > 0);
-        status.accumulate("topCount", marker.getTopCount() == null ?0:marker.getTopCount());
-        return status;
-    }
-
-    @RequestMapping("/gettask")
-    @ResponseBody
-    public Task getTask(HttpServletRequest request) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        Task task = getTask(marker);
-        if (task == null) {
-            task = new Task();
-            task.setExist(false);
-            task.setMessage("当前无评卷任务");
-        }
-        return task;
-    }
-
-    /**
-     * 设置任务通用属性
-     * 
-     * @param task
-     * @param marker
-     * @param stage
-     * @param count
-     * @param bmList
-     */
-    private void setTaskParameter(Task task, Marker marker) {
-        task.setMarkId(marker.getId());
-        task.setSpent(new Date().getTime());
-    }
-
-    private Task getTask(Marker marker) {
-        int retry = 1;
-        Task task = null;
-        Set<LibraryStatus> set = new HashSet<LibraryStatus>();
-        set.add(LibraryStatus.WAITING);
-        set.add(LibraryStatus.BACKED);
-        while (retry <= 5 && task == null) {
-            List<MarkLibrary> list = libraryService.findByStatusSet(marker.getExamId(), marker.getSubjectCode(),
-                    marker.getGroupNumber(), set, retry, 20);
-            for (MarkLibrary library : list) {
-                if (setCurrentTask(marker, library.getId())) {
-                    task = taskService.build(library);
-                    setTaskParameter(task, marker);
-                    break;
-                }
-            }
-
-            if (task == null) {
-                retry++;
-            }
-        }
-        return task;
-    }
-
-    @RequestMapping(value = "/savetask", method = RequestMethod.POST)
-    @ResponseBody
-    public JSONObject saveTask(HttpServletRequest request, @RequestBody Task task) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        JSONObject result = new JSONObject();
-        try {
-            task.setSpent((new Date().getTime() - task.getSpent()) / 1000);
-            if (taskService.submit(task)) {
-                releaseCurrentTask(marker, task);
-                result.accumulate("success", true);
-                result.accumulate("status", status(request));
-            } else {
-                result.accumulate("success", false);
-            }
-        } catch (Exception e) {
-            log.error("MarkController-保存任务出错", e);
-            result.accumulate("success", false);
-        }
-        return result;
-    }
-
-    @RequestMapping("/gethistory")
-    @ResponseBody
-    public Object history(HttpServletRequest request, @RequestParam int pageNumber, @RequestParam int pageSize)
-            throws Exception {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        // 查找给分任务历史
-        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-        query.setExamId(marker.getExamId());
-        query.setSubjectCode(marker.getSubjectCode());
-        query.setMarkerId(marker.getId());
-        query.setStatus(LibraryStatus.MARKED);
-        query.setGroupNumber(marker.getGroupNumber());
-        query.setPageNumber(pageNumber);
-        query.setPageSize(pageSize);
-        query.orderByMarkerTimeDesc();
-        List<Task> list = taskService.findByQuery(query);
-        for (Task task : list) {
-            task.setPrevious(true);
-            setTaskParameter(task, marker);
-        }
-        return list;
-    }
-
-    @RequestMapping("/change-name")
-    @ResponseBody
-    public JSONObject changeName(HttpServletRequest request, @RequestParam String name,@RequestParam(required = false) String password) {
-        Marker marker = RequestUtils.getWebUser(request).getMarker();
-        JSONObject result = new JSONObject();
-        marker.setName(name);
-        if(StringUtils.isNotEmpty(password)){
-            marker.setPassword(password);
-        }
-        marker = markerService.save(marker);
-        result.accumulate("success", marker != null);
-        if (marker != null) {
-            result.accumulate("name", marker.getName());
-        }
-        return result;
-    }
-
-    @RequestMapping("/tags")
-    @ResponseBody
-    public JSONArray getTags(HttpServletRequest request) {
-        JSONArray array = new JSONArray();
-        List<Tag> list = tagService.findAll();
-        for (Tag tag : list) {
-            JSONObject obj = new JSONObject();
-            obj.accumulate("value", tag.getId());
-            obj.accumulate("name", tag.getName());
-            array.add(obj);
-        }
-        return array;
-    }
-
-    /**
-     * 清除当前评卷员正在评卷的所有任务记录
-     * 
-     * @param marker
-     * @param task
-     * @param session
-     */
-    private void clearCurrentTask(Marker marker) {
-        taskService.clearCurrent(marker);
-    }
-
-    /**
-     * 清除当前评卷员已给分的评卷任务
-     * 
-     * @param marker
-     * @param task
-     * @param session
-     */
-    private void releaseCurrentTask(Marker marker, Task task) {
-        taskService.removeCurrent(marker, task.getLibraryId());
-    }
-
-    /**
-     * 尝试设置当前任务
-     * 
-     * @param marker
-     * @param libraryId
-     * @return
-     */
-    private boolean setCurrentTask(Marker marker, int libraryId) {
-        return taskService.setCurrent(marker, libraryId);
-    }
-}
+package cn.com.qmth.stmms.mark;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.exam.model.Tag;
+import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.exam.service.TagService;
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.biz.mark.model.Task;
+import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
+import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
+import cn.com.qmth.stmms.biz.mark.service.TaskService;
+import cn.com.qmth.stmms.common.controller.BaseController;
+import cn.com.qmth.stmms.common.enums.ExamSubjectStatus;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import cn.com.qmth.stmms.common.session.model.StmmsSession;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+@Controller
+@RequestMapping("/mark")
+public class MarkController extends BaseController {
+
+    private static Logger log = LoggerFactory.getLogger(MarkController.class);
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Autowired
+    private TaskService taskService;
+
+    @Autowired
+    private TagService tagService;
+
+    @Value("${slice.image.server}")
+    private String sliceServer;
+
+    @Value("${sheet.image.server}")
+    private String sheetServer;
+
+    @Value("${card.server}")
+    private String cardServer;
+
+    @RequestMapping(value = "/reset", method = RequestMethod.GET)
+    public ModelAndView reset(HttpServletRequest request) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        ModelAndView modelAndView = new ModelAndView("modules/mark/reset");
+        modelAndView.addObject("marker", marker);
+        return modelAndView;
+    }
+
+    @RequestMapping(value = "/reset", method = RequestMethod.POST)
+    public ModelAndView reset(HttpServletRequest request, Marker marker) {
+        Marker current = RequestUtils.getWebUser(request).getMarker();
+        current.setName(marker.getName());
+        current.setPassword(marker.getPassword());
+        current.setLastLoginIp(request.getRemoteAddr());
+        current.setLastLoginTime(new Date());
+        markerService.save(current);
+        return new ModelAndView("redirect:/mark/index");
+    }
+
+    @RequestMapping(value = "/subject-select", method = RequestMethod.GET)
+    public ModelAndView select(HttpServletRequest request) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        ModelAndView modelAndView = new ModelAndView("modules/mark/subjectSelect");
+        modelAndView.addObject("marker", marker);
+        modelAndView.addObject("subjectList", subjectService.list(marker.getExamId(), ExamSubjectStatus.MARKING, 0));
+
+        if (StringUtils.isNotBlank(marker.getSubjectCode())) {
+            clearCurrentTask(marker);
+        }
+        return modelAndView;
+    }
+
+    @RequestMapping(value = "/subject-select", method = RequestMethod.POST)
+    public ModelAndView select(HttpServletRequest request, @RequestParam String subjectCode) {
+        Marker current = RequestUtils.getWebUser(request).getMarker();
+        current.setSubjectCode(subjectCode);
+        markerService.save(current);
+        return new ModelAndView("redirect:/mark/index");
+    }
+
+    @RequestMapping("/index")
+    public ModelAndView index(HttpServletRequest request, @RequestParam(value = "mode", required = false) String mode) {
+        StmmsSession session = RequestUtils.getSession(request);
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        ModelAndView modelAndView = getMarkModeView(marker, mode);
+        preProcess(marker, session, modelAndView);
+        return modelAndView;
+    }
+
+    private ModelAndView getMarkModeView(Marker marker, String mode) {
+        if (StringUtils.isNotBlank(mode)) {
+            marker.setMode(mode);
+        }
+        String view = null;
+        if ("track".equals(marker.getMode())) {
+            view = "modules/mark/markTrack";
+        } else {
+            marker.setMode("common");
+            view = "modules/mark/markNew";
+        }
+        markerService.save(marker);
+        return new ModelAndView(view);
+    }
+
+    @RequestMapping("/logout")
+    public ModelAndView logout(HttpServletRequest request) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        clearCurrentTask(marker);
+        return new ModelAndView("redirect:/mark-logout");
+    }
+
+    /**
+     * 进入评卷界面后的通用预处理
+     * 
+     * @param marker
+     * @param session
+     * @param modelAndView
+     * @param modelAndView
+     */
+    private void preProcess(Marker marker, StmmsSession session, ModelAndView modelAndView) {
+        modelAndView.addObject("sliceServer", sliceServer);
+        modelAndView.addObject("sheetServer", sheetServer);
+        modelAndView.addObject("cardServer", cardServer);
+        modelAndView.addObject("marker", marker);
+        modelAndView.addObject("subject", subjectService.find(marker.getExamId(), marker.getSubjectCode()));
+        clearCurrentTask(marker);
+    }
+
+    @RequestMapping("/clear")
+    @ResponseBody
+    public void clear(HttpServletRequest request) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        if (marker != null) {
+            // 清除该评卷员当前正在评卷的指定任务
+            clearCurrentTask(marker);
+        }
+    }
+
+    @RequestMapping("/status")
+    @ResponseBody
+    public JSONObject status(HttpServletRequest request) {
+        JSONObject status = new JSONObject();
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
+        if (subject == null || subject.getStatus() != ExamSubjectStatus.MARKING) {
+            status.accumulate("valid", false);
+            return status;
+        }
+
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setExamId(marker.getExamId());
+        query.setSubjectCode(marker.getSubjectCode());
+        query.setGroupNumber(marker.getGroupNumber());
+        long totalCount = libraryService.countByQuery(query);
+
+        query.setStatus(LibraryStatus.MARKED);
+        long markedCount = libraryService.countByQuery(query);
+
+        query.setMarkerId(marker.getId());
+        long personCount = libraryService.countByQuery(query);
+
+        status.accumulate("personCount", personCount);
+        status.accumulate("totalCount", totalCount);
+        status.accumulate("markedCount", markedCount);
+        status.accumulate("exceptionCount", 0);
+        status.accumulate("valid", totalCount > 0);
+        status.accumulate("topCount", marker.getTopCount() == null ? 0 : marker.getTopCount());
+        return status;
+    }
+
+    @RequestMapping("/gettask")
+    @ResponseBody
+    public Task getTask(HttpServletRequest request) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        Task task = getTask(marker);
+        if (task == null) {
+            task = new Task();
+            task.setExist(false);
+            task.setMessage("当前无评卷任务");
+        }
+        return task;
+    }
+
+    /**
+     * 设置任务通用属性
+     * 
+     * @param task
+     * @param marker
+     * @param stage
+     * @param count
+     * @param bmList
+     */
+    private void setTaskParameter(Task task, Marker marker) {
+        task.setMarkId(marker.getId());
+        task.setSpent(new Date().getTime());
+    }
+
+    private Task getTask(Marker marker) {
+        int retry = 1;
+        Task task = null;
+        Set<LibraryStatus> set = new HashSet<LibraryStatus>();
+        set.add(LibraryStatus.WAITING);
+        set.add(LibraryStatus.BACKED);
+        while (retry <= 10 && task == null) {
+            List<MarkLibrary> list = libraryService.findByStatusSet(marker.getExamId(), marker.getSubjectCode(),
+                    marker.getGroupNumber(), set, retry, 20);
+            if (list.isEmpty()) {
+                break;
+            }
+            for (MarkLibrary library : list) {
+                if (setCurrentTask(marker, library)) {
+                    task = taskService.build(library);
+                    setTaskParameter(task, marker);
+                    break;
+                }
+            }
+            if (task == null) {
+                retry++;
+            }
+        }
+        return task;
+    }
+
+    @RequestMapping(value = "/savetask", method = RequestMethod.POST)
+    @ResponseBody
+    public JSONObject saveTask(HttpServletRequest request, @RequestBody Task task) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        JSONObject result = new JSONObject();
+        try {
+            task.setSpent((new Date().getTime() - task.getSpent()) / 1000);
+            if (taskService.submit(task)) {
+                releaseCurrentTask(marker, task);
+                result.accumulate("success", true);
+                result.accumulate("status", status(request));
+            } else {
+                result.accumulate("success", false);
+            }
+        } catch (Exception e) {
+            log.error("MarkController-保存任务出错", e);
+            result.accumulate("success", false);
+        }
+        return result;
+    }
+
+    @RequestMapping("/gethistory")
+    @ResponseBody
+    public Object history(HttpServletRequest request, @RequestParam int pageNumber, @RequestParam int pageSize)
+            throws Exception {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        // 查找给分任务历史
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setExamId(marker.getExamId());
+        query.setSubjectCode(marker.getSubjectCode());
+        query.setMarkerId(marker.getId());
+        query.setStatus(LibraryStatus.MARKED);
+        query.setGroupNumber(marker.getGroupNumber());
+        query.setPageNumber(pageNumber);
+        query.setPageSize(pageSize);
+        query.orderByMarkerTimeDesc();
+        List<Task> list = taskService.findByQuery(query);
+        for (Task task : list) {
+            task.setPrevious(true);
+            setTaskParameter(task, marker);
+        }
+        return list;
+    }
+
+    @RequestMapping("/change-name")
+    @ResponseBody
+    public JSONObject changeName(HttpServletRequest request, @RequestParam String name,
+            @RequestParam(required = false) String password) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        JSONObject result = new JSONObject();
+        marker.setName(name);
+        if (StringUtils.isNotEmpty(password)) {
+            marker.setPassword(password);
+        }
+        marker = markerService.save(marker);
+        result.accumulate("success", marker != null);
+        if (marker != null) {
+            result.accumulate("name", marker.getName());
+        }
+        return result;
+    }
+
+    @RequestMapping("/tags")
+    @ResponseBody
+    public JSONArray getTags(HttpServletRequest request) {
+        JSONArray array = new JSONArray();
+        List<Tag> list = tagService.findAll();
+        for (Tag tag : list) {
+            JSONObject obj = new JSONObject();
+            obj.accumulate("value", tag.getId());
+            obj.accumulate("name", tag.getName());
+            array.add(obj);
+        }
+        return array;
+    }
+
+    /**
+     * 清除当前评卷员正在评卷的所有任务记录
+     * 
+     * @param marker
+     * @param task
+     * @param session
+     */
+    private void clearCurrentTask(Marker marker) {
+        taskService.clearCurrent(marker);
+    }
+
+    /**
+     * 清除当前评卷员已给分的评卷任务
+     * 
+     * @param marker
+     * @param task
+     * @param session
+     */
+    private void releaseCurrentTask(Marker marker, Task task) {
+        taskService.removeCurrent(marker, task.getLibraryId());
+    }
+
+    /**
+     * 尝试设置当前任务
+     * 
+     * @param marker
+     * @param libraryId
+     * @return
+     */
+    private boolean setCurrentTask(Marker marker, MarkLibrary library) {
+        // 首先判断多评情况下,同一个studentId是否已被该评卷员处理过
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setStudentId(library.getStudentId());
+        query.setMarkerId(marker.getId());
+        if (libraryService.countByQuery(query) > 0) {
+            return false;
+        }
+        return taskService.setCurrent(marker, library.getId());
+    }
+}

+ 159 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/arbitrateList.jsp

@@ -0,0 +1,159 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+	<title>仲裁管理</title>
+	<meta name="decorator" content="default"/>
+	<%@include file="/WEB-INF/views/include/head.jsp" %>
+	<style type="text/css">.sort{color:#0663A2;cursor:pointer;}</style>
+</head>
+<body>
+    <ul class="nav nav-tabs">
+        <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
+        <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">评卷任务管理</a></li>
+        <li class="active"><a href="##">仲裁管理</a></li>
+    </ul>
+	<form id="searchForm" action="${ctx}/admin/exam/arbitrate" method="post" class="breadcrumb form-search">
+	    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>
+	    <input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize }"/>
+	    <div>
+			<label>科目</label>
+			<select class="input-large" id="subject-select" name="subjectCode">
+				<c:forEach items="${subjectList}" var="item">
+				<option value="${item.code}" <c:if test="${item.code==query.subjectCode}">selected</c:if>>${item.code}-${item.name}</option>
+				</c:forEach>
+			</select>
+			<label>大题</label>
+            <select class="input-medium" id="group-select" name="groupNumber">
+                <c:forEach items="${groupList}" var="item">
+                <option value="${item.number}" <c:if test="${item.number==query.groupNumber}">selected</c:if>>${item.number}-${item.title}</option>
+                </c:forEach>
+            </select>
+            <label>状态</label>
+            <select class="input-small" id="status-select" name="status">
+                <option value="">不限</option>
+                <c:forEach items="${statusList}" var="item">
+                <option value="${item.value}" <c:if test="${query.status!=null && item.value==query.status.value}">selected</c:if>>${item.name}</option>
+                </c:forEach>
+            </select>
+            <label>准考证号</label>
+            <input type="text" name="examNumber" value="${query.examNumber}" maxlength="10" class="input-medium"/>
+			&nbsp;
+			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+			&nbsp;
+            <a href="##" class="btn" target="_blank" id="process-link">批量处理</a>
+		</div>
+	</form>
+	<tags:message content="${message}"/>
+	<table id="contentTable" class="table table-striped table-bordered table-condensed">
+		<thead>
+			<tr>
+				<th>科目代码</th>
+				<th>大题号</th>
+				<th>准考证号</th>
+				<th>状态</th>
+				<th>创建时间</th>
+				<th>处理时间</th>
+				<th>处理人</th>
+				<th>操作</th>
+			</tr>
+		</thead>
+		<tbody>
+		<c:forEach items="${query.result}" var="result">
+			<tr>
+				<td>${result.subjectCode}</td>
+				<td>${result.groupNumber}</td>
+				<td>${result.examNumber}</td>
+				<td>${result.status.name}</td>
+				<td>
+                    <fmt:formatDate value="${result.createTime}" pattern="yyyy-MM-dd HH:mm:ss" />
+                </td>
+				<td>
+				    <c:if test="${result.updateTime!=null}">
+                    <fmt:formatDate value="${result.updateTime}" pattern="yyyy-MM-dd HH:mm:ss" />
+                    </c:if>
+                    <c:if test="${result.updateTime==null}">
+                    &nbsp;
+                    </c:if>
+				</td>
+				<td>
+                    <c:if test="${result.user!=null}">
+                    <a href="##" data-toggle="tooltip" title="${result.user.name}">${result.user.loginName}</a>
+                    </c:if>
+                    <c:if test="${result.user==null}">
+                    &nbsp;
+                    </c:if>
+                </td>
+				<td>
+				    <c:if test="${result.status.value==0}">
+                    <a href="##" data-id="${result.id}" class="back-link">打回</a>
+					</c:if>
+				</td>
+			</tr>
+		</c:forEach>
+		</tbody>
+	</table>
+	<div class="pagination">${query}</div>
+<script type="text/javascript">
+$('.back-link').click(function(){
+	if(!confirm('确定要打回该仲裁记录的所有评卷任务吗?')){
+	    return;
+	}
+	$.post('${ctx}/admin/exam/arbitrate/back', {id: $(this).attr('data-id')}, function(result){
+	    if(result.success==true){
+            alert('打回成功');
+            $("#searchForm").submit();
+        }else{
+            alert(result.message);
+        }
+	});
+});
+$('#process-link').click(function(){
+    var subjectCode = $('#subject-select').val();
+    var groupNumber = $('#group-select').val();
+    if(subjectCode=='') {
+        alert('请选择科目')
+        return false;
+    }
+    if(groupNumber=='') {
+        alert('请选择大题')
+        return false;
+    }
+    $('#process-link').attr('href', '${ctx}/admin/exam/arbitrate/process?subjectCode='+subjectCode+'&groupNumber='+groupNumber);
+    return true;
+});
+$('#subject-select').change(function(){
+    var code = $(this).val();
+    $('#group-select').empty();
+    if(code==''){
+        $('#group-select').val('').trigger('change');
+        return;
+    }
+    $.post('${ctx}/admin/exam/group/query', {subjectCode: code, withDouble: true}, function(result){
+        var parent = $('#group-select');
+        var first = '';
+        for(var i=0;i<result.length;i++){
+            var group = result[i];
+            $('<option value="'+group.number+'">'+group.number+'-'+group.title+'</option>').appendTo(parent);
+            if(i==0){
+                first = group.number;
+            }
+        }
+        parent.val(first).trigger('change');
+    });
+});
+function page(n,s){
+    $("#pageNumber").val(n);
+    $("#pageSize").val(s);
+    $("#searchForm").submit();
+    return false;
+}
+function goSearch(){
+    $("#pageNumber").val(1);
+    $("#searchForm").submit();
+    return false;
+}
+</script>	
+</body>
+</html>

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

@@ -12,6 +12,7 @@
         <li class="active"><a href="##">大题管理</a></li>
         <li><a href="${ctx}/admin/exam/marker?subjectCode=${subject.code}">评卷员管理</a></li>
         <li><a href="${ctx}/admin/exam/library?subjectCode=${subject.code}">评卷任务管理</a></li>
+        <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${subject.code}">仲裁管理</a></li>
     </ul>
 	<form id="searchForm" action="${ctx}/admin/exam/group" method="post" class="breadcrumb form-search">
 		<div>

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

@@ -1,193 +1,194 @@
-<%@ page contentType="text/html;charset=UTF-8" %>
-<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
-<html>
-<head>
-	<title>评卷任务</title>
-	<meta name="decorator" content="default"/>
-	<%@include file="/WEB-INF/views/include/head.jsp" %>
-	<style type="text/css">.sort{color:#0663A2;cursor:pointer;}</style>
-</head>
-<body>
-    <ul class="nav nav-tabs">
-        <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
-        <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
-        <li class="active"><a href="##">评卷任务管理</a></li>
-    </ul>
-	<form id="searchForm" action="${ctx}/admin/exam/library" method="post" class="breadcrumb form-search">
-	    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>
-	    <input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize }"/>
-	    <div>
-			<label>科目</label>
-			<select class="input-large" id="subject-select" name="subjectCode">
-				<c:forEach items="${subjectList}" var="item">
-				<option value="${item.code}" <c:if test="${item.code==query.subjectCode}">selected</c:if>>${item.code}-${item.name}</option>
-				</c:forEach>
-			</select>
-			<label>大题</label>
-            <select class="input-medium" id="group-select" name="groupNumber">
-                <c:forEach items="${groupList}" var="item">
-                <option value="${item.number}" <c:if test="${item.number==query.groupNumber}">selected</c:if>>${item.number}-${item.title}</option>
-                </c:forEach>
-            </select>
-            <label>状态</label>
-            <select class="input-small" id="status-select" name="status">
-                <option value="">不限</option>
-                <c:forEach items="${statusList}" var="item">
-                <option value="${item.value}" <c:if test="${query.status!=null && item.value==query.status.value}">selected</c:if>>${item.name}</option>
-                </c:forEach>
-            </select>
-            <label>评卷员</label>
-            <select class="input-medium" id="marker-select" name="markerId">
-                <option value="0">不限</option>
-                <c:forEach items="${markerList}" var="item">
-                <option value="${item.id}" <c:if test="${item.id==query.markerId}">selected</c:if>>${item.loginName}</option>
-                </c:forEach>
-            </select>
-            <br/><br/>
-            <label>准考证号</label>
-            <input type="text" name="examNumber" value="${query.examNumber}" maxlength="10" class="input-medium"/>
-			&nbsp;
-			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
-		</div>
-	</form>
-	<tags:message content="${message}"/>
-	<table id="contentTable" class="table table-striped table-bordered table-condensed">
-		<thead>
-			<tr>
-				<th>科目代码</th>
-				<th>大题号</th>
-				<th>准考证号</th>
-				<th>状态</th>
-				<th>评卷员</th>
-				<th>评卷总分</th>
-				<th>给分明细</th>
-				<th>评卷时间</th>
-				<th>操作</th>
-			</tr>
-		</thead>
-		<tbody>
-		<c:forEach items="${query.result}" var="result">
-			<tr>
-				<td>${result.subjectCode}</td>
-				<td>${result.groupNumber}</td>
-				<td>${result.examNumber}</td>
-				<td>${result.status.name}</td>
-                <td>
-                    <c:if test="${result.marker!=null}">
-                    ${result.marker.loginName}
-                    </c:if>
-                    <c:if test="${result.marker==null}">
-                    &nbsp;
-                    </c:if>
-                </td>
-				<td>
-				    <c:if test="${result.markerScore!=null}">
-				    ${result.markerScore}
-				    </c:if>
-				    <c:if test="${result.markerScore==null}">
-				    &nbsp;
-				    </c:if>
-				</td>
-				<td>
-				    <c:if test="${result.markerScoreList!=null}">
-                    ${result.markerScoreList}
-                    </c:if>
-                    <c:if test="${result.markerScoreList==null}">
-                    &nbsp;
-                    </c:if>
-				</td>
-				<td>
-				    <c:if test="${result.markerTime!=null}">
-                    <fmt:formatDate value="${result.markerTime}" pattern="yyyy-MM-dd HH:mm:ss" />
-                    </c:if>
-                    <c:if test="${result.markerTime==null}">
-                    &nbsp;
-                    </c:if>
-				</td>
-				<td>
-				    <c:if test="${result.status.value==1}">
-				    <a class="track-link" href="##" data-image-url="${ctx}/admin/exam/track?studentId=${result.studentId}" data-title="${result.examNumber}">阅卷轨迹</a>
-                    &nbsp;
-                    <a href="##" data-id="${result.id}" class="back-link">打回</a>
-					</c:if>
-				</td>
-			</tr>
-		</c:forEach>
-		</tbody>
-	</table>
-	<div class="pagination">${query}</div>
-	<%@include file="/WEB-INF/views/include/trackView.jsp" %>
-<script type="text/javascript">
-$('.back-link').click(function(){
-	if(!confirm('确定要打回该评卷任务吗?')){
-	    return;
-	}
-	$.post('${ctx}/admin/exam/library/back', {id: $(this).attr('data-id')}, function(result){
-	    if(result.success==true){
-            alert('打回成功');
-            $("#searchForm").submit();
-        }else{
-            alert(result.message);
-        }
-	});
-});
-$('.track-link').click(function(){
-    initTrackPopover($(this).attr('data-title'),$(this).attr('data-image-url'));
-    return false;
-});
-$('#subject-select').change(function(){
-    var code = $(this).val();
-    $('#group-select').empty();
-    if(code==''){
-        $('#group-select').val('').trigger('change');
-        return;
-    }
-    $.post('${ctx}/admin/exam/group/query', {subjectCode: code}, function(result){
-        var parent = $('#group-select');
-        var first = '';
-        for(var i=0;i<result.length;i++){
-            var group = result[i];
-            $('<option value="'+group.number+'">'+group.number+'-'+group.title+'</option>').appendTo(parent);
-            if(i==0){
-                first = group.number;
-            }
-        }
-        parent.val(first).trigger('change');
-    });
-});
-$('#group-select').change(function(){
-    var subjectCode = $('#subject-select').val();
-    var groupNumber = $('#group-select').val();
-    $('#marker-select').empty();
-    $('#marker-select').append('<option value="0">不限</option>');
-    $('#marker-select').val('0').trigger('change');
-    if(subjectCode=='' || groupNumber==''){
-        return;
-    }
-    $.post('${ctx}/admin/exam/marker/query', {subjectCode: subjectCode, groupNumber: groupNumber}, function(result){
-        var parent = $('#marker-select');
-        var first = '';
-        for(var i=0;i<result.length;i++){
-            var marker = result[i];
-            $('<option value="'+marker.id+'">'+marker.loginName+'</option>').appendTo(parent);
-            if(i==0){
-                first = marker.id;
-            }
-        }
-        //parent.val(first).trigger('change');
-    });
-});
-function page(n,s){
-    $("#pageNumber").val(n);
-    $("#pageSize").val(s);
-    $("#searchForm").submit();
-    return false;
-}
-function goSearch(){
-    $("#pageNumber").val(1);
-    $("#searchForm").submit();
-    return false;
-}
-</script>	
-</body>
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+	<title>评卷任务</title>
+	<meta name="decorator" content="default"/>
+	<%@include file="/WEB-INF/views/include/head.jsp" %>
+	<style type="text/css">.sort{color:#0663A2;cursor:pointer;}</style>
+</head>
+<body>
+    <ul class="nav nav-tabs">
+        <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
+        <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
+        <li class="active"><a href="##">评卷任务管理</a></li>
+        <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${query.subjectCode}">仲裁管理</a></li>
+    </ul>
+	<form id="searchForm" action="${ctx}/admin/exam/library" method="post" class="breadcrumb form-search">
+	    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>
+	    <input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize }"/>
+	    <div>
+			<label>科目</label>
+			<select class="input-large" id="subject-select" name="subjectCode">
+				<c:forEach items="${subjectList}" var="item">
+				<option value="${item.code}" <c:if test="${item.code==query.subjectCode}">selected</c:if>>${item.code}-${item.name}</option>
+				</c:forEach>
+			</select>
+			<label>大题</label>
+            <select class="input-medium" id="group-select" name="groupNumber">
+                <c:forEach items="${groupList}" var="item">
+                <option value="${item.number}" <c:if test="${item.number==query.groupNumber}">selected</c:if>>${item.number}-${item.title}</option>
+                </c:forEach>
+            </select>
+            <label>状态</label>
+            <select class="input-small" id="status-select" name="status">
+                <option value="">不限</option>
+                <c:forEach items="${statusList}" var="item">
+                <option value="${item.value}" <c:if test="${query.status!=null && item.value==query.status.value}">selected</c:if>>${item.name}</option>
+                </c:forEach>
+            </select>
+            <label>评卷员</label>
+            <select class="input-medium" id="marker-select" name="markerId">
+                <option value="0">不限</option>
+                <c:forEach items="${markerList}" var="item">
+                <option value="${item.id}" <c:if test="${item.id==query.markerId}">selected</c:if>>${item.loginName}</option>
+                </c:forEach>
+            </select>
+            <br/><br/>
+            <label>准考证号</label>
+            <input type="text" name="examNumber" value="${query.examNumber}" maxlength="10" class="input-medium"/>
+			&nbsp;
+			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+		</div>
+	</form>
+	<tags:message content="${message}"/>
+	<table id="contentTable" class="table table-striped table-bordered table-condensed">
+		<thead>
+			<tr>
+				<th>科目代码</th>
+				<th>大题号</th>
+				<th>准考证号</th>
+				<th>状态</th>
+				<th>评卷员</th>
+				<th>评卷总分</th>
+				<th>给分明细</th>
+				<th>评卷时间</th>
+				<th>操作</th>
+			</tr>
+		</thead>
+		<tbody>
+		<c:forEach items="${query.result}" var="result">
+			<tr>
+				<td>${result.subjectCode}</td>
+				<td>${result.groupNumber}</td>
+				<td>${result.examNumber}</td>
+				<td>${result.status.name}</td>
+                <td>
+                    <c:if test="${result.marker!=null}">
+                    ${result.marker.loginName}
+                    </c:if>
+                    <c:if test="${result.marker==null}">
+                    &nbsp;
+                    </c:if>
+                </td>
+				<td>
+				    <c:if test="${result.markerScore!=null}">
+				    ${result.markerScore}
+				    </c:if>
+				    <c:if test="${result.markerScore==null}">
+				    &nbsp;
+				    </c:if>
+				</td>
+				<td>
+				    <c:if test="${result.markerScoreList!=null}">
+                    ${result.markerScoreList}
+                    </c:if>
+                    <c:if test="${result.markerScoreList==null}">
+                    &nbsp;
+                    </c:if>
+				</td>
+				<td>
+				    <c:if test="${result.markerTime!=null}">
+                    <fmt:formatDate value="${result.markerTime}" pattern="yyyy-MM-dd HH:mm:ss" />
+                    </c:if>
+                    <c:if test="${result.markerTime==null}">
+                    &nbsp;
+                    </c:if>
+				</td>
+				<td>
+				    <c:if test="${result.status.value==1}">
+				    <a class="track-link" href="##" data-image-url="${ctx}/admin/exam/track?studentId=${result.studentId}" data-title="${result.examNumber}">阅卷轨迹</a>
+                    &nbsp;
+                    <a href="##" data-id="${result.id}" class="back-link">打回</a>
+					</c:if>
+				</td>
+			</tr>
+		</c:forEach>
+		</tbody>
+	</table>
+	<div class="pagination">${query}</div>
+	<%@include file="/WEB-INF/views/include/trackView.jsp" %>
+<script type="text/javascript">
+$('.back-link').click(function(){
+	if(!confirm('确定要打回该评卷任务吗?')){
+	    return;
+	}
+	$.post('${ctx}/admin/exam/library/back', {id: $(this).attr('data-id')}, function(result){
+	    if(result.success==true){
+            alert('打回成功');
+            $("#searchForm").submit();
+        }else{
+            alert(result.message);
+        }
+	});
+});
+$('.track-link').click(function(){
+    initTrackPopover($(this).attr('data-title'),$(this).attr('data-image-url'));
+    return false;
+});
+$('#subject-select').change(function(){
+    var code = $(this).val();
+    $('#group-select').empty();
+    if(code==''){
+        $('#group-select').val('').trigger('change');
+        return;
+    }
+    $.post('${ctx}/admin/exam/group/query', {subjectCode: code}, function(result){
+        var parent = $('#group-select');
+        var first = '';
+        for(var i=0;i<result.length;i++){
+            var group = result[i];
+            $('<option value="'+group.number+'">'+group.number+'-'+group.title+'</option>').appendTo(parent);
+            if(i==0){
+                first = group.number;
+            }
+        }
+        parent.val(first).trigger('change');
+    });
+});
+$('#group-select').change(function(){
+    var subjectCode = $('#subject-select').val();
+    var groupNumber = $('#group-select').val();
+    $('#marker-select').empty();
+    $('#marker-select').append('<option value="0">不限</option>');
+    $('#marker-select').val('0').trigger('change');
+    if(subjectCode=='' || groupNumber==''){
+        return;
+    }
+    $.post('${ctx}/admin/exam/marker/query', {subjectCode: subjectCode, groupNumber: groupNumber}, function(result){
+        var parent = $('#marker-select');
+        var first = '';
+        for(var i=0;i<result.length;i++){
+            var marker = result[i];
+            $('<option value="'+marker.id+'">'+marker.loginName+'</option>').appendTo(parent);
+            if(i==0){
+                first = marker.id;
+            }
+        }
+        //parent.val(first).trigger('change');
+    });
+});
+function page(n,s){
+    $("#pageNumber").val(n);
+    $("#pageSize").val(s);
+    $("#searchForm").submit();
+    return false;
+}
+function goSearch(){
+    $("#pageNumber").val(1);
+    $("#searchForm").submit();
+    return false;
+}
+</script>	
+</body>
 </html>

+ 364 - 363
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/markerList.jsp

@@ -1,364 +1,365 @@
-<%@ page contentType="text/html;charset=UTF-8" %>
-<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
-<html>
-<head>
-	<title>评卷员管理</title>
-	<meta name="decorator" content="default"/>
-	<%@include file="/WEB-INF/views/include/head.jsp" %>
-	<style type="text/css">.sort{color:#0663A2;cursor:pointer;}</style>
-	<style type="text/css">
-        .sort{color:#0663A2;cursor:pointer;}
-        .taskWindow,.reSetPasswordWin{
-            width: 400px;
-            min-height: 150px;
-            background: #fff;
-            font-family: "微软雅黑", Fixedsys;
-            border: #5d6d7d solid 1px;
-            position: absolute;
-            left: 50%;
-            top: 50%;
-            margin: -150px 0 0 -200px;
-            text-align: center;
-            z-index: 99999;
-        }
-        .task-header,.password-header{
-            width: 100%;
-            height: 46px;
-            background: #5d6d7d;
-            color: #fff;
-        }
-        .task-content,.password-content{
-            font-size: 18px;
-            color: #005277;
-            text-align: left;
-            padding: 15px;
-            line-height: 30px;
-            word-wrap: break-word;
-        }
-        .image-close {
-            margin-top: 15px;
-            margin-right: 15px;
-            cursor: pointer;
-            float: right;
-        }
-        .title {
-            font-size: 22px;
-            font-weight: bold;
-            color: #fff;
-            margin: 0px;
-            padding: 13px 0 0 13px;
-            float: left;
-        }
-        .task-count,.password-value{
-            width: 150px;
-        }
-        .btn-info{
-            height: 25px;
-            margin-left: 320px;
-            margin-bottom: 20px;
-        }
-        .wrong,.passwordWrong{
-            font-size: 12px;
-            color: #f00;
-            line-height: 30px;
-            padding-left: 20px;
-        }
-        #cover{
-            position: fixed;
-            z-index:9999;
-            top:0px;
-            left:0px;
-            display: none;
-            width: 100%;
-            height: 100%;
-            opacity: 0.5;
-            background: #000 none repeat scroll 0% 0%;
-        }
-    </style>
-</head>
-<body>
-    <ul class="nav nav-tabs">
-        <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
-        <li class="active"><a href="##">评卷员管理</a></li>
-        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">评卷任务管理</a></li>
-    </ul>
-    <div id="importBox" class="hide">
-        <form id="importForm" action="${ctx}/admin/exam/marker/import" method="post" enctype="multipart/form-data"
-              style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
-            <input id="uploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
-            <input id="btnImportSubmit" class="btn btn-primary" type="submit" value="   导    入   "/>
-            <a href="${ctx}/admin/exam/marker/template">下载模板</a>
-        </form>
-    </div>
-
-<%--     <div id="importUpdateBox" class="hide">
-        <form id="importUpdateForm" action="${ctx}/admin/exam/marker/importUpdate" method="post" enctype="multipart/form-data"
-              style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
-            <input id="uploadUpdateFile" name="file" type="file" style="width:330px"/><br/><br/>  
-            <input id="btnUpdateImportSubmit" class="btn btn-primary" type="submit" value="   导    入   "/>
-            <a href="${ctx}/admin/exam/marker/updateLoginNameTemplate">下载模板</a>
-        </form>
-    </div> --%>
-    
-	<form id="searchForm"  action="${ctx}/admin/exam/marker" method="post" class="breadcrumb form-search">
-		<input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber}"/>
-		<input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize}"/>
-		<div>
-			<label>科目</label>
-			<select id="subject-select" name="subjectCode">
-				<c:forEach items="${subjectList}" var="subject">
-				<option value="${subject.code}" <c:if test="${subject.code==query.subjectCode}">selected</c:if>>${subject.code}-${subject.name}</option>
-				</c:forEach>
-			</select>
-			<label>大题</label>
-            <select id="group-select" name="groupNumber">
-            </select>
-			<label>登录名</label>
-			<input type="text" name="loginName" value="${query.loginName}"  maxlength="10" class="input-small"/>
-			&nbsp;
-			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
-			<c:if test="${web_user.schoolAdmin==true}">
-            &nbsp;
-            <a href="${ctx}/admin/exam/marker/batch-create" class="btn btn-success">新增</a>
-            </c:if>
-			&nbsp;
-			<c:if test="${showBtnImport}">
-				&nbsp;<input id="btnImport" class="btn" type="button" value="导入"/>
-<!-- 				&nbsp;<input id="btnUpdateImport" class="btn" type="button" value="批量修改评卷员账号"/> -->
-			</c:if>
-			<input id="btnExport" class="btn" type="button" value="导出"/>
-		</div>
-	</form>
-	<tags:message content="${message}"/>
-	<table id="contentTable" class="table table-striped table-bordered table-condensed">
-		<thead>
-			<tr>
-				<th>科目</th>
-				<th>大题</th>
-				<th>登录名</th>
-				<th>姓名</th>
-				<th>密码</th>
-				<th>状态</th>
-				<th>已评数量</th>
-				<th>正在评卷</th>
-				<th>任务数</th>
-				<th>操作</th>
-			</tr>
-		</thead>
-		<tbody>
-		<c:forEach items="${query.result}" var="marker">
-			<tr>
-				<td>
-				<c:if test="${marker.subject!=null}">
-				${marker.subject.code}-${marker.subject.name}
-				</c:if>
-				</td>
-				<td>
-                <c:if test="${marker.group!=null}">
-                ${marker.group.number}-${marker.group.title}
-                </c:if>
-                </td>
-				<td>${marker.loginName}</td>
-				<td>${marker.name}</td>
-				<td>${marker.password}</td>
-				<td>${marker.enable eq true ? "启用" : "禁用"}</td>
-				<td>${marker.markedCount}</td>
-				<td>${marker.currentCount}</td>
-				<td>${marker.topCount}</td>
-				<td>
-				    <c:if test="${web_user.schoolAdmin==true}">
-					<a href="javascript:void(0)" class="delete-button" data-id="${marker.id}">删除</a>
-					<c:if test="${marker.enable==true}">
-					<a href="javascript:void(0)" class="toggle-button" data-id="${marker.id}" data-value="false">禁用</a>
-					</c:if>
-					<c:if test="${marker.enable==false}">
-					<a href="javascript:void(0)" class="toggle-button" data-id="${marker.id}" data-value="true">启用</a>
-					</c:if>
-					<a href="javascript:void(0)" class="release-button" data-id="${marker.id}">回收</a>
-					<a href="javascript:void(0)" class="task-button" data-id="${marker.id}" onclick="showTaskWin('${marker.id}');">设置评卷数</a>
-                    <a href="javascript:void(0)" class="reSetPassword-button" data-id="${marker.id}" onclick="reSetPassword('${marker.id}');">重置密码</a>
-					</c:if>
-				</td>
-			</tr>
-		</c:forEach>
-		</tbody>
-	</table>
-	    <div class="taskWindow" style="display:none"><div class="task-header">
-        <p class="title">设置任务数</p><p class="image-close"><img src="${ctxStatic}/mark-new/images/images-close.png" /></p></div>
-        <div class="task-content"><input type="text" class="task-count" placeholder="请输入任务数"/><i class="wrong"></i></div>
-        <a href="#" class="btn btn-small btn-info task-btn">确定</a>
-    </div>
-
-    <div class="reSetPasswordWin" style="display:none"><div class="password-header">
-        <p class="title">重置密码</p><p class="image-close password-close"><img src="${ctxStatic}/mark-new/images/images-close.png" /></p></div>
-        <div class="password-content"><input type="text" class="password-value" placeholder="请输入新的密码"/><i class="passwordWrong"></i></div>
-        <a href="#" class="btn btn-small btn-info password-btn">确定</a>
-    </div>
-	<div class="pagination">${query}</div>
-<script type="text/javascript">
-var searchSubjectCode = '${query.subjectCode}';
-var searchGroupNumber = '${query.groupNumber}';
-var markerId ;
-$(document).ready(function () {
-  $('#cover').hide();
-});
-$("#btnImport").click(function(){
-$.jBox($("#importBox").html(), {title:"导入数据", buttons:{"关闭":true},
-bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
-});
-/* $("#btnUpdateImport").click(function(){
-$.jBox($("#importUpdateBox").html(), {title:"导入数据", buttons:{"关闭":true},
-bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
-}); */
-
-$("#btnExport").click(function(){
-	top.$.jBox.confirm("确认要导出评卷员数据吗?","系统提示",function(v,h,f){
-		if(v=="ok"){
-			$("#searchForm").attr("action","/admin/exam/marker/export");
-			$("#searchForm").submit();
-		}
-	},{buttonsFocus:1});
-	top.$('.jbox-body .jbox-icon').css('top','55px');
-});
-$('.delete-button').click(function(){
-	if(!confirm("确定要删除改评卷员吗?")){
-	    return;
-	}
-	var id = $(this).attr('data-id');
-	$.post('${ctx}/admin/exam/marker/delete', {id: id}, function(result){
-		if(result.success==true){
-			alert('删除成功');
-			$("#searchForm").submit();
-		}else{
-			alert(result.message);
-		}
-	});
-});
-$('.toggle-button').click(function(){
-	var id = $(this).attr('data-id');
-	var enable = $(this).attr('data-value');
-	$.post('${ctx}/admin/exam/marker/toggle', {id: id, enable: enable}, function(result){
-		if(result.success==true){
-			alert('修改成功');
-			$("#searchForm").submit();
-		}else{
-			alert(result.message);
-		}
-	});
-});
-$('.release-button').click(function(){
-    var id = $(this).attr('data-id');
-    $.post('${ctx}/admin/exam/marker/release', {id: id}, function(result){
-        if(result.success==true){
-            alert('回收成功');
-            $("#searchForm").submit();
-        }else{
-            alert(result.message);
-        }
-    });
-});
-$('#subject-select').change(function(){
-    var code = $(this).val();
-    $('#group-select').empty();
-    $('#group-select').append('<option value="0">请选择</option>');
-    if(code==''){
-        $('#group-select').val('0').trigger('change');
-        return;
-    }
-    $.post('${ctx}/admin/exam/group/query', {subjectCode: code}, function(result){
-        var parent = $('#group-select');
-        for(var i=0;i<result.length;i++){
-            var group = result[i];
-            var dom = $('<option value="'+group.number+'">'+group.number+'-'+group.title+'</option>').appendTo(parent);
-            if(searchSubjectCode==code && searchGroupNumber==group.number){
-                dom.attr('selected', 'selected');
-            }
-        }
-        parent.trigger('change');
-    });
-});
-$('#subject-select').trigger('change');
-
-function page(n,s){
-	$("#pageNumber").val(n);
-	$("#pageSize").val(s);
-	$("#searchForm").attr("action","${ctx}/admin/exam/marker");
-	$("#searchForm").submit();
-	return false;
-}
-function goSearch(){
-	$("#pageNumber").val(1);
-	$("#pageSize").val('${query.pageSize}');
-	$("#searchForm").attr("action","${ctx}/admin/exam/marker");
-	$("#searchForm").submit();
-	return false;
-}
-function showTaskWin(obj){
-	  $('.wrong').html('');
-	  $('.task-count').val('');
-	  $('.taskWindow').show();
-	  $('#cover').show();
-	  markerId = obj;
-	}
-	function reSetPassword(obj){
-	  $('.passwordWrong').html('');
-	  $('.password-value').val('');
-	  $('.reSetPasswordWin').show();
-	  $('#cover').show();
-	  markerId = obj;
-	}
-	$('.image-close').click(function () {
-	  $('.taskWindow').hide();
-	  $('#cover').hide();
-	});
-	$('.password-close').click(function () {
-	  $('.reSetPasswordWin').hide();
-	  $('#cover').hide();
-	});
-
-	$('.task-btn').click(function () {
-	  var taskCount = $('.task-count').val();
-	  var wrongMessage = $('.wrong');
-	       taskCount = taskCount.replace(/(^\s*)|(\s*$)/g, "");
-	       if(taskCount.length == 0){
-	         wrongMessage.html('任务数不能为空!');
-	         return false;
-	       }else {
-	         if(!/^\+?[1-9][0-9]*$/.test(taskCount)){
-	           wrongMessage.html('请输入正整数!');
-	           return false;
-	         }
-	       }
-	  $.post('${ctx}/admin/exam/marker/setTaskCount', {id: markerId,taskCount:taskCount}, function(result){
-	    if(result.success==true){
-	      $("#searchForm").submit();
-	    }else{
-	      alert(result.message);
-	    }
-	    $('.taskWindow').hide();
-	  });
-	});
-	    $('.password-btn').click(function () {
-	      var password = $('.password-value').val();
-	      var wrongMessage = $('.passwordWrong');
-	      password = password.replace(/(^\s*)|(\s*$)/g, "");
-	      if(password.length == 0){
-	        wrongMessage.html('密码不能为空!');
-	        return false;
-	      }else if(password.length < 4){
-	        wrongMessage.html('密码至少4位!');
-	        return false;
-	      }
-	      $.post('${ctx}/admin/exam/marker/reSetPassword', {id: markerId,password:password}, function(result){
-	        if(result.success==true){
-	          $("#searchForm").submit();
-	        }else{
-	          alert(result.message);
-	        }
-	        $('.reSetPasswordWin').hide();
-	      });
-	    });
-	    
-</script>	
-</body>
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+	<title>评卷员管理</title>
+	<meta name="decorator" content="default"/>
+	<%@include file="/WEB-INF/views/include/head.jsp" %>
+	<style type="text/css">.sort{color:#0663A2;cursor:pointer;}</style>
+	<style type="text/css">
+        .sort{color:#0663A2;cursor:pointer;}
+        .taskWindow,.reSetPasswordWin{
+            width: 400px;
+            min-height: 150px;
+            background: #fff;
+            font-family: "微软雅黑", Fixedsys;
+            border: #5d6d7d solid 1px;
+            position: absolute;
+            left: 50%;
+            top: 50%;
+            margin: -150px 0 0 -200px;
+            text-align: center;
+            z-index: 99999;
+        }
+        .task-header,.password-header{
+            width: 100%;
+            height: 46px;
+            background: #5d6d7d;
+            color: #fff;
+        }
+        .task-content,.password-content{
+            font-size: 18px;
+            color: #005277;
+            text-align: left;
+            padding: 15px;
+            line-height: 30px;
+            word-wrap: break-word;
+        }
+        .image-close {
+            margin-top: 15px;
+            margin-right: 15px;
+            cursor: pointer;
+            float: right;
+        }
+        .title {
+            font-size: 22px;
+            font-weight: bold;
+            color: #fff;
+            margin: 0px;
+            padding: 13px 0 0 13px;
+            float: left;
+        }
+        .task-count,.password-value{
+            width: 150px;
+        }
+        .btn-info{
+            height: 25px;
+            margin-left: 320px;
+            margin-bottom: 20px;
+        }
+        .wrong,.passwordWrong{
+            font-size: 12px;
+            color: #f00;
+            line-height: 30px;
+            padding-left: 20px;
+        }
+        #cover{
+            position: fixed;
+            z-index:9999;
+            top:0px;
+            left:0px;
+            display: none;
+            width: 100%;
+            height: 100%;
+            opacity: 0.5;
+            background: #000 none repeat scroll 0% 0%;
+        }
+    </style>
+</head>
+<body>
+    <ul class="nav nav-tabs">
+        <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
+        <li class="active"><a href="##">评卷员管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">评卷任务管理</a></li>
+        <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${query.subjectCode}">仲裁管理</a></li>
+    </ul>
+    <div id="importBox" class="hide">
+        <form id="importForm" action="${ctx}/admin/exam/marker/import" method="post" enctype="multipart/form-data"
+              style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+            <input id="uploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
+            <input id="btnImportSubmit" class="btn btn-primary" type="submit" value="   导    入   "/>
+            <a href="${ctx}/admin/exam/marker/template">下载模板</a>
+        </form>
+    </div>
+
+<%--     <div id="importUpdateBox" class="hide">
+        <form id="importUpdateForm" action="${ctx}/admin/exam/marker/importUpdate" method="post" enctype="multipart/form-data"
+              style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+            <input id="uploadUpdateFile" name="file" type="file" style="width:330px"/><br/><br/>  
+            <input id="btnUpdateImportSubmit" class="btn btn-primary" type="submit" value="   导    入   "/>
+            <a href="${ctx}/admin/exam/marker/updateLoginNameTemplate">下载模板</a>
+        </form>
+    </div> --%>
+    
+	<form id="searchForm"  action="${ctx}/admin/exam/marker" method="post" class="breadcrumb form-search">
+		<input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber}"/>
+		<input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize}"/>
+		<div>
+			<label>科目</label>
+			<select id="subject-select" name="subjectCode">
+				<c:forEach items="${subjectList}" var="subject">
+				<option value="${subject.code}" <c:if test="${subject.code==query.subjectCode}">selected</c:if>>${subject.code}-${subject.name}</option>
+				</c:forEach>
+			</select>
+			<label>大题</label>
+            <select id="group-select" name="groupNumber">
+            </select>
+			<label>登录名</label>
+			<input type="text" name="loginName" value="${query.loginName}"  maxlength="10" class="input-small"/>
+			&nbsp;
+			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+			<c:if test="${web_user.schoolAdmin==true}">
+            &nbsp;
+            <a href="${ctx}/admin/exam/marker/batch-create" class="btn btn-success">新增</a>
+            </c:if>
+			&nbsp;
+			<c:if test="${showBtnImport}">
+				&nbsp;<input id="btnImport" class="btn" type="button" value="导入"/>
+<!-- 				&nbsp;<input id="btnUpdateImport" class="btn" type="button" value="批量修改评卷员账号"/> -->
+			</c:if>
+			<input id="btnExport" class="btn" type="button" value="导出"/>
+		</div>
+	</form>
+	<tags:message content="${message}"/>
+	<table id="contentTable" class="table table-striped table-bordered table-condensed">
+		<thead>
+			<tr>
+				<th>科目</th>
+				<th>大题</th>
+				<th>登录名</th>
+				<th>姓名</th>
+				<th>密码</th>
+				<th>状态</th>
+				<th>已评数量</th>
+				<th>正在评卷</th>
+				<th>任务数</th>
+				<th>操作</th>
+			</tr>
+		</thead>
+		<tbody>
+		<c:forEach items="${query.result}" var="marker">
+			<tr>
+				<td>
+				<c:if test="${marker.subject!=null}">
+				${marker.subject.code}-${marker.subject.name}
+				</c:if>
+				</td>
+				<td>
+                <c:if test="${marker.group!=null}">
+                ${marker.group.number}-${marker.group.title}
+                </c:if>
+                </td>
+				<td>${marker.loginName}</td>
+				<td>${marker.name}</td>
+				<td>${marker.password}</td>
+				<td>${marker.enable eq true ? "启用" : "禁用"}</td>
+				<td>${marker.markedCount}</td>
+				<td>${marker.currentCount}</td>
+				<td>${marker.topCount}</td>
+				<td>
+				    <c:if test="${web_user.schoolAdmin==true}">
+					<a href="javascript:void(0)" class="delete-button" data-id="${marker.id}">删除</a>
+					<c:if test="${marker.enable==true}">
+					<a href="javascript:void(0)" class="toggle-button" data-id="${marker.id}" data-value="false">禁用</a>
+					</c:if>
+					<c:if test="${marker.enable==false}">
+					<a href="javascript:void(0)" class="toggle-button" data-id="${marker.id}" data-value="true">启用</a>
+					</c:if>
+					<a href="javascript:void(0)" class="release-button" data-id="${marker.id}">回收</a>
+					<a href="javascript:void(0)" class="task-button" data-id="${marker.id}" onclick="showTaskWin('${marker.id}');">设置评卷数</a>
+                    <a href="javascript:void(0)" class="reSetPassword-button" data-id="${marker.id}" onclick="reSetPassword('${marker.id}');">重置密码</a>
+					</c:if>
+				</td>
+			</tr>
+		</c:forEach>
+		</tbody>
+	</table>
+	    <div class="taskWindow" style="display:none"><div class="task-header">
+        <p class="title">设置任务数</p><p class="image-close"><img src="${ctxStatic}/mark-new/images/images-close.png" /></p></div>
+        <div class="task-content"><input type="text" class="task-count" placeholder="请输入任务数"/><i class="wrong"></i></div>
+        <a href="#" class="btn btn-small btn-info task-btn">确定</a>
+    </div>
+
+    <div class="reSetPasswordWin" style="display:none"><div class="password-header">
+        <p class="title">重置密码</p><p class="image-close password-close"><img src="${ctxStatic}/mark-new/images/images-close.png" /></p></div>
+        <div class="password-content"><input type="text" class="password-value" placeholder="请输入新的密码"/><i class="passwordWrong"></i></div>
+        <a href="#" class="btn btn-small btn-info password-btn">确定</a>
+    </div>
+	<div class="pagination">${query}</div>
+<script type="text/javascript">
+var searchSubjectCode = '${query.subjectCode}';
+var searchGroupNumber = '${query.groupNumber}';
+var markerId ;
+$(document).ready(function () {
+  $('#cover').hide();
+});
+$("#btnImport").click(function(){
+$.jBox($("#importBox").html(), {title:"导入数据", buttons:{"关闭":true},
+bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
+});
+/* $("#btnUpdateImport").click(function(){
+$.jBox($("#importUpdateBox").html(), {title:"导入数据", buttons:{"关闭":true},
+bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
+}); */
+
+$("#btnExport").click(function(){
+	top.$.jBox.confirm("确认要导出评卷员数据吗?","系统提示",function(v,h,f){
+		if(v=="ok"){
+			$("#searchForm").attr("action","/admin/exam/marker/export");
+			$("#searchForm").submit();
+		}
+	},{buttonsFocus:1});
+	top.$('.jbox-body .jbox-icon').css('top','55px');
+});
+$('.delete-button').click(function(){
+	if(!confirm("确定要删除改评卷员吗?")){
+	    return;
+	}
+	var id = $(this).attr('data-id');
+	$.post('${ctx}/admin/exam/marker/delete', {id: id}, function(result){
+		if(result.success==true){
+			alert('删除成功');
+			$("#searchForm").submit();
+		}else{
+			alert(result.message);
+		}
+	});
+});
+$('.toggle-button').click(function(){
+	var id = $(this).attr('data-id');
+	var enable = $(this).attr('data-value');
+	$.post('${ctx}/admin/exam/marker/toggle', {id: id, enable: enable}, function(result){
+		if(result.success==true){
+			alert('修改成功');
+			$("#searchForm").submit();
+		}else{
+			alert(result.message);
+		}
+	});
+});
+$('.release-button').click(function(){
+    var id = $(this).attr('data-id');
+    $.post('${ctx}/admin/exam/marker/release', {id: id}, function(result){
+        if(result.success==true){
+            alert('回收成功');
+            $("#searchForm").submit();
+        }else{
+            alert(result.message);
+        }
+    });
+});
+$('#subject-select').change(function(){
+    var code = $(this).val();
+    $('#group-select').empty();
+    $('#group-select').append('<option value="0">请选择</option>');
+    if(code==''){
+        $('#group-select').val('0').trigger('change');
+        return;
+    }
+    $.post('${ctx}/admin/exam/group/query', {subjectCode: code}, function(result){
+        var parent = $('#group-select');
+        for(var i=0;i<result.length;i++){
+            var group = result[i];
+            var dom = $('<option value="'+group.number+'">'+group.number+'-'+group.title+'</option>').appendTo(parent);
+            if(searchSubjectCode==code && searchGroupNumber==group.number){
+                dom.attr('selected', 'selected');
+            }
+        }
+        parent.trigger('change');
+    });
+});
+$('#subject-select').trigger('change');
+
+function page(n,s){
+	$("#pageNumber").val(n);
+	$("#pageSize").val(s);
+	$("#searchForm").attr("action","${ctx}/admin/exam/marker");
+	$("#searchForm").submit();
+	return false;
+}
+function goSearch(){
+	$("#pageNumber").val(1);
+	$("#pageSize").val('${query.pageSize}');
+	$("#searchForm").attr("action","${ctx}/admin/exam/marker");
+	$("#searchForm").submit();
+	return false;
+}
+function showTaskWin(obj){
+	  $('.wrong').html('');
+	  $('.task-count').val('');
+	  $('.taskWindow').show();
+	  $('#cover').show();
+	  markerId = obj;
+	}
+	function reSetPassword(obj){
+	  $('.passwordWrong').html('');
+	  $('.password-value').val('');
+	  $('.reSetPasswordWin').show();
+	  $('#cover').show();
+	  markerId = obj;
+	}
+	$('.image-close').click(function () {
+	  $('.taskWindow').hide();
+	  $('#cover').hide();
+	});
+	$('.password-close').click(function () {
+	  $('.reSetPasswordWin').hide();
+	  $('#cover').hide();
+	});
+
+	$('.task-btn').click(function () {
+	  var taskCount = $('.task-count').val();
+	  var wrongMessage = $('.wrong');
+	       taskCount = taskCount.replace(/(^\s*)|(\s*$)/g, "");
+	       if(taskCount.length == 0){
+	         wrongMessage.html('任务数不能为空!');
+	         return false;
+	       }else {
+	         if(!/^\+?[1-9][0-9]*$/.test(taskCount)){
+	           wrongMessage.html('请输入正整数!');
+	           return false;
+	         }
+	       }
+	  $.post('${ctx}/admin/exam/marker/setTaskCount', {id: markerId,taskCount:taskCount}, function(result){
+	    if(result.success==true){
+	      $("#searchForm").submit();
+	    }else{
+	      alert(result.message);
+	    }
+	    $('.taskWindow').hide();
+	  });
+	});
+	    $('.password-btn').click(function () {
+	      var password = $('.password-value').val();
+	      var wrongMessage = $('.passwordWrong');
+	      password = password.replace(/(^\s*)|(\s*$)/g, "");
+	      if(password.length == 0){
+	        wrongMessage.html('密码不能为空!');
+	        return false;
+	      }else if(password.length < 4){
+	        wrongMessage.html('密码至少4位!');
+	        return false;
+	      }
+	      $.post('${ctx}/admin/exam/marker/reSetPassword', {id: markerId,password:password}, function(result){
+	        if(result.success==true){
+	          $("#searchForm").submit();
+	        }else{
+	          alert(result.message);
+	        }
+	        $('.reSetPasswordWin').hide();
+	      });
+	    });
+	    
+</script>	
+</body>
 </html>