Przeglądaj źródła

Squashed commit of the following:

commit d4395266039ede9d184eeec98ae45033966aaa57
Author: ting.yin <ting.yin@192.168.11.32>
Date:   Sun Feb 7 10:23:47 2021 +0800

    update

commit 032ce03d1056940f8a7f6db1e16f5c5e3969a212
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Feb 5 17:05:35 2021 +0800

    fixbugs

commit 10ff5b01320be37bfd2ad27f3cbbe61b84b3b9ed
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Feb 5 14:48:46 2021 +0800

    未上传和缺考不显示图片

commit b793ac7d1198627e43164a5ac98d55d0e8e3b3ea
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Feb 5 14:26:10 2021 +0800

    update

commit f6a93a591635e3295c110af5a1dd5d82e45a1d16
Author: ting.yin <yinting@qmth.com.cn>
Date:   Fri Feb 5 09:26:36 2021 +0800

    update

commit e907cc35b7f88f0720cc0e771b304a5fd5be7f04
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Feb 3 14:09:50 2021 +0800

    update

commit 045df7136c940a6aab8d5c233ece637a01ae41d8
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Feb 3 10:17:50 2021 +0800

    update

commit 87769e4d53d2caf6c8b9608c58220884bf51a9a8
Author: ting.yin <yinting@qmth.com.cn>
Date:   Wed Feb 3 10:09:09 2021 +0800

    update

commit 2988d454f74af162cb8bfd06beb4bcfe6b1ffbe0
Author: ting.yin <yinting@qmth.com.cn>
Date:   Tue Feb 2 15:15:03 2021 +0800

    update

commit 48da26073a3f38de943857cdbaf5b2db740c3522
Author: ting.yin <yinting@qmth.com.cn>
Date:   Mon Feb 1 17:33:33 2021 +0800

    评卷复核功能扩展
luoshi 4 lat temu
rodzic
commit
ae7f2df981
23 zmienionych plików z 1080 dodań i 21 usunięć
  1. 1 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamDao.java
  2. 5 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamStudentDao.java
  3. 18 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ImportQueryDao.java
  4. 163 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ImportQuery.java
  5. 1 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamService.java
  6. 3 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamStudentService.java
  7. 13 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ImportQueryService.java
  8. 2 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamServiceImpl.java
  9. 6 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamStudentServiceImpl.java
  10. 39 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ImportQueryServiceImpl.java
  11. 31 0
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/ImportType.java
  12. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/BaseExamController.java
  13. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ExamController.java
  14. 311 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ImportQueryController.java
  15. 4 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/InspectedController.java
  16. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/log/OperationLogController.java
  17. 64 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/utils/PageUtil.java
  18. 25 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/vo/InspectedStudentVO.java
  19. 241 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/inspectedImport.jsp
  20. 103 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/inspectedImportList.jsp
  21. 21 7
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/inspectedList.jsp
  22. 20 1
      stmms-web/src/main/webapp/sql/stmms_ft.sql
  23. 6 1
      stmms-web/src/main/webapp/static/inspected/css/style.css

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

@@ -34,7 +34,7 @@ public interface ExamDao extends PagingAndSortingRepository<Exam, Integer>, JpaS
 
     List<Exam> findBySchoolIdAndTypeAndStatusOrderByIdDesc(Integer schoolId, ExamType type, ExamStatus status);
 
-    List<Exam> findBySchoolIdAndStatusOrderByIdDesc(Integer schoolId, ExamStatus status);
+    List<Exam> findBySchoolIdOrderByIdDesc(Integer schoolId);
 
     public Exam findFirstBySchoolIdAndCode(Integer schoolId, String code);
 

+ 5 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamStudentDao.java

@@ -2,6 +2,7 @@ package cn.com.qmth.stmms.biz.exam.dao;
 
 import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
 import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
+
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
@@ -11,8 +12,8 @@ import org.springframework.data.repository.PagingAndSortingRepository;
 import java.util.Date;
 import java.util.List;
 
-public interface ExamStudentDao
-        extends PagingAndSortingRepository<ExamStudent, Integer>, JpaSpecificationExecutor<ExamStudent> {
+public interface ExamStudentDao extends PagingAndSortingRepository<ExamStudent, Integer>,
+        JpaSpecificationExecutor<ExamStudent> {
 
     public List<ExamStudent> findByExamId(int examId, Pageable pageable);
 
@@ -191,4 +192,6 @@ public interface ExamStudentDao
     public void updateSubjectiveStatusAndTimeAndInspectorId(Integer studentId, SubjectiveStatus status,
             Date inspectTime, Integer inspectorId);
 
+    public List<ExamStudent> findByExamIdAndStudentCode(int examId, String studentCode);
+
 }

+ 18 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ImportQueryDao.java

@@ -0,0 +1,18 @@
+package cn.com.qmth.stmms.biz.exam.dao;
+
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import cn.com.qmth.stmms.biz.exam.model.ImportQuery;
+import cn.com.qmth.stmms.common.enums.ImportType;
+
+public interface ImportQueryDao extends PagingAndSortingRepository<ImportQuery, Integer>,
+        JpaSpecificationExecutor<ImportQuery> {
+
+    @Modifying
+    void deleteByExamIdAndUserIdAndType(int examId, Integer userId, ImportType type);
+
+    ImportQuery findByExamIdAndUserIdAndType(int examId, Integer userId, ImportType type);
+
+}

+ 163 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ImportQuery.java

@@ -0,0 +1,163 @@
+package cn.com.qmth.stmms.biz.exam.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.apache.commons.lang3.StringUtils;
+
+import net.sf.json.JSONObject;
+import cn.com.qmth.stmms.common.enums.ImportType;
+
+@Entity
+@Table(name = "eb_import_query")
+public class ImportQuery implements Serializable {
+
+    private static final long serialVersionUID = -7983129784062675039L;
+
+    public static final String DB_ITEM_JOINER = ",";
+
+    public static final String SUCCESS = "success";
+
+    public static final String FAILURE = "failure";
+
+    @Id
+    @GeneratedValue
+    private Integer id;
+
+    @Column(name = "exam_id", nullable = false)
+    private Integer examId;
+
+    @Column(name = "user_id", nullable = false)
+    private Integer userId;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "type", length = 16, nullable = false)
+    private ImportType type;
+
+    @Column(name = "description")
+    private String description;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(name = "create_time")
+    private Date createTime;
+
+    public ImportQuery(Integer examId, Integer userId, ImportType type, String description) {
+        this.examId = examId;
+        this.userId = userId;
+        this.type = type;
+        this.description = description;
+        this.createTime = new Date();
+    }
+
+    public ImportQuery() {
+    }
+
+    public ImportQuery(Integer examId, Integer userId, ImportType type, Set<Integer> successStudent,
+            Set<String> failureStudent) {
+        this.examId = examId;
+        this.userId = userId;
+        this.type = type;
+        JSONObject json = new JSONObject();
+        json.accumulate(SUCCESS, StringUtils.join(successStudent, DB_ITEM_JOINER));
+        json.accumulate(FAILURE, StringUtils.join(failureStudent, DB_ITEM_JOINER));
+        this.description = json.toString();
+        this.createTime = new Date();
+    }
+
+    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 Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public ImportType getType() {
+        return type;
+    }
+
+    public void setType(ImportType type) {
+        this.type = type;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public List<String> getStudentCodeList() {
+        List<String> list = new ArrayList<String>();
+        JSONObject json = JSONObject.fromObject(description);
+        String failure = json.getString(FAILURE);
+        String[] values = StringUtils.split(failure, DB_ITEM_JOINER);
+        for (String studentCode : values) {
+            list.add(studentCode);
+        }
+        return list;
+    }
+
+    public List<Integer> getStudentIdList() {
+        List<Integer> list = new ArrayList<Integer>();
+        JSONObject json = JSONObject.fromObject(description);
+        String success = json.getString(SUCCESS);
+        String[] values = StringUtils.split(success, DB_ITEM_JOINER);
+        for (String studentId : values) {
+            list.add(Integer.parseInt(studentId));
+        }
+        return list;
+    }
+
+    public String getStudentIdString() {
+        JSONObject json = JSONObject.fromObject(description);
+        String success = json.getString(SUCCESS);
+        return success;
+    }
+
+    public String buildDescription(Set<Integer> successStudent, Set<String> failureStudent) {
+        JSONObject json = new JSONObject();
+        json.accumulate(SUCCESS, StringUtils.join(successStudent, DB_ITEM_JOINER));
+        json.accumulate(FAILURE, StringUtils.join(failureStudent, DB_ITEM_JOINER));
+        return json.toString();
+
+    }
+}

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

@@ -22,7 +22,7 @@ public interface ExamService {
 
     List<Exam> findBySchoolIdAndTypeAndStatus(Integer schoolId, ExamType type);
 
-    List<Exam> findBySchoolIdAndStatus(Integer schoolId);
+    List<Exam> findBySchoolId(Integer schoolId);
 
     Exam findBySchoolAndCode(Integer schoolId, String code);
 

+ 3 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamStudentService.java

@@ -103,8 +103,7 @@ public interface ExamStudentService {
     public Long countByExamIdAndSubjectCodeAndCampus(Integer examId, String code, String campusName, boolean upload,
             boolean absent);
 
-    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);
 
     public long countByAbsentAndBreach(int examId, String subjectCode, Boolean absent, Boolean breach);
 
@@ -143,4 +142,6 @@ public interface ExamStudentService {
 
     public void updateSubjectiveStatusAndTimeAndInspectorId(Integer studentId, SubjectiveStatus status,
             Date inspectTime, Integer inspectorId);
+
+    public List<ExamStudent> findByExamIdAndStudentCode(int examId, String studentCode);
 }

+ 13 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ImportQueryService.java

@@ -0,0 +1,13 @@
+package cn.com.qmth.stmms.biz.exam.service;
+
+import cn.com.qmth.stmms.biz.exam.model.ImportQuery;
+import cn.com.qmth.stmms.common.enums.ImportType;
+
+public interface ImportQueryService {
+
+    ImportQuery save(ImportQuery i);
+
+    void deleteByExamIdAndUserIdAndType(int examId, Integer userId, ImportType type);
+
+    ImportQuery findByExamIdAndUserIdAndType(int examId, Integer userId, ImportType type);
+}

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

@@ -125,8 +125,8 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
     }
 
     @Override
-    public List<Exam> findBySchoolIdAndStatus(Integer schoolId) {
-        return examDao.findBySchoolIdAndStatusOrderByIdDesc(schoolId, ExamStatus.START);
+    public List<Exam> findBySchoolId(Integer schoolId) {
+        return examDao.findBySchoolIdOrderByIdDesc(schoolId);
     }
 
     @Override

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

@@ -667,7 +667,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     @Override
     public ExamStudent findBySchoolIdAndSubjectCodeAndStudentCode(Integer schoolId, String subjectCode,
             String studentCode) {
-        List<Exam> exams = examService.findBySchoolIdAndStatus(schoolId);
+        List<Exam> exams = examService.findBySchoolId(schoolId);
         if (exams != null && exams.size() > 0) {
             return studentDao.findByExamIdAndSubjectCodeAndStudentCode(exams.get(0).getId(), subjectCode, studentCode);
         } else {
@@ -1024,4 +1024,9 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             Date inspectTime, Integer inspectorId) {
         studentDao.updateSubjectiveStatusAndTimeAndInspectorId(studentId, status, inspectTime, inspectorId);
     }
+
+    @Override
+    public List<ExamStudent> findByExamIdAndStudentCode(int examId, String studentCode) {
+        return studentDao.findByExamIdAndStudentCode(examId, studentCode);
+    }
 }

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

@@ -0,0 +1,39 @@
+package cn.com.qmth.stmms.biz.exam.service.impl;
+
+import java.util.Date;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import cn.com.qmth.stmms.biz.common.BaseQueryService;
+import cn.com.qmth.stmms.biz.exam.dao.ImportQueryDao;
+import cn.com.qmth.stmms.biz.exam.model.ImportQuery;
+import cn.com.qmth.stmms.biz.exam.service.ImportQueryService;
+import cn.com.qmth.stmms.common.enums.ImportType;
+
+@Service
+public class ImportQueryServiceImpl extends BaseQueryService<ImportQuery> implements ImportQueryService {
+
+    @Autowired
+    private ImportQueryDao queryDao;
+
+    @Transactional
+    @Override
+    public ImportQuery save(ImportQuery i) {
+        i.setCreateTime(new Date());
+        return queryDao.save(i);
+    }
+
+    @Transactional
+    @Override
+    public void deleteByExamIdAndUserIdAndType(int examId, Integer userId, ImportType type) {
+        queryDao.deleteByExamIdAndUserIdAndType(examId, userId, type);
+    }
+
+    @Override
+    public ImportQuery findByExamIdAndUserIdAndType(int examId, Integer userId, ImportType type) {
+        return queryDao.findByExamIdAndUserIdAndType(examId, userId, type);
+    }
+
+}

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

@@ -0,0 +1,31 @@
+package cn.com.qmth.stmms.common.enums;
+
+public enum ImportType {
+    INSPECTED("复核", 0);
+
+    private String name;
+
+    private int value;
+
+    private ImportType(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ImportType findByValue(int value) {
+        for (ImportType c : ImportType.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/BaseExamController.java

@@ -53,7 +53,7 @@ public class BaseExamController extends BaseController {
     }
 
     protected List<Exam> getExamList(WebUser wu) {
-        return examService.findBySchoolIdAndStatus(wu.getUser().getSchoolId());
+        return examService.findBySchoolId(wu.getUser().getSchoolId());
     }
 
     protected List<ExamSubject> getExamSubject(Integer examId, WebUser wu) {

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ExamController.java

@@ -252,7 +252,7 @@ public class ExamController extends BaseExamController {
         if (wu.isSubjectHeader() || wu.isInspector()) {
             examList = examService.findBySubjectHeaderUserId(user.getSchoolId(), user.getId());
         } else {
-            examList = examService.findBySchoolIdAndStatus(user.getSchoolId());
+            examList = examService.findBySchoolId(user.getSchoolId());
         }
         model.addAttribute("examList", examList);
         SessionExamUtils.clearExamId(request);

+ 311 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ImportQueryController.java

@@ -0,0 +1,311 @@
+package cn.com.qmth.stmms.admin.exam;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.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.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import cn.com.qmth.stmms.admin.utils.PageUtil;
+import cn.com.qmth.stmms.admin.vo.InspectedStudentVO;
+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.ImportQuery;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.SubjectiveScore;
+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.ImportQueryService;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.SubjectiveScoreService;
+import cn.com.qmth.stmms.biz.file.service.FileService;
+import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
+import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
+import cn.com.qmth.stmms.biz.utils.OriginTag;
+import cn.com.qmth.stmms.biz.utils.PictureTag;
+import cn.com.qmth.stmms.common.annotation.Logging;
+import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.ImportType;
+import cn.com.qmth.stmms.common.enums.LogType;
+import cn.com.qmth.stmms.common.utils.ExportExcel;
+import cn.com.qmth.stmms.common.utils.ImportExcel;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+
+@Controller("importQueryController")
+@RequestMapping("/admin/exam/inspected/import")
+public class ImportQueryController extends BaseExamController {
+
+    protected static Logger log = LoggerFactory.getLogger(ImportQueryController.class);
+
+    @Autowired
+    private ExamStudentService studentService;
+
+    @Autowired
+    private ImportQueryService queryService;
+
+    @Autowired
+    private FileService fileService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private SubjectiveScoreService scoreService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @Autowired
+    private MarkTrackService markTrackService;
+
+    @Autowired
+    private MarkSpecialTagService markSpecialTagService;
+
+    @RequestMapping("/list")
+    public String list(Model model, HttpServletRequest request, ExamStudentSearchQuery query) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        ImportQuery importQuery = queryService.findByExamIdAndUserIdAndType(examId, wu.getId(), ImportType.INSPECTED);
+        int inspectCount = 0;
+        if (importQuery != null) {
+            inspectCount = importQuery.getStudentCodeList().size() > 0 ? 0 : importQuery.getStudentIdList().size();
+        }
+        model.addAttribute("inspectCount", inspectCount);
+        if (inspectCount > 0) {
+            List<?> ids = PageUtil
+                    .startPage(importQuery.getStudentIdList(), query.getPageNumber(), query.getPageSize());
+            List<ExamStudent> list = new ArrayList<ExamStudent>();
+            if (ids != null) {
+                for (Object id : ids) {
+                    list.add(studentService.findById((int) id));
+                }
+            }
+            query.setTotalPage(PageUtil.pageCount(importQuery.getStudentIdList(), query.getPageNumber(),
+                    query.getPageSize()));
+            query.setTotalCount(inspectCount);
+            query.setResult(list);
+        }
+        model.addAttribute("query", query);
+        return "modules/exam/inspectedImportList";
+    }
+
+    @RequestMapping(value = "/template")
+    public String template(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "复核名单导入模板.xlsx";
+            List<InspectedStudentVO> list = Lists.newArrayList();
+            list.add(new InspectedStudentVO());
+            new ExportExcel("复核名单", InspectedStudentVO.class, 2).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:/admin/exam/inspected";
+    }
+
+    @Logging(menu = "导入复核名单", type = LogType.IMPORT_FILE)
+    @RequestMapping(method = RequestMethod.POST)
+    public String importFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        queryService.deleteByExamIdAndUserIdAndType(examId, wu.getId(), ImportType.INSPECTED);
+        try {
+            int successNum = 0;
+            int failureNum = 0;
+            Set<Integer> successStudent = new HashSet<Integer>();
+            Set<String> failureStudent = new HashSet<String>();
+            ImportExcel ei = new ImportExcel(file, 1, 0);
+            List<InspectedStudentVO> list = ei.getDataList(InspectedStudentVO.class);
+            if (list.size() > 1000) {
+                addMessage(redirectAttributes, "导入考生失败!数据超过1000行");
+                return "redirect:/admin/exam/inspected";
+            }
+            for (InspectedStudentVO studentVO : list) {
+                if (StringUtils.isBlank(studentVO.getStudentCode())) {
+                    continue;
+                }
+                List<ExamStudent> studentList = studentService.findByExamIdAndStudentCode(examId,
+                        studentVO.getStudentCode());
+                if (!studentList.isEmpty()) {
+                    for (ExamStudent examStudent : studentList) {
+                        successStudent.add(examStudent.getId());
+                    }
+                    successNum++;
+                } else {
+                    failureStudent.add(studentVO.getStudentCode());
+                    failureNum++;
+                }
+            }
+            ImportQuery importQuery = new ImportQuery(examId, wu.getId(), ImportType.INSPECTED, successStudent,
+                    failureStudent);
+            queryService.save(importQuery);
+            String message = "已成功导入 " + successNum + " 条,关联考生记录 " + successStudent.size() + " 条";
+            if (failureNum > 0) {
+                message = "失败 " + failureNum + " 条";
+            }
+            addMessage(redirectAttributes, message);
+            RequestUtils.setLog(request, message);
+        } catch (Exception e) {
+            log.error("Batch import inpectedStudent error!", e);
+            addMessage(redirectAttributes, "导入考生失败!失败信息:" + e.getMessage());
+            return "redirect:/admin/exam/inspected";
+        }
+        return "redirect:/admin/exam/inspected/import/list";
+    }
+
+    @Logging(menu = "复核名单重置", type = LogType.UPDATE)
+    @RequestMapping(value = "/reset")
+    public String reset(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        queryService.deleteByExamIdAndUserIdAndType(examId, wu.getId(), ImportType.INSPECTED);
+        addMessage(redirectAttributes, "重置成功");
+        return "redirect:/admin/exam/inspected";
+    }
+
+    @RequestMapping(value = "/export")
+    public String export(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        try {
+            String fileName = "错误信息.xlsx";
+            List<InspectedStudentVO> list = Lists.newArrayList();
+            ImportQuery importQuery = queryService.findByExamIdAndUserIdAndType(examId, wu.getId(),
+                    ImportType.INSPECTED);
+            for (String studentCode : importQuery.getStudentCodeList()) {
+                list.add(new InspectedStudentVO(studentCode));
+            }
+            new ExportExcel("错误信息", InspectedStudentVO.class, 2).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "错误信息下载失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:/admin/exam/inspected/import/list";
+    }
+
+    @RequestMapping("/start")
+    @ResponseBody
+    public ModelAndView start(HttpServletRequest request) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        ImportQuery importQuery = queryService.findByExamIdAndUserIdAndType(examId, wu.getId(), ImportType.INSPECTED);
+        int inspectCount = 0;
+        if (importQuery != null) {
+            inspectCount = importQuery.getStudentCodeList().size() > 0 ? 0 : importQuery.getStudentIdList().size();
+        }
+        ModelAndView view = new ModelAndView("modules/exam/inspectedImport");
+        view.addObject("inspectCount", inspectCount);
+        view.addObject("fileServer", fileService.getFileServer());
+        view.addObject("ids", inspectCount > 0 ? importQuery.getStudentIdString() : "");
+        view.addObject("message", inspectCount > 0 ? "" : "没有待复核的任务");
+        return view;
+    }
+
+    @RequestMapping("/startById")
+    public ModelAndView startById(HttpServletRequest request, RedirectAttributes redirectAttributes,
+            @RequestParam Integer studentId) {
+        ModelAndView view = new ModelAndView("modules/exam/inspectedImport");
+        List<Integer> ids = new ArrayList<Integer>();
+        ids.add(studentId);
+        view.addObject("inspectCount", ids.size());
+        view.addObject("fileServer", fileService.getFileServer());
+        view.addObject("ids", StringUtils.join(ids, ","));
+        view.addObject("studentId", studentId);
+        return view;
+    }
+
+    @RequestMapping("/info")
+    @ResponseBody
+    public Object info(HttpServletRequest request, @RequestParam Integer studentId) {
+        ExamStudent student = studentService.findById(studentId);
+        JSONObject result = new JSONObject();
+        result.accumulate("id", student.getId());
+        result.accumulate("secretNumber", student.getSecretNumber());
+        result.accumulate("studentCode", student.getStudentCode());
+        result.accumulate("name", student.getName());
+        result.accumulate("subjectCode", student.getSubjectCode());
+        result.accumulate("subjectName", student.getSubjectName());
+        result.accumulate("totalScore", student.getTotalScore());
+        result.accumulate("upload", student.isUpload());
+        result.accumulate("absent", student.isAbsent());
+        result.accumulate("breach", student.isBreach());
+        List<MarkGroup> groups = groupService.findByExamAndSubject(student.getExamId(), student.getSubjectCode());
+        JSONArray groupArray = new JSONArray();
+        Map<Integer, String> mainTitleMap = new HashMap<Integer, String>();
+        for (MarkGroup markGroup : groups) {
+            JSONObject group = new JSONObject();
+            group.accumulate("groupNumber", markGroup.getNumber());
+            List<SubjectiveScore> scores = scoreService.findByStudentIdAndGroupNumber(student.getId(),
+                    markGroup.getNumber());
+            JSONArray array = new JSONArray();
+            for (SubjectiveScore scoreItem : scores) {
+                JSONObject obj = new JSONObject();
+                String mainTitle = mainTitleMap.get(scoreItem.getMainNumber());
+                if (mainTitle == null) {
+                    ExamQuestion q = questionService.findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(
+                            student.getExamId(), student.getSubjectCode(), false, scoreItem.getMainNumber(),
+                            scoreItem.getSubNumber());
+                    mainTitleMap.put(scoreItem.getMainNumber(), mainTitle);
+                    mainTitle = q.getMainTitle();
+                }
+                obj.accumulate("mainTitle", mainTitle);
+                obj.accumulate("questionNumber", scoreItem.getMainNumber() + "-" + scoreItem.getSubNumber());
+                obj.accumulate("score", scoreItem.getScore());
+                array.add(obj);
+            }
+            group.accumulate("questions", array);
+            groupArray.add(group);
+        }
+        result.accumulate("groups", groupArray);
+        List<String> picUrls = fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1,
+                student.getSheetCount());
+        result.accumulate("picUrls", picUrls);
+        Map<Integer, List<PictureTag>> maps = studentService.buildSheetTags(student, false);
+        List<OriginTag> tags = new ArrayList<OriginTag>();
+        for (Entry<Integer, List<PictureTag>> entry : maps.entrySet()) {
+            List<PictureTag> pictureTags = entry.getValue();
+            for (PictureTag pictureTag : pictureTags) {
+                if (pictureTag.getContent().length == 1) {
+                    tags.add(new OriginTag(pictureTag.getContent()[0], entry.getKey(), pictureTag.getLeft(), pictureTag
+                            .getTop()));
+                }
+            }
+        }
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            result.accumulate("tags", mapper.writeValueAsString(tags));
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+            log.error("MarkTrackController-轨迹坐标获取出错", e);
+        }
+        result.accumulate("success", true);
+        return result;
+    }
+}

+ 4 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/InspectedController.java

@@ -144,6 +144,7 @@ public class InspectedController extends BaseExamController {
         model.addAttribute("subjectList", subjectList);
         model.addAttribute("statusList", SubjectiveStatus.getOptionList());
         model.addAttribute("status", status);
+        model.addAttribute("exam", exam);
         return "modules/exam/inspectedList";
     }
 
@@ -163,6 +164,7 @@ public class InspectedController extends BaseExamController {
         query.setAbsent(false);
         query.setBreach(false);
         query.addStatus(SubjectiveStatus.MARKED);
+        query.setPageNumber(1);
         query.setPageSize(Integer.MAX_VALUE);
         List<ExamSubject> subjectList = getExamSubject(examId, wu);
         if (StringUtils.isBlank(query.getSubjectCode()) && !subjectList.isEmpty()) {
@@ -225,6 +227,8 @@ public class InspectedController extends BaseExamController {
                 && student.getSubjectiveStatus().equals(SubjectiveStatus.MARKED)) {
             result.accumulate("id", student.getId());
             result.accumulate("secretNumber", student.getSecretNumber());
+            result.accumulate("studentCode", student.getStudentCode());
+            result.accumulate("name", student.getName());
             result.accumulate("subjectCode", student.getSubjectCode());
             result.accumulate("subjectName", student.getSubjectName());
             result.accumulate("totalScore", student.getTotalScore());

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/log/OperationLogController.java

@@ -38,7 +38,7 @@ public class OperationLogController extends BaseExamController {
         query.orderByCreateTime();
         query = logService.findByQuery(query);
         model.addAttribute("query", query);
-        model.addAttribute("examList", examService.findBySchoolIdAndStatus(wu.getUser().getSchoolId()));
+        model.addAttribute("examList", examService.findBySchoolId(wu.getUser().getSchoolId()));
         model.addAttribute("typeList", LogType.values());
         return "modules/log/logList";
     }

+ 64 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/utils/PageUtil.java

@@ -0,0 +1,64 @@
+package cn.com.qmth.stmms.admin.utils;
+
+import java.util.List;
+
+public class PageUtil {
+
+    /**
+     * 开始分页
+     * 
+     * @param list
+     * @param pageNum
+     *            页码
+     * @param pageSize
+     *            每页多少条数据
+     * @return
+     */
+    public static List<?> startPage(List<?> list, Integer pageNum, Integer pageSize) {
+        if (list == null) {
+            return null;
+        }
+        if (list.size() == 0) {
+            return null;
+        }
+
+        Integer count = list.size(); // 记录总数
+        Integer pageCount = pageCount(list, pageNum, pageSize);
+
+        int fromIndex = 0; // 开始索引
+        int toIndex = 0; // 结束索引
+
+        if (pageCount < pageNum) {
+            return null;
+        }
+        if (pageCount - pageNum != 0) {
+            fromIndex = (pageNum - 1) * pageSize;
+            toIndex = fromIndex + pageSize;
+        } else {
+            fromIndex = (pageNum - 1) * pageSize;
+            toIndex = count;
+        }
+
+        List<?> pageList = list.subList(fromIndex, toIndex);
+
+        return pageList;
+    }
+
+    public static Integer pageCount(List<?> list, Integer pageNum, Integer pageSize) {
+        if (list == null) {
+            return 0;
+        }
+        if (list.size() == 0) {
+            return 0;
+        }
+        Integer count = list.size(); // 记录总数
+        Integer pageCount = 0; // 页数
+        if (count % pageSize == 0) {
+            pageCount = count / pageSize;
+        } else {
+            pageCount = count / pageSize + 1;
+        }
+
+        return pageCount;
+    }
+}

+ 25 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/vo/InspectedStudentVO.java

@@ -0,0 +1,25 @@
+package cn.com.qmth.stmms.admin.vo;
+
+import cn.com.qmth.stmms.common.annotation.ExcelField;
+
+public class InspectedStudentVO {
+
+    @ExcelField(title = "学号", align = 2, sort = 10)
+    private String studentCode;
+
+    public InspectedStudentVO(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public InspectedStudentVO() {
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+}

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

@@ -0,0 +1,241 @@
+<%@ page language="java" pageEncoding="utf-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>云阅卷</title>
+    <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
+    <link rel="stylesheet" href="${ctxStatic}/inspected/css/style.css"/>
+    <script type="text/javascript" src="${ctxStatic}/mark-new/js/jquery.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/mark-new/js/jquery-ui.min.js "></script>
+    <script type="text/javascript" src="${ctxStatic}/mark-new/js/jquery.mousewheel.min.js"></script>
+    
+    <script type="text/javascript" src="${ctxStatic}/answer-check/js/common.js"></script>
+    
+    <link rel="stylesheet" href="${ctxStatic}/iviewer/jquery.iviewer.css"/>
+    <script type="text/javascript" src="${ctxStatic}/iviewer/jquery.iviewer.js"></script>
+    
+    <script type="text/javascript" src="${ctxStatic}/mark-new/js/jquery-ui.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/mark-new/js/jquery.mousewheel.min.js"></script>
+    
+    <script type="text/javascript" src="${ctxStatic}/utils/image-utils.js"></script>
+
+</head>
+<body>
+<div style="height: 100vh;">
+    <div class="c-top cl">
+        <div class="z">
+            <span><b>学号:</b><span id="studentCode"></span></span>
+            <span><b>姓名:</b><span id="studentName"></span></span>
+            <span><b>科目:</b><span id="subject"></span></span>
+            <span><b>待复核:</b><span id="progress">${inspectCount}</span></span>
+        </div>
+        <div class="y">
+            <span><a class="user" href="">${web_user.name}</a></span>
+            <span><a class="close" href="javascript:window.close()">关闭</a></span>
+        </div>
+    </div>
+    <div class="c-cont cl">
+        <div class="mn">
+            <div id="image-holder-track" class="image-content" style="position: relative; "></div>
+        </div>
+        <div class="sd">
+            <div class="c-button pre-button">
+            	<a href="#" id="pre-button">上一个</a>
+            	<span></span>
+            	<a href="#" id="next-button">下一个</a>
+            </div>
+            <div class="c-theadlist">
+                <h1>试卷总分:<span id="totalScore"></span></h1>
+                <div id="question-content">
+                    <div class="mt">
+                        <table cellpadding="0" cellspacing="0" width="100%">
+                            <!-- <thead>
+                                <tr>
+                                    <td>题号</td>
+                                    <td>给分</td>
+                                    <td class="td"><a href="" id="back-button">打回</a></td>
+                                </tr>
+                            </thead>
+                            <tbody>
+                                <tr>
+                                    <td>1</td>
+                                    <td>2</td>
+                                    <td class="td"></td>
+                                </tr>
+                            </tbody> -->
+                        </table>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+</body>
+<script type="text/javascript">
+    var message = '${message}';
+    var ids = [${ids}];
+    var studentId = '${studentId}';
+    var current;
+    var student;
+    var iviewer;
+    var regex = /^[a-z]+$/ig;
+    $(document).ready(function () {
+        if (message != undefined && message != '') {
+            alert(message);
+            return;
+        }
+
+        $('#pre-button').click(pre);
+        $('#next-button').click(next);
+
+        if (ids.length == 0) {
+            $(".cont cl").css("display", "none");
+            return;
+        }
+        $(".tipsbox").css("display", "none");
+
+        window.onbeforeunload = function () {
+            $.post('${ctx}/admin/exam/inspected/clear', {
+                studentId: student.id
+            }, function (result) {
+            });
+        }
+		if(studentId){
+			$.post('${ctx}/admin/exam/inspected/clear', {
+                studentId: studentId
+            }, function (result) {
+            });
+		}
+		
+        $('#progress').html(ids.length);
+        process(1);
+    });
+
+    function process(index) {
+
+        if (index < 1) {
+            return;
+        }
+        if (index > ids.length) {
+            alert('所有考生已处理完毕,请返回重新搜索');
+            window.close();
+            return;
+        }
+        current = index;
+        $('#answer-content').empty();
+        $('#image-holder-track').hide();
+        $.post('${ctx}/admin/exam/inspected/import/info', {
+            studentId: ids[index - 1]
+        }, function (result) {
+            if (result.success == true) {
+                student = result;
+                render();
+            } else {
+                //$('#progress').html(ids.length-current);
+                process(current + 1);
+            }
+        }).error(function () {
+            alert('获取考生信息出错');
+            onProcessFinish(true);
+        });
+    }
+
+    function onProcessFinish(error) {
+        if (!error) {
+            $('#save-button').removeAttr("disabled");
+        }
+    }
+
+    function render() {
+        $('#studentCode').html(student.studentCode);
+        $('#studentName').html(student.name);
+        $('#subject').html(student.subjectCode + '-' + student.subjectName);
+        $('#totalScore').html(student.totalScore);
+        $("#question-content").empty();
+		if(!student.upload){
+			alert("该考生未上传,请点击下一个");
+			return;
+		}
+		if(student.absent){
+			alert("该考生缺考,请点击下一个");
+			return;
+		}
+		if(student.breach){
+			alert("该考生违纪,请点击下一个");
+			var pane = $('<canvas id="track-builder-canvas"></canvas>').appendTo($('#image-holder-track'));
+			var canvas = document.getElementById('track-builder-canvas');
+			var ctx = canvas.getContext('2d');
+			buildImages('${fileServer}', student.picUrls, null, canvas, ctx, null);
+		    $('#image-holder-track').show();
+			return;
+		}
+		
+        for (var i = 0; i < student.groups.length; i++) {
+            var group = student.groups[i];
+            $('<div class="mt" id="div_' + group.groupNumber + '"></div>').appendTo("#question-content");
+
+            $('<table id="table_' + group.groupNumber + '" cellpadding="0" cellspacing="0" width="100%"></table>').appendTo("#div_" + group.groupNumber);
+
+            $("<thead><tr><td>分组" + group.groupNumber + "</td><td>给分 &nbsp;</td></tr></thead>").appendTo("#table_" + group.groupNumber);
+            $('<tbody id="tbody_' + group.groupNumber + '"></tbody>').appendTo("#table_" + group.groupNumber);
+            for (var j = 0; j < group.questions.length; j++) {
+                var question = group.questions[j];
+                $("<tr><td>" +question.mainTitle+":"+ question.questionNumber + "</td><td>" + question.score + "</td></tr>").appendTo("#tbody_" + group.groupNumber);
+            }
+        }
+
+        var pane = $('<canvas id="track-builder-canvas"></canvas>').appendTo($('#image-holder-track'));
+        var canvas = document.getElementById('track-builder-canvas');
+        var ctx = canvas.getContext('2d');
+        var tags = student.tags;
+        buildImages('${fileServer}', student.picUrls, null, canvas, ctx, tags);
+        $('#image-holder-track').show();
+        onProcessFinish(false);
+    }
+
+    function next() {
+        if (student == undefined) {
+            return;
+        }
+		$('#progress').html(ids.length - current);
+		process(current + 1);
+    }
+    
+    function pre() {
+        if (student == undefined) {
+            return;
+        }
+        var index  = ids.length - current + 2;
+        if(index <= ids.length){
+			$('#progress').html(index);
+			process(current - 1);
+        }
+    }
+
+    function buildImages(imageServer, urls, config, canvas, ctx, tags) {
+    	canvas.style="width:100%;height:100%";
+        new ImageLoader({
+            server: imageServer,
+            flush: true,
+            strict: false,
+            split: [0,1]
+        }).combine(urls, canvas, [], function (layout) {
+            //阅卷轨迹
+            if (tags != undefined && tags.length > 0) {
+                ctx.font = "30px Arial";
+                ctx.fillStyle = 'red';
+                for (var j = 0; j < tags.length; j++) {
+                	var tag = tags[j];
+                    ctx.fillText(
+                        		tag.content,
+                        		tag.offsetX,
+                        		tag.offsetY+layout[tag.offsetIndex-1].top);
+                }
+            }
+        });
+    }
+
+</script>
+</html>

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

@@ -0,0 +1,103 @@
+<%@ 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/inspected/import/list" method="post" class="breadcrumb form-search" >
+    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>
+    <input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize }"/>
+    <div>
+        <input id="reset-button" class="btn btn-primary" type="button" value="重置" onclick="goReset()"/>
+        &nbsp;
+        <input id="export-button" class="btn" type="button" value="错误日志" onclick="goExport()"/>
+        &nbsp;
+        <input id="btnStart" class="btn" type="button" value="批量复核:${inspectCount }" onclick="goStart()"/>
+    </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>
+    </tr>
+    </thead>
+    <tbody>
+    <c:forEach items="${query.result}" var="result">
+        <tr>
+            <td>${result.subjectCode}-${result.subjectName}</td>
+            <td>${result.studentCode}</td>
+            <td>${result.totalScore}</td>
+            <td>
+            	<c:choose>
+            		<c:when test="${result.absent == true || result.upload == false}">
+                        缺考
+                    </c:when>
+                     <c:when test="${result.breach == true}">
+                        违纪
+                    </c:when>
+                    <c:otherwise>
+                        ${result.subjectiveScoreList}
+                    </c:otherwise>
+            	</c:choose>
+            </td>
+            <td>
+            	<c:choose>
+            		<c:when test="${result.absent == true || result.upload == false}">
+                    </c:when>
+                    <c:otherwise>
+						<a target="_blank" href="${ctx}/admin/exam/inspected/import/startById?studentId=${result.id}">进入复核</a>
+                    </c:otherwise>
+            	</c:choose>
+            </td>
+        </tr>
+    </c:forEach>
+    </tbody>
+</table>
+<div class="pagination">${query}</div>
+<script type="text/javascript">
+    function page(n, s) {
+        $("#pageNumber").val(n);
+        $("#searchForm").attr('target', "_self");
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspected/import/list');
+        $("#searchForm").submit();
+        return false;
+    }
+    function goSearch() {
+        $("#pageNumber").val(1);
+        $("#searchForm").attr('target', "_self");
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspected/import/list');
+        $("#searchForm").submit();
+        return false;
+    }
+    function goStart() {
+    	$("#searchForm").attr('target', "_blank");
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspected/import/start');
+        $("#searchForm").submit();
+        return false;
+    }
+    function goExport() {
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspected/import/export');
+        $("#searchForm").submit();
+    }
+    function goReset() {
+    	$("#searchForm").attr('target', "");
+        $("#searchForm").attr('action', '${ctx}/admin/exam/inspected/import/reset');
+        $("#searchForm").submit();
+    }
+</script>
+</body>
+</html>

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

@@ -11,6 +11,14 @@
     }</style>
 </head>
 <body>
+<div id="importBox" class="hide">
+    <form id="importForm" action="${ctx}/admin/exam/inspected/import" method="post" enctype="multipart/form-data"
+          style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+        <input id="uploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
+        <input id="btnImportSubmit" class="btn btn-primary" type="submit" value="   导    入   "/>
+        <a href="${ctx}/admin/exam/inspected/import/template">下载模板</a>
+    </form>
+</div>
 <form id="searchForm" action="${ctx}/admin/exam/inspected" 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 }"/>
@@ -56,7 +64,11 @@
         &nbsp;
         <input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
         &nbsp;
-         <input id="btnStart" class="btn" type="button" value="批量复核:${inspectCount }" onclick="goStart()"/>
+        <input id="btnStart" class="btn" type="button" value="批量复核:${inspectCount }" onclick="goStart()"/>
+        &nbsp;
+        <c:if test="${exam.status=='FINISH' && web_user.schoolAdmin==true}">
+       	<input id="btnImport" class="btn" type="button" value="导入"/>
+       	</c:if>
     </div>
 </form>
 <tags:message content="${message}"/>
@@ -82,12 +94,7 @@
             <td>${result.subjectiveScoreList}</td>
             <td>${result.inspectTime}</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 href="${ctx}/admin/exam/track/student/${result.id}" target="_blank">轨迹图</a>
-                </c:if>
+                <a href="${ctx}/admin/exam/track/student/${result.id}" target="_blank">轨迹图</a>
                 <c:if test="${result.subjectiveStatus=='MARKED'}">
 	                <a target="_blank" href="${ctx}/admin/exam/inspected/startById?studentId=${result.id}">进入复核</a>
                 </c:if>
@@ -146,6 +153,13 @@
                 parent.val(first).trigger('change');
             });
         });
+        
+        $("#btnImport").click(function () {
+            $.jBox($("#importBox").html(), {
+                title: "导入数据", buttons: {"关闭": true},
+                bottomText: "导入文件不能超过1000行,仅允许导入“xls”或“xlsx”格式文件!"
+            });
+        });
     });
 
     function page(n, s) {

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

@@ -946,4 +946,23 @@ CREATE TABLE `s_range_subject`
     PRIMARY KEY (`id`),
     KEY `index1` (`exam_id`, `subject_code`)
 ) ENGINE = InnoDB
-  DEFAULT CHARSET = utf8mb4 COMMENT ='分段统计表';
+  DEFAULT CHARSET = utf8mb4 COMMENT ='分段统计表';
+  
+
+# Dump of table b_school
+# ------------------------------------------------------------
+
+DROP TABLE IF EXISTS `eb_import_query`;
+
+CREATE TABLE `eb_import_query` 
+(
+  `id` 			int(11) 	NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `create_time` datetime    NOT NULL COMMENT '创建时间',
+  `description` text 		DEFAULT NULL COMMENT '描述',
+  `exam_id` 	int(11) 	NOT NULL COMMENT '考试ID',
+  `type` 		varchar(16) NOT NULL COMMENT '类型',
+  `user_id` 	int(11)  	NOT NULL COMMENT '用户ID',
+  PRIMARY KEY (`id`),
+  KEY `index1` (`exam_id`, `user_id`, `type`)
+)  ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT ='导入查询表';

+ 6 - 1
stmms-web/src/main/webapp/static/inspected/css/style.css

@@ -159,7 +159,12 @@ a {
 .c-button a:hover {
 	background: #697B8D;
 }
-
+.pre-button{
+	display: flex;
+}
+.pre-button span{
+	width:30%;
+}