1
0
xiatian 21 hodín pred
rodič
commit
8388e5f93e

+ 49 - 33
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/basic/bean/RolePrivilegeDomain.java

@@ -1,33 +1,49 @@
-package cn.com.qmth.stmms.biz.basic.bean;
-
-public class RolePrivilegeDomain {
-	private String role;
-	private Integer schoolId;
-	private String selectPrivileges;
-	private Integer userId;
-	public String getRole() {
-		return role;
-	}
-	public void setRole(String role) {
-		this.role = role;
-	}
-	public Integer getSchoolId() {
-		return schoolId;
-	}
-	public void setSchoolId(Integer schoolId) {
-		this.schoolId = schoolId;
-	}
-	public String getSelectPrivileges() {
-		return selectPrivileges;
-	}
-	public void setSelectPrivileges(String selectPrivileges) {
-		this.selectPrivileges = selectPrivileges;
-	}
-	public Integer getUserId() {
-		return userId;
-	}
-	public void setUserId(Integer userId) {
-		this.userId = userId;
-	}
-	
-}
+package cn.com.qmth.stmms.biz.basic.bean;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class RolePrivilegeDomain {
+
+    @ApiModelProperty("校色code")
+    private String role;
+
+    private Integer schoolId;
+
+    @ApiModelProperty("勾选的权限code,逗号分隔")
+    private String selectPrivileges;
+
+    private Integer userId;
+
+    public String getRole() {
+        return role;
+    }
+
+    public void setRole(String role) {
+        this.role = role;
+    }
+
+    public Integer getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Integer schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getSelectPrivileges() {
+        return selectPrivileges;
+    }
+
+    public void setSelectPrivileges(String selectPrivileges) {
+        this.selectPrivileges = selectPrivileges;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+}

+ 24 - 7
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/common/BaseQuery.java

@@ -1,9 +1,11 @@
 package cn.com.qmth.stmms.biz.common;
 package cn.com.qmth.stmms.biz.common;
 
 
+import java.util.List;
+
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.domain.Sort;
 
 
-import java.util.List;
+import io.swagger.annotations.ApiModelProperty;
 
 
 public class BaseQuery<T> implements Pageable {
 public class BaseQuery<T> implements Pageable {
 
 
@@ -13,34 +15,49 @@ public class BaseQuery<T> implements Pageable {
 
 
     private int pageSize = 20;
     private int pageSize = 20;
 
 
+    @ApiModelProperty(hidden = true)
     private Sort sort;
     private Sort sort;
 
 
+    @ApiModelProperty(hidden = true)
     private List<T> result;
     private List<T> result;
 
 
+    @ApiModelProperty(hidden = true)
     private long currentCount;
     private long currentCount;
 
 
+    @ApiModelProperty(hidden = true)
     private int totalPage;
     private int totalPage;
 
 
+    @ApiModelProperty(hidden = true)
     private long totalCount;
     private long totalCount;
 
 
+    @ApiModelProperty(hidden = true)
     private int first;// 首页索引
     private int first;// 首页索引
 
 
+    @ApiModelProperty(hidden = true)
     private int last;// 尾页索引
     private int last;// 尾页索引
 
 
+    @ApiModelProperty(hidden = true)
     private int prev;// 上一页索引
     private int prev;// 上一页索引
 
 
+    @ApiModelProperty(hidden = true)
     private int next;// 下一页索引
     private int next;// 下一页索引
 
 
+    @ApiModelProperty(hidden = true)
     private boolean firstPage;// 是否是第一页
     private boolean firstPage;// 是否是第一页
 
 
+    @ApiModelProperty(hidden = true)
     private boolean lastPage;// 是否是最后一页
     private boolean lastPage;// 是否是最后一页
 
 
+    @ApiModelProperty(hidden = true)
     private int length = 8;// 显示页面长度
     private int length = 8;// 显示页面长度
 
 
+    @ApiModelProperty(hidden = true)
     private int slider = 1;// 前后显示页面长度
     private int slider = 1;// 前后显示页面长度
 
 
+    @ApiModelProperty(hidden = true)
     private String funcName = "page"; // 设置点击页码调用的js函数名称,默认为page,在一页有多个分页对象时使用。
     private String funcName = "page"; // 设置点击页码调用的js函数名称,默认为page,在一页有多个分页对象时使用。
 
 
+    @ApiModelProperty(hidden = true)
     private String message = ""; // 设置提示消息,显示在“共n条”之后
     private String message = ""; // 设置提示消息,显示在“共n条”之后
 
 
     public BaseQuery() {
     public BaseQuery() {
@@ -224,8 +241,8 @@ public class BaseQuery<T> implements Pageable {
         if (begin > first) {
         if (begin > first) {
             int i = 0;
             int i = 0;
             for (i = first; i < first + slider && i < begin; i++) {
             for (i = first; i < first + slider && i < begin; i++) {
-                sb.append("<li><a href=\"javascript:\" onclick=\"" + funcName + "(" + i + "," + pageSize + ");\">" + (
-                        i + 1 - first) + "</a></li>\n");
+                sb.append("<li><a href=\"javascript:\" onclick=\"" + funcName + "(" + i + "," + pageSize + ");\">"
+                        + (i + 1 - first) + "</a></li>\n");
             }
             }
             if (i < begin) {
             if (i < begin) {
                 sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
                 sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
@@ -236,8 +253,8 @@ public class BaseQuery<T> implements Pageable {
             if (i == pageNumber) {
             if (i == pageNumber) {
                 sb.append("<li class=\"active\"><a href=\"javascript:\">" + (i + 1 - first) + "</a></li>\n");
                 sb.append("<li class=\"active\"><a href=\"javascript:\">" + (i + 1 - first) + "</a></li>\n");
             } else {
             } else {
-                sb.append("<li><a href=\"javascript:\" onclick=\"" + funcName + "(" + i + "," + pageSize + ");\">" + (
-                        i + 1 - first) + "</a></li>\n");
+                sb.append("<li><a href=\"javascript:\" onclick=\"" + funcName + "(" + i + "," + pageSize + ");\">"
+                        + (i + 1 - first) + "</a></li>\n");
             }
             }
         }
         }
 
 
@@ -247,8 +264,8 @@ public class BaseQuery<T> implements Pageable {
         }
         }
 
 
         for (int i = end + 1; i <= last; i++) {
         for (int i = end + 1; i <= last; i++) {
-            sb.append("<li><a href=\"javascript:\" onclick=\"" + funcName + "(" + i + "," + pageSize + ");\">" + (i + 1
-                    - first) + "</a></li>\n");
+            sb.append("<li><a href=\"javascript:\" onclick=\"" + funcName + "(" + i + "," + pageSize + ");\">"
+                    + (i + 1 - first) + "</a></li>\n");
         }
         }
 
 
         if (pageNumber == last) {
         if (pageNumber == last) {

+ 6 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/ExamVo.java

@@ -476,6 +476,9 @@ public class ExamVo {
     }
     }
 
 
     public static ExamVo of(Exam from) {
     public static ExamVo of(Exam from) {
+        if (from == null) {
+            return null;
+        }
         ExamVo ret = new ExamVo();
         ExamVo ret = new ExamVo();
         ret.setId(from.getId());
         ret.setId(from.getId());
         ret.setName(from.getName());
         ret.setName(from.getName());
@@ -516,6 +519,9 @@ public class ExamVo {
     }
     }
 
 
     public static Exam of(ExamVo from) {
     public static Exam of(ExamVo from) {
+        if (from == null) {
+            return null;
+        }
         Exam ret = new Exam();
         Exam ret = new Exam();
         ret.setId(from.getId());
         ret.setId(from.getId());
         ret.setName(from.getName());
         ret.setName(from.getName());

+ 25 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/LibraryStatusInfo.java

@@ -0,0 +1,25 @@
+package cn.com.qmth.stmms.biz.exam.bean;
+
+public class LibraryStatusInfo {
+
+    private Long totalCount;
+
+    private Boolean valid;
+
+    public Long getTotalCount() {
+        return totalCount;
+    }
+
+    public void setTotalCount(Long totalCount) {
+        this.totalCount = totalCount;
+    }
+
+    public Boolean getValid() {
+        return valid;
+    }
+
+    public void setValid(Boolean valid) {
+        this.valid = valid;
+    }
+
+}

+ 362 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/MarkLibraryVo.java

@@ -0,0 +1,362 @@
+package cn.com.qmth.stmms.biz.exam.bean;
+
+import java.util.Date;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import io.swagger.annotations.ApiModelProperty;
+
+public class MarkLibraryVo {
+
+    @ApiModelProperty("任务id")
+    private Integer id;
+
+    /**
+     * 考试ID
+     */
+    @ApiModelProperty("考试ID")
+    private Integer examId;
+
+    /**
+     * 科目CODE
+     */
+    @ApiModelProperty("科目CODE")
+    private String subjectCode;
+
+    /**
+     * 大题序号
+     */
+    @ApiModelProperty("分组号")
+    private Integer groupNumber;
+
+    /**
+     * 考生编号
+     */
+    @ApiModelProperty("考生id")
+    private Integer studentId;
+
+    /**
+     * 准考证号
+     */
+    @ApiModelProperty("准考证号")
+    private String examNumber;
+
+    /**
+     * 考生密号
+     */
+    @ApiModelProperty("考生密号")
+    private String secretNumber;
+
+    /**
+     * 多评任务编号,单评时为1
+     */
+    @ApiModelProperty("多评任务编号,单评时为1")
+    private Integer taskNumber;
+
+    /**
+     * 任务状态
+     */
+    @ApiModelProperty("任务状态")
+    private LibraryStatus status;
+
+    /**
+     * 评卷员
+     */
+    @ApiModelProperty("评卷员id")
+    private Integer markerId;
+
+    /**
+     * 评卷时间
+     */
+    @ApiModelProperty("评卷时间")
+    private Date markerTime;
+
+    /**
+     * 评卷员给分总分
+     */
+    @ApiModelProperty("评卷员给分总分")
+    private Double markerScore;
+
+    /**
+     * 评卷员给分明细
+     */
+    @ApiModelProperty("评卷员给分明细")
+    private String markerScoreList;
+
+    /**
+     * 评卷时长
+     */
+    @ApiModelProperty("评卷时长")
+    private Integer markerSpent;
+
+    /**
+     * 科组长
+     */
+    @ApiModelProperty("科组长id")
+    private Integer headerId;
+
+    /**
+     * 科组长评卷时间
+     */
+    @ApiModelProperty("科组长评卷时间")
+    private Date headerTime;
+
+    /**
+     * 科组长给分总分
+     */
+    @ApiModelProperty("科组长给分总分")
+    private Double headerScore;
+
+    /**
+     * 科组长给分明细
+     */
+    @ApiModelProperty("科组长给分明细")
+    private String headerScoreList;
+
+    /**
+     * 未作答的步骤数量
+     */
+    @ApiModelProperty("未作答的步骤数量")
+    private Integer unansweredCount;
+
+    @ApiModelProperty("打回原因")
+    private String rejectReason;
+
+    @ApiModelProperty("评卷员登录名")
+    private String markerLoginName;
+
+    @ApiModelProperty("分组名")
+    private String title;
+
+    @ApiModelProperty("科组长登录名")
+    private String headerLoginName;
+
+    @ApiModelProperty("科目信息")
+    private ExamSubject subject;
+
+    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 String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public Integer getTaskNumber() {
+        return taskNumber;
+    }
+
+    public void setTaskNumber(Integer taskNumber) {
+        this.taskNumber = taskNumber;
+    }
+
+    public LibraryStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(LibraryStatus status) {
+        this.status = status;
+    }
+
+    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 Integer getMarkerSpent() {
+        return markerSpent;
+    }
+
+    public void setMarkerSpent(Integer markerSpent) {
+        this.markerSpent = markerSpent;
+    }
+
+    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 getUnansweredCount() {
+        return unansweredCount;
+    }
+
+    public void setUnansweredCount(Integer unansweredCount) {
+        this.unansweredCount = unansweredCount;
+    }
+
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
+    public String getMarkerLoginName() {
+        return markerLoginName;
+    }
+
+    public void setMarkerLoginName(String markerLoginName) {
+        this.markerLoginName = markerLoginName;
+    }
+
+    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;
+    }
+
+    public ExamSubject getSubject() {
+        return subject;
+    }
+
+    public void setSubject(ExamSubject subject) {
+        this.subject = subject;
+    }
+
+    public static MarkLibraryVo of(MarkLibrary from) {
+        if (from == null) {
+            return null;
+        }
+        MarkLibraryVo ret = new MarkLibraryVo();
+        ret.setId(from.getId());
+        ret.setExamId(from.getExamId());
+        ret.setSubjectCode(from.getSubjectCode());
+        ret.setGroupNumber(from.getGroupNumber());
+        ret.setStudentId(from.getStudentId());
+        ret.setExamNumber(from.getExamNumber());
+        ret.setSecretNumber(from.getSecretNumber());
+        ret.setTaskNumber(from.getTaskNumber());
+        ret.setStatus(from.getStatus());
+        ret.setMarkerId(from.getMarkerId());
+        ret.setMarkerTime(from.getMarkerTime());
+        ret.setMarkerScore(from.getMarkerScore());
+        ret.setMarkerScoreList(from.getMarkerScoreList());
+        ret.setMarkerSpent(from.getMarkerSpent());
+        ret.setHeaderId(from.getHeaderId());
+        ret.setHeaderTime(from.getHeaderTime());
+        ret.setHeaderScore(from.getHeaderScore());
+        ret.setHeaderScoreList(from.getHeaderScoreList());
+        ret.setUnansweredCount(from.getUnansweredCount());
+        ret.setRejectReason(from.getRejectReason());
+        ret.setMarkerLoginName(from.getMarkerLoginName());
+        ret.setTitle(from.getTitle());
+        ret.setHeaderLoginName(from.getHeaderLoginName());
+        ret.setSubject(from.getSubject());
+        return ret;
+    }
+
+}

+ 3 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/MarkerInfo.java

@@ -378,6 +378,9 @@ public class MarkerInfo {
     }
     }
 
 
     public static MarkerInfo of(Marker from) {
     public static MarkerInfo of(Marker from) {
+        if (from == null) {
+            return null;
+        }
         MarkerInfo ret = new MarkerInfo();
         MarkerInfo ret = new MarkerInfo();
         ret.setId(from.getId());
         ret.setId(from.getId());
         ret.setExamId(from.getExamId());
         ret.setExamId(from.getExamId());

+ 3 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/MarkerVo.java

@@ -198,6 +198,9 @@ public class MarkerVo {
     }
     }
 
 
     public static MarkerVo of(Marker from) {
     public static MarkerVo of(Marker from) {
+        if (from == null) {
+            return null;
+        }
         MarkerVo ret = new MarkerVo();
         MarkerVo ret = new MarkerVo();
         ret.setId(from.getId());
         ret.setId(from.getId());
         ret.setExamId(from.getExamId());
         ret.setExamId(from.getExamId());

+ 451 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/TaskVo.java

@@ -0,0 +1,451 @@
+package cn.com.qmth.stmms.biz.exam.bean;
+
+import java.util.Date;
+import java.util.List;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.mark.model.MarkConfigItem;
+import cn.com.qmth.stmms.biz.mark.model.MarkStepDTO;
+import cn.com.qmth.stmms.biz.mark.model.SpecialTagDTO;
+import cn.com.qmth.stmms.biz.mark.model.Task;
+import io.swagger.annotations.ApiModelProperty;
+
+public class TaskVo {
+
+    /**
+     * 评卷任务编号
+     */
+    @ApiModelProperty(value = "评卷任务id")
+    private Integer libraryId;
+
+    /**
+     * 考生编号
+     */
+    @ApiModelProperty(value = "考生id")
+    private Integer studentId;
+
+    /**
+     * 显示考生密号
+     */
+    @ApiModelProperty(value = "密号")
+    private String secretNumber;
+
+    /**
+     * 考生名称
+     */
+    @ApiModelProperty(value = "考生名称")
+    private String studentName;
+
+    /**
+     * 学号
+     */
+    @ApiModelProperty(value = "学号")
+    private String studentCode;
+
+    /**
+     * 准考证号
+     */
+    @ApiModelProperty(value = "准考证号")
+    private String examNumber;
+
+    /**
+     * 科目
+     */
+    @ApiModelProperty(value = "科目信息")
+    private ExamSubject subject;
+
+    /**
+     * 裁切图地址
+     */
+    @ApiModelProperty(value = "裁切图地址")
+    private List<String> sliceUrls;
+
+    /**
+     * 题卡图片拼接配置
+     */
+    @ApiModelProperty(value = "题卡图片拼接配置")
+    private List<MarkConfigItem> sliceConfig;
+
+    /**
+     * 多媒体地址
+     */
+    @ApiModelProperty(value = "多媒体地址")
+    private String jsonUrl;
+
+    /**
+     * 给分步骤
+     */
+    @ApiModelProperty(value = "给分步骤")
+    private List<MarkStepDTO> questionList;
+
+    /**
+     * 特殊标记列表
+     */
+    @ApiModelProperty(value = "特殊标记列表")
+    private SpecialTagDTO[] specialTagList;
+
+    /**
+     * 组长特殊标记列表
+     */
+    @ApiModelProperty(value = "组长特殊标记列表")
+    private SpecialTagDTO[] headerTagList;
+
+    /**
+     * 题卡原图地址
+     */
+    @ApiModelProperty(value = "题卡原图地址")
+    private List<String> sheetUrls;
+
+    /**
+     * 客观题总分
+     */
+    @ApiModelProperty(value = "客观题总分")
+    private Double objectiveScore;
+
+    /**
+     * 评分
+     */
+    @ApiModelProperty(value = "评分")
+    private Double markerScore;
+
+    /**
+     * 评卷时间
+     */
+    @ApiModelProperty(value = "评卷时间")
+    private Date markerTime;
+
+    /**
+     * 是否自评
+     */
+    @ApiModelProperty(value = "是否自评")
+    private Boolean self;
+
+    /**
+     * 是否回评
+     */
+    @ApiModelProperty(value = "是否回评")
+    private Boolean previous;
+
+    /**
+     * 是否打回
+     */
+    @ApiModelProperty(value = "是否打回")
+    private Boolean rejected;
+
+    /**
+     * 打回原因
+     */
+    @ApiModelProperty(value = "打回原因")
+    private String rejectReason;
+
+    /**
+     * 打回上次分数
+     */
+    @ApiModelProperty(value = "打回上次分数")
+    private String rejectScoreList;
+
+    /**
+     * 打回后的分数
+     */
+    @ApiModelProperty(value = "打回后的分数")
+    private String afterRejectScoreList;
+
+    /**
+     * 评卷员登录名
+     */
+    @ApiModelProperty(value = "评卷员登录名")
+    private String markerName;
+
+    /**
+     * 复核时间
+     */
+    @ApiModelProperty(value = "复核时间")
+    private Date inspectTime;
+
+    /**
+     * 错误信息
+     */
+    @ApiModelProperty(value = "错误信息")
+    private String message;
+
+    /**
+     * 仲裁题目位置
+     */
+    @ApiModelProperty(value = "仲裁题目位置")
+    private String arbitrateIndex;
+
+    @ApiModelProperty(value = "")
+    private String collationLabelCode;
+
+    @ApiModelProperty(value = "")
+    private Boolean selectiveError;
+
+    public Integer getLibraryId() {
+        return libraryId;
+    }
+
+    public void setLibraryId(Integer libraryId) {
+        this.libraryId = libraryId;
+    }
+
+    public Integer getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Integer studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public ExamSubject getSubject() {
+        return subject;
+    }
+
+    public void setSubject(ExamSubject subject) {
+        this.subject = subject;
+    }
+
+    public List<String> getSliceUrls() {
+        return sliceUrls;
+    }
+
+    public void setSliceUrls(List<String> sliceUrls) {
+        this.sliceUrls = sliceUrls;
+    }
+
+    public List<MarkConfigItem> getSliceConfig() {
+        return sliceConfig;
+    }
+
+    public void setSliceConfig(List<MarkConfigItem> sliceConfig) {
+        this.sliceConfig = sliceConfig;
+    }
+
+    public String getJsonUrl() {
+        return jsonUrl;
+    }
+
+    public void setJsonUrl(String jsonUrl) {
+        this.jsonUrl = jsonUrl;
+    }
+
+    public List<MarkStepDTO> getQuestionList() {
+        return questionList;
+    }
+
+    public void setQuestionList(List<MarkStepDTO> questionList) {
+        this.questionList = questionList;
+    }
+
+    public SpecialTagDTO[] getSpecialTagList() {
+        return specialTagList;
+    }
+
+    public void setSpecialTagList(SpecialTagDTO[] specialTagList) {
+        this.specialTagList = specialTagList;
+    }
+
+    public SpecialTagDTO[] getHeaderTagList() {
+        return headerTagList;
+    }
+
+    public void setHeaderTagList(SpecialTagDTO[] headerTagList) {
+        this.headerTagList = headerTagList;
+    }
+
+    public List<String> getSheetUrls() {
+        return sheetUrls;
+    }
+
+    public void setSheetUrls(List<String> sheetUrls) {
+        this.sheetUrls = sheetUrls;
+    }
+
+    public Double getObjectiveScore() {
+        return objectiveScore;
+    }
+
+    public void setObjectiveScore(Double objectiveScore) {
+        this.objectiveScore = objectiveScore;
+    }
+
+    public Double getMarkerScore() {
+        return markerScore;
+    }
+
+    public void setMarkerScore(Double markerScore) {
+        this.markerScore = markerScore;
+    }
+
+    public Date getMarkerTime() {
+        return markerTime;
+    }
+
+    public void setMarkerTime(Date markerTime) {
+        this.markerTime = markerTime;
+    }
+
+    public Boolean getSelf() {
+        return self;
+    }
+
+    public void setSelf(Boolean self) {
+        this.self = self;
+    }
+
+    public Boolean getPrevious() {
+        return previous;
+    }
+
+    public void setPrevious(Boolean previous) {
+        this.previous = previous;
+    }
+
+    public Boolean getRejected() {
+        return rejected;
+    }
+
+    public void setRejected(Boolean rejected) {
+        this.rejected = rejected;
+    }
+
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
+    public String getRejectScoreList() {
+        return rejectScoreList;
+    }
+
+    public void setRejectScoreList(String rejectScoreList) {
+        this.rejectScoreList = rejectScoreList;
+    }
+
+    public String getAfterRejectScoreList() {
+        return afterRejectScoreList;
+    }
+
+    public void setAfterRejectScoreList(String afterRejectScoreList) {
+        this.afterRejectScoreList = afterRejectScoreList;
+    }
+
+    public String getMarkerName() {
+        return markerName;
+    }
+
+    public void setMarkerName(String markerName) {
+        this.markerName = markerName;
+    }
+
+    public Date getInspectTime() {
+        return inspectTime;
+    }
+
+    public void setInspectTime(Date inspectTime) {
+        this.inspectTime = inspectTime;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getArbitrateIndex() {
+        return arbitrateIndex;
+    }
+
+    public void setArbitrateIndex(String arbitrateIndex) {
+        this.arbitrateIndex = arbitrateIndex;
+    }
+
+    public String getCollationLabelCode() {
+        return collationLabelCode;
+    }
+
+    public void setCollationLabelCode(String collationLabelCode) {
+        this.collationLabelCode = collationLabelCode;
+    }
+
+    public Boolean getSelectiveError() {
+        return selectiveError;
+    }
+
+    public void setSelectiveError(Boolean selectiveError) {
+        this.selectiveError = selectiveError;
+    }
+
+    public static TaskVo of(Task from) {
+        if (from == null) {
+            return null;
+        }
+        TaskVo ret = new TaskVo();
+        ret.setLibraryId(from.getLibraryId());
+        ret.setStudentId(from.getStudentId());
+        ret.setSecretNumber(from.getSecretNumber());
+        ret.setStudentName(from.getStudentName());
+        ret.setStudentCode(from.getStudentCode());
+        ret.setExamNumber(from.getExamNumber());
+        ret.setSubject(from.getSubject());
+        ret.setSliceUrls(from.getSliceUrls());
+        ret.setSliceConfig(from.getSliceConfig());
+        ret.setJsonUrl(from.getJsonUrl());
+        ret.setQuestionList(from.getQuestionList());
+        ret.setSpecialTagList(from.getSpecialTagList());
+        ret.setHeaderTagList(from.getHeaderTagList());
+        ret.setSheetUrls(from.getSheetUrls());
+        ret.setObjectiveScore(from.getObjectiveScore());
+        ret.setMarkerScore(from.getMarkerScore());
+        ret.setMarkerTime(from.getMarkerTime());
+        ret.setSelf(from.isSelf());
+        ret.setPrevious(from.isPrevious());
+        ret.setRejected(from.isRejected());
+        ret.setRejectReason(from.getRejectReason());
+        ret.setRejectScoreList(from.getRejectScoreList());
+        ret.setAfterRejectScoreList(from.getAfterRejectScoreList());
+        ret.setMarkerName(from.getMarkerName());
+        ret.setInspectTime(from.getInspectTime());
+        ret.setMessage(from.getMessage());
+        ret.setArbitrateIndex(from.getArbitrateIndex());
+        ret.setCollationLabelCode(from.getCollationLabelCode());
+        ret.setSelectiveError(from.getSelectiveError());
+        return ret;
+    }
+}

+ 227 - 206
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/MarkLibrarySearchQuery.java

@@ -1,206 +1,227 @@
-package cn.com.qmth.stmms.biz.mark.query;
-
-import cn.com.qmth.stmms.biz.common.BaseQuery;
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-import org.springframework.data.domain.Sort;
-import org.springframework.data.domain.Sort.Direction;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class MarkLibrarySearchQuery extends BaseQuery<MarkLibrary> {
-
-    private int examId;
-
-    private String subjectCode;
-
-    private int campusId;
-
-    private Integer studentId;
-
-    private String examNumber;
-
-    private String secretNumber;
-
-    private Set<LibraryStatus> statusSet;
-
-    private int markerId;
-
-    private Integer groupNumber;
-
-    private Double markerScore;
-
-    private Double startScore;
-
-    private Double endScore;
-
-    private boolean unselective;
-
-    private String questionScore;
-
-    private Integer headerId;
-
-    private String rejectReason;
-
-    private String subjectCodeIn;
-
-    public MarkLibrarySearchQuery() {
-        super();
-        this.statusSet = new HashSet<>();
-    }
-
-    public void orderByMarkerTimeDesc() {
-        setSort(new Sort(Direction.DESC, "markerTime"));
-    }
-
-    public void orderByHeaderTimeDesc() {
-        setSort(new Sort(Direction.DESC, "headerTime"));
-    }
-
-    public void orderByExamNumber() {
-        setSort(new Sort(Direction.ASC, "examNumber"));
-    }
-
-    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 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 int getMarkerId() {
-        return markerId;
-    }
-
-    public void setMarkerId(int markerId) {
-        this.markerId = markerId;
-    }
-
-    public int getCampusId() {
-        return campusId;
-    }
-
-    public void setCampusId(int campusId) {
-        this.campusId = campusId;
-    }
-
-    public Integer getGroupNumber() {
-        return groupNumber;
-    }
-
-    public void setGroupNumber(Integer groupNumber) {
-        this.groupNumber = groupNumber;
-    }
-
-    public Set<LibraryStatus> getStatusSet() {
-        return statusSet;
-    }
-
-    public void clearStatus() {
-        this.statusSet.clear();
-    }
-
-    public void addStatus(LibraryStatus status) {
-        this.statusSet.add(status);
-    }
-
-    public Double getMarkerScore() {
-        return markerScore;
-    }
-
-    public void setMarkerScore(Double markerScore) {
-        this.markerScore = markerScore;
-    }
-
-    public boolean isUnselective() {
-        return unselective;
-    }
-
-    public void setUnselective(boolean unselective) {
-        this.unselective = unselective;
-    }
-
-    public String getQuestionScore() {
-        return questionScore;
-    }
-
-    public void setQuestionScore(String questionScore) {
-        this.questionScore = questionScore;
-    }
-
-    public Integer getHeaderId() {
-        return headerId;
-    }
-
-    public void setHeaderId(Integer headerId) {
-        this.headerId = headerId;
-    }
-
-    public Double getStartScore() {
-        return startScore;
-    }
-
-    public void setStartScore(Double startScore) {
-        this.startScore = startScore;
-    }
-
-    public Double getEndScore() {
-        return endScore;
-    }
-
-    public void setEndScore(Double endScore) {
-        this.endScore = endScore;
-    }
-
-    public String getRejectReason() {
-        return rejectReason;
-    }
-
-    public void setRejectReason(String rejectReason) {
-        this.rejectReason = rejectReason;
-    }
-
-    public String getSubjectCodeIn() {
-        return subjectCodeIn;
-    }
-
-    public void setSubjectCodeIn(String subjectCodeIn) {
-        this.subjectCodeIn = subjectCodeIn;
-    }
-
-}
+package cn.com.qmth.stmms.biz.mark.query;
+
+import cn.com.qmth.stmms.biz.common.BaseQuery;
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import io.swagger.annotations.ApiModelProperty;
+
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class MarkLibrarySearchQuery extends BaseQuery<MarkLibrary> {
+
+    @ApiModelProperty("任务状态")
+    private LibraryStatus status;
+
+    private int examId;
+
+    @ApiModelProperty("科目代码")
+    private String subjectCode;
+
+    private int campusId;
+
+    private Integer studentId;
+
+    @ApiModelProperty("准考证号")
+    private String examNumber;
+
+    @ApiModelProperty("密号")
+    private String secretNumber;
+
+    private Set<LibraryStatus> statusSet;
+
+    @ApiModelProperty("评卷员id")
+    private int markerId;
+
+    @ApiModelProperty("分组号")
+    private Integer groupNumber;
+
+    private Double markerScore;
+
+    @ApiModelProperty("总分起始")
+    private Double startScore;
+
+    @ApiModelProperty("总分截止")
+    private Double endScore;
+
+    @ApiModelProperty("选做题")
+    private boolean unselective;
+
+    @ApiModelProperty("小题得分")
+    private String questionScore;
+
+    private Integer headerId;
+
+    private String rejectReason;
+
+    private String subjectCodeIn;
+
+    public MarkLibrarySearchQuery() {
+        super();
+        this.statusSet = new HashSet<>();
+    }
+
+    public void orderByMarkerTimeDesc() {
+        setSort(new Sort(Direction.DESC, "markerTime"));
+    }
+
+    public void orderByHeaderTimeDesc() {
+        setSort(new Sort(Direction.DESC, "headerTime"));
+    }
+
+    public void orderByExamNumber() {
+        setSort(new Sort(Direction.ASC, "examNumber"));
+    }
+
+    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 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 int getMarkerId() {
+        return markerId;
+    }
+
+    public void setMarkerId(int markerId) {
+        this.markerId = markerId;
+    }
+
+    public int getCampusId() {
+        return campusId;
+    }
+
+    public void setCampusId(int campusId) {
+        this.campusId = campusId;
+    }
+
+    public Integer getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(Integer groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+
+    public Set<LibraryStatus> getStatusSet() {
+        return statusSet;
+    }
+
+    public void clearStatus() {
+        this.statusSet.clear();
+    }
+
+    public void addStatus(LibraryStatus status) {
+        this.statusSet.add(status);
+    }
+
+    public Double getMarkerScore() {
+        return markerScore;
+    }
+
+    public void setMarkerScore(Double markerScore) {
+        this.markerScore = markerScore;
+    }
+
+    public boolean isUnselective() {
+        return unselective;
+    }
+
+    public void setUnselective(boolean unselective) {
+        this.unselective = unselective;
+    }
+
+    public String getQuestionScore() {
+        return questionScore;
+    }
+
+    public void setQuestionScore(String questionScore) {
+        this.questionScore = questionScore;
+    }
+
+    public Integer getHeaderId() {
+        return headerId;
+    }
+
+    public void setHeaderId(Integer headerId) {
+        this.headerId = headerId;
+    }
+
+    public Double getStartScore() {
+        return startScore;
+    }
+
+    public void setStartScore(Double startScore) {
+        this.startScore = startScore;
+    }
+
+    public Double getEndScore() {
+        return endScore;
+    }
+
+    public void setEndScore(Double endScore) {
+        this.endScore = endScore;
+    }
+
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
+    public String getSubjectCodeIn() {
+        return subjectCodeIn;
+    }
+
+    public void setSubjectCodeIn(String subjectCodeIn) {
+        this.subjectCodeIn = subjectCodeIn;
+    }
+
+    public LibraryStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(LibraryStatus status) {
+        this.status = status;
+    }
+
+}

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/config/SwaggerConfig.java

@@ -26,7 +26,7 @@ public class SwaggerConfig extends WebMvcConfigurationSupport {
     }
     }
 
 
     @Bean
     @Bean
-    private ApiInfo apiInfo() {
+    public ApiInfo apiInfo() {
         return new ApiInfoBuilder().title("stmms api").build();
         return new ApiInfoBuilder().title("stmms api").build();
     }
     }
 
 

+ 2 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/admin/utils/CopyObjectCodeGenerator.java

@@ -2,14 +2,14 @@ package cn.com.qmth.stmms.admin.utils;
 
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
 
 
-import cn.com.qmth.stmms.biz.exam.bean.MarkerVo;
+import cn.com.qmth.stmms.biz.exam.bean.TaskVo;
 
 
 /**
 /**
  * 对象复制,属性copy代码生成
  * 对象复制,属性copy代码生成
  */
  */
 public class CopyObjectCodeGenerator {
 public class CopyObjectCodeGenerator {
 
 
-    private static Object ob = new MarkerVo();
+    private static Object ob = new TaskVo();
 
 
     private static String setName = "ret";
     private static String setName = "ret";
 
 

+ 13 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/BaseApiController.java

@@ -145,6 +145,19 @@ public class BaseApiController extends BaseController {
         return list;
         return list;
     }
     }
 
 
+    protected boolean subjectCheck(String subjectCode, ApiUser wu) {
+        if (wu.isSubjectHeader() || wu.isInspector() || wu.isSchoolViewer()) {
+            for (String code : wu.getSubjectCodeSet()) {
+                if (code.equalsIgnoreCase(subjectCode)) {
+                    return true;
+                }
+            }
+            return false;
+        } else {
+            return true;
+        }
+    }
+
     public WebUser getWebUser() {
     public WebUser getWebUser() {
         return RequestUtils.getWebUser();
         return RequestUtils.getWebUser();
     }
     }

+ 7 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/ExamController.java

@@ -1,6 +1,7 @@
 package cn.com.qmth.stmms.api.controller.admin;
 package cn.com.qmth.stmms.api.controller.admin;
 
 
 import java.math.BigDecimal;
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Calendar;
 import java.util.List;
 import java.util.List;
@@ -91,12 +92,16 @@ public class ExamController extends BaseApiController {
     @ApiOperation(value = "考试分页查询")
     @ApiOperation(value = "考试分页查询")
     @RequestMapping(value = "list", method = RequestMethod.POST)
     @RequestMapping(value = "list", method = RequestMethod.POST)
     @ResponseBody
     @ResponseBody
-    public PageResult<Exam> list(ExamSearchQuery query) {
+    public PageResult<ExamVo> list(ExamSearchQuery query) {
         ApiUser user = getApiUser();
         ApiUser user = getApiUser();
         query.setSchoolId(user.getSchoolId());
         query.setSchoolId(user.getSchoolId());
         query.orderByIdDesc();
         query.orderByIdDesc();
         query = examService.findByQuery(query);
         query = examService.findByQuery(query);
-        return PageUtil.of(query);
+        List<ExamVo> ret = new ArrayList<>();
+        for (Exam e : query.getResult()) {
+            ret.add(ExamVo.of(e));
+        }
+        return PageUtil.of(ret, query);
     }
     }
 
 
     @ApiOperation(value = "考试类型")
     @ApiOperation(value = "考试类型")

+ 427 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/LibraryController.java

@@ -0,0 +1,427 @@
+package cn.com.qmth.stmms.api.controller.admin;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+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.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.qmth.boot.core.collection.PageResult;
+
+import cn.com.qmth.stmms.admin.dto.RejectResult;
+import cn.com.qmth.stmms.api.controller.BaseApiController;
+import cn.com.qmth.stmms.biz.exam.bean.LibraryStatusInfo;
+import cn.com.qmth.stmms.biz.exam.bean.MarkLibraryVo;
+import cn.com.qmth.stmms.biz.exam.bean.ResultMessage;
+import cn.com.qmth.stmms.biz.exam.bean.TaskVo;
+import cn.com.qmth.stmms.biz.exam.model.Exam;
+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.service.ExamService;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.exception.StatusException;
+import cn.com.qmth.stmms.biz.lock.LockService;
+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.MarkService;
+import cn.com.qmth.stmms.biz.mark.service.TaskService;
+import cn.com.qmth.stmms.biz.user.model.User;
+import cn.com.qmth.stmms.biz.user.service.UserService;
+import cn.com.qmth.stmms.biz.utils.PageUtil;
+import cn.com.qmth.stmms.common.annotation.Logging;
+import cn.com.qmth.stmms.common.domain.ApiUser;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+import cn.com.qmth.stmms.common.enums.LockType;
+import cn.com.qmth.stmms.common.enums.LogType;
+import cn.com.qmth.stmms.common.enums.MarkStatus;
+import cn.com.qmth.stmms.common.enums.Role;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+
+@Api(tags = "任务管理")
+@Controller("adminLibraryController")
+@RequestMapping("/api/admin/exam/library")
+public class LibraryController extends BaseApiController {
+
+    protected static Logger log = LoggerFactory.getLogger(LibraryController.class);
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private MarkService markService;
+
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private TaskService taskService;
+
+    public static final String UN_SELECTIVE_SCORE = "-1";
+
+    private static final String DEFAULT_SECRET_NUMBER = "***";
+
+    @ApiOperation(value = "待复核任务数")
+    @ResponseBody
+    @RequestMapping(value = "inspected/count", method = RequestMethod.POST)
+    public Long inspectedCount(MarkLibrarySearchQuery query) {
+        long inspectedCount = 0;
+        LibraryStatus status = query.getStatus();
+        if (LibraryStatus.MARKED.equals(status) || status == null) {
+            query.addStatus(LibraryStatus.MARKED);
+            inspectedCount = libraryService.countByQuery(query);
+        }
+        return inspectedCount;
+    }
+
+    @ApiOperation(value = "任务分页查询")
+    @Logging(menu = "评卷任务查询", type = LogType.QUERY)
+    @ResponseBody
+    @RequestMapping(value = "list", method = RequestMethod.POST)
+    public PageResult<MarkLibraryVo> list(MarkLibrarySearchQuery query) {
+
+        LibraryStatus status = query.getStatus();
+        int examId = getSessionExamId();
+        ApiUser wu = getApiUser();
+        List<ExamSubject> subjectList = getExamSubject(examId, wu);
+        if (subjectList.isEmpty()) {
+            return PageUtil.emptyPage();
+        }
+        query.setExamId(examId);
+        if (status != null) {
+            query.addStatus(status);
+        }
+        if (status != LibraryStatus.REJECTED) {
+            query.setRejectReason(null);
+        }
+        if (StringUtils.isEmpty(query.getSubjectCode()) && !subjectList.isEmpty()) {
+            query.setSubjectCode(subjectList.get(0).getCode());
+        }
+        query = libraryService.findByQuery(query);
+        List<MarkLibraryVo> ret = new ArrayList<>();
+        for (MarkLibrary library : query.getResult()) {
+            if (library.getMarkerId() != null) {
+                User marker = userService.findByMarkerId(library.getMarkerId());
+                library.setMarkerLoginName(marker.getLoginName() + "/" + marker.getName());
+                if (library.getHeaderId() != null) {
+                    User header = userService.findById(library.getHeaderId());
+                    library.setHeaderLoginName(header.getLoginName() + "/" + header.getName());
+                }
+            }
+            if (library.getMarkerScoreList() != null) {
+                library.setMarkerScoreList(library.getMarkerScoreList().replace(UN_SELECTIVE_SCORE, "/"));
+            }
+            ret.add(MarkLibraryVo.of(library));
+        }
+        return PageUtil.of(ret, query);
+    }
+
+    @ApiOperation(value = "打回或重置")
+    @Logging(menu = "打回或重置评卷任务", type = LogType.UPDATE)
+    @RequestMapping(value = "reject", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage reject(@ApiParam("任务id") @RequestParam Integer id,
+            @ApiParam("是否重置") @RequestParam(required = false, defaultValue = "false") boolean isRest,
+            @ApiParam("打回原因") @RequestParam(required = false) String reason) {
+        MarkLibrary library = libraryService.findById(id);
+        ApiUser wu = getApiUser();
+        if (library != null) {
+            if (subjectCheck(library.getSubjectCode(), wu)) {
+                try {
+                    lockService.watch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
+                    lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
+                            library.getGroupNumber());
+                    lockService.waitlock(LockType.STUDENT, library.getStudentId());
+                    if ((library.getStatus().equals(LibraryStatus.MARKED)
+                            || library.getStatus().equals(LibraryStatus.PROBLEM)
+                            || library.getStatus().equals(LibraryStatus.INSPECTED))
+                            && markService.rejectLibrary(library, wu.getUser().getId(), reason, isRest)) {
+                        return resultOk();
+                    } else {
+                        throw new StatusException("无法打回该评卷任务");
+                    }
+                } catch (Exception e) {
+                    log.error("back library error", e);
+                    throw new StatusException("打回评卷任务失败");
+                } finally {
+                    lockService.unlock(LockType.STUDENT, library.getStudentId());
+                    lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
+                            library.getGroupNumber());
+                    lockService.unwatch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
+                }
+            } else {
+                throw new StatusException("没有操作该评卷任务的权限");
+            }
+        } else {
+            throw new StatusException("该评卷任务不存在");
+        }
+    }
+
+    @ApiOperation(value = "获取复核任务")
+    @Logging(menu = "开始任务复核", type = LogType.QUERY)
+    @RequestMapping(value = "get-task", method = RequestMethod.POST)
+    @ResponseBody
+    public TaskVo getTask(MarkLibrarySearchQuery query) {
+        int examId = getSessionExamId();
+        MarkGroup group = groupService.findOne(examId, query.getSubjectCode(), query.getGroupNumber());
+        Exam exam = examService.findById(examId);
+        if (group == null) {
+            return null;
+        } else if (group.getStatus() == MarkStatus.FINISH) {
+            return null;
+        } else if (group.getStatus() == MarkStatus.TRIAL) {
+            return null;
+        }
+        Task task = null;
+        ApiUser wu = getApiUser();
+        int retry = 1;
+        while (task == null) {
+            query.setExamId(examId);
+            query.addStatus(LibraryStatus.MARKED);
+            query.setPageNumber(retry);
+            query.setPageSize(20);
+            query = libraryService.findByQuery(query);
+            if (query.getResult().isEmpty()) {
+                break;
+            }
+            for (MarkLibrary library : query.getResult()) {
+                if (libraryService.applyLibrary(library, wu.getUser().getId())) {
+                    task = taskService.build(library);
+                    if (exam.isForbiddenInfo() && !Role.SCHOOL_ADMIN.equals(wu.getRole())) {
+                        task.setSecretNumber(DEFAULT_SECRET_NUMBER);
+                    }
+                    break;
+                }
+            }
+            if (task == null) {
+                retry++;
+            }
+        }
+        return TaskVo.of(task);
+    }
+
+    @ApiOperation(value = "复核")
+    @Logging(menu = "考生评卷复核", type = LogType.UPDATE)
+    @RequestMapping(value = "inspected/save", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage save(@RequestParam Integer libraryId) {
+        ApiUser wu = getApiUser();
+        MarkLibrary library = libraryService.findById(libraryId);
+        try {
+            if (libraryId != null && library.getStatus().equals(LibraryStatus.MARKED)
+                    && libraryService.hasApplied(library, wu.getUser().getId())) {
+                library.setHeaderId(wu.getUser().getId());
+                library.setHeaderTime(new Date());
+                library.setStatus(LibraryStatus.INSPECTED);
+                libraryService.save(library);
+                libraryService.releaseByLibrary(library);
+                return resultOk();
+            } else {
+                throw new StatusException("无法复核,请刷新页面");
+            }
+        } catch (Exception e) {
+            log.error("inspected library save error", e);
+            throw new StatusException("无法复核,请刷新页面");
+        }
+    }
+
+    @ApiOperation(value = "任务释放")
+    @RequestMapping(value = "clear", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage clear(@RequestParam String subjectCode, @RequestParam Integer groupNumber,
+            @RequestParam(required = false) Integer libraryId) {
+        ApiUser wu = getApiUser();
+        if (libraryId != null) {
+            releaseLibrary(libraryId);
+            return resultOk();
+        } else {
+            int examId = getSessionExamId();
+            releaseUser(examId, subjectCode, groupNumber, wu.getUser().getId());
+            return resultOk();
+        }
+    }
+
+    @ApiOperation(value = "获取状态信息")
+    @RequestMapping(value = "get-status", method = RequestMethod.POST)
+    @ResponseBody
+    public LibraryStatusInfo status(MarkLibrarySearchQuery query) {
+        LibraryStatusInfo status = new LibraryStatusInfo();
+        int examId = getSessionExamId();
+        query.setExamId(examId);
+        query.addStatus(LibraryStatus.MARKED);
+        long inspectedCount = libraryService.countByQuery(query);
+        status.setTotalCount(inspectedCount);
+        status.setValid(true);
+        return status;
+    }
+
+    private void releaseUser(Integer examId, String subjectCode, Integer groupNumber, Integer userId) {
+        try {
+            libraryService.releaseByUserId(examId, subjectCode, groupNumber, userId);
+        } catch (Exception e) {
+            log.error("release user error", e);
+        }
+    }
+
+    private void releaseLibrary(Integer libraryId) {
+        try {
+            MarkLibrary library = libraryService.findById(libraryId);
+            libraryService.releaseByLibrary(library);
+        } catch (Exception e) {
+            log.error("release library error", e);
+        }
+    }
+
+    @ApiOperation(value = "打回")
+    @Logging(menu = "打回", type = LogType.UPDATE)
+    @RequestMapping(value = "rejected", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage rejected(@RequestBody RejectResult rejectResult) {
+        ApiUser wu = getApiUser();
+        MarkLibrary library = libraryService.findById(rejectResult.getLibraryId());
+        if (library != null) {
+            if (subjectCheck(library.getSubjectCode(), wu)) {
+                try {
+                    lockService.watch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
+                    lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
+                            library.getGroupNumber());
+                    lockService.waitlock(LockType.STUDENT, library.getStudentId());
+                    if (((libraryService.hasApplied(library, wu.getUser().getId())
+                            && (library.getStatus().equals(LibraryStatus.MARKED))
+                            || library.getStatus().equals(LibraryStatus.INSPECTED))
+                            && markService.rejectLibrary(library, rejectResult.getQuestionList(), wu.getUser().getId(),
+                                    rejectResult.getReason()))) {
+                        libraryService.releaseByLibrary(library);
+                        return resultOk();
+                    } else {
+                        throw new StatusException("无法打回该评卷任务");
+                    }
+                } catch (Exception e) {
+                    log.error("back library error", e);
+                    throw new StatusException("打回评卷任务失败");
+                } finally {
+                    lockService.unlock(LockType.STUDENT, library.getStudentId());
+                    lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
+                            library.getGroupNumber());
+                    lockService.unwatch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
+                }
+            } else {
+                throw new StatusException("没有操作该评卷任务的权限");
+            }
+        } else {
+            throw new StatusException("该评卷任务不存在");
+        }
+    }
+
+    @ApiOperation(value = "回看评卷复核任务")
+    @Logging(menu = "回看评卷复核任务", type = LogType.QUERY)
+    @RequestMapping(value = "get-history", method = RequestMethod.POST)
+    @ResponseBody
+    public List<TaskVo> getHistory(@RequestParam String subjectCode, @RequestParam Integer groupNumber,
+            @RequestParam int pageNumber, @RequestParam int pageSize) {
+        int examId = getSessionExamId();
+        Exam exam = examService.findById(examId);
+        ApiUser wu = getApiUser();
+        List<TaskVo> list = new ArrayList<>();
+        MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
+        query.setExamId(examId);
+        query.setSubjectCode(subjectCode);
+        query.setGroupNumber(groupNumber);
+        query.addStatus(LibraryStatus.INSPECTED);
+        query.setHeaderId(wu.getUser().getId());
+        query.setPageNumber(pageNumber);
+        query.setPageSize(pageSize);
+        query.orderByHeaderTimeDesc();
+        query = libraryService.findByQuery(query);
+        for (MarkLibrary library : query.getResult()) {
+            Task task = taskService.build(library);
+            if (exam.isForbiddenInfo() && !Role.SCHOOL_ADMIN.equals(wu.getRole())) {
+                task.setSecretNumber(DEFAULT_SECRET_NUMBER);
+            }
+            task.setPrevious(true);
+            list.add(TaskVo.of(task));
+        }
+        return list;
+    }
+
+    @ApiOperation(value = "评卷员任务指定")
+    @Logging(menu = "评卷员任务指定", type = LogType.UPDATE)
+    @RequestMapping(value = "assigned", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage assigned(@RequestParam Integer libraryId, @RequestParam String marker) {
+        User user = userService.findByLoginName(marker);
+        if (user == null || !Role.MARKER.equals(user.getRole())) {
+            throw new StatusException("指定失败,未找到评卷员");
+        }
+        MarkLibrary library = libraryService.findById(libraryId);
+        if (library == null) {
+            throw new StatusException("指定失败,未找到评卷任务");
+        }
+        MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
+        try {
+            lockService.watch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
+            lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
+            lockService.waitlock(LockType.STUDENT, library.getStudentId());
+            Marker mk = markerService.findByExamAndSubjectAndNumberAndUserId(library.getExamId(),
+                    library.getSubjectCode(), library.getGroupNumber(), user.getId());
+            if (mk == null) {
+                throw new StatusException("指定失败,评卷员不在该任务分组");
+            }
+            if (library.getMarkerId().equals(mk.getId())) {
+                throw new StatusException("指定失败,当前任务已属于该评卷员");
+            }
+            if (group.getDoubleRate() != null && group.getDoubleRate() > 0) {
+                List<MarkLibrary> libraryList = libraryService.findByStudentAndGroup(library.getStudentId(),
+                        library.getGroupNumber());
+                for (MarkLibrary l : libraryList) {
+                    if (mk.getId().equals(l.getMarkerId())) {
+                        throw new StatusException("指定失败,当前任务已属于该评卷员");
+                    }
+                }
+            }
+            markService.releaseByLibrary(library);
+            if (markService.applyLibrary(library, mk)) {
+                library = libraryService.findById(libraryId);
+                if (!LibraryStatus.WAITING.equals(library.getStatus())
+                        && !LibraryStatus.REJECTED.equals(library.getStatus())) {
+                    throw new StatusException("指定失败,当前任务已评");
+                }
+                libraryService.assigned(library.getId(), mk.getId());
+                return resultOk();
+            } else {
+                throw new StatusException("指定失败,请更换评卷员重试");
+            }
+        } finally {
+            lockService.unlock(LockType.STUDENT, library.getStudentId());
+            lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
+                    library.getGroupNumber());
+            lockService.unwatch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
+        }
+    }
+}