Sfoglia il codice sorgente

增加复核相关

ting.yin 4 anni fa
parent
commit
efb8beaf5a

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

@@ -3,6 +3,7 @@ package cn.com.qmth.stmms.biz.exam.dao;
 import cn.com.qmth.stmms.biz.exam.model.SubjectiveScore;
 import cn.com.qmth.stmms.biz.exam.model.SubjectiveScorePK;
 import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
+
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.PagingAndSortingRepository;
@@ -37,4 +38,7 @@ public interface SubjectiveScoreDao extends PagingAndSortingRepository<Subjectiv
             + "(select g.pk.studentId from MarkGroupStudent g where g.pk.studentId=s.pk.studentId and g.status=?4)")
     void deleteByStudentGroupStatus(Integer examId, String subjectCode, Integer groupNumber, SubjectiveStatus status);
 
+    @Query("select s.pk.studentId from SubjectiveScore s where "
+            + "s.examId=?1 and s.subjectCode=?2 and s.groupScore=?3 and s.score=?4")
+    List<Integer> findStudentIdByGroupScoreAndScore(Integer examId, String subjectCode, Double groupScore, Double score);
 }

+ 16 - 4
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/query/ExamStudentSearchQuery.java

@@ -1,12 +1,14 @@
 package cn.com.qmth.stmms.biz.exam.query;
 
-import cn.com.qmth.stmms.biz.common.BaseQuery;
-import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
-import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
+import java.util.Date;
+import java.util.List;
+
 import org.springframework.data.domain.Sort;
 import org.springframework.data.domain.Sort.Direction;
 
-import java.util.Date;
+import cn.com.qmth.stmms.biz.common.BaseQuery;
+import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
+import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
 
 public class ExamStudentSearchQuery extends BaseQuery<ExamStudent> {
 
@@ -86,6 +88,8 @@ public class ExamStudentSearchQuery extends BaseQuery<ExamStudent> {
 
     private String paperType;
 
+    private List<Integer> studentIds;
+
     public void orderByExamNumber() {
         setSort(new Sort(Direction.ASC, "examNumber"));
     }
@@ -397,4 +401,12 @@ public class ExamStudentSearchQuery extends BaseQuery<ExamStudent> {
     public void setSubjectiveStatus(SubjectiveStatus subjectiveStatus) {
         this.subjectiveStatus = subjectiveStatus;
     }
+
+    public List<Integer> getStudentIds() {
+        return studentIds;
+    }
+
+    public void setStudentIds(List<Integer> studentIds) {
+        this.studentIds = studentIds;
+    }
 }

+ 30 - 32
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamStudentServiceImpl.java

@@ -155,8 +155,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             if (student.getSecretNumber() == null) {
                 student.randomSecretNumber();
                 while (secretNumberSet.contains(student.getSecretNumber())
-                        || studentDao.countByExamIdAndSecretNumber(student.getExamId(), student.getSecretNumber())
-                        > 0) {
+                        || studentDao.countByExamIdAndSecretNumber(student.getExamId(), student.getSecretNumber()) > 0) {
                     student.randomSecretNumber();
                 }
             }
@@ -376,10 +375,9 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     @Transactional
     public boolean updateScanInfo(ExamStudent student) {
         student.setUploadTime(new Date());
-        return studentDao
-                .updateScanInfo(student.getId(), student.getSheetCount(), student.getSliceCount(), student.getAnswers(),
-                        student.getBatchCode(), student.getPaperType(), student.isAbsent(), student.getUploadTime(),
-                        student.getObjectiveScore(), student.getObjectiveScoreList()) > 0;
+        return studentDao.updateScanInfo(student.getId(), student.getSheetCount(), student.getSliceCount(),
+                student.getAnswers(), student.getBatchCode(), student.getPaperType(), student.isAbsent(),
+                student.getUploadTime(), student.getObjectiveScore(), student.getObjectiveScoreList()) > 0;
     }
 
     @Override
@@ -446,14 +444,14 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             @Override
             public Predicate toPredicate(Root<ExamStudent> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                 List<Predicate> predicates = new LinkedList<Predicate>();
-                Expression<Double> evaluationItemSum = cb
-                        .sum(root.get("objectiveScore").as(Double.class), root.get("subjectiveScore").as(Double.class));
+                Expression<Double> evaluationItemSum = cb.sum(root.get("objectiveScore").as(Double.class),
+                        root.get("subjectiveScore").as(Double.class));
                 if (query.getStartScroe() != null) {
                     Predicate predicate1 = cb.ge(evaluationItemSum, query.getStartScroe());
                     Predicate predicate2 = cb.le(evaluationItemSum, query.getEndScroe());
                     if (query.getStartScroe() == 0) {
-                        Predicate predicate = cb
-                                .or(cb.equal(root.get("absent"), true), cb.equal(root.get("breach"), true));
+                        Predicate predicate = cb.or(cb.equal(root.get("absent"), true),
+                                cb.equal(root.get("breach"), true));
                         Predicate predicate3 = cb.and(predicate1, predicate2);
                         predicates.add(cb.or(predicate, predicate3));
                     } else {
@@ -481,6 +479,9 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                     }
                     predicates.add(root.get("id").in(list));
                 }
+                if (query.getStudentIds() != null) {
+                    predicates.add(root.get("id").in(query.getStudentIds()));
+                }
                 if (StringUtils.isNotBlank(query.getExamNumber())) {
                     predicates.add(cb.equal(root.get("examNumber"), query.getExamNumber()));
                 } else if (StringUtils.isNotBlank(query.getExamNumberIn())) {
@@ -620,9 +621,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                 if (StringUtils.isNotBlank(query.getTeacher())) {
                     predicates.add(cb.equal(root.get("teacher"), query.getTeacher()));
                 }
-                return predicates.isEmpty() ?
-                        cb.conjunction() :
-                        cb.and(predicates.toArray(new Predicate[predicates.size()]));
+                return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[predicates
+                        .size()]));
             }
         };
     }
@@ -641,8 +641,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     @Override
     public ExamStudent findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(Integer schoolId, String subjectCode,
             String studentCode, String examSeqCode) {
-        return studentDao
-                .findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(schoolId, subjectCode, studentCode, examSeqCode);
+        return studentDao.findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(schoolId, subjectCode, studentCode,
+                examSeqCode);
     }
 
     @Override
@@ -681,9 +681,9 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         query.setPageNumber(1);
         query.setPageSize(1);
         query.setSort(new Sort(Direction.ASC, "uploadTime", "id"));
-        List<ExamStudent> list = minUploadTime != null ?
-                studentDao.findUnLibraryStudent(examId, subjectCode, groupNumber, minUploadTime, query) :
-                studentDao.findUnLibraryStudent(examId, subjectCode, groupNumber, query);
+        List<ExamStudent> list = minUploadTime != null ? studentDao.findUnLibraryStudent(examId, subjectCode,
+                groupNumber, minUploadTime, query) : studentDao.findUnLibraryStudent(examId, subjectCode, groupNumber,
+                query);
         return list.isEmpty() ? null : list.get(0);
     }
 
@@ -722,8 +722,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return countByQuery(query);
     }
 
-    public long countByNoAbsentAndBreach(int examId, String subjectCode, boolean upload, boolean absent,
-            boolean breach) {
+    public long countByNoAbsentAndBreach(int examId, String subjectCode, boolean upload, boolean absent, boolean breach) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
         query.setSubjectCode(subjectCode);
@@ -816,8 +815,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     @Override
     public Map<MarkGroup, List<OriginTag>> getSliceTags(ExamStudent student) {
         Map<MarkGroup, List<OriginTag>> tagMap = new HashMap<MarkGroup, List<OriginTag>>();
-        List<ExamQuestion> questions = questionService
-                .findByExamAndSubjectAndObjective(student.getExamId(), student.getSubjectCode(), false);
+        List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjective(student.getExamId(),
+                student.getSubjectCode(), false);
         List<ScoreItem> scoreList = student.getScoreList(false);
         List<MarkGroup> markGroups = groupService.findByExamAndSubject(student.getExamId(), student.getSubjectCode());
         for (MarkGroup group : markGroups) {
@@ -839,14 +838,13 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         List<String> lines = new LinkedList<>();
         lines.add("成绩明细");
         // 总分得分明细
-        lines.add("总分 (客观+主观) | " + format.format(student.getTotalScore()) + "=" + format
-                .format(student.getObjectiveScore() != null ? student.getObjectiveScore() : 0) + "+" + format
-                .format(student.getSubjectiveScore() != null ? student.getSubjectiveScore() : 0));
+        lines.add("总分 (客观+主观) | " + format.format(student.getTotalScore()) + "="
+                + format.format(student.getObjectiveScore() != null ? student.getObjectiveScore() : 0) + "+"
+                + format.format(student.getSubjectiveScore() != null ? student.getSubjectiveScore() : 0));
         // 客观题得分明细
         List<String> objectives = new LinkedList<>();
-        List<ExamQuestion> questions = questionService
-                .findByExamAndSubjectAndObjectiveAndPaperType(student.getExamId(), student.getSubjectCode(), true,
-                        student.getPaperType());
+        List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndPaperType(
+                student.getExamId(), student.getSubjectCode(), true, student.getPaperType());
         List<ScoreItem> scoreList = student.getScoreList(true);
         List<String> details = new ArrayList<>();
         int i = 0;
@@ -914,10 +912,10 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         // 首先添加本大题总得分
         List<PictureConfigItem> configList = group.getPictureConfigList();
         if (configList.isEmpty()) {
-            //未设置评卷区域,则自动取第一张裁切图的固定位置
+            // 未设置评卷区域,则自动取第一张裁切图的固定位置
             originTags.add(new OriginTag(format.format(score), 1, 10, 10));
         } else {
-            //取第一个显示区域相对裁切图的位置
+            // 取第一个显示区域相对裁切图的位置
             PictureConfigItem config = configList.get(0);
             originTags.add(new OriginTag(format.format(score), config.getI(), config.getX(), config.getY()));
         }
@@ -934,8 +932,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             // 添加轨迹分
             List<MarkTrack> tracks = trackService.findByLibraryId(selected.getId());
             for (MarkTrack markTrack : tracks) {
-                originTags.add(new OriginTag(format.format(markTrack.getScore()), markTrack.getOffsetIndex(),
-                        markTrack.getOffsetX(), markTrack.getOffsetY()));
+                originTags.add(new OriginTag(format.format(markTrack.getScore()), markTrack.getOffsetIndex(), markTrack
+                        .getOffsetX(), markTrack.getOffsetY()));
             }
             // 添加特殊标记
             List<MarkSpecialTag> specialTags = specialTagService.findByLibraryId(selected.getId());

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

@@ -1,11 +1,16 @@
 package cn.com.qmth.stmms.common.enums;
 
+import java.util.LinkedList;
+import java.util.List;
+
 public enum SubjectiveStatus {
 
     UNMARK("未评完"), MARKED("已评完"), INSPECTED("已复核");
 
     private String name;
 
+    private static List<SubjectiveStatus> options;
+
     private SubjectiveStatus(String name) {
         this.name = name;
     }
@@ -22,4 +27,16 @@ public enum SubjectiveStatus {
         }
         return null;
     }
+
+    public static List<SubjectiveStatus> getOptionList() {
+        if (options == null) {
+            options = new LinkedList<>();
+            for (SubjectiveStatus status : SubjectiveStatus.values()) {
+                if (status != UNMARK) {
+                    options.add(status);
+                }
+            }
+        }
+        return options;
+    }
 }

+ 146 - 96
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/InspectedController.java

@@ -1,47 +1,53 @@
 package cn.com.qmth.stmms.admin.exam;
 
-import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import cn.com.qmth.stmms.biz.exam.dao.SubjectiveScoreDao;
 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;
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
 import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
 import cn.com.qmth.stmms.biz.exam.service.MarkerService;
 import cn.com.qmth.stmms.biz.file.service.FileService;
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
-import cn.com.qmth.stmms.biz.mark.model.MarkTrack;
-import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
+import cn.com.qmth.stmms.biz.lock.LockService;
 import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
 import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
 import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
-import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.biz.user.service.UserService;
 import cn.com.qmth.stmms.biz.utils.ScoreItem;
 import cn.com.qmth.stmms.common.annotation.Logging;
 import cn.com.qmth.stmms.common.annotation.RoleRequire;
 import cn.com.qmth.stmms.common.domain.WebUser;
-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 cn.com.qmth.stmms.common.enums.SubjectiveStatus;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.servlet.ModelAndView;
-import org.springframework.web.servlet.mvc.support.RedirectAttributes;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.*;
 
 @Controller("inspectedController")
 @RequestMapping("/admin/exam/inspected")
@@ -76,92 +82,103 @@ public class InspectedController extends BaseExamController {
     @Autowired
     private FileService fileService;
 
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private SubjectiveScoreDao scoreDao;
+
     // 并发处理互斥锁
     private Map<Integer, Integer> currentTaskMap = new HashMap<Integer, Integer>();
 
+    @RequestMapping
+    public String list(Model model, HttpServletRequest request, ExamStudentSearchQuery query,
+            @RequestParam(required = false) Integer groupNumber, @RequestParam(required = false) Double groupScore,
+            @RequestParam(required = false) Double questionScore) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        query.setExamId(examId);
+        List<ExamSubject> subjectList = getExamSubject(examId, wu);
+        if (query.getSubjectCode() == null && !subjectList.isEmpty()) {
+            query.setSubjectCode(subjectList.get(0).getCode());
+        }
+        if (groupNumber != null || groupScore != null || questionScore != null) {
+            List<Integer> studentIds = scoreDao.findStudentIdByGroupScoreAndScore(examId, query.getSubjectCode(),
+                    groupScore, questionScore);
+            query.setStudentIds(studentIds);
+        }
+        query = studentService.findByQuery(query);
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", subjectList);
+        model.addAttribute("statusList", SubjectiveStatus.getOptionList());
+        return "modules/exam/inspectedList";
+    }
+
     @Logging(menu = "开始复核", type = LogType.QUERY)
     @RequestMapping("/start")
     @ResponseBody
     public ModelAndView start(HttpServletRequest request, RedirectAttributes redirectAttributes,
-            @RequestParam String subjectCode, @RequestParam Integer groupNumber) {
+            ExamStudentSearchQuery query, @RequestParam(required = false) Integer groupNumber,
+            @RequestParam(required = false) Double groupScore, @RequestParam(required = false) Double questionScore) {
         int examId = getSessionExamId(request);
-        MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
         WebUser wu = RequestUtils.getWebUser(request);
         releaseByUser(wu.getUser().getId());
         ModelAndView view = new ModelAndView("modules/exam/inspected");
-
-        if (group == null) {
-            view.addObject("message", "大题不存在或评卷已结束");
-            return view;
-        } else if (group.getStatus() == MarkStatus.FINISH) {
-            view.addObject("message", "评卷已结束");
-            return view;
-        } else if (group.getStatus() == MarkStatus.TRIAL) {
-            view.addObject("message", "试评任务无需复核");
-            return view;
-        } else {
-            List<Integer> ids = new ArrayList<Integer>();
-            MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
-            query.setExamId(examId);
-            query.setSubjectCode(subjectCode);
-            query.setGroupNumber(groupNumber);
-            query.setPageNumber(1);
-            query.setPageSize(1000);
-            query.addStatus(LibraryStatus.MARKED);
-            query = libraryService.findByQuery(query);
-            while (query.getCurrentCount() > 0) {
-                for (MarkLibrary library : query.getResult()) {
-                    ids.add(library.getId());
-                }
-                query.setPageNumber(query.getPageNumber() + 1);
-                query = libraryService.findByQuery(query);
-            }
-            view.addObject("fileServer", fileService.getFileServer());
-            view.addObject("ids", StringUtils.join(ids, ","));
-            return view;
+        query.setExamId(examId);
+        List<ExamSubject> subjectList = getExamSubject(examId, wu);
+        if (query.getSubjectCode() == null && !subjectList.isEmpty()) {
+            query.setSubjectCode(subjectList.get(0).getCode());
         }
+        if (groupNumber != null || groupScore != null || questionScore != null) {
+            List<Integer> studentIds = scoreDao.findStudentIdByGroupScoreAndScore(examId, query.getSubjectCode(),
+                    groupScore, questionScore);
+            query.setStudentIds(studentIds);
+        }
+        query = studentService.findByQuery(query);
+        List<Integer> ids = new ArrayList<Integer>();
+        for (ExamStudent student : query.getResult()) {
+            ids.add(student.getId());
+        }
+        view.addObject("fileServer", fileService.getFileServer());
+        view.addObject("ids", StringUtils.join(ids, ","));
+        return view;
     }
 
     @RequestMapping("/info")
     @ResponseBody
-    public Object info(HttpServletRequest request, @RequestParam Integer libraryId) {
+    public Object info(HttpServletRequest request, @RequestParam Integer studentId) {
         WebUser wu = RequestUtils.getWebUser(request);
-        MarkLibrary library = libraryService.findById(libraryId);
+        ExamStudent student = studentService.findById(studentId);
         JSONObject result = new JSONObject();
-        if (setCurrent(library.getId(), wu.getUser().getId())) {
-            ExamStudent student = studentService.findById(library.getStudentId());
-            result.accumulate("id", libraryId);
-            result.accumulate("studentId", library.getStudentId());
-            result.accumulate("subjectCode", library.getSubjectCode());
+        if (setCurrent(student.getId(), wu.getUser().getId())) {
+            result.accumulate("id", student.getId());
+            result.accumulate("subjectCode", student.getSubjectCode());
             result.accumulate("subjectName", student.getSubjectName());
-            Marker marker = markerService.findById(library.getMarkerId());
-            User user = userService.findById(marker.getUserId());
-            result.accumulate("markerName", user.getLoginName());
-            result.accumulate("markerScore", library.getMarkerScore());
-
             JSONArray array = new JSONArray();
-            List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(
-                    library.getExamId(), library.getSubjectCode(), false, library.getGroupNumber());
-            List<ScoreItem> scores = library.getScoreList();
-            for (int i = 0; i < questions.size(); i++) {
-                ExamQuestion question = questions.get(i);
+            List<ScoreItem> scores = student.getScoreList(false);
+            for (ScoreItem scoreItem : scores) {
                 JSONObject obj = new JSONObject();
-                obj.accumulate("questionNumber", question.getMainTitle() + " " + question.getQuestionNumber());
-                obj.accumulate("score", scores.get(i).getScore());
+                obj.accumulate("questionNumber", scoreItem.getMainNumber() + "-" + scoreItem.getSubNumber());
+                obj.accumulate("score", scoreItem.getScore());
                 array.add(obj);
             }
             result.accumulate("questions", array);
 
-            MarkGroup group = groupService.findOne(student.getExamId(), student.getSubjectCode(),
-                    library.getGroupNumber());
-            List<String> picUrls = fileService.getSliceUris(student.getExamId(), student.getSecretNumber(), 1,
-                    student.getSliceCount());
-            List<MarkTrack> markTracks = markTrackService.findByLibraryId(library.getId());
-            List<MarkSpecialTag> markSpecialTagList = markSpecialTagService.findByLibraryId(library.getId());
-            result.accumulate("picUrls", picUrls);
-            result.accumulate("pictureConfig", group.getPictureConfigList());
-            result.accumulate("markTracks", markTracks);
-            result.accumulate("markSpecialTagList", markSpecialTagList);
+            // MarkGroup group = groupService.findOne(student.getExamId(),
+            // student.getSubjectCode(),
+            // library.getGroupNumber());
+            // List<String> picUrls =
+            // fileService.getSliceUris(student.getExamId(),
+            // student.getSecretNumber(), 1,
+            // student.getSliceCount());
+            // List<MarkTrack> markTracks =
+            // markTrackService.findByLibraryId(library.getId());
+            // List<MarkSpecialTag> markSpecialTagList =
+            // markSpecialTagService.findByLibraryId(library.getId());
+            // result.accumulate("picUrls", picUrls);
+            // result.accumulate("pictureConfig", group.getPictureConfigList());
+            // result.accumulate("markTracks", markTracks);
+            // result.accumulate("markSpecialTagList", markSpecialTagList);
             result.accumulate("success", true);
         } else {
             result.accumulate("success", false);
@@ -169,18 +186,14 @@ public class InspectedController extends BaseExamController {
         return result;
     }
 
-    @Logging(menu = "复核评卷任务", type = LogType.UPDATE)
+    @Logging(menu = "评卷复核", type = LogType.UPDATE)
     @RequestMapping("/save")
     @ResponseBody
-    public Object save(HttpServletRequest request, @RequestParam Integer libraryId) {
-        MarkLibrary library = libraryService.findById(libraryId);
-        WebUser wu = RequestUtils.getWebUser(request);
-        if (library != null && library.getStatus().equals(LibraryStatus.MARKED)) {
-            // library.setStatus(LibraryStatus.INSPECTED);
-            library.setHeaderId(wu.getUser().getId());
-            library.setHeaderTime(new Date());
-            libraryService.save(library);
-            releaseTask(libraryId);
+    public Object save(HttpServletRequest request, @RequestParam Integer studentId) {
+        ExamStudent student = studentService.findById(studentId);
+        if (student != null && student.getSubjectiveStatus().equals(SubjectiveStatus.INSPECTED)) {
+            studentService.updateSubjectiveStatusAndScore(studentId, SubjectiveStatus.INSPECTED,
+                    student.getTotalScore(), student.getSubjectiveScoreList());
             return true;
         } else {
             return false;
@@ -200,6 +213,43 @@ public class InspectedController extends BaseExamController {
         return true;
     }
 
+    @Logging(menu = "取消复核", type = LogType.UPDATE)
+    @RequestMapping(value = "/back", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    public JSONObject back(HttpServletRequest request, @RequestParam Integer id) {
+        JSONObject obj = new JSONObject();
+        ExamStudent student = studentService.findById(id);
+        WebUser wu = RequestUtils.getWebUser(request);
+        if (studentService != null) {
+            if (subjectCheck(student.getSubjectCode(), wu)) {
+                try {
+                    if (lockService.trylock(LockType.STUDENT, student.getId())) {
+                        studentService.updateSubjectiveStatusAndScore(id, SubjectiveStatus.MARKED,
+                                student.getTotalScore(), student.getSubjectiveScoreList());
+                        obj.accumulate("success", true);
+                    } else {
+                        obj.accumulate("success", false);
+                        obj.accumulate("message", "无法取消复核");
+                    }
+                } catch (Exception e) {
+                    obj.accumulate("success", false);
+                    obj.accumulate("message", "取消复核失败");
+                    log.error("back library error", e);
+                } finally {
+                    lockService.unlock(LockType.STUDENT, student.getId());
+                }
+            } else {
+                obj.accumulate("success", false);
+                obj.accumulate("message", "没有操作该评卷任务的权限");
+            }
+        } else {
+            obj.accumulate("success", false);
+            obj.accumulate("message", "该阩不存在");
+        }
+        return obj;
+    }
+
     private boolean setCurrent(Integer taskId, Integer userId) {
         Integer value = currentTaskMap.get(taskId);
         if (value == null) {

+ 2 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/interceptor/AdminInterceptor.java

@@ -42,7 +42,8 @@ public class AdminInterceptor extends SessionInterceptor {
                         || wu.getRole() == Role.SUBJECT_HEADER || wu.getRole() == Role.SCHOOL_VIEWER)) {
             Integer examId = SessionExamUtils.getExamId(request);
             String uri = request.getRequestURI();
-            if (examId > 0 || uri.startsWith("/admin/exam/select") || uri.startsWith("/admin/home")) {
+            if (examId > 0 || uri.startsWith("/admin/exam/select") || uri.startsWith("/admin/home")
+                    || uri.startsWith("/admin/exam/create") || uri.startsWith("/admin/exam/save")) {
                 return true;
             }
             return redirect(request, response, "/admin/exam/select");

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

@@ -81,6 +81,11 @@
 					</c:forEach>
 				</select>
 	      </div>
+	      <c:if test="${web_user.schoolAdmin==true}">
+	      <div class="">
+	      	or <a href="${ctx}/admin/exam/create">新建考试</a>
+	      </div>
+	      </c:if>
 	        <div class="point hide" >
 	        	<em class="error"></em>
 	        </div>

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

@@ -0,0 +1,161 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
+<html>
+<head>
+    <title>成绩复核</title>
+    <meta name="decorator" content="default"/>
+    <%@include file="/WEB-INF/views/include/head.jsp" %>
+    <style type="text/css">.sort {
+        color: #0663A2;
+        cursor: pointer;
+    }</style>
+</head>
+<body>
+<form id="searchForm" action="${ctx}/admin/exam/problem/history" method="post" class="breadcrumb form-search">
+    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>
+    <input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize }"/>
+    <div>
+        <label>科目</label>
+        <select class="input-large" name="subjectCode" id="subject-select">
+            <option value="">请选择</option>
+            <c:forEach items="${subjectList}" var="subject">
+                <option value="${subject.code}" <c:if test="${subject.code==query.subjectCode}">selected</c:if>>${subject.code}-${subject.name}</option>
+            </c:forEach>
+        </select>
+        <label>分组</label>
+        <select class="input-medium" id="group-select" name="groupNumber">
+            <option value="">请选择</option>
+            <c:forEach items="${groupList}" var="item">
+                <option value="${item.number}" >${item.number}-${item.title}</option>
+            </c:forEach>
+        </select>
+        <label>状态</label>
+        <select class="input-medium" name="subjectiveScoreList">
+            <option value="">请选择</option>
+            <c:forEach items="${statusList}" var="status">
+                <option value="${status}">${status.name}</option>
+            </c:forEach>
+        </select>
+        &nbsp;
+        <label>试卷总分:从</label>
+        <input type="text" number="true" id="startScroe" name="startScroe" value="${query.startScroe}" class="input-medium"/>
+        <label> 到&nbsp;&nbsp;&nbsp;</label>
+        <input type="text" number="true" id="endScroe" name="endScroe" value="${query.endScroe}" class="input-medium"/>
+        &nbsp;
+        <label>大题得分</label>
+        <input type="text" number="true" name="groupScore" id="groupScore" value="" class="input-medium"/>
+        &nbsp;
+        <label>小题得分</label>
+        <input type="text" number="true" name="questionScore" id="questionScore" value="" class="input-medium"/>
+        &nbsp;
+        <input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+        <input id="btnSubmit" class="btn btn-primary" type="button" value="批量复核" onclick="goSearch()"/>
+    </div>
+</form>
+<tags:message content="${message}"/>
+<table id="contentTable" class="table table-striped table-bordered table-condensed">
+    <thead>
+    <tr>
+        <th>科目</th>
+        <th>考生编号</th>
+        <th>状态</th>
+        <th>试卷总分</th>
+        <th>大题得分明细</th>
+        <th>复核时间</th>
+        <th>操作</th>
+    </tr>
+    </thead>
+    <tbody>
+    <c:forEach items="${query.result}" var="result">
+        <tr>
+            <td>${result.subjectCode}-${result.subjectName}</td>
+            <td>${result.secretNumber}</td>
+            <td>${result.subjectiveStatus.name}</td>
+            <td>${result.totalScore}</td>
+            <td>${result.subjectiveScoreList}</td>
+            <td>${result.uploadTime}</td>
+            <td>
+                <c:if test="${examType=='MULTI_MEDIA'}">
+                    <a class="json-link" href="${ctx}/admin/exam/library/getJson?studentId=${result.id}" target="_blank">原图</a>
+                </c:if>
+                <c:if test="${examType!='MULTI_MEDIA'}">
+                    <a class="track-link" href="#" data-image-url="${ctx}/admin/exam/track/byLibrary?libraryId=${result.libraryId}" data-title="${result.examNumber}">阅卷轨迹</a>
+                </c:if>
+                <c:if test="${result.subjectiveStatus=='MARKED'}">
+	                <a class="json-link" href="${ctx}/admin/">进入复核</a>
+                </c:if>
+                <c:if test="${result.subjectiveStatus=='INSPECTED'}">
+                <a class="back-link" href="#" data-id="${result.id}">取消复核</a>
+                </c:if>
+            </td>
+        </tr>
+    </c:forEach>
+    </tbody>
+</table>
+<div class="pagination">${query}</div>
+<%@include file="/WEB-INF/views/include/trackView.jsp" %>
+<script type="text/javascript">
+    $(document).ready(function () {
+        /* new jBox('Image', {
+            imageFade: 0,
+            delayOpen: 0,
+            delayClose: 0,
+            maxHeight: $(window).height()*0.88
+        }); */
+        $('.back-link').click(function () {
+            if (!confirm('确定要打回该评卷任务吗?')) {
+                return;
+            }
+            $.post('${ctx}/admin/exam/inspacted/back', {id: $(this).attr('data-id')}, function (result) {
+                if (result.success == true) {
+                    alert('取消成功');
+                    $("#searchForm").submit();
+                } else {
+                    alert(result.message);
+                }
+            });
+        });
+        $('.track-link').click(function () {
+            initTrackPopover($(this).attr('data-title'), $(this).attr('data-image-url'));
+            return false;
+        });
+        $('#subject-select').change(function () {
+            var code = $(this).val();
+            $('#group-select').empty();
+            $("<option value='0'>请选择</option>").appendTo('#group-select');
+            if (code == '') {
+                $('#group-select').val('').trigger('change');
+                return;
+            }
+
+            $.post('${ctx}/admin/exam/group/query', {subjectCode: code, status: 'FORMAL'}, function (result) {
+                var parent = $('#group-select');
+                var first = '';
+                for (var i = 0; i < result.length; i++) {
+                    var group = result[i];
+                    $('<option value="' + group.number + '">' + group.number + '-' + group.title + '</option>').appendTo(parent);
+                    if (i == 0) {
+                        first = group.number;
+                    }
+                }
+                parent.val(first).trigger('change');
+            });
+        });
+    });
+
+    function page(n, s) {
+        $("#pageNumber").val(n);
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspacted');
+        $("#searchForm").submit();
+        return false;
+    }
+
+    function goSearch() {
+        $("#pageNumber").val(1);
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspacted');
+        $("#searchForm").submit();
+        return false;
+    }
+</script>
+</body>
+</html>