Browse Source

新增打回记录

ting.yin 2 years ago
parent
commit
3d4420f6ec
31 changed files with 1246 additions and 44 deletions
  1. 8 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/SubjectiveScoreDao.java
  2. 14 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/Exam.java
  3. 14 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/SubjectiveScore.java
  4. 2 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/SubjectiveScoreService.java
  5. 29 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/SubjectiveScoreServiceImpl.java
  6. 7 5
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkLibraryDao.java
  7. 25 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/RejectHistoryDao.java
  8. 22 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkLibrary.java
  9. 10 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkStepDTO.java
  10. 290 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/RejectHistory.java
  11. 13 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/Task.java
  12. 116 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/RejectHistorySearchQuery.java
  13. 68 20
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkServiceImpl.java
  14. 86 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/RejectHistoryServiceImpl.java
  15. 25 6
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/TaskServiceImpl.java
  16. 12 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/RejectHistoryService.java
  17. 129 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/RejectHistoryController.java
  18. 6 4
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/examIndex.jsp
  19. 43 8
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/libraryList.jsp
  20. 148 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/rejectHistory.jsp
  21. 171 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/rejectList.jsp
  22. 1 0
      stmms-web/src/main/webapp/sql/stmms_ft.sql
  23. 3 0
      stmms-web/src/main/webapp/sql/upgrade/1.3.12.sql
  24. 1 0
      stmms-web/src/main/webapp/static/i18n/messages.properties
  25. 1 0
      stmms-web/src/main/webapp/static/i18n/messages_en.properties
  26. 1 0
      stmms-web/src/main/webapp/static/i18n/messages_ja.properties
  27. 1 0
      stmms-web/src/main/webapp/static/i18n/messages_zh.properties
  28. BIN
      stmms-web/src/main/webapp/static/images/emono-on.png
  29. BIN
      stmms-web/src/main/webapp/static/images/empno-on@2x.png
  30. BIN
      stmms-web/src/main/webapp/static/images/empno.png
  31. BIN
      stmms-web/src/main/webapp/static/images/empno@2x.png

+ 8 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/SubjectiveScoreDao.java

@@ -44,4 +44,12 @@ public interface SubjectiveScoreDao extends JpaRepository<SubjectiveScore, Subje
     @Query("select s from SubjectiveScore s where s.pk.studentId=?1 and s.uncalculate=?2 order by s.pk.mainNumber, s.pk.subNumber")
     List<SubjectiveScore> findByStudentIdAndUncalculate(Integer studentId, Boolean uncalculate);
 
+    @Modifying(clearAutomatically = true)
+    @Query("update SubjectiveScore s set s.rejected=?4 where s.pk.studentId=?1 and s.pk.mainNumber=?2 and s.pk.subNumber=?3")
+    void updateRejected(Integer studentId, Integer mainNumber, String subNumber, boolean rejected);
+
+    @Modifying(clearAutomatically = true)
+    @Query("update SubjectiveScore s set s.rejected=?3 where s.pk.studentId=?1 and s.groupNumber=?2")
+    void updateRejected(Integer studentId, Integer groupNumber, boolean rejected);
+
 }

+ 14 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/Exam.java

@@ -168,6 +168,12 @@ public class Exam implements Serializable {
     @Column(name = "enable_split", nullable = false)
     private boolean enableSplit;
 
+    /**
+     * 打回后是否显示原分值
+     */
+    @Column(name = "show_reject", nullable = false)
+    private boolean showReject;
+
     public Integer getId() {
         return id;
     }
@@ -404,4 +410,12 @@ public class Exam implements Serializable {
         this.enableSplit = enableSplit;
     }
 
+    public boolean isShowReject() {
+        return showReject;
+    }
+
+    public void setShowReject(boolean showReject) {
+        this.showReject = showReject;
+    }
+
 }

+ 14 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/SubjectiveScore.java

@@ -67,6 +67,12 @@ public class SubjectiveScore implements Serializable, Comparable<SubjectiveScore
     @Column(name = "uncalculate", nullable = false)
     private Boolean uncalculate;
 
+    /**
+     * 未计分
+     */
+    @Column(name = "rejected", nullable = false)
+    private Boolean rejected;
+
     public SubjectiveScore() {
         this.pk = new SubjectiveScorePK();
     }
@@ -179,4 +185,12 @@ public class SubjectiveScore implements Serializable, Comparable<SubjectiveScore
         this.uncalculate = uncalculate;
     }
 
+    public Boolean getRejected() {
+        return rejected;
+    }
+
+    public void setRejected(Boolean rejected) {
+        this.rejected = rejected;
+    }
+
 }

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

@@ -14,4 +14,6 @@ public interface SubjectiveScoreService {
 
     Set<Integer> findMainNumberByStudentIdAndUncalculate(Integer studentId, Boolean uncalculate);
 
+    List<SubjectiveScore> findByStudentId(Integer studentId);
+
 }

+ 29 - 1
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/SubjectiveScoreServiceImpl.java

@@ -106,10 +106,31 @@ public class SubjectiveScoreServiceImpl extends BaseQueryService<SubjectiveScore
     @Override
     public List<SubjectiveScore> findByStudentIdAndGroupNumber(Integer studentId, Integer groupNumber) {
         List<SubjectiveScore> list = scoreDao.findByStudentIdAndGroupNumber(studentId, groupNumber);
-        list.sort(null);
+        sort(list);
         return list;
     }
 
+    private void sort(List<SubjectiveScore> list) {
+        list.sort((o1, o2) -> {
+            int i = o1.getMainNumber() - o2.getMainNumber();
+            if (i == 0) {
+                if (o1.getSubNumber().contains("-")) {
+                    String[] o1s = o1.getSubNumber().split("-");
+                    String[] o2s = o2.getSubNumber().split("-");
+                    int j = Integer.parseUnsignedInt(o1s[0]) - Integer.parseUnsignedInt(o2s[0]);
+                    if (j == 0) {
+                        return Integer.parseUnsignedInt(o1s[1]) - Integer.parseUnsignedInt(o2s[1]);
+                    } else {
+                        return j;
+                    }
+                } else {
+                    return Integer.parseUnsignedInt(o1.getSubNumber()) - Integer.parseUnsignedInt(o2.getSubNumber());
+                }
+            }
+            return i;
+        });
+    }
+
     @Override
     public Set<Integer> findMainNumberByStudentIdAndUncalculate(Integer studentId, Boolean uncalculate) {
         Set<Integer> mainNumbers = new HashSet<Integer>();
@@ -119,4 +140,11 @@ public class SubjectiveScoreServiceImpl extends BaseQueryService<SubjectiveScore
         }
         return mainNumbers;
     }
+
+    @Override
+    public List<SubjectiveScore> findByStudentId(Integer studentId) {
+        List<SubjectiveScore> list = scoreDao.findByStudentId(studentId);
+        sort(list);
+        return list;
+    }
 }

+ 7 - 5
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkLibraryDao.java

@@ -85,9 +85,10 @@ public interface MarkLibraryDao extends JpaRepository<MarkLibrary, Integer>, Jpa
     void resetByMarkerId(Integer markerId, LibraryStatus status, LibraryStatus... notInStatus);
 
     @Modifying(clearAutomatically = true)
-    @Query("update MarkLibrary m set m.status=?4, m.markerId=?2, m.rejectReason=?3, m.markerTime=null, m.markerScore=null, m.markerScoreList=null, m.markerSpent=null, "
-            + "m.headerId=null , m.headerTime=null , m.headerScore=null , m.headerScoreList=null where m.id=?1 and m.status in (?5)")
-    int resetById(Integer id, Integer markerId, String reason, LibraryStatus newStatus, LibraryStatus... previousStatus);
+    @Query("update MarkLibrary m set m.status=?6, m.markerId=?2, m.rejectReason=?3, m.markerTime=null, m.markerScore=null, m.markerScoreList=null, m.markerSpent=null, "
+            + "m.headerId=?4 , m.headerTime=?5 , m.headerScore=null , m.headerScoreList=null where m.id=?1 and m.status in (?7)")
+    int resetById(Integer id, Integer markerId, String reason, Integer rejecterId, Date date, LibraryStatus newStatus,
+            LibraryStatus... previousStatus);
 
     @Query("select f.markerId, count(f) as markerCount from MarkLibrary f where f.examId=?1 and f.status in (?2) group by f.markerId")
     List<Object[]> countMarkerAndStatus(Integer examId, LibraryStatus... status);
@@ -124,9 +125,10 @@ public interface MarkLibraryDao extends JpaRepository<MarkLibrary, Integer>, Jpa
 
     @Modifying(clearAutomatically = true)
     @Query("update MarkLibrary l set l.status=?2, l.markerId=?3, l.markerScore=?4, l.markerScoreList=?5, l.markerTime=?6, "
-            + "l.markerSpent=?7 ,l.rejectReason=?8 where l.id=?1 and l.status in (?9) and (l.markerId=null or l.markerId=?3)")
+            + "l.markerSpent=?7 ,l.rejectReason=?8 ,l.headerId=?9,l.headerTime=?10,  where l.id=?1 and l.status in (?11) and (l.markerId=null or l.markerId=?3)")
     int updateMarkerResult(Integer id, LibraryStatus newStatus, Integer markerId, Double markerScore,
-            String markerScoreList, Date markerTime, Integer spent, String resson, LibraryStatus... previousStatus);
+            String markerScoreList, Date markerTime, Integer spent, String resson, Integer rejecterId, Date rejectTime,
+            LibraryStatus... previousStatus);
 
     @Query("select m.markerScore ,count(m) from MarkLibrary m where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3 and m.markerId=?4 and m.markerScore != -1 and m.status in (?5)  group by m.markerScore ")
     List<Object[]> findScoreCount(int examId, String subjectCode, Integer groupNumber, Integer markerId,

+ 25 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/RejectHistoryDao.java

@@ -0,0 +1,25 @@
+package cn.com.qmth.stmms.biz.mark.dao;
+
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
+
+public interface RejectHistoryDao extends JpaRepository<RejectHistory, Integer>,
+        JpaSpecificationExecutor<RejectHistory> {
+
+    @Modifying
+    @Query("delete RejectHistory m where m.studentId=?1")
+    void deleteByStudentId(Integer studentId);
+
+    @Modifying
+    @Query("delete from RejectHistory s where s.examId=?1 and s.subjectCode=?2 and s.groupNumber=?3  ")
+    void deleteByExamIdAndSubjectCodeAndGroupNumber(Integer examId, String subjectCode, Integer groupNumber);
+
+    List<RejectHistory> findByLibraryIdOrderByIdDesc(Integer libraryId);
+
+}

+ 22 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkLibrary.java

@@ -135,6 +135,12 @@ public class MarkLibrary implements Serializable {
     @Transient
     private String markerLoginName;
 
+    @Transient
+    private String title;
+
+    @Transient
+    private String headerLoginName;
+
     public Integer getId() {
         return id;
     }
@@ -333,4 +339,20 @@ public class MarkLibrary implements Serializable {
         this.rejectReason = rejectReason;
     }
 
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getHeaderLoginName() {
+        return headerLoginName;
+    }
+
+    public void setHeaderLoginName(String headerLoginName) {
+        this.headerLoginName = headerLoginName;
+    }
+
 }

+ 10 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkStepDTO.java

@@ -32,6 +32,8 @@ public class MarkStepDTO implements Serializable {
 
     private Integer selectiveIndex;
 
+    private boolean rejected;
+
     private List<TrackDTO> trackList = new ArrayList<TrackDTO>();
 
     public int getMainNumber() {
@@ -142,4 +144,12 @@ public class MarkStepDTO implements Serializable {
         this.questionName = questionName;
     }
 
+    public boolean isRejected() {
+        return rejected;
+    }
+
+    public void setRejected(boolean rejected) {
+        this.rejected = rejected;
+    }
+
 }

+ 290 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/RejectHistory.java

@@ -0,0 +1,290 @@
+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.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.user.model.User;
+import cn.com.qmth.stmms.biz.utils.ScoreItem;
+
+/**
+ * 打回记录表
+ */
+@Entity
+@Table(name = "m_reject_history")
+public class RejectHistory implements Serializable {
+
+    private static final long serialVersionUID = 1571356905196537231L;
+
+    @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 = "library_id")
+    private Integer libraryId;
+
+    /**
+     * 准考证号
+     */
+    @Column(name = "exam_number")
+    private String examNumber;
+
+    /**
+     * 考生密号
+     */
+    @Column(name = "secret_number")
+    private String secretNumber;
+
+    /**
+     * 评卷员ID
+     */
+    @Column(name = "marker_id", nullable = true)
+    private Integer markerId;
+
+    /**
+     * 处理用户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 = "reject_score_list", nullable = true, length = 255)
+    private String rejectScoreList;
+
+    @Column(name = "reason", nullable = true)
+    private String reason;
+
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_time", nullable = false)
+    private Date createTime;
+
+    @Transient
+    private User user;
+
+    public RejectHistory() {
+    }
+
+    public RejectHistory(MarkLibrary library) {
+        this.createTime = new Date();
+        this.examId = library.getExamId();
+        this.examNumber = library.getExamNumber();
+        this.groupNumber = library.getGroupNumber();
+        this.libraryId = library.getId();
+        this.markerId = library.getMarkerId();
+        this.scoreList = library.getMarkerScoreList();
+        this.secretNumber = library.getSecretNumber();
+        this.studentId = library.getStudentId();
+        this.subjectCode = library.getSubjectCode();
+        this.totalScore = library.getMarkerScore();
+    }
+
+    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 String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    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 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;
+    }
+
+    public Integer getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(Integer groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+
+    public Integer getLibraryId() {
+        return libraryId;
+    }
+
+    public void setLibraryId(Integer libraryId) {
+        this.libraryId = libraryId;
+    }
+
+    public Integer getMarkerId() {
+        return markerId;
+    }
+
+    public void setMarkerId(Integer markerId) {
+        this.markerId = markerId;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public String getRejectScoreList() {
+        return rejectScoreList;
+    }
+
+    public void setRejectScoreList(String rejectScoreList) {
+        this.rejectScoreList = rejectScoreList;
+    }
+
+    public List<ScoreItem> getScoreItems() {
+        List<ScoreItem> scoreItems = new LinkedList<ScoreItem>();
+        String list = null;
+        if (StringUtils.isNotBlank(scoreList)) {
+            list = scoreList;
+        }
+        if (StringUtils.isNotBlank(list)) {
+            try {
+                String[] values = list.split(",");
+                for (String value : values) {
+                    if (value.equals("#")) {
+                        scoreItems.add(new ScoreItem(false));
+                    } else {
+                        ScoreItem item = ScoreItem.parse(value, false);
+                        if (item != null) {
+                            scoreItems.add(item);
+                        }
+                    }
+                }
+                if (list.endsWith(",")) {
+                    scoreItems.add(new ScoreItem(false));
+                }
+            } catch (Exception e) {
+            }
+        }
+        return scoreItems;
+    }
+
+}

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

@@ -110,6 +110,11 @@ public class Task implements Serializable {
      */
     private String rejectReason;
 
+    /**
+     * 打回上次分数
+     */
+    private String rejectScoreList;
+
     /**
      * 评卷员登录名
      */
@@ -309,4 +314,12 @@ public class Task implements Serializable {
         this.rejectReason = rejectReason;
     }
 
+    public String getRejectScoreList() {
+        return rejectScoreList;
+    }
+
+    public void setRejectScoreList(String rejectScoreList) {
+        this.rejectScoreList = rejectScoreList;
+    }
+
 }

+ 116 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/RejectHistorySearchQuery.java

@@ -0,0 +1,116 @@
+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.RejectHistory;
+import cn.com.qmth.stmms.common.enums.HistoryStatus;
+
+public class RejectHistorySearchQuery extends BaseQuery<RejectHistory> {
+
+    private int examId;
+
+    private String subjectCode;
+
+    private Integer studentId;
+
+    private Integer libraryId;
+
+    private String examNumber;
+
+    private String secretNumber;
+
+    private int groupNumber;
+
+    private HistoryStatus status;
+
+    private int userId;
+
+    private String subjectCodeIn;
+
+    public void orderByIdDesc() {
+        setSort(new Sort(Direction.DESC, "id"));
+    }
+
+    public int getExamId() {
+        return examId;
+    }
+
+    public void setExamId(int 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 Integer getLibraryId() {
+        return libraryId;
+    }
+
+    public void setLibraryId(Integer libraryId) {
+        this.libraryId = libraryId;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public HistoryStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(HistoryStatus status) {
+        this.status = status;
+    }
+
+    public int getUserId() {
+        return userId;
+    }
+
+    public void setUserId(int userId) {
+        this.userId = userId;
+    }
+
+    public int getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(int groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+
+    public String getSubjectCodeIn() {
+        return subjectCodeIn;
+    }
+
+    public void setSubjectCodeIn(String subjectCodeIn) {
+        this.subjectCodeIn = subjectCodeIn;
+    }
+
+}

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

@@ -41,11 +41,13 @@ import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
 import cn.com.qmth.stmms.biz.exam.service.InspectHistoryService;
 import cn.com.qmth.stmms.biz.exam.service.MarkerService;
 import cn.com.qmth.stmms.biz.exam.service.SelectiveGroupService;
+import cn.com.qmth.stmms.biz.exam.service.SubjectiveScoreService;
 import cn.com.qmth.stmms.biz.mark.dao.ArbitrateHistoryDao;
 import cn.com.qmth.stmms.biz.mark.dao.MarkLibraryDao;
 import cn.com.qmth.stmms.biz.mark.dao.MarkSpecialTagDao;
 import cn.com.qmth.stmms.biz.mark.dao.MarkTrackDao;
 import cn.com.qmth.stmms.biz.mark.dao.ProblemHistoryDao;
+import cn.com.qmth.stmms.biz.mark.dao.RejectHistoryDao;
 import cn.com.qmth.stmms.biz.mark.dao.TrialLibraryDao;
 import cn.com.qmth.stmms.biz.mark.dao.TrialTagDao;
 import cn.com.qmth.stmms.biz.mark.dao.TrialTrackDao;
@@ -55,6 +57,7 @@ import cn.com.qmth.stmms.biz.mark.model.MarkResult;
 import cn.com.qmth.stmms.biz.mark.model.MarkStepDTO;
 import cn.com.qmth.stmms.biz.mark.model.MarkTrack;
 import cn.com.qmth.stmms.biz.mark.model.ProblemHistory;
+import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
 import cn.com.qmth.stmms.biz.mark.model.SubmitResult;
 import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
@@ -143,6 +146,12 @@ public class MarkServiceImpl implements MarkService {
     @Autowired
     private InspectHistoryService inspectHistoryService;
 
+    @Autowired
+    private RejectHistoryDao rejectHistoryDao;
+
+    @Autowired
+    private SubjectiveScoreService scoreService;
+
     private Map<Integer, Long> markerLastUpdateTime = new ConcurrentHashMap<>();
 
     /**
@@ -264,6 +273,8 @@ public class MarkServiceImpl implements MarkService {
                 group.getNumber());
         problemHistoryDao.deleteByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
                 group.getNumber());
+        rejectHistoryDao.deleteByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
+                group.getNumber());
         libraryDao.deleteByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
                 group.getNumber());
         // 评卷员数据
@@ -289,7 +300,8 @@ public class MarkServiceImpl implements MarkService {
         if (groupCount == 0 || unGroupQuestionCount > 0) {
             studentService.updateSubjectiveStatusAndScoreAndInspectorId(group.getExamId(), group.getSubjectCode(),
                     SubjectiveStatus.UNMARK, 0, null, null, null);
-            //studentService.resetSubjectiveStatusAndScoreWithoutTrial(group.getExamId(), group.getSubjectCode());
+            // studentService.resetSubjectiveStatusAndScoreWithoutTrial(group.getExamId(),
+            // group.getSubjectCode());
             inspectHistoryService.deleteByExamIdAndSubjectCode(group.getExamId(), group.getSubjectCode());
         } else {
             List<Integer> studentList = studentService.findIdByExamIdAndSubjectCodeAndSubjectiveStatus(
@@ -496,7 +508,8 @@ public class MarkServiceImpl implements MarkService {
             for (MarkLibrary library : list) {
                 trackDao.deleteByLibraryId(library.getId());
                 specialTagDao.deleteByLibraryId(library.getId());
-                libraryDao.resetById(library.getId(), null, null, LibraryStatus.WAITING, library.getStatus());
+                libraryDao.resetById(library.getId(), null, null, null, null, LibraryStatus.WAITING,
+                        library.getStatus());
                 updateStudentGroupStatus(library.getStudentId(), library.getExamId(), library.getSubjectCode(),
                         library.getGroupNumber(), SubjectiveStatus.UNMARK);
                 studentService.updateSubjectiveStatusAndScore(library.getStudentId(), SubjectiveStatus.UNMARK, 0, null);
@@ -537,6 +550,8 @@ public class MarkServiceImpl implements MarkService {
         updateAllCount(student.getExamId(), student.getSubjectCode());
         // 复核记录
         inspectHistoryService.deleteByStudentId(student.getId());
+        // 打回记录
+        rejectHistoryDao.deleteByStudentId(student.getId());
     }
 
     /**
@@ -599,7 +614,7 @@ public class MarkServiceImpl implements MarkService {
                     return SubmitResult.faile();
                 }
                 library.setMarkerId(marker.getId());
-                library.setMarkerTime(new Date());
+                library.setMarkerTime(now);
                 // 未选做
                 if (result.isUnselective() && group.isSelective()) {
                     result.setMarkerScore(UN_SELECTIVE_SCORE);
@@ -683,8 +698,8 @@ public class MarkServiceImpl implements MarkService {
         // 尝试提交评卷结果
         Date now = new Date();
         if (libraryDao.updateMarkerResult(library.getId(), LibraryStatus.MARKED, marker.getId(),
-                result.getMarkerScore(), result.getScoreList(), now, result.getSpent(), null, LibraryStatus.WAITING,
-                LibraryStatus.MARKED, LibraryStatus.INSPECTED, LibraryStatus.REJECTED) == 0) {
+                result.getMarkerScore(), result.getScoreList(), now, result.getSpent(), null, null, null,
+                LibraryStatus.WAITING, LibraryStatus.MARKED, LibraryStatus.INSPECTED, LibraryStatus.REJECTED) == 0) {
             // 条件不符更新失败,直接返回
             return false;
         }
@@ -827,18 +842,22 @@ public class MarkServiceImpl implements MarkService {
         if (group.getStatus() == MarkStatus.FINISH) {
             return false;
         }
-        if (libraryDao.resetById(library.getId(), null, reason,
-                isRest ? LibraryStatus.WAITING : LibraryStatus.REJECTED, LibraryStatus.MARKED, LibraryStatus.PROBLEM,
-                LibraryStatus.INSPECTED) > 0) {
+        RejectHistory history = new RejectHistory(library);
+        history.setUserId(userId);
+        history.setReason(reason);
+        Date now = new Date();
+        if (libraryDao.resetById(library.getId(), null, reason, userId, now, isRest ? LibraryStatus.WAITING
+                : LibraryStatus.REJECTED, LibraryStatus.MARKED, LibraryStatus.PROBLEM, LibraryStatus.INSPECTED) > 0) {
             if (!isRest) {
                 markerService.updateRejectCountById(library.getMarkerId());
+                rejectHistoryDao.save(history);
             }
             trackDao.deleteByLibraryId(library.getId());
             specialTagDao.deleteByLibraryId(library.getId());
+            scoreDao.updateRejected(library.getStudentId(), library.getGroupNumber(), true);
             resetStudentGroup(library.getStudentId(), library.getExamId(), library.getSubjectCode(),
                     library.getGroupNumber());
-            problemHistoryDao.resetByLibraryId(library.getId(), HistoryStatus.WAITING, userId, HistoryStatus.BACK,
-                    new Date());
+            problemHistoryDao.resetByLibraryId(library.getId(), HistoryStatus.WAITING, userId, HistoryStatus.BACK, now);
             // 开启三评时,打回1,2任务则删除第3条任务
             long count = libraryDao.countByStudentIdAndGroupNumber(library.getStudentId(), library.getGroupNumber());
             if (library.getTaskNumber() != 3 && count == 3) {
@@ -1512,7 +1531,7 @@ public class MarkServiceImpl implements MarkService {
      */
     private void resetStudentGroup(Integer studentId, Integer examId, String subjectCode, Integer groupNumber) {
         updateStudentGroupStatus(studentId, examId, subjectCode, groupNumber, SubjectiveStatus.UNMARK);
-        scoreDao.deleteByStudentIdAndGroupNumber(studentId, groupNumber);
+        // scoreDao.deleteByStudentIdAndGroupNumber(studentId, groupNumber);
         studentService.updateSubjectiveStatusAndScore(studentId, SubjectiveStatus.UNMARK, 0, null);
     }
 
@@ -1527,6 +1546,7 @@ public class MarkServiceImpl implements MarkService {
         groupStudentDao.updateStatusByExamIdAndSubjectCodeAndGroupNumber(examId, subjectCode, groupNumber,
                 SubjectiveStatus.UNMARK);
         scoreDao.deleteByExamIdAndSubjectCodeAndGroupNumber(examId, subjectCode, groupNumber);
+        rejectHistoryDao.deleteByExamIdAndSubjectCodeAndGroupNumber(examId, subjectCode, groupNumber);
         selectiveStudentDao.deleteByExamIdAndSubjectCode(examId, subjectCode);
         studentService.updateSubjectiveStatusAndScoreAndInspectorId(examId, subjectCode, SubjectiveStatus.UNMARK, 0,
                 null, null, null);
@@ -1549,9 +1569,17 @@ public class MarkServiceImpl implements MarkService {
         // scoreDao.deleteByStudentIdAndGroupNumber(studentId, groupNumber);
         List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
                 subjectCode, false, group.getNumber());
+        List<SubjectiveScore> subjectiveScores = scoreService.findByStudentIdAndGroupNumber(studentId,
+                group.getNumber());
         for (int i = 0; i < questions.size(); i++) {
             ExamQuestion question = questions.get(i);
-            SubjectiveScore ss = new SubjectiveScore();
+            SubjectiveScore ss;
+            if (!subjectiveScores.isEmpty() && subjectiveScores.size() == questions.size()) {
+                ss = subjectiveScores.get(i);
+            } else {
+                ss = new SubjectiveScore();
+                ss.setRejected(false);
+            }
             ss.setStudentId(studentId);
             ss.setExamId(examId);
             ss.setSubjectCode(subjectCode);
@@ -1645,6 +1673,7 @@ public class MarkServiceImpl implements MarkService {
                 return false;
             }
         }
+        Date now = new Date();
         for (Integer groupNumber : map.keySet()) {
             List<MarkLibrary> list = libraryDao.findByStudentIdAndGroupNumber(student.getId(), groupNumber);
             List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(
@@ -1661,11 +1690,17 @@ public class MarkServiceImpl implements MarkService {
                     count++;
                     continue;
                 }
+                RejectHistory history = new RejectHistory(library);
+                history.setUserId(userId);
+                history.setReason(reason);
+
                 if (library.getStatus().equals(LibraryStatus.ARBITRATED) || qList.size() == questions.size()) {
                     // 仲裁任务直接重置 或者该分组下所有分数被打回也重置
                     markerService.updateRejectCountById(library.getMarkerId());
-                    libraryDao.resetById(library.getId(), null, reason, LibraryStatus.REJECTED, LibraryStatus.MARKED,
-                            LibraryStatus.PROBLEM, LibraryStatus.INSPECTED, LibraryStatus.ARBITRATED);
+                    libraryDao.resetById(library.getId(), null, reason, userId, now, LibraryStatus.REJECTED,
+                            LibraryStatus.MARKED, LibraryStatus.PROBLEM, LibraryStatus.INSPECTED,
+                            LibraryStatus.ARBITRATED);
+                    rejectHistoryDao.save(history);
                     trackDao.deleteByLibraryId(library.getId());
                     specialTagDao.deleteByLibraryId(library.getId());
                     arbitrateDao.deleteByStudentIdAndGroupNumber(student.getId(), groupNumber);
@@ -1678,6 +1713,8 @@ public class MarkServiceImpl implements MarkService {
                     for (MarkStepDTO markStepDTO : qList) {
                         trackDao.deleteByLibraryIdAndQuestionNumber(library.getId(), markStepDTO.getMainNumber() + "."
                                 + markStepDTO.getSubNumber());
+                        scoreDao.updateRejected(library.getStudentId(), markStepDTO.getMainNumber(),
+                                markStepDTO.getSubNumber(), true);
                         for (int i = 0; i < questions.size(); i++) {
                             ExamQuestion question = questions.get(i);
                             if (markStepDTO.getMainNumber() == question.getMainNumber()
@@ -1700,9 +1737,11 @@ public class MarkServiceImpl implements MarkService {
                         // }
                     }
                     if (libraryDao.updateMarkerResult(library.getId(), LibraryStatus.REJECTED, library.getMarkerId(),
-                            null, StringUtils.join(markerScoreList, ","), null, null, reason, LibraryStatus.MARKED,
-                            LibraryStatus.INSPECTED) == 1) {
+                            null, StringUtils.join(markerScoreList, ","), null, null, reason, userId, now,
+                            LibraryStatus.MARKED, LibraryStatus.INSPECTED) == 1) {
                         markerService.updateRejectCountById(library.getMarkerId());
+                        history.setRejectScoreList(StringUtils.join(markerScoreList, ","));
+                        rejectHistoryDao.save(history);
                         count++;
                     }
                 }
@@ -1746,7 +1785,8 @@ public class MarkServiceImpl implements MarkService {
                 if (groupCount == 0 || unGroupQuestionCount > 0) {
                     studentService.updateSubjectiveStatusAndScoreAndInspectorId(examId, subjectCode,
                             SubjectiveStatus.UNMARK, 0, null, null, null);
-                    //studentService.resetSubjectiveStatusAndScoreWithoutTrial(examId, subjectCode);
+                    // studentService.resetSubjectiveStatusAndScoreWithoutTrial(examId,
+                    // subjectCode);
                     inspectHistoryService.deleteByExamIdAndSubjectCode(examId, subjectCode);
                 } else {
                     List<Integer> studentList = studentService.findIdByExamIdAndSubjectCodeAndSubjectiveStatus(examId,
@@ -1773,10 +1813,17 @@ public class MarkServiceImpl implements MarkService {
         if (group.getStatus() == MarkStatus.FINISH) {
             return false;
         }
+        RejectHistory history = new RejectHistory(library);
+        history.setUserId(userId);
+        history.setReason(reason);
+
+        Date now = new Date();
         List<ScoreItem> sList = library.getScoreList();
         for (MarkStepDTO markStepDTO : questionList) {
             trackDao.deleteByLibraryIdAndQuestionNumber(library.getId(), markStepDTO.getMainNumber() + "."
                     + markStepDTO.getSubNumber());
+            scoreDao.updateRejected(library.getStudentId(), markStepDTO.getMainNumber(), markStepDTO.getSubNumber(),
+                    true);
             for (int i = 0; i < questions.size(); i++) {
                 ExamQuestion question = questions.get(i);
                 if (markStepDTO.getMainNumber() == question.getMainNumber()
@@ -1799,13 +1846,14 @@ public class MarkServiceImpl implements MarkService {
             // }
         }
         if (libraryDao.updateMarkerResult(library.getId(), LibraryStatus.REJECTED, library.getMarkerId(), null,
-                StringUtils.join(markerScoreList, ","), null, null, reason, LibraryStatus.MARKED,
+                StringUtils.join(markerScoreList, ","), null, null, reason, userId, now, LibraryStatus.MARKED,
                 LibraryStatus.INSPECTED) == 1) {
             markerService.updateRejectCountById(library.getMarkerId());
+            history.setRejectScoreList(StringUtils.join(markerScoreList, ","));
+            rejectHistoryDao.save(history);
             resetStudentGroup(library.getStudentId(), library.getExamId(), library.getSubjectCode(),
                     library.getGroupNumber());
-            problemHistoryDao.resetByLibraryId(library.getId(), HistoryStatus.WAITING, userId, HistoryStatus.BACK,
-                    new Date());
+            problemHistoryDao.resetByLibraryId(library.getId(), HistoryStatus.WAITING, userId, HistoryStatus.BACK, now);
             // 开启三评时,打回1,2任务则删除第3条任务
             long count = libraryDao.countByStudentIdAndGroupNumber(library.getStudentId(), library.getGroupNumber());
             if (library.getTaskNumber() != 3 && count == 3) {

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

@@ -0,0 +1,86 @@
+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 cn.com.qmth.stmms.biz.common.BaseQueryService;
+import cn.com.qmth.stmms.biz.mark.dao.RejectHistoryDao;
+import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
+import cn.com.qmth.stmms.biz.mark.query.RejectHistorySearchQuery;
+import cn.com.qmth.stmms.biz.mark.service.RejectHistoryService;
+
+@Service
+public class RejectHistoryServiceImpl extends BaseQueryService<RejectHistory> implements RejectHistoryService {
+
+    @Autowired
+    private RejectHistoryDao historyDao;
+
+    @Override
+    public RejectHistorySearchQuery findByQuery(final RejectHistorySearchQuery query) {
+        checkQuery(query);
+        Page<RejectHistory> result = historyDao.findAll(buildSpecification(query), query);
+        fillResult(result, query);
+        return query;
+    }
+
+    private Specification<RejectHistory> buildSpecification(final RejectHistorySearchQuery query) {
+        return new Specification<RejectHistory>() {
+
+            @Override
+            public Predicate toPredicate(Root<RejectHistory> 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 (StringUtils.isNotBlank(query.getExamNumber())) {
+                    predicates.add(cb.equal(root.get("examNumber"), query.getExamNumber()));
+                }
+                if (StringUtils.isNotBlank(query.getSecretNumber())) {
+                    predicates.add(cb.equal(root.get("secretNumber"), query.getSecretNumber()));
+                }
+                if (query.getStudentId() != null) {
+                    predicates.add(cb.equal(root.get("studentId"), query.getStudentId()));
+                }
+                if (query.getUserId() > 0) {
+                    predicates.add(cb.equal(root.get("userId"), query.getUserId()));
+                }
+                if (query.getGroupNumber() > 0) {
+                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
+                }
+                if (StringUtils.isNotBlank(query.getSubjectCodeIn())) {
+                    String[] list = query.getSubjectCodeIn().split(",");
+                    if (list.length > 0) {
+                        Predicate[] sub = new Predicate[list.length];
+                        for (int i = 0; i < list.length; i++) {
+                            sub[i] = cb.equal(root.get("subjectCode"), list[i]);
+                        }
+                        predicates.add(cb.or(sub));
+                    }
+                }
+                return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[predicates
+                        .size()]));
+            }
+        };
+    }
+
+    @Override
+    public RejectHistory findLastByLibraryId(Integer libraryId) {
+        List<RejectHistory> list = historyDao.findByLibraryIdOrderByIdDesc(libraryId);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+}

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

@@ -19,6 +19,7 @@ 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.SelectiveGroup;
+import cn.com.qmth.stmms.biz.exam.model.SubjectiveScore;
 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;
@@ -33,6 +34,7 @@ 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;
 import cn.com.qmth.stmms.biz.mark.model.MarkTrack;
+import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
 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;
@@ -43,6 +45,7 @@ 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.biz.mark.service.RejectHistoryService;
 import cn.com.qmth.stmms.biz.mark.service.TaskService;
 import cn.com.qmth.stmms.biz.mark.service.TrialService;
 import cn.com.qmth.stmms.biz.user.service.UserService;
@@ -106,6 +109,9 @@ public class TaskServiceImpl implements TaskService {
     @Autowired
     private SelectiveGroupService selectiveGroupService;
 
+    @Autowired
+    private RejectHistoryService rejectHistoryService;
+
     @Override
     public List<Task> findByQuery(MarkLibrarySearchQuery query) {
         List<Task> list = new LinkedList<Task>();
@@ -197,7 +203,8 @@ public class TaskServiceImpl implements TaskService {
             task.setSheetUrls(fileService.getSheetUris(library.getExamId(), library.getExamNumber(), 1,
                     student.getSheetCount()));
         }
-        task.setQuestionList(buildMarkStep(group, library));
+        RejectHistory rejectHistory = rejectHistoryService.findLastByLibraryId(library.getId());
+        task.setQuestionList(buildMarkStep(group, library, rejectHistory));
         task.setSpecialTagList(getMarkSpecialTagList(library.getId()));
         if (StringUtils.isNotBlank(student.getObjectiveScoreList())) {
             task.setObjectiveScore(student.getObjectiveScore());
@@ -206,6 +213,9 @@ public class TaskServiceImpl implements TaskService {
         if (library.getStatus() == LibraryStatus.REJECTED) {
             task.setRejected(true);
             task.setRejectReason(library.getRejectReason());
+            if (exam.isShowReject()) {
+                task.setRejectScoreList(rejectHistory == null ? null : rejectHistory.getScoreList());
+            }
         }
         if (library.getStatus() == LibraryStatus.MARKED || library.getStatus() == LibraryStatus.INSPECTED) {
             task.setMarkerScore(library.getMarkerScore());
@@ -251,16 +261,20 @@ public class TaskServiceImpl implements TaskService {
         return task;
     }
 
-    private List<MarkStepDTO> buildMarkStep(MarkGroup group, MarkLibrary library) {
+    private List<MarkStepDTO> buildMarkStep(MarkGroup group, MarkLibrary library, RejectHistory rejectHistory) {
         List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
         List<ExamQuestion> sList = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(group.getExamId(),
                 group.getSubjectCode(), false, group.getNumber());
         List<MarkTrack> tracks = new ArrayList<MarkTrack>();
         List<ScoreItem> sItems = new ArrayList<ScoreItem>();
+        List<ScoreItem> rItems = new ArrayList<ScoreItem>();
         if (library != null) {
             tracks = trackService.findByLibraryId(library.getId());
             sItems = library.getScoreList();
         }
+        if (rejectHistory != null) {
+            rItems = rejectHistory.getScoreItems();
+        }
         for (int i = 0; i < sList.size(); i++) {
             ExamQuestion question = sList.get(i);
             MarkStepDTO step = buildStep(question);
@@ -268,6 +282,9 @@ public class TaskServiceImpl implements TaskService {
                 if (!sItems.isEmpty() && sItems.size() == sList.size()) {
                     step.setScore(sItems.get(i).getScore());
                 }
+                if (!rItems.isEmpty() && rItems.size() == sList.size()) {
+                    step.setRejected(rItems.get(i).getScore() == null);
+                }
                 // 未选做
                 if (library.getMarkerScore() != null && library.getMarkerScore() == UN_SELECTIVE_SCORE) {
                     step.setScore(UN_SELECTIVE_SCORE);
@@ -432,18 +449,20 @@ public class TaskServiceImpl implements TaskService {
         for (SelectiveGroup selectiveGroup : selectiveGroups) {
             map.put(selectiveGroup.getMainNumber(), selectiveGroup);
         }
-        List<ScoreItem> sItems = student.getScoreList(false);
-        for (int i = 0; i < sList.size(); i++) {
+        List<SubjectiveScore> scoreList = scoreService.findByStudentId(student.getId());
+        // List<ScoreItem> sItems = student.getScoreList(false);
+        for (int i = 0; i < scoreList.size(); i++) {
             ExamQuestion question = sList.get(i);
             if (map.containsKey(question.getMainNumber())) {
                 question.setSelectiveIndex(map.get(question.getMainNumber()).getSelectiveIndex());
             }
             MarkStepDTO step = buildStep(question);
-            if (!sItems.isEmpty() && sItems.size() == sList.size()) {
-                step.setScore(sItems.get(i).getScore());
+            if (!scoreList.isEmpty() && scoreList.size() == sList.size()) {
+                step.setScore(scoreList.get(i).getScore());
                 if (mainList.contains(step.getMainNumber())) {
                     step.setUncalculate(true);
                 }
+                step.setRejected(scoreList.get(i).getRejected());
             }
             // 增加阅卷轨迹列表获取
             if (trialGroupCount > 0) {

+ 12 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/RejectHistoryService.java

@@ -0,0 +1,12 @@
+package cn.com.qmth.stmms.biz.mark.service;
+
+import cn.com.qmth.stmms.biz.mark.model.RejectHistory;
+import cn.com.qmth.stmms.biz.mark.query.RejectHistorySearchQuery;
+
+public interface RejectHistoryService {
+
+    RejectHistorySearchQuery findByQuery(RejectHistorySearchQuery query);
+
+    RejectHistory findLastByLibraryId(Integer libraryId);
+
+}

+ 129 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/RejectHistoryController.java

@@ -0,0 +1,129 @@
+package cn.com.qmth.stmms.admin.exam;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+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.MarkerSearchQuery;
+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.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.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.RejectHistoryService;
+import cn.com.qmth.stmms.biz.user.model.User;
+import cn.com.qmth.stmms.biz.user.service.UserService;
+import cn.com.qmth.stmms.common.annotation.Logging;
+import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import cn.com.qmth.stmms.common.enums.LogType;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+
+@Controller
+@RequestMapping("/admin/exam/reject")
+public class RejectHistoryController extends BaseExamController {
+
+    protected static Logger log = LoggerFactory.getLogger(RejectHistoryController.class);
+
+    @Autowired
+    private RejectHistoryService historyService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Logging(menu = "打回任务查询", type = LogType.QUERY)
+    @RequestMapping(value = "/list")
+    public String list(Model model, HttpServletRequest request, MarkLibrarySearchQuery query) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        query.setExamId(examId);
+        query.addStatus(LibraryStatus.REJECTED);
+        query = libraryService.findByQuery(query);
+        for (MarkLibrary library : query.getResult()) {
+            if (library.getMarkerId() != null) {
+                Marker marker = markerService.findById(library.getMarkerId());
+                User user = userService.findById(marker.getUserId());
+                library.setMarkerLoginName(user.getLoginName() + "/" + user.getName());
+            }
+            if (library.getHeaderId() != null) {
+                User user = userService.findById(library.getHeaderId());
+                library.setHeaderLoginName(user.getLoginName() + "/" + user.getName());
+            }
+            MarkGroup group = groupService.findOne(examId, library.getSubjectCode(), library.getGroupNumber());
+            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
+                    group.getSubjectCode(), false, group.getNumber()));
+            library.setTitle(group.getTitle());
+        }
+
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", getExamSubject(examId, wu));
+        List<Marker> markerList = new ArrayList<Marker>();
+        if (query.getSubjectCode() != null) {
+            MarkerSearchQuery mQuery = new MarkerSearchQuery();
+            mQuery.setExamId(examId);
+            mQuery.setSubjectCode(query.getSubjectCode());
+            mQuery.setPageSize(Integer.MAX_VALUE);
+            markerList = markerService.findByQuery(mQuery).getResult();
+            for (Marker marker : markerList) {
+                marker.setLoginName(userService.findById(marker.getUserId()).getLoginName());
+            }
+        }
+        model.addAttribute("markerList", markerList);
+        return "modules/exam/rejectList";
+    }
+
+    @Logging(menu = "打回任务查询", type = LogType.QUERY)
+    @RequestMapping(value = "/history")
+    public String history(Model model, HttpServletRequest request, MarkLibrarySearchQuery query) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        query.setExamId(examId);
+        query.addStatus(LibraryStatus.REJECTED);
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", getExamSubject(examId, wu));
+        List<Marker> markerList = new ArrayList<Marker>();
+        if (query.getSubjectCode() != null) {
+            MarkerSearchQuery mQuery = new MarkerSearchQuery();
+            mQuery.setExamId(examId);
+            mQuery.setSubjectCode(query.getSubjectCode());
+            mQuery.setPageSize(Integer.MAX_VALUE);
+            markerList = markerService.findByQuery(mQuery).getResult();
+            for (Marker marker : markerList) {
+                marker.setLoginName(userService.findById(marker.getUserId()).getLoginName());
+            }
+        }
+        model.addAttribute("markerList", markerList);
+        return "modules/exam/rejectList";
+    }
+}

+ 6 - 4
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/examIndex.jsp

@@ -133,9 +133,10 @@
                                         <li><a href="${ctx}/admin/exam/paper" target="mainFrame"><i class="icon-book"></i><span data-i18n-text="index.paper">科目管理</span></a></li>
                                         <li><a href="${ctx}/admin/exam/scan" target="mainFrame"><i class="icon-print"></i><span data-i18n-text="index.scan">扫描进度</span></a></li>
                                         <li><a href="${ctx}/admin/exam/mark" target="mainFrame"><i class="icon-pencil"></i><span data-i18n-text="index.mark">评卷管理</span></a></li>
-                                        <li><a href="${ctx}/admin/exam/score" target="mainFrame"><i class="icon-search"></i><span data-i18n-text="index.score">成绩查询</span></a></li>
-                                        <li><a href="${ctx}/admin/exam/inspected/info" target="mainFrame"><i class="icon-flag"></i><span data-i18n-text="index.inspected">成绩复核</span></a></li>
+                                        <li><a href="${ctx}/admin/exam/reject/list" target="mainFrame"><i class="icon-bookmark"></i><span data-i18n-text="index.reject">打回试卷</span></a></li>
                                         <li><a href="${ctx}/admin/exam/problem/history" target="mainFrame"><i class="icon-tag"></i><span data-i18n-text="index.problem">问题试卷</span></a></li>
+                                        <li><a href="${ctx}/admin/exam/inspected/info" target="mainFrame"><i class="icon-flag"></i><span data-i18n-text="index.inspected">成绩复核</span></a></li>
+                                        <li><a href="${ctx}/admin/exam/score" target="mainFrame"><i class="icon-search"></i><span data-i18n-text="index.score">成绩查询</span></a></li>
                                         <li><a href="${ctx}/admin/exam/reportSubject" target="mainFrame"><i class="icon-signal"></i><span data-i18n-text="index.report.total">总量分析</span></a></li>
                                         <li><a href="${ctx}/admin/exam/reportSubjectRange" target="mainFrame"><i class="icon-asterisk"></i><span data-i18n-text="index.report.subject">科目分析</span></a></li>
                                         <li><a href="${ctx}/admin/exam/check/answer" target="mainFrame"><i class="icon-check"></i><span data-i18n-text="index.check">数据检查</span></a></li>
@@ -144,11 +145,12 @@
                                     
                                     <c:if test="${web_user.subjectHeader==true}">
                                         <li><a href="${ctx}/admin/exam/mark" target="mainFrame"><i class="icon-pencil"></i><span data-i18n-text="index.mark">评卷管理</span></a></li>
+                                        <li><a href="${ctx}/admin/exam/reject/list" target="mainFrame"><i class="fa-undo"></i><span data-i18n-text="index.reject">打回试卷</span></a></li>
+                                        <li><a href="${ctx}/admin/exam/problem/history" target="mainFrame"><i class="icon-tag"></i><span data-i18n-text="index.problem">问题试卷</span></a></li>
+                                        <li><a href="${ctx}/admin/exam/inspected/info" target="mainFrame"><i class="icon-flag"></i><span data-i18n-text="index.inspected">成绩复核</span></a></li>
                                         <c:if test="${forbiddenScore!=true}">
                                         <li><a href="${ctx}/admin/exam/score" target="mainFrame"><i class="icon-search"></i><span data-i18n-text="index.score">成绩查询</span></a></li>
                                         </c:if>
-                                        <li><a href="${ctx}/admin/exam/inspected/info" target="mainFrame"><i class="icon-flag"></i><span data-i18n-text="index.inspected">成绩复核</span></a></li>
-                                        <li><a href="${ctx}/admin/exam/problem/history" target="mainFrame"><i class="icon-tag"></i><span data-i18n-text="index.problem">问题试卷</span></a></li>
                                         <li><a href="${ctx}/admin/exam/reportSubject" target="mainFrame"><i class="icon-signal"></i><span data-i18n-text="index.report.total">总量分析</span></a></li>
                                         <li><a href="${ctx}/admin/exam/reportSubjectRange" target="mainFrame"><i class="icon-asterisk"></i><span data-i18n-text="index.report.subject">科目分析</span></a></li>
                                     </c:if>

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

@@ -13,10 +13,12 @@
         color: #0663A2;
         cursor: pointer;
     }
-        .rejectWindow {
-            width: 400px;
+         .rejectWindow {
+            width: 500px;
             min-height: 200px;
             background: #fff;
+          
+            padding-bottom:30px;
             font-family: "微软雅黑", Fixedsys;
             border: #5d6d7d solid 1px;
             position: absolute;
@@ -24,7 +26,13 @@
             top: 50%;
             margin: -150px 0 0 -200px;
             text-align: center;
-            z-index: 99999;
+            z-index: 9999;
+        }
+        .rejectWindow .form-horizontal .control-label{
+        	width:100px;
+        }
+		.rejectWindow .form-horizontal .controls{
+        	margin-left:120px;
         }
         
         .task-header, .password-header {
@@ -32,6 +40,7 @@
             height: 46px;
             background: #5d6d7d;
             color: #fff;
+            margin-bottom:30px;
         }
         
         .task-content, .password-content {
@@ -74,7 +83,7 @@
             color: #f00;
             line-height: 30px;
             padding-left: 20px;
-        }
+        } 
     </style>
 </head>
 <body>
@@ -245,15 +254,38 @@
 	        <p class="title">打回</p>
 	        <p class="image-close"><img src="${ctxStatic}/mark-new/images/images-close.png"/></p></div>
 	        <input id="rejectId" type="hidden"/>
-	    	<div class="task-content">打回原因:	<br/>
+<!-- 	    	<div class="task-content">打回原因:	<br/>
 	    		<input name="rejectReasonSelect" type="radio"  value="给分较高"/>给分较高<br/>
             	<input name="rejectReasonSelect" type="radio"  value="给分较低"/>给分较低<br/>
             	<input name="rejectReasonSelect" type="radio"  value="判分错误"/>判分错误<br/>
             	<input name="rejectReasonSelect" type="radio"  value="其它"/>其它<br/>
 	    		<textarea id="rejectReasonInput" rows="3" maxlength="60" class="input-large"></textarea>
 	    <i class="wrong">
-	    </i></div>
-	    <a href="#" class="btn btn-small btn-info task-btn">确认</a>
+	    </i></div> -->
+	    <form class="form-horizontal">
+            <div class="control-group">
+                <label class="control-label"><span style="color:red;font-size:16px;margin-right:3px">*</span>打回原因</label>
+                <div class="controls">
+                    <select id="rejectReasonSelect" name="rejectReasonSelect">
+                        <option value = '给分较高'>给分较高</option>
+                        <option value = '给分较低'>给分较低</option>
+                        <option value = '判分错误'>判分错误</option>
+                        <option value = '其他'>其他</option>
+                    </select>
+                </div>
+            </div>
+            <div class="control-group">
+                <label class="control-label">详情描述</label>
+                <div class="controls">
+                    <textarea rows="3" id="rejectReasonInput" maxlength="60"></textarea>
+                </div>
+            </div>
+            <div style="text-align:center;">
+                <a class="btn btn-primary task-btn">打回</a>
+                &nbsp;
+                <a class="btn task-cancel">取消</a>
+            </div>
+        </form>
 	</div>
 <div class="pagination">${query}</div>
 <%@include file="/WEB-INF/views/include/trackView.jsp" %>
@@ -360,8 +392,11 @@
     $('.image-close').click(function () {
         $('.rejectWindow').hide();
     });
+    $('.task-cancel').click(function () {
+        $('.rejectWindow').hide();
+    });
     $('.task-btn').click(function () {
-        var rejectReason =$("input[name='rejectReasonSelect']:checked").val();
+        var rejectReason =$("#rejectReasonSelect").val();
         var rejectReasonInput = $('#rejectReasonInput').val();
         var rejectId=$("#rejectId").val();
         if(rejectReason==""||rejectReason==undefined){

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

@@ -0,0 +1,148 @@
+<%@ 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/reject/list">打回卷</a></li>
+    <li class="active"><a href="##">打回记录</a></li>
+</ul>
+<form id="searchForm" action="${ctx}/admin/exam/reject/history" 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" name="subjectCode" id="subject-select">
+            <option value="">请选择</option>
+            <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 class="input-medium" id="group-select" name="groupNumber">
+            <option value="0">请选择</option>
+            <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="reason-select" name="rejectReason">
+            <option value="">不限</option>
+            <option value="给分较高" <c:if test="${query.rejectReason=='给分较高'}">selected</c:if>>给分较高</option>
+            <option value="给分较低" <c:if test="${query.rejectReason=='给分较低'}">selected</c:if>>给分较低</option>
+            <option value="判分错误" <c:if test="${query.rejectReason=='判分错误'}">selected</c:if>>判分错误</option>
+            <option value="其它" <c:if test="${query.rejectReason=='其它'}">selected</c:if>>其它</option>
+        </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>
+        <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>
+        &nbsp;
+        <input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+    </div>
+</form>
+<tags:message content="${message}"/>
+<form id="restForm" action="${ctx}/admin/exam/problem/history/restBatch" method="post" class="breadcrumb form-search">
+<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="${resultList}" var="result">
+        <tr>
+            <td>${result.subjectCode}-${result.subjectName}</td>
+            <td>${result.number}</td>
+            <td>
+            	<c:if test="${web_user.subjectHeader==true && forbiddenInfo==true}">
+	            ***
+	            </c:if>
+	            <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
+	            ${result.examNumber}
+	            </c:if>
+            </td>
+            <td>${result.secretNumber}</td>
+            <td>${result.markLogin}</td>
+            <td>${result.problemUserName}</td>
+            <td>${result.problemRestTime}</td>
+        </tr>
+    </c:forEach>
+    </tbody>
+</table>
+</form>
+<div class="pagination">${query}</div>
+<%@include file="/WEB-INF/views/include/trackView.jsp" %>
+<script type="text/javascript">
+    $(document).ready(function () {
+        $('.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();
+            $("<option value='0'>请选择</option>").appendTo('#group-select');
+            if (code == '') {
+                $('#group-select').val('').trigger('change');
+                return;
+            }
+
+            $.post('${ctx}/admin/exam/group/query', {subjectCode: code, status: 'FORMAL'}, 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").attr('action', '${ctx}/admin/exam/reject/history');
+        $("#searchForm").submit();
+        return false;
+    }
+
+    function goSearch() {
+        $("#pageNumber").val(1);
+        $("#pageSize").val('${query.pageSize}');
+        $("#searchForm").attr('action', '${ctx}/admin/exam/reject/history');
+        $("#searchForm").submit();
+        return false;
+    }
+</script>
+</body>
+</html>

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

@@ -0,0 +1,171 @@
+<%@ 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 class="active"><a href="##">打回卷</a></li>
+    <li><a href="${ctx}/admin/exam/reject/history">打回记录</a></li>
+</ul>
+<form id="searchForm" action="${ctx}/admin/exam/reject/list" 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" name="subjectCode" id="subject-select">
+            <option value="">请选择</option>
+            <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 class="input-medium" id="group-select" name="groupNumber">
+            <option value="0">请选择</option>
+            <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="reason-select" name="rejectReason">
+            <option value="">不限</option>
+            <option value="给分较高" <c:if test="${query.rejectReason=='给分较高'}">selected</c:if>>给分较高</option>
+            <option value="给分较低" <c:if test="${query.rejectReason=='给分较低'}">selected</c:if>>给分较低</option>
+            <option value="判分错误" <c:if test="${query.rejectReason=='判分错误'}">selected</c:if>>判分错误</option>
+            <option value="其它" <c:if test="${query.rejectReason=='其它'}">selected</c:if>>其它</option>
+        </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>
+        <label>打回人</label>
+        <select class="input-medium" id="rejecter-select" name="rejecterId">
+            <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>
+        &nbsp;
+        <input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+    </div>
+</form>
+<tags:message content="${message}"/>
+<form id="restForm" action="${ctx}/admin/exam/problem/history/restBatch" method="post" class="breadcrumb form-search">
+<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="${resultList}" var="result">
+        <tr>
+            <td>${result.subjectCode}-${result.subjectName}</td>
+            <td>${result.groupNumber}-${result.title}</td>
+            <td>
+            	<c:if test="${web_user.subjectHeader==true && forbiddenInfo==true}">
+	            ***
+	            </c:if>
+	            <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
+	            ${result.examNumber}
+	            </c:if>
+            </td>
+            <td>${result.secretNumber}</td>
+            <td>${result.rejectReason}</td>
+            <td>${result.markerLoginName}</td>
+            <td>${result.markerScoreList}</td>
+            <td>${result.headerLoginName}</td>
+            <td>${result.headerTime}</td>
+            <td>
+               	<a href="${ctx}/web/admin/exam/track/library?libraryId=${result.libraryId}&subjectCode=${result.subjectCode}" target="_blank">试卷详情</a>
+            </td>
+        </tr>
+    </c:forEach>
+    </tbody>
+</table>
+</form>
+<div class="pagination">${query}</div>
+<%@include file="/WEB-INF/views/include/trackView.jsp" %>
+<script type="text/javascript">
+    $(document).ready(function () {
+        $('.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();
+            $("<option value='0'>请选择</option>").appendTo('#group-select');
+            if (code == '') {
+                $('#group-select').val('').trigger('change');
+                return;
+            }
+
+            $.post('${ctx}/admin/exam/group/query', {subjectCode: code, status: 'FORMAL'}, 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');
+            });
+            
+            $('#marker-select').empty();
+            $('#marker-select').append('<option value="0">不限</option>');
+            $('#marker-select').val('0').trigger('change');
+            var subjectCode = $('#subject-select').val();
+            $.post('${ctx}/admin/exam/marker/query', {subjectCode: subjectCode}, 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;
+                    }
+                }
+            });
+        });
+    });
+
+    function page(n, s) {
+        $("#pageNumber").val(n);
+        $("#pageSize").val(s);
+        $("#searchForm").attr('action', '${ctx}/admin/exam/reject/list');
+        $("#searchForm").submit();
+        return false;
+    }
+
+    function goSearch() {
+        $("#pageNumber").val(1);
+        $("#pageSize").val('${query.pageSize}');
+        $("#searchForm").attr('action', '${ctx}/admin/exam/reject/list');
+        $("#searchForm").submit();
+        return false;
+    }
+</script>
+</body>
+</html>

+ 1 - 0
stmms-web/src/main/webapp/sql/stmms_ft.sql

@@ -224,6 +224,7 @@ CREATE TABLE `eb_exam`
 	`scan_config`       text         DEFAULT NULL COMMENT '扫描配置',
     `auto_scroll`   	tinyint(1) 		NOT NULL COMMENT '评卷提交自动定位',
 	`enable_split`   	tinyint(1)  	NOT NULL COMMENT '自动对切题卡',
+	`show_reject`   	tinyint(1)  	NOT NULL COMMENT '显示打回前原分值',
     PRIMARY KEY (`id`),
     UNIQUE KEY `index1` (`school_id`, `code`)
 ) ENGINE = InnoDB

+ 3 - 0
stmms-web/src/main/webapp/sql/upgrade/1.3.12.sql

@@ -13,6 +13,9 @@ ALTER TABLE eb_subjective_score ADD COLUMN `rejected`	tinyint (1) NOT NULL COMME
 ALTER TABLE b_user ADD COLUMN `empno` 			varchar(128) DEFAULT NULL COMMENT '工号';
 ALTER TABLE b_user ADD COLUMN `random_password` varchar(64)  DEFAULT NULL COMMENT '随机密码';
 
+-- 新增eb_exam字段
+ALTER TABLE eb_exam ADD COLUMN `show_reject`   	tinyint(1)  	NOT NULL COMMENT '显示打回前原分值';
+
 -- 新增eb_user_exam用户考试关联表
 CREATE TABLE `eb_user_exam`
 (

+ 1 - 0
stmms-web/src/main/webapp/static/i18n/messages.properties

@@ -156,6 +156,7 @@ index.student=\u8003\u751f\u7ba1\u7406
 index.paper=\u79d1\u76ee\u7ba1\u7406
 index.scan=\u626b\u63cf\u8fdb\u5ea6
 index.mark=\u8bc4\u5377\u7ba1\u7406
+index.reject=\u6253\u56de\u8bd5\u5377
 index.score=\u6210\u7ee9\u67e5\u8be2
 index.problem=\u95ee\u9898\u8bd5\u5377
 index.inspected=\u6210\u7ee9\u590d\u6838

+ 1 - 0
stmms-web/src/main/webapp/static/i18n/messages_en.properties

@@ -157,6 +157,7 @@ index.paper=Subject
 index.scan=Scan Progress
 index.mark=Mark
 index.score=Score
+index.reject=Reject Paper
 index.inspected=Score inspected
 index.problem=Problem Paper
 index.report.total=Total analysis

+ 1 - 0
stmms-web/src/main/webapp/static/i18n/messages_ja.properties

@@ -156,6 +156,7 @@ index.student=\u53d7\u9a13\u751f\u7ba1\u7406
 index.paper=\u79d1\u76ee\u7ba1\u7406
 index.scan=\u30b9\u30ad\u30e3\u30f3\u9032\u5ea6
 index.mark=\u30de\u30fc\u30ad\u30f3\u30b0\u7ba1\u7406
+index.reject=\u8fd4\u9001\u3042\u308b\u8a66\u9a13\u7528\u7d19
 index.score=\u6210\u7e3e\u30af\u30a8\u30ea\u30fc
 index.inspected=\u6210\u7e3e\u590d\u6838
 index.problem=\u554f\u984c\u3042\u308b\u8a66\u9a13\u7528\u7d19

+ 1 - 0
stmms-web/src/main/webapp/static/i18n/messages_zh.properties

@@ -156,6 +156,7 @@ index.student=\u8003\u751f\u7ba1\u7406
 index.paper=\u79d1\u76ee\u7ba1\u7406
 index.scan=\u626b\u63cf\u8fdb\u5ea6
 index.mark=\u8bc4\u5377\u7ba1\u7406
+index.reject=\u6253\u56de\u8bd5\u5377
 index.score=\u6210\u7ee9\u67e5\u8be2
 index.inspected=\u6210\u7ee9\u590d\u6838
 index.problem=\u95ee\u9898\u8bd5\u5377

BIN
stmms-web/src/main/webapp/static/images/emono-on.png


BIN
stmms-web/src/main/webapp/static/images/empno-on@2x.png


BIN
stmms-web/src/main/webapp/static/images/empno.png


BIN
stmms-web/src/main/webapp/static/images/empno@2x.png