浏览代码

修改生成评卷任务与仲裁相关bug

luoshi 6 年之前
父节点
当前提交
dd123bf0f7
共有 23 个文件被更改,包括 407 次插入350 次删除
  1. 0 5
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamDao.java
  2. 4 4
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/MarkGroupDao.java
  3. 0 12
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/Exam.java
  4. 0 11
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/query/ExamSearchQuery.java
  5. 0 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamService.java
  6. 0 9
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamServiceImpl.java
  7. 2 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/ArbitrateHistoryDao.java
  8. 132 120
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/MarkLibrarySearchQuery.java
  9. 147 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkCronService.java
  10. 8 4
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkLibraryServiceImpl.java
  11. 49 137
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkServiceImpl.java
  12. 1 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/TaskServiceImpl.java
  13. 7 7
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkService.java
  14. 12 11
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/CurrentTaskUtil.java
  15. 5 3
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ArbitrateController.java
  16. 0 1
      stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/BaseController.java
  17. 10 5
      stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java
  18. 4 4
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/arbitrateBatchProcess.jsp
  19. 3 3
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/arbitrateList.jsp
  20. 7 6
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/arbitrateSingleProcess.jsp
  21. 1 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markNew.jsp
  22. 13 2
      stmms-web/src/main/webapp/static/mark-new/js/mark-control.js
  23. 2 2
      stmms-web/src/main/webapp/static/mark-new/js/modules/header-mark-status.js

+ 0 - 5
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamDao.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.stmms.biz.exam.dao;
 
-import java.util.Date;
 import java.util.List;
 
 import org.springframework.data.domain.Page;
@@ -26,9 +25,5 @@ public interface ExamDao extends PagingAndSortingRepository<Exam, Integer>, JpaS
     @Query("update Exam e set e.status=?2 where e.id=?1")
     public void updateStatus(Integer examId, ExamStatus status);
 
-    @Modifying
-    @Query("update Exam e set e.uploadTime=?2 where e.id=?1")
-    public void updateUploadTime(Integer examId, Date uploadTime);
-
     public List<Exam> findBySchoolIdOrderByIdDesc(Integer schoolId);
 }

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

@@ -50,7 +50,7 @@ public interface MarkGroupDao
 
     @Modifying
     @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
-            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number and l.status in ?3) "
+            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=g.pk.number and l.status in (?3)) "
             + "where g.pk.examId=?1 and g.pk.subjectCode=?2")
     void updateMarkedCount(int examId, String subjectCode, LibraryStatus... status);
 
@@ -67,7 +67,7 @@ public interface MarkGroupDao
 
     @Modifying
     @Query("update MarkGroup g set g.markedCount=(select count(l) from MarkLibrary l "
-            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3 and l.status in ?4 ) "
+            + "where l.examId=?1 and l.subjectCode=?2 and l.groupNumber=?3 and l.status in (?4) ) "
             + "where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
     void updateMarkedCount(int examId, String subjectCode, int number, LibraryStatus... status);
 
@@ -93,11 +93,11 @@ public interface MarkGroupDao
     @Query("update MarkGroup g set g.totalScore=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
     void updateTotalScore(int examId, String subjectCode, int number, Double score);
 
-    @Modifying
+    @Modifying(clearAutomatically = true)
     @Query("update MarkGroup g set g.buildTime=?4 where g.pk.examId=?1 and g.pk.subjectCode=?2 and g.pk.number=?3")
     void updateBuildTime(int examId, String subjectCode, int number, Date time);
 
-    @Modifying
+    @Modifying(clearAutomatically = true)
     @Query("update MarkGroup g set g.buildTime=?3 where g.pk.examId=?1 and g.pk.subjectCode=?2")
     void updateBuildTime(int examId, String subjectCode, Date time);
 

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

@@ -40,10 +40,6 @@ public class Exam implements Serializable {
     @Column(name = "status", length = 16, nullable = false)
     private ExamStatus status;
 
-    @Temporal(TemporalType.TIMESTAMP)
-    @Column(name = "upload_time", nullable = true)
-    private Date uploadTime;
-
     private String description;
 
     @Temporal(TemporalType.TIMESTAMP)
@@ -129,12 +125,4 @@ public class Exam implements Serializable {
         this.schoolId = schoolId;
     }
 
-    public Date getUploadTime() {
-        return uploadTime;
-    }
-
-    public void setUploadTime(Date uploadTime) {
-        this.uploadTime = uploadTime;
-    }
-
 }

+ 0 - 11
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/query/ExamSearchQuery.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.stmms.biz.exam.query;
 
-import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -22,8 +21,6 @@ public class ExamSearchQuery extends BaseQuery<Exam> {
 
     private Boolean orderByCreateTimeDesc;
 
-    private Date uploadTimeGt;
-
     public Integer getCreatorId() {
         return creatorId;
     }
@@ -82,12 +79,4 @@ public class ExamSearchQuery extends BaseQuery<Exam> {
         this.schoolId = schoolId;
     }
 
-    public Date getUploadTimeGt() {
-        return uploadTimeGt;
-    }
-
-    public void setUploadTimeGt(Date uploadTimeGt) {
-        this.uploadTimeGt = uploadTimeGt;
-    }
-
 }

+ 0 - 1
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamService.java

@@ -26,5 +26,4 @@ public interface ExamService {
 
     List<Exam> findBySchoolId(Integer schoolId);
 
-    void updateUploadTime(Integer id);
 }

+ 0 - 9
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamServiceImpl.java

@@ -71,12 +71,6 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
         examDao.delete(exam);
     }
 
-    @Override
-    @Transactional
-    public void updateUploadTime(Integer id) {
-        examDao.updateUploadTime(id, new Date());
-    }
-
     @Override
     public ExamSearchQuery findByQuery(final ExamSearchQuery query) {
         checkQuery(query);
@@ -99,9 +93,6 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
                 if (StringUtils.isNotBlank(query.getName())) {
                     predicates.add(cb.like(root.get("name").as(String.class), query.getName() + "%"));
                 }
-                if (query.getUploadTimeGt() != null) {
-                    predicates.add(cb.greaterThan(root.get("uploadTime").as(Date.class), query.getUploadTimeGt()));
-                }
 
                 if (query.getStatusSet() != null && query.getStatusSet().size() > 0) {
                     List<Predicate> statusPredicates = new LinkedList<Predicate>();

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

@@ -4,16 +4,16 @@ import java.util.List;
 import java.util.Set;
 
 import org.springframework.data.domain.Pageable;
+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 org.springframework.data.repository.PagingAndSortingRepository;
 
 import cn.com.qmth.stmms.biz.mark.model.ArbitrateHistory;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
 
 public interface ArbitrateHistoryDao
-        extends PagingAndSortingRepository<ArbitrateHistory, Integer>, JpaSpecificationExecutor<ArbitrateHistory> {
+        extends JpaRepository<ArbitrateHistory, Integer>, JpaSpecificationExecutor<ArbitrateHistory> {
 
     List<ArbitrateHistory> findByExamIdAndSubjectCodeAndGroupNumber(Integer examId, String subjectCode,
             Integer groupNumber, Pageable page);

+ 132 - 120
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/query/MarkLibrarySearchQuery.java

@@ -1,120 +1,132 @@
-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.MarkLibrary;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-
-public class MarkLibrarySearchQuery extends BaseQuery<MarkLibrary> {
-
-    private int examId;
-
-    private String subjectCode;
-
-    private int campusId;
-
-    private int studentId;
-
-    private String examNumber;
-
-    private LibraryStatus status;
-
-    private int markerId;
-
-    private int tagId;
-
-    private Boolean tagNotNull;
-    
-    private int groupNumber;
-
-    public void orderByMarkerTimeDesc() {
-        setSort(new Sort(Direction.DESC, "markerTime"));
-    }
-
-    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 int getStudentId() {
-        return studentId;
-    }
-
-    public void setStudentId(int studentId) {
-        this.studentId = studentId;
-    }
-
-    public String getExamNumber() {
-        return examNumber;
-    }
-
-    public void setExamNumber(String examNumber) {
-        this.examNumber = examNumber;
-    }
-
-    public LibraryStatus getStatus() {
-        return status;
-    }
-
-    public void setStatus(LibraryStatus status) {
-        this.status = status;
-    }
-
-    public int getMarkerId() {
-        return markerId;
-    }
-
-    public void setMarkerId(int markerId) {
-        this.markerId = markerId;
-    }
-
-    public int getTagId() {
-        return tagId;
-    }
-
-    public void setTagId(int tagId) {
-        this.tagId = tagId;
-    }
-
-    public Boolean getTagNotNull() {
-        return tagNotNull;
-    }
-
-    public void setTagNotNull(Boolean tagNotNull) {
-        this.tagNotNull = tagNotNull;
-    }
-
-    public int getCampusId() {
-        return campusId;
-    }
-
-    public void setCampusId(int campusId) {
-        this.campusId = campusId;
-    }
-
-	public int getGroupNumber() {
-		return groupNumber;
-	}
-
-	public void setGroupNumber(int groupNumber) {
-		this.groupNumber = groupNumber;
-	}
-
-}
+package cn.com.qmth.stmms.biz.mark.query;
+
+import java.util.HashSet;
+import java.util.Set;
+
+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.MarkLibrary;
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
+
+public class MarkLibrarySearchQuery extends BaseQuery<MarkLibrary> {
+
+    private int examId;
+
+    private String subjectCode;
+
+    private int campusId;
+
+    private int studentId;
+
+    private String examNumber;
+
+    private Set<LibraryStatus> statusSet;
+
+    private int markerId;
+
+    private int tagId;
+
+    private Boolean tagNotNull;
+
+    private int groupNumber;
+
+    public MarkLibrarySearchQuery() {
+        super();
+        this.statusSet = new HashSet<>();
+    }
+
+    public void orderByMarkerTimeDesc() {
+        setSort(new Sort(Direction.DESC, "markerTime"));
+    }
+
+    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 int getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(int studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+
+    public int getMarkerId() {
+        return markerId;
+    }
+
+    public void setMarkerId(int markerId) {
+        this.markerId = markerId;
+    }
+
+    public int getTagId() {
+        return tagId;
+    }
+
+    public void setTagId(int tagId) {
+        this.tagId = tagId;
+    }
+
+    public Boolean getTagNotNull() {
+        return tagNotNull;
+    }
+
+    public void setTagNotNull(Boolean tagNotNull) {
+        this.tagNotNull = tagNotNull;
+    }
+
+    public int getCampusId() {
+        return campusId;
+    }
+
+    public void setCampusId(int campusId) {
+        this.campusId = campusId;
+    }
+
+    public int getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(int 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);
+    }
+
+}

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

@@ -0,0 +1,147 @@
+package cn.com.qmth.stmms.biz.mark.service.Impl;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import cn.com.qmth.stmms.biz.campus.model.Campus;
+import cn.com.qmth.stmms.biz.campus.service.CampusService;
+import cn.com.qmth.stmms.biz.exam.model.Exam;
+import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.query.ExamSearchQuery;
+import cn.com.qmth.stmms.biz.exam.service.ExamService;
+import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
+import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
+import cn.com.qmth.stmms.biz.utils.CurrentTaskUtil;
+import cn.com.qmth.stmms.common.enums.ExamStatus;
+
+@Component
+public class MarkCronService {
+
+    protected static final Logger log = LoggerFactory.getLogger(MarkCronService.class);
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private CampusService campusService;
+
+    @Autowired
+    private ExamStudentService studentService;
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private MarkService markService;
+
+    @Value("${mark.cleanTimeoutMinute}")
+    private long timeoutMinute;
+
+    /**
+     * 自动释放超时未处理的评卷任务
+     */
+    @Scheduled(cron = "${mark.cleanSchedule}")
+    public void cronCleanTask() {
+        try {
+            CurrentTaskUtil.clearTimeoutTask(timeoutMinute);
+        } catch (Exception e) {
+            log.error("CronCleanTask error", e);
+        }
+    }
+
+    /**
+     * 定时生成评卷任务
+     */
+    @Scheduled(fixedDelay = 2 * 60 * 1000, initialDelay = 60 * 1000)
+    public void buildLibrary() {
+        log.debug("start auto-create library");
+        try {
+            Map<String, Campus> campusMap = new HashMap<String, Campus>();
+
+            ExamSearchQuery query = new ExamSearchQuery();
+            query.addStatus(ExamStatus.START);
+            query.setSort(new Sort(Direction.DESC, "id"));
+            query.setPageNumber(1);
+            query.setPageSize(10);
+            query = examService.findByQuery(query);
+            while (query.getCurrentCount() > 0) {
+                for (Exam exam : query.getResult()) {
+                    buildLibraryByExam(exam, campusMap);
+                }
+                query.setPageNumber(query.getPageNumber() + 1);
+                query = examService.findByQuery(query);
+            }
+        } catch (Exception e) {
+            log.error("auto-create library error", e);
+        } finally {
+            log.debug("finish auto-create library");
+        }
+    }
+
+    private void buildLibraryByExam(Exam exam, Map<String, Campus> campusMap) {
+        // 获取主观题总分大于0的科目
+        List<ExamSubject> subjects = subjectService.list(exam.getId(), 0);
+        for (ExamSubject subject : subjects) {
+            // 清除缺考考生和违纪考生
+            List<ExamStudent> list = studentService.findAbsentOrBreachLibraryStudent(subject.getExamId(),
+                    subject.getCode());
+            if (list != null) {
+                for (ExamStudent student : list) {
+                    markService.deleteByStudent(student);
+                }
+            }
+            // 处理正常考生
+            List<MarkGroup> groups = groupService.findByExamAndSubject(subject.getExamId(), subject.getCode());
+            for (MarkGroup group : groups) {
+                Date lastBuildTime = group.getBuildTime();
+                ExamStudent student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(),
+                        group.getNumber(), lastBuildTime);
+                while (student != null) {
+                    // 重复检测大题状态
+                    // TODO - 需要替换成读写锁
+                    // MarkGroup current = group;
+                    // if (current == null || (current.getBuildTime() == null &&
+                    // lastBuildTime != null)) {
+                    // // 大题已被删除,或者已被重置,直接退出循环
+                    // break;
+                    // }
+                    // 补充学习中心集合
+                    Campus campus = campusMap.get(student.getSchoolId() + "_" + student.getCampusName());
+                    if (campus == null) {
+                        campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
+                        if (campus == null) {
+                            log.error("campus unexist for student id=" + student.getId());
+                            continue;
+                        } else {
+                            campusMap.put(student.getSchoolId() + "_" + student.getCampusName(), campus);
+                        }
+                    }
+                    // 尝试构造评卷任务
+                    markService.buildLibrary(student, campus, group);
+                    lastBuildTime = student.getUploadTime();
+                    // 取下一个考生
+                    student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(), group.getNumber(),
+                            lastBuildTime);
+                }
+            }
+        }
+    }
+}

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

@@ -80,7 +80,7 @@ public class MarkLibraryServiceImpl extends BaseQueryService<MarkLibrary> implem
         query.setExamId(examId);
         query.setSubjectCode(subjectCode);
         query.setGroupNumber(groupNumber);
-        query.setStatus(status);
+        query.addStatus(status);
         return countByQuery(query);
     }
 
@@ -88,7 +88,7 @@ public class MarkLibraryServiceImpl extends BaseQueryService<MarkLibrary> implem
     public long countByMarker(int markerId) {
         MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
         query.setMarkerId(markerId);
-        query.setStatus(LibraryStatus.MARKED);
+        // query.addStatus(LibraryStatus.MARKED);
         return countByQuery(query);
     }
 
@@ -132,8 +132,12 @@ public class MarkLibraryServiceImpl extends BaseQueryService<MarkLibrary> implem
                 if (query.getMarkerId() > 0) {
                     predicates.add(cb.equal(root.get("markerId"), query.getMarkerId()));
                 }
-                if (query.getStatus() != null) {
-                    predicates.add(cb.equal(root.get("status").as(LibraryStatus.class), query.getStatus()));
+                if (query.getStatusSet() != null && query.getStatusSet().size() > 0) {
+                    List<Predicate> sub = new LinkedList<>();
+                    for (LibraryStatus status : query.getStatusSet()) {
+                        sub.add(cb.equal(root.get("status").as(LibraryStatus.class), status));
+                    }
+                    predicates.add(cb.or(sub.toArray(new Predicate[sub.size()])));
                 }
                 if (query.getTagNotNull() != null && query.getTagNotNull().booleanValue()) {
                     predicates.add(cb.isNotNull(root.get("tags")));

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

@@ -1,9 +1,7 @@
 package cn.com.qmth.stmms.biz.mark.service.Impl;
 
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -11,25 +9,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.domain.Sort.Direction;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import cn.com.qmth.stmms.biz.campus.model.Campus;
-import cn.com.qmth.stmms.biz.campus.service.CampusService;
 import cn.com.qmth.stmms.biz.exam.dao.ExamQuestionDao;
 import cn.com.qmth.stmms.biz.exam.dao.MarkGroupDao;
 import cn.com.qmth.stmms.biz.exam.dao.MarkerDao;
-import cn.com.qmth.stmms.biz.exam.model.Exam;
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
-import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.exam.query.ExamSearchQuery;
-import cn.com.qmth.stmms.biz.exam.service.ExamService;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
 import cn.com.qmth.stmms.biz.mark.dao.ArbitrateHistoryDao;
@@ -44,7 +34,6 @@ import cn.com.qmth.stmms.biz.mark.service.MarkService;
 import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.biz.utils.CurrentTaskUtil;
 import cn.com.qmth.stmms.biz.utils.ScoreItem;
-import cn.com.qmth.stmms.common.enums.ExamStatus;
 import cn.com.qmth.stmms.common.enums.HistoryStatus;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
 import cn.com.qmth.stmms.common.enums.ScorePolicy;
@@ -60,15 +49,9 @@ public class MarkServiceImpl implements MarkService {
 
     protected static final Logger log = LoggerFactory.getLogger(MarkServiceImpl.class);
 
-    @Autowired
-    private ExamService examService;
-
     @Autowired
     private ExamStudentService studentService;
 
-    @Autowired
-    private CampusService campusService;
-
     @Autowired
     private ExamSubjectService subjectService;
 
@@ -214,7 +197,7 @@ public class MarkServiceImpl implements MarkService {
         if (libraryDao.countByStudentIdAndMarkerId(library.getStudentId(), marker.getId()) > 0) {
             return false;
         }
-        return CurrentTaskUtil.add(marker, library.getId());
+        return CurrentTaskUtil.add(marker, getApplyTaskId(library));
     }
 
     /**
@@ -225,7 +208,7 @@ public class MarkServiceImpl implements MarkService {
     @Override
     @Transactional
     public void releaseLibrary(MarkLibrary library, Marker marker) {
-        CurrentTaskUtil.remove(marker, library.getId());
+        CurrentTaskUtil.remove(marker, getApplyTaskId(library));
     }
 
     /**
@@ -374,123 +357,13 @@ public class MarkServiceImpl implements MarkService {
     @Override
     @Transactional
     public void processArbitrate(ArbitrateHistory history) {
-        arbitrateDao.save(history);
+        arbitrateDao.saveAndFlush(history);
         libraryDao.updateHeaderResult(history.getStudentId(), history.getGroupNumber(), history.getUserId(),
                 history.getTotalScore(), history.getScoreList(), history.getUpdateTime(), LibraryStatus.ARBITRATED);
         updateLibraryCount(history.getExamId(), history.getSubjectCode(), history.getGroupNumber());
         scoreCalculate(history.getExamId(), history.getSubjectCode(), history.getStudentId());
     }
 
-    /**
-     * 定时生成评卷任务
-     */
-    @Scheduled(fixedDelay = 2 * 60 * 1000, initialDelay = 60 * 1000)
-    @Override
-    public void buildLibrary() {
-        log.debug("start auto-create library");
-        try {
-            Map<String, Campus> campusMap = new HashMap<String, Campus>();
-
-            ExamSearchQuery query = new ExamSearchQuery();
-            // 过去48小时内有考生更新上传的考试,才会尝试生成评卷任务
-            Calendar now = Calendar.getInstance();
-            now.add(Calendar.DAY_OF_YEAR, -2);
-            query.setUploadTimeGt(now.getTime());
-            query.addStatus(ExamStatus.START);
-            query.setSort(new Sort(Direction.DESC, "id"));
-            query.setPageNumber(1);
-            query.setPageSize(10);
-            query = examService.findByQuery(query);
-            while (query.getCurrentCount() > 0) {
-                for (Exam exam : query.getResult()) {
-                    buildLibraryByExam(exam, campusMap);
-                }
-                query.setPageNumber(query.getPageNumber() + 1);
-                query = examService.findByQuery(query);
-            }
-        } catch (Exception e) {
-        } finally {
-            log.debug("finish auto-create library");
-        }
-    }
-
-    private void buildLibraryByExam(Exam exam, Map<String, Campus> campusMap) {
-        // 获取主观题总分大于0的科目
-        List<ExamSubject> subjects = subjectService.list(exam.getId(), 0);
-        for (ExamSubject subject : subjects) {
-            // 清除缺考考生和违纪考生
-            List<ExamStudent> list = studentService.findAbsentOrBreachLibraryStudent(subject.getExamId(),
-                    subject.getCode());
-            if (list != null) {
-                for (ExamStudent student : list) {
-                    deleteByStudent(student);
-                }
-            }
-            // 处理正常考生
-            List<MarkGroup> groups = groupDao.findByExamIdAndSubjectCode(exam.getId(), subject.getCode());
-            for (MarkGroup group : groups) {
-                Date lastBuildTime = group.getBuildTime();
-                ExamStudent student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(),
-                        group.getNumber(), lastBuildTime);
-                while (student != null) {
-                    // 重复检测大题状态
-                    // TODO - 需要替换成读写锁
-                    // MarkGroup current = group;
-                    // if (current == null || (current.getBuildTime() == null &&
-                    // lastBuildTime != null)) {
-                    // // 大题已被删除,或者已被重置,直接退出循环
-                    // break;
-                    // }
-                    // 补充学习中心集合
-                    Campus campus = campusMap.get(student.getSchoolId() + "_" + student.getCampusName());
-                    if (campus == null) {
-                        campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
-                        if (campus == null) {
-                            log.error("campus unexist for student id=" + student.getId());
-                            continue;
-                        } else {
-                            campusMap.put(student.getSchoolId() + "_" + student.getCampusName(), campus);
-                        }
-                    }
-                    // 查询是否已创建评卷任务
-                    if (libraryDao.countByStudentIdAndGroupNumber(student.getId(), group.getNumber()) == 0) {
-                        MarkLibrary library = new MarkLibrary();
-                        library.setExamId(student.getExamId());
-                        library.setSubjectCode(student.getSubjectCode());
-                        library.setGroupNumber(group.getNumber());
-                        library.setCampusId(campus.getId());
-                        library.setStudentId(student.getId());
-                        library.setExamNumber(student.getExamNumber());
-                        library.setTaskNumber(1);
-                        library.setStatus(LibraryStatus.WAITING);
-                        libraryDao.save(library);
-                        // 开启双评,且随机数超过双评比例,生成第二份评卷任务
-                        if (group.getDoubleRate() != null && group.getDoubleRate() > Math.random()) {
-                            library = new MarkLibrary();
-                            library.setExamId(student.getExamId());
-                            library.setSubjectCode(student.getSubjectCode());
-                            library.setGroupNumber(group.getNumber());
-                            library.setCampusId(campus.getId());
-                            library.setStudentId(student.getId());
-                            library.setExamNumber(student.getExamNumber());
-                            library.setTaskNumber(2);
-                            library.setStatus(LibraryStatus.WAITING);
-                            libraryDao.save(library);
-                        }
-                    }
-                    lastBuildTime = student.getUploadTime();
-                    group.setBuildTime(lastBuildTime);
-                    groupDao.updateBuildTime(group.getExamId(), group.getSubjectCode(), group.getNumber(),
-                            lastBuildTime);
-                    updateLibraryCount(group.getExamId(), group.getSubjectCode(), group.getNumber());
-                    // 取下一个考生
-                    student = studentService.findUnLibraryStudent(exam.getId(), subject.getCode(), group.getNumber(),
-                            lastBuildTime);
-                }
-            }
-        }
-    }
-
     /**
      * 对某个考生某个科目进行主观题统分
      * 
@@ -612,16 +485,55 @@ public class MarkServiceImpl implements MarkService {
     }
 
     /**
-     * 自动释放超时未处理的评卷任务
+     * 根据考生、学习中心、大题构造评卷任务
+     * 
+     * @param student
+     * @param campus
+     * @param group
      */
-    @Scheduled(cron = "${mark.cleanSchedule}")
     @Override
-    public void cronCleanTask() {
-        try {
-            CurrentTaskUtil.clearTimeoutTask(timeoutMinute);
-        } catch (Exception e) {
-            log.error("CronCleanTask error", e);
+    @Transactional
+    public void buildLibrary(ExamStudent student, Campus campus, MarkGroup group) {
+        // 查询是否已创建评卷任务
+        if (libraryDao.countByStudentIdAndGroupNumber(student.getId(), group.getNumber()) == 0) {
+            MarkLibrary library = new MarkLibrary();
+            library.setExamId(student.getExamId());
+            library.setSubjectCode(student.getSubjectCode());
+            library.setGroupNumber(group.getNumber());
+            library.setCampusId(campus.getId());
+            library.setStudentId(student.getId());
+            library.setExamNumber(student.getExamNumber());
+            library.setTaskNumber(1);
+            library.setStatus(LibraryStatus.WAITING);
+            libraryDao.saveAndFlush(library);
+            // 开启双评,且随机数超过双评比例,生成第二份评卷任务
+            if (group.getDoubleRate() != null && group.getDoubleRate() > Math.random()) {
+                library = new MarkLibrary();
+                library.setExamId(student.getExamId());
+                library.setSubjectCode(student.getSubjectCode());
+                library.setGroupNumber(group.getNumber());
+                library.setCampusId(campus.getId());
+                library.setStudentId(student.getId());
+                library.setExamNumber(student.getExamNumber());
+                library.setTaskNumber(2);
+                library.setStatus(LibraryStatus.WAITING);
+                libraryDao.saveAndFlush(library);
+            }
         }
+        group.setBuildTime(student.getUploadTime());
+        groupDao.updateBuildTime(group.getExamId(), group.getSubjectCode(), group.getNumber(), student.getUploadTime());
+        updateLibraryCount(group.getExamId(), group.getSubjectCode(), group.getNumber());
+    }
+
+    /**
+     * 领取评卷任务时,用来区分的唯一标识<br/>
+     * 多评时同一个考生的多份任务不能被同一位评卷员领取
+     * 
+     * @param library
+     * @return
+     */
+    private String getApplyTaskId(MarkLibrary library) {
+        return library.getStudentId() + "_" + library.getGroupNumber();
     }
 
 }

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

@@ -114,7 +114,7 @@ public class TaskServiceImpl implements TaskService {
         // 构造仲裁信息
         List<ArbitrationDTO> list = new ArrayList<ArbitrationDTO>();
         for (MarkLibrary library : libraryList) {
-            if (library.getStatus() == LibraryStatus.WAIT_ARBITRATE) {
+            if (library.getStatus() != LibraryStatus.WAITING) {
                 list.add(new ArbitrationDTO(library, markerService.findById(library.getMarkerId())));
             }
         }

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

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.biz.mark.service;
 import java.util.List;
 import java.util.Map;
 
+import cn.com.qmth.stmms.biz.campus.model.Campus;
 import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.model.Marker;
@@ -153,13 +154,12 @@ public interface MarkService {
     int applyCount(Marker marker);
 
     /**
-     * 定时生成评卷任务
-     */
-    void buildLibrary();
-
-    /**
-     * 自动释放超时未处理的评卷任务
+     * 根据考生、学习中心、大题构造评卷任务
+     * 
+     * @param student
+     * @param campus
+     * @param group
      */
-    void cronCleanTask();
+    void buildLibrary(ExamStudent student, Campus campus, MarkGroup group);
 
 }

+ 12 - 11
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/CurrentTaskUtil.java

@@ -5,6 +5,8 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang.StringUtils;
+
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multiset;
 import com.google.common.collect.SetMultimap;
@@ -28,9 +30,9 @@ public class CurrentTaskUtil {
      * @param libraryId
      * @return
      */
-    public static boolean add(Marker marker, int libraryId) {
+    public static boolean add(Marker marker, String taskId) {
         String key = getKey(marker);
-        TaskEntry obj = new TaskEntry(marker.getId(), libraryId);
+        TaskEntry obj = new TaskEntry(marker.getId(), taskId);
 
         synchronized (CurrentTaskUtil.class) {
             if (taskMap.containsEntry(key, obj)) {
@@ -48,8 +50,8 @@ public class CurrentTaskUtil {
      * @param marker
      * @param libraryId
      */
-    public static void remove(Marker marker, int libraryId) {
-        TaskEntry obj = new TaskEntry(marker.getId(), libraryId);
+    public static void remove(Marker marker, String taskId) {
+        TaskEntry obj = new TaskEntry(marker.getId(), taskId);
         synchronized (CurrentTaskUtil.class) {
             taskMap.remove(getKey(marker), obj);
         }
@@ -178,32 +180,31 @@ class TaskEntry {
 
     int markerId;
 
-    int libraryId;
+    String taskId;
 
     public long timestamp;
 
-    public TaskEntry(int markerId, int libraryId) {
+    public TaskEntry(int markerId, String taskId) {
         this.markerId = markerId;
-        this.libraryId = libraryId;
+        this.taskId = taskId;
         this.timestamp = System.currentTimeMillis();
-        ;
     }
 
     @Override
     public int hashCode() {
-        return libraryId;
+        return taskId.hashCode();
     }
 
     @Override
     public String toString() {
-        return markerId + "-" + libraryId;
+        return markerId + "-" + taskId;
     }
 
     @Override
     public boolean equals(Object obj) {
         if (obj != null && obj instanceof TaskEntry) {
             TaskEntry mt = (TaskEntry) obj;
-            return mt.libraryId == this.libraryId;
+            return StringUtils.equals(mt.taskId, this.taskId);
         } else {
             return false;
         }

+ 5 - 3
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ArbitrateController.java

@@ -128,6 +128,7 @@ public class ArbitrateController extends BaseExamController {
         model.addAttribute("cardServer", cardServer);
         model.addAttribute("subject", subjectService.find(group.getExamId(), group.getSubjectCode()));
         model.addAttribute("group", group);
+        model.addAttribute("history", history);
         return "modules/exam/arbitrateSingleProcess";
     }
 
@@ -225,7 +226,7 @@ public class ArbitrateController extends BaseExamController {
         return task;
     }
 
-    @RequestMapping(value = "/getTask", method = RequestMethod.POST)
+    @RequestMapping("/getTask")
     @ResponseBody
     @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
     public Task getTask(HttpServletRequest request, @RequestParam String subjectCode,
@@ -271,7 +272,8 @@ public class ArbitrateController extends BaseExamController {
         WebUser wu = RequestUtils.getWebUser(request);
         ArbitrateHistory history = arbitrateService.findById(task.getLibraryId());
         JSONObject result = new JSONObject();
-        if (history != null && subjectCheck(history.getSubjectCode(), wu)) {
+        if (history != null && subjectCheck(history.getSubjectCode(), wu) && task.getTotalScore() >= 0
+                && task.getScoreList() != null) {
             try {
                 history.setUserId(wu.getUser().getId());
                 history.setTotalScore(task.getTotalScore());
@@ -356,7 +358,7 @@ public class ArbitrateController extends BaseExamController {
 
     private boolean setCurrent(Integer taskId, Integer userId) {
         Integer value = currentTaskMap.get(taskId);
-        if (value != null) {
+        if (value == null) {
             synchronized (currentTaskMap) {
                 value = currentTaskMap.get(taskId);
                 if (value == null) {

+ 0 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/BaseController.java

@@ -145,7 +145,6 @@ public class BaseController {
         }
         calculateObjectiveScore(student);
         ExamStudent saved = studentService.save(student);
-        examService.updateUploadTime(student.getExamId());
         subjectService.updateUploadCount(student.getExamId(), student.getSubjectCode());
         return saved;
     }

+ 10 - 5
stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java

@@ -188,16 +188,21 @@ public class MarkController extends BaseController {
         query.setGroupNumber(marker.getGroupNumber());
         long totalCount = libraryService.countByQuery(query);
 
-        query.setStatus(LibraryStatus.MARKED);
-        long markedCount = libraryService.countByQuery(query);
-
         query.setMarkerId(marker.getId());
         long personCount = libraryService.countByQuery(query);
 
+        query.addStatus(LibraryStatus.MARKED);
+        query.addStatus(LibraryStatus.ARBITRATED);
+        long markedCount = libraryService.countByQuery(query);
+
+        query.clearStatus();
+        query.addStatus(LibraryStatus.WAIT_ARBITRATE);
+        long exceptionCount = libraryService.countByQuery(query);
+
         status.accumulate("personCount", personCount);
         status.accumulate("totalCount", totalCount);
         status.accumulate("markedCount", markedCount);
-        status.accumulate("exceptionCount", 0);
+        status.accumulate("exceptionCount", exceptionCount);
         status.accumulate("valid", totalCount > 0);
         status.accumulate("topCount", marker.getTopCount() == null ? 0 : marker.getTopCount());
         return status;
@@ -295,7 +300,7 @@ public class MarkController extends BaseController {
         query.setExamId(marker.getExamId());
         query.setSubjectCode(marker.getSubjectCode());
         query.setMarkerId(marker.getId());
-        query.setStatus(LibraryStatus.MARKED);
+        query.addStatus(LibraryStatus.MARKED);
         query.setGroupNumber(marker.getGroupNumber());
         query.setPageNumber(pageNumber);
         query.setPageSize(pageSize);

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

@@ -41,14 +41,14 @@
 				staticServer : '${ctxStatic}',
 				imageServer : '${sliceServer}',
 				userName : '${web_user.name}',
-				logoutTitle: '返回',
-				logoutUrl: '${ctx}/admin/exam/arbitrate?subjectCode=${group.subjectCode}&groupNumber=${group.number}',
+				logoutTitle: '关闭',
+				logoutUrl: 'javascript:window.close()',
 				clearUrl: '${ctx}/admin/exam/arbitrate/clear',
 				modules : {
 					'single-image-view' : {},
 					'image-builder': {},
 					'header-mark-status': {
-						title : '${group.subjectCode}_${group.title}'
+						title : '${subject.code}_${subject.name}_${group.title}'
 					},
 					'mark-history':{
                         pageSize:10
@@ -79,7 +79,7 @@
 				mode : 'loop',
 				statusUrl : '${ctx}/admin/exam/arbitrate/status?subjectCode=${group.subjectCode}&groupNumber=${group.number}',
 				getUrl : '${ctx}/admin/exam/arbitrate/getTask?subjectCode=${group.subjectCode}&groupNumber=${group.number}',
-				historyUrl : '${ctx}/subjectheader/arbitration/history/${group.subjectCode}/${group.number}',
+				historyUrl : '${ctx}/subjectheader/arbitrate/history/${group.subjectCode}/${group.number}',
 				submitUrl : '${ctx}/admin/exam/arbitrate/saveTask',
 				clearUrl : '${ctx}/admin/exam/arbitrate/clear'
 			});

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

@@ -42,7 +42,7 @@
 			&nbsp;
 			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
 			&nbsp;
-            <a href="##" class="btn" id="batch-process-link">批量处理</a>
+            <a href="##" class="btn" id="batch-process-link" target="_blank">批量处理</a>
 		</div>
 	</form>
 	<tags:message content="${message}"/>
@@ -87,7 +87,7 @@
                 </td>
 				<td>
 				    <c:if test="${result.status.value==0 || result.status.value==1}">
-                    <a href="${ctx}/admin/exam/arbitrte/process?historyId=${reusult.id}" class="process-link">处理</a>
+                    <a href="${ctx}/admin/exam/arbitrate/process?historyId=${result.id}" target="_blank" class="process-link">处理</a>
 					</c:if>
 				</td>
 			</tr>
@@ -120,7 +120,7 @@ $('#batch-process-link').click(function(){
         alert('请选择大题')
         return false;
     }
-    $('#process-link').attr('href', '${ctx}/admin/exam/arbitrate/batchProcess?subjectCode='+subjectCode+'&groupNumber='+groupNumber);
+    $('#batch-process-link').attr('href', '${ctx}/admin/exam/arbitrate/batchProcess?subjectCode='+subjectCode+'&groupNumber='+groupNumber);
     return true;
 });
 $('#subject-select').change(function(){

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

@@ -40,13 +40,14 @@
 				staticServer : '${ctxStatic}',
 				imageServer : '${sliceServer}',
 				userName : '${web_user.name}',
-				logoutTitle: '返回',
-				logoutUrl: '${ctx}/admin/exam/arbitrate?subjectCode=${group.subjectCode}&groupNumber=${group.number}',
+				logoutTitle: '关闭',
+				logoutUrl: 'javascript:window.close()',
+				submitUrl: '${ctx}/admin/exam/arbitrate/saveTask',
 				modules : {
 					'single-image-view' : {},
 					'image-builder': {},
 					'header-mark-status': {
-						title : '${group.subjectCode}_${group.title}'
+						title : '${subject.code}_${subject.name}_${group.title}'
 					},
 					'mark-board' : {
 						showScoreBoard : false,
@@ -71,12 +72,12 @@
 				}
 			});
 			mc.on('task.submit.success', this, function(event, context){
-                window.location.href='${ctx}/admin/exam/arbitrate?subjectCode=${group.subjectCode}&groupNumber=${group.number}';
+                window.close();
             });
             mc.on('task.submit.error', this, function(event, context){
-                window.location.href='${ctx}/admin/exam/arbitrate?subjectCode=${group.subjectCode}&groupNumber=${group.number}';
+                //window.close();
             });
-            $.post('${ctx}/admin/exam/arbitration/singleTask?historyId=${history.id}', {}, function(task){
+            $.post('${ctx}/admin/exam/arbitrate/singleTask?historyId=${history.id}', {}, function(task){
                 mc.setTask(task);
             });
 		});

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

@@ -46,6 +46,7 @@
 				userName : '${web_user.name}',
 				logoutUrl: '${ctx}/mark/logout',
 				clearUrl: '${ctx}/mark/clear',
+				switchTrackUrl: '${ctx}/mark/index?mode=track',
 				modules : {
 					'single-image-view' : {},
 					'image-builder': {},

+ 13 - 2
stmms-web/src/main/webapp/static/mark-new/js/mark-control.js

@@ -38,6 +38,11 @@ MarkControl.prototype.initContainer = function() {
     }
     this.container.center = getDom(this.center_dom, this).appendTo(this.container);
     this.container.header = getDom(this.center_header_dom, this).appendTo(this.container.center).find('.header');
+    if(this.option.switchTrackUrl!=undefined && this.option.switchTrackUrl.length>0){
+    	var switchButton = this.container.header.find('#switch-track-button');
+    	switchButton.attr('href', this.option.switchTrackUrl);
+    	switchButton.show();
+    }
     this.container.centerContent = getDom(this.center_content_dom, this).appendTo(this.container.center);
     this.container.imageContent = getDom(this.image_content_dom, this).appendTo(this.container.centerContent);
 
@@ -490,10 +495,14 @@ MarkControl.prototype.submitTask = function(submitUrl) {
     if (task != undefined && this.context.submitting != true) {
         task.markStepList = undefined;
         task.pictureUrls = undefined;
+        task.pictureConfig = undefined;
         task.sheetUrls = undefined;
+        task.paperUrl = undefined;
+        task.answerUrl = undefined;
         task.imageData = undefined;
         task.markFinish = undefined;
         task.markTime = undefined;
+        task.arbitrationList = undefined;
 
         this.trigger('task.submit.before');
         if (this.taskControl != undefined) {
@@ -514,7 +523,9 @@ MarkControl.prototype.submitTask = function(submitUrl) {
             $.ajax({
                 url: submitUrl,
                 type: 'POST',
-                data: task,
+        		data: JSON.stringify(task),
+        		dataType: "json",
+        		contentType : 'application/json;charset=utf-8',
                 success: function(result) {
                     if (result.success == true) {
                         //markControl.context.task = undefined;
@@ -547,7 +558,7 @@ MarkControl.prototype.sidebar_dom = '<div class="mark-sidebar span2 hide"></div>
 MarkControl.prototype.center_dom = '<div class="center-content span12"></div>';
 
 MarkControl.prototype.center_header_dom = '<div class="row-fluid"><div class="header"><p class="tips">\
-<em><a href="/mark/index?mode=track" class="btn">切换到轨迹模式</a>\
+<em><a href="##" class="btn" id="switch-track-button" style="display:none">切换到轨迹模式</a>\
 <a href="javascript:void(0)" id="assistant-button" class="btn"><i class="icon-wrench"></i> 小助手</a></em>\
 <a class="useinfo" href="#"><i class="icon-user icon-white"></i><i id="mark-user-name"></i></a>\
 <a class="logout" id="logout-link" href="{logoutUrl}"><i class="icon-off icon-white"></i> <i id="logout-title">退出</i></a>\

+ 2 - 2
stmms-web/src/main/webapp/static/mark-new/js/modules/header-mark-status.js

@@ -45,8 +45,8 @@ HeaderMarkStatus.prototype.render = function(status) {
     if (status != undefined && status.valid === true) {
         this.progress.show();
         //进度信息区域
-        var totalCount = status.blockTotalCount;
-        var markedCount = status.blockMarkedCount;
+        var totalCount = status.totalCount;
+        var markedCount = status.markedCount;
         var leftCount = totalCount > markedCount ? (totalCount - markedCount) : 0;
         var markedPercent = totalCount > 0 ? new Number((totalCount - leftCount) * 100 / totalCount).toFixed(0) : 0;
         if (markedPercent == '100' && leftCount > 0) {