Browse Source

增加导入缺考名单,导入违纪名单;

ting.yin 5 years ago
parent
commit
c12b09224f
23 changed files with 437 additions and 156 deletions
  1. 2 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/CheckStudentDao.java
  2. 6 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamSubjectDao.java
  3. 19 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamSubject.java
  4. 2 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/CheckStudentService.java
  5. 4 1
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamSubjectService.java
  6. 5 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/CheckStudentServiceImpl.java
  7. 4 2
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamStudentServiceImpl.java
  8. 11 3
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamSubjectServiceImpl.java
  9. 1 1
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/CheckType.java
  10. 5 11
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/CheckStudentController.java
  11. 55 39
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ScoreController.java
  12. 182 61
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/StudentController.java
  13. 0 25
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/thread/ScoreCalculateThread.java
  14. 17 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/vo/ExamStudentVO.java
  15. 25 2
      stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ExamInfoController.java
  16. 10 0
      stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ScanController.java
  17. 11 0
      stmms-web/src/main/java/cn/com/qmth/stmms/api/utils/ScanStudentParameter.java
  18. 1 1
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkAnswer.jsp
  19. 1 1
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkImage.jsp
  20. 1 1
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkStudent.jsp
  21. 2 2
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkStudentEdit.jsp
  22. 5 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/groupList.jsp
  23. 68 4
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/studentList.jsp

+ 2 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/CheckStudentDao.java

@@ -21,4 +21,6 @@ public interface CheckStudentDao extends PagingAndSortingRepository<CheckStudent
 
     long countByExamIdAndChecked(int examId, boolean checked);
 
+    long countByExamIdAndSubjectCodeAndChecked(int examId, String subjectCode, boolean checked);
+
 }

+ 6 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamSubjectDao.java

@@ -10,8 +10,8 @@ import org.springframework.data.repository.PagingAndSortingRepository;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubjectPK;
 
-public interface ExamSubjectDao
-        extends PagingAndSortingRepository<ExamSubject, ExamSubjectPK>, JpaSpecificationExecutor<ExamSubject> {
+public interface ExamSubjectDao extends PagingAndSortingRepository<ExamSubject, ExamSubjectPK>,
+        JpaSpecificationExecutor<ExamSubject> {
 
     @Query("select s from ExamSubject s where s.pk.examId=?1")
     public List<ExamSubject> findByExamId(int examId);
@@ -58,4 +58,8 @@ public interface ExamSubjectDao
     @Query("select s from ExamSubject s where s.pk.examId=?1 and s.subjectiveScore>?2")
     public List<ExamSubject> listSubjectiveScore(int examId, double subjectiveScore);
 
+    @Modifying
+    @Query("update ExamSubject s set s.sliceConfig=?3 where s.pk.examId=?1 and s.pk.code=?2")
+    public void updateSliceConfig(Integer examId, String subjectCode, String configString);
+
 }

+ 19 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamSubject.java

@@ -1,6 +1,7 @@
 package cn.com.qmth.stmms.biz.exam.model;
 
 import java.io.Serializable;
+import java.util.List;
 
 import javax.persistence.Column;
 import javax.persistence.EmbeddedId;
@@ -10,6 +11,7 @@ import javax.persistence.Transient;
 
 import org.apache.commons.lang.StringUtils;
 
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 import cn.com.qmth.stmms.common.utils.PictureUrlBuilder;
 
 @Entity
@@ -54,6 +56,12 @@ public class ExamSubject implements Serializable {
     @Column(name = "remark")
     private String remark;
 
+    /**
+     * 裁切图配置
+     */
+    @Column(name = "slice_config", nullable = true)
+    private String sliceConfig;
+
     /**
      * 大题数量
      */
@@ -193,4 +201,15 @@ public class ExamSubject implements Serializable {
         this.hasAnswer = hasAnswer;
     }
 
+    public String getSliceConfig() {
+        return sliceConfig;
+    }
+
+    public void setSliceConfig(String sliceConfig) {
+        this.sliceConfig = sliceConfig;
+    }
+
+    public List<PictureConfigItem> getSliceConfigList() {
+        return PictureConfigItem.parse(sliceConfig);
+    }
 }

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

@@ -20,4 +20,6 @@ public interface CheckStudentService {
 
     public CheckStudentSearchQuery findByQuery(CheckStudentSearchQuery query);
 
+    long countByExamIdAndSubjectCodeAndChecked(int examId, String subjectCode, boolean checked);
+
 }

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

@@ -4,6 +4,7 @@ import java.util.List;
 
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 
 public interface ExamSubjectService {
 
@@ -24,7 +25,7 @@ public interface ExamSubjectService {
     void deleteByExamId(int examId);
 
     List<ExamSubject> list(int examId, int uploadCountGt);
-    
+
     List<ExamSubject> listSubjectiveScore(int examId, double subjectiveScoreGt);
 
     List<String> listLevel(int examId);
@@ -37,4 +38,6 @@ public interface ExamSubjectService {
 
     void updateScore(int examId, String code, boolean objective, double score);
 
+    void updateSliceConfig(Integer examId, String subjectCode, List<PictureConfigItem> configList);
+
 }

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

@@ -86,4 +86,9 @@ public class CheckStudentServiceImpl extends BaseQueryService<CheckStudent> impl
         return query;
     }
 
+    @Override
+    public long countByExamIdAndSubjectCodeAndChecked(int examId, String subjectCode, boolean checked) {
+        return checkStudentDao.countByExamIdAndSubjectCodeAndChecked(examId,subjectCode,checked);
+    }
+
 }

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

@@ -744,7 +744,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         // }
         // 构造评卷标记信息
         Exam exam = examService.findById(student.getExamId());
-        List<PictureConfigItem> sliceConfig = exam.getSliceConfigList();
+        ExamSubject subject = subjectService.find(student.getExamId(), student.getSubjectCode());
+        List<PictureConfigItem> sliceConfig = subject.getSliceConfigList().isEmpty()?subject.getSliceConfigList():exam.getSliceConfigList();
         if (!sliceConfig.isEmpty()) {
             List<PictureTag> tags = PictureConfigTransform.process(sliceConfig, getSliceTags(student)).get(index);
             if (tags != null) {
@@ -761,7 +762,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     public Map<Integer, List<PictureTag>> buildSheetTags(ExamStudent student) {
         Map<MarkGroup, List<OriginTag>> tagMap = new HashMap<MarkGroup, List<OriginTag>>();
         Exam exam = examService.findById(student.getExamId());
-        List<PictureConfigItem> sliceConfig = exam.getSliceConfigList();
+        ExamSubject subject = subjectService.find(student.getExamId(), student.getSubjectCode());
+        List<PictureConfigItem> sliceConfig = subject.getSliceConfigList().isEmpty()?subject.getSliceConfigList():exam.getSliceConfigList();
         if (!sliceConfig.isEmpty()) {
             // 有裁切图配置时才需要获取原始评卷标记信息
             tagMap = getSliceTags(student);

+ 11 - 3
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamSubjectServiceImpl.java

@@ -20,6 +20,7 @@ import cn.com.qmth.stmms.biz.exam.dao.ExamSubjectDao;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 
 @Service("examSubjectService")
 public class ExamSubjectServiceImpl extends BaseQueryService<ExamSubject> implements ExamSubjectService {
@@ -149,8 +150,8 @@ public class ExamSubjectServiceImpl extends BaseQueryService<ExamSubject> implem
                 if (query.getUploadCountEqual() != null) {
                     predicates.add(cb.equal(root.get("uploadCount").as(Integer.class), query.getUploadCountEqual()));
                 }
-                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()]));
             }
         };
     }
@@ -163,7 +164,14 @@ public class ExamSubjectServiceImpl extends BaseQueryService<ExamSubject> implem
 
     @Override
     public List<ExamSubject> listSubjectiveScore(int examId, double subjectiveScore) {
-        return subjectDao.listSubjectiveScore(examId,subjectiveScore);
+        return subjectDao.listSubjectiveScore(examId, subjectiveScore);
+    }
+
+    @Override
+    public void updateSliceConfig(Integer examId, String subjectCode, List<PictureConfigItem> configList) {
+        subjectDao.updateSliceConfig(examId, subjectCode,
+                configList != null ? StringUtils.join(configList, PictureConfigItem.DB_ITEM_JOINER) : "");
+
     }
 
 }

+ 1 - 1
stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/CheckType.java

@@ -2,7 +2,7 @@ package cn.com.qmth.stmms.common.enums;
 
 public enum CheckType {
 
-    SCAN_ABSENT("识别缺考", 1), EXCEPTION(" 客观题0分主观题有分", 2);
+    MANUAL("手动更新", 1);
 
     private String name;
 

+ 5 - 11
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/CheckStudentController.java

@@ -44,7 +44,7 @@ public class CheckStudentController extends BaseExamController {
             query.setExamId(examId);
             query.setChecked(false);
             if (query.getType() == null) {
-                query.setType(CheckType.SCAN_ABSENT);
+                query.setType(CheckType.MANUAL);
             }
             query = checkStudentService.findByQuery(query);
             for (CheckStudent c : query.getResult()) {
@@ -80,20 +80,14 @@ public class CheckStudentController extends BaseExamController {
 
     @RequestMapping("/save")
     @ResponseBody
-    public Object save(HttpServletRequest request, @RequestParam Integer studentId, @RequestParam String answers,
-            @RequestParam(required = false) Boolean absent) {
+    public Object save(HttpServletRequest request, @RequestParam Integer studentId, @RequestParam String answers) {
         ExamStudent student = studentService.findById(studentId);
         CheckStudent cs = checkStudentService.findByStudentId(studentId);
         if (student != null && cs != null) {
-            if (absent != null) {
-                student.setAbsent(absent);
-            }
             student.setAnswers(answers);
-            if (saveUploadStudent(student)) {
-                cs.setChecked(true);
-                cs.setUpdateTime(new Date());
-                checkStudentService.save(cs);
-            }
+            cs.setChecked(true);
+            cs.setUpdateTime(new Date());
+            checkStudentService.save(cs);
             return true;
         } else {
             return false;

+ 55 - 39
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ScoreController.java

@@ -32,6 +32,7 @@ import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
+import cn.com.qmth.stmms.biz.exam.service.CheckStudentService;
 import cn.com.qmth.stmms.biz.exam.service.ExamPackageService;
 import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
 import cn.com.qmth.stmms.biz.exam.service.ExamService;
@@ -85,6 +86,9 @@ public class ScoreController extends BaseExamController {
     @Autowired
     private ReportService reportService;
 
+    @Autowired
+    private CheckStudentService checkStudentService;
+
     @Value("${sheet.image.server}")
     private String imageServer;
 
@@ -232,15 +236,15 @@ public class ScoreController extends BaseExamController {
                 if (student.isBreach() || student.isAbsent()) {
                     student.setObjectiveScore(0d);
                     student.setSubjectiveScore(0d);
-                }else if(paperType == null){
+                } else if (paperType == null) {
                     paperType = student.getPaperType();
                 }
                 list.add(new ExamStudentDTO(student));
             }
             if (StringUtils.isNotBlank(query.getSubjectCode()) && !query.getResult().isEmpty()) {
-                List<String> headerList = getOptionHeader(examId, query.getSubjectCode(),paperType);
+                List<String> headerList = getOptionHeader(examId, query.getSubjectCode(), paperType);
                 ExportStudentExcel excel = new ExportStudentExcel("成绩单", headerList, ExamStudentDTO.class);
-                excel.setDataList(list,true);
+                excel.setDataList(list, true);
                 excel.write(response, fileName).dispose();
                 return null;
             }
@@ -268,7 +272,7 @@ public class ScoreController extends BaseExamController {
     }
 
     private String getTitle(ExamQuestion examQuestion) {
-        return examQuestion.getMainTitle() + " " + examQuestion.getMainNumber()+"-"+examQuestion.getSubNumber();
+        return examQuestion.getMainTitle() + " " + examQuestion.getMainNumber() + "-" + examQuestion.getSubNumber();
     }
 
     @RequestMapping("/enableExport")
@@ -373,49 +377,61 @@ public class ScoreController extends BaseExamController {
     }
 
     private String enableExport(int examId) {
-        String message = isChecked(examId);
-        if (message == null) {
-            List<ExamSubject> subjects = subjectService.list(examId);
-            for (ExamSubject subject : subjects) {
-                message = enableExport(examId, subject.getCode());
-                if (message != null) {
-                    return message;
-                }
-            }
+        Exam exam = examService.findById(examId);
+        if (exam.isNeedCalculate()) {
+            String message = "该考试需要统分";
+            return message;
+        }
+        
+        if (checkStudentService.countByExamIdAndChecked(examId, false) != 0) {
+            String message = "人工确认未完成";
+            return message;
+        }
+        
+        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
+        query.setExamId(examId);
+        query.setUpload(false);
+        query.setManualAbsent(false);
+        long unUploadManualAbsentCount = studentService.countByQuery(query);
+        if (unUploadManualAbsentCount > 0) {
+            String message = "未上传考生必须人工指定缺考";
+            return message;
         }
-        return message;
+        
+        return null;
     }
 
-    private String isChecked(int examId) {
-        String message = null;
+    private String enableExport(int examId, String subjectCode) {
         Exam exam = examService.findById(examId);
-        // ExamStudentSearchQuery query = new ExamStudentSearchQuery();
-        // query.setExamId(examId);
-        // query.setUpload(false);
-        // query.setManualAbsent(false);
-        // long unUploadManualAbsentCount = studentService.countByQuery(query);
         if (exam.isNeedCalculate()) {
-            message = "该考试需要统分";
+            String message = "该考试需要统分";
+            return message;
         }
-        // else if (unUploadManualAbsentCount > 0) {
-        // message = "未上传考生必须人工指定缺考";
-        // } else if (checkStudentService.countByExamIdAndChecked(examId, false)
-        // != 0) {
-        // message = "人工确认未完成";
-        // }
-        return message;
-    }
 
-    private String enableExport(int examId, String subjectCode) {
-        String message = isChecked(examId);
-        if (message == null) {
-            List<MarkGroup> groups = groupService.findByExamAndSubjectAndStatus(examId, subjectCode, MarkStatus.FORMAL,
-                    MarkStatus.TRIAL);
-            if (groups != null && !groups.isEmpty()) {
-                message = subjectCode + " 科目未评卷完成";
-            }
+        List<MarkGroup> groups = groupService.findByExamAndSubjectAndStatus(examId, subjectCode, MarkStatus.FORMAL,
+                MarkStatus.TRIAL);
+        if (groups != null && !groups.isEmpty()) {
+            String message = subjectCode + " 科目未评卷完成";
+            return message;
+        }
+
+        if (checkStudentService.countByExamIdAndSubjectCodeAndChecked(examId, subjectCode, false) != 0) {
+            String message = "人工确认未完成";
+            return message;
+        }
+        
+        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
+        query.setExamId(examId);
+        query.setUpload(false);
+        query.setManualAbsent(false);
+        query.setSubjectCode(subjectCode);
+        long unUploadManualAbsentCount = studentService.countByQuery(query);
+        if (unUploadManualAbsentCount > 0) {
+            String message = "未上传考生必须人工指定缺考";
+            return message;
         }
-        return message;
+        
+        return null;
     }
 
 }

+ 182 - 61
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/StudentController.java

@@ -8,6 +8,8 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import net.sf.json.JSONObject;
+
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -22,6 +24,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import cn.com.qmth.stmms.admin.vo.ExamStudentVO;
 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;
@@ -64,13 +67,13 @@ public class StudentController extends BaseExamController {
 
     @Autowired
     private MarkService markService;
-    
+
     @Autowired
     private ExamPackageService packageService;
 
     @Value("${sheet.image.server}")
     private String imageServer;
-    
+
     @Value("${package.image.server}")
     private String packageServer;
 
@@ -139,45 +142,46 @@ public class StudentController extends BaseExamController {
             if (student.getId() != null) {
                 ExamStudent previous = studentService.findById(student.getId());
                 if (previous != null) {
-                	// String previousSubjectCode = previous.getSubjectCode();
-                	student.setExamId(examId);
-                	ExamStudent old = checkExamNumber(student, new HashMap<String, ExamStudent>(), new HashMap<String, ExamStudent>());
-                	if(old !=null && !old.getExamNumber().equals(previous.getExamNumber())){
-                		addMessage(redirectAttributes, "准考证号" + student.getExamNumber() + "已经存在");
-                		return "redirect:/admin/exam/student";
-                	}
-                	if (!previous.isUpload()) {
+                    // String previousSubjectCode = previous.getSubjectCode();
+                    student.setExamId(examId);
+                    ExamStudent old = checkExamNumber(student, new HashMap<String, ExamStudent>(),
+                            new HashMap<String, ExamStudent>());
+                    if (old != null && !old.getExamNumber().equals(previous.getExamNumber())) {
+                        addMessage(redirectAttributes, "准考证号" + student.getExamNumber() + "已经存在");
+                        return "redirect:/admin/exam/student";
+                    }
+                    if (!previous.isUpload()) {
                         // 还未扫描上传的考生,才能修改准考证号、学习中心、科目
                         previous.setCampusName(student.getCampusName());
                         previous.setSubjectCode(subject.getCode());
                         previous.setSubjectName(subject.getName());
                         previous.setExamNumber(student.getExamNumber());
-                	}
+                    }
                     previous.setStudentCode(student.getStudentCode());
                     previous.setName(student.getName());
                     previous.setPackageCode(student.getPackageCode());
                     previous.setCollege(student.getCollege());
-            		previous.setClassName(student.getClassName());
-            		previous.setTeacher(student.getTeacher());
+                    previous.setClassName(student.getClassName());
+                    previous.setTeacher(student.getTeacher());
                     previous = studentService.save(previous);
-                        // if
-                        // (!previousSubjectCode.equals(previous.getSubjectCode()))
-                        // {
-                        // // 更新科目上传考生数量
-                        // subjectService.updateUploadCount(examId,
-                        // previousSubjectCode);
-                        // subjectService.updateUploadCount(examId,
-                        // previous.getSubjectCode());
-                        // // 删除已生成的评卷任务
-                        // libraryService.deleteByStudent(previous.getId());
-                        // // 更新科目大题任务数量
-                        // groupService.updateLibraryCount(examId,
-                        // previousSubjectCode);
-                        // // 重置科目所有大题构造评卷任务时间
-                        // groupService.resetBuildTime(examId,
-                        // previous.getSubjectCode());
-                        // }
-                        addMessage(redirectAttributes, "考生" + previous.getName() + "保存成功");
+                    // if
+                    // (!previousSubjectCode.equals(previous.getSubjectCode()))
+                    // {
+                    // // 更新科目上传考生数量
+                    // subjectService.updateUploadCount(examId,
+                    // previousSubjectCode);
+                    // subjectService.updateUploadCount(examId,
+                    // previous.getSubjectCode());
+                    // // 删除已生成的评卷任务
+                    // libraryService.deleteByStudent(previous.getId());
+                    // // 更新科目大题任务数量
+                    // groupService.updateLibraryCount(examId,
+                    // previousSubjectCode);
+                    // // 重置科目所有大题构造评卷任务时间
+                    // groupService.resetBuildTime(examId,
+                    // previous.getSubjectCode());
+                    // }
+                    addMessage(redirectAttributes, "考生" + previous.getName() + "保存成功");
                 } else {
                     addMessage(redirectAttributes, "考生不存在");
                 }
@@ -192,12 +196,13 @@ public class StudentController extends BaseExamController {
                 student.setSheetCount(0);
                 student.setObjectiveScore(0d);
                 student.setSubjectiveScore(0d);
-                ExamStudent old = checkExamNumber(student, new HashMap<String, ExamStudent>(), new HashMap<String, ExamStudent>());
-                if(old!=null){
-                	addMessage(redirectAttributes, "准考证号" + student.getExamNumber() + "已经存在");
-                	return "redirect:/admin/exam/student";
-                } else{
-                	studentService.save(student);
+                ExamStudent old = checkExamNumber(student, new HashMap<String, ExamStudent>(),
+                        new HashMap<String, ExamStudent>());
+                if (old != null) {
+                    addMessage(redirectAttributes, "准考证号" + student.getExamNumber() + "已经存在");
+                    return "redirect:/admin/exam/student";
+                } else {
+                    studentService.save(student);
                 }
                 addMessage(redirectAttributes, "考生" + student.getName() + "保存成功");
             }
@@ -212,8 +217,11 @@ public class StudentController extends BaseExamController {
         if (student != null) {
             studentService.deleteById(id);
             markService.deleteByStudent(student);
-            subjectService.updateUploadCount(student.getExamId(), student.getSubjectCode(), (int) studentService
-                    .countUploadedByExamIdAndSubjectCode(student.getExamId(), student.getSubjectCode()));
+            subjectService.updateUploadCount(
+                    student.getExamId(),
+                    student.getSubjectCode(),
+                    (int) studentService.countUploadedByExamIdAndSubjectCode(student.getExamId(),
+                            student.getSubjectCode()));
             addMessage(redirectAttributes, "删除考生成功");
         } else {
             addMessage(redirectAttributes, "找不到对应的考生");
@@ -262,11 +270,9 @@ public class StudentController extends BaseExamController {
                 if (StringUtils.isBlank(student.getExamNumber()) || StringUtils.isBlank(student.getName())
                         || StringUtils.isBlank(student.getSubjectCode())
                         || StringUtils.isBlank(student.getSubjectName())
-                        || StringUtils.isBlank(student.getCampusName())
-                        || StringUtils.isBlank(student.getCollege())
-                        || StringUtils.isBlank(student.getClassName())
-                        || StringUtils.isBlank(student.getTeacher())
-                        || StringUtils.isBlank(student.getStudentCode()) ) {
+                        || StringUtils.isBlank(student.getCampusName()) || StringUtils.isBlank(student.getCollege())
+                        || StringUtils.isBlank(student.getClassName()) || StringUtils.isBlank(student.getTeacher())
+                        || StringUtils.isBlank(student.getStudentCode())) {
                     continue;
                 }
 
@@ -280,8 +286,8 @@ public class StudentController extends BaseExamController {
                 student.setObjectiveScore(0d);
                 student.setSubjectiveScore(0d);
                 ExamStudent previous = checkExamNumber(student, current, saveMap);
-                if(previous!=null){
-                	student = updatePrevious(student, previous);
+                if (previous != null) {
+                    student = updatePrevious(student, previous);
                 }
                 saveList.add(student);
                 saveMap.put(student.getExamNumber(), student);
@@ -340,12 +346,127 @@ public class StudentController extends BaseExamController {
         }
     }
 
+    @RequestMapping(value = "/absentTemplate")
+    public String absentTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "缺考考生导入模板.xlsx";
+            List<ExamStudentVO> list = Lists.newArrayList();
+            list.add(new ExamStudentVO());
+            new ExportExcel("缺考考生", ExamStudentVO.class, 2).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam-param/student";
+    }
+
+    @RequestMapping(value = "/absentImport", method = RequestMethod.POST)
+    public String absentImportFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+        int examId = getSessionExamId(request);
+        try {
+            int successNum = 0;
+            int failureNum = 0;
+            StringBuilder failureMsg = new StringBuilder();
+            ImportExcel ei = new ImportExcel(file, 1, 0);
+            List<ExamStudentVO> list = ei.getDataList(ExamStudentVO.class);
+            studentService.clearManualAbsent(examId);
+            for (ExamStudentVO studentVO : list) {
+                if (StringUtils.isBlank(studentVO.getExamNumber())) {
+                    continue;
+                }
+                ExamStudent student = studentService.findByExamIdAndExamNumber(examId, studentVO.getExamNumber());
+                if (student != null) {
+                    student.setManualAbsent(true);
+                    successNum++;
+                } else {
+                    failureMsg.append("<br/>准考证号 " + studentVO.getExamNumber() + " 不存在; ");
+                    failureNum++;
+                }
+
+            }
+            if (failureNum > 0) {
+                failureMsg.insert(0, ",失败 " + failureNum + " 条用户");
+            }
+            addMessage(redirectAttributes, "已成功导入 " + successNum + " 条用户" + failureMsg);
+        } catch (Exception e) {
+            log.error("Batch import absentStudent error!", e);
+            addMessage(redirectAttributes, "导入缺考考生失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam-param/student";
+    }
+
+    @RequestMapping(value = "/breachTemplate")
+    public String breachTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "违纪考生导入模板.xlsx";
+            List<ExamStudentVO> list = Lists.newArrayList();
+            list.add(new ExamStudentVO());
+            new ExportExcel("违纪考生", ExamStudentVO.class, 2).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入模板下载失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam-param/student";
+    }
+
+    @RequestMapping(value = "/breachImport", method = RequestMethod.POST)
+    public String breachImportFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+        int examId = getSessionExamId(request);
+        // Exam exam = examService.findById(examId);
+        try {
+            int successNum = 0;
+            int failureNum = 0;
+            StringBuilder failureMsg = new StringBuilder();
+            ImportExcel ei = new ImportExcel(file, 1, 0);
+            List<ExamStudentVO> list = ei.getDataList(ExamStudentVO.class);
+            for (ExamStudentVO studentVO : list) {
+                if (StringUtils.isBlank(studentVO.getExamNumber())) {
+                    continue;
+                }
+                ExamStudent student = studentService.findByExamIdAndExamNumber(examId, studentVO.getExamNumber());
+                if (student != null) {
+                    student.setBreach(true);
+                    successNum++;
+                } else {
+                    failureMsg.append("<br/>准考证号 " + studentVO.getExamNumber() + " 不存在; ");
+                    failureNum++;
+                }
+
+            }
+            if (failureNum > 0) {
+                failureMsg.insert(0, ",失败 " + failureNum + " 条用户");
+            }
+            addMessage(redirectAttributes, "已成功导入 " + successNum + " 条用户" + failureMsg);
+        } catch (Exception e) {
+            log.error("Batch import BreachStudent error!", e);
+            addMessage(redirectAttributes, "导入违纪考生失败!失败信息:" + e.getMessage());
+        }
+        return "redirect:" + "/admin/exam-param/student";
+    }
+
+    @RequestMapping(value = "/updateBreach", method = RequestMethod.POST)
+    @ResponseBody
+    public JSONObject updateBreach(HttpServletRequest request, Integer id) {
+        JSONObject result = new JSONObject();
+        ExamStudent student = studentService.findById(id);
+        student.setBreach(false);
+        student = studentService.save(student);
+        if (student != null) {
+            result.accumulate("message", "重置成功!");
+            result.accumulate("success", true);
+        } else {
+            result.accumulate("message", "将违纪考生信息重置为正常时出错!");
+            result.accumulate("success", false);
+        }
+        return result;
+    }
+
     private ExamStudent checkExamNumber(ExamStudent student, Map<String, ExamStudent> current,
             Map<String, ExamStudent> saveMap) {
         ExamStudent previous = saveMap.get(student.getExamNumber());
 
         if (previous != null) {
-        	return previous;
+            return previous;
         }
         if (current != null && !current.isEmpty()) {
             previous = current.get(student.getExamNumber());
@@ -353,30 +474,30 @@ public class StudentController extends BaseExamController {
             previous = studentService.findByExamIdAndExamNumber(student.getExamId(), student.getExamNumber());
         }
         if (previous != null) {
-        	return previous;
+            return previous;
         }
         return null;
     }
 
-	private ExamStudent updatePrevious(ExamStudent student, ExamStudent previous) {
-		previous.setCollege(student.getCollege());
-		previous.setClassName(student.getClassName());
-		previous.setTeacher(student.getTeacher());
-		previous.setExamRoom(student.getExamRoom());
-		previous.setExamSite(student.getExamSite());
-		previous.setRemark(student.getRemark());
-		previous.setSubjectLevel(student.getSubjectLevel());
-		previous.setSubjectCategory(student.getSubjectCategory());
-		previous.setSubjectRemark(student.getSubjectRemark());
-		return previous;
-	}
+    private ExamStudent updatePrevious(ExamStudent student, ExamStudent previous) {
+        previous.setCollege(student.getCollege());
+        previous.setClassName(student.getClassName());
+        previous.setTeacher(student.getTeacher());
+        previous.setExamRoom(student.getExamRoom());
+        previous.setExamSite(student.getExamSite());
+        previous.setRemark(student.getRemark());
+        previous.setSubjectLevel(student.getSubjectLevel());
+        previous.setSubjectCategory(student.getSubjectCategory());
+        previous.setSubjectRemark(student.getSubjectRemark());
+        return previous;
+    }
 
     private void buildSheetUrl(ExamStudent student) {
         Campus campus = campusService.findBySchoolAndName(student.getSchoolId(), student.getCampusName());
         student.setSheetUrls(PictureUrlBuilder.getSheetUrls(student.getExamId(), campus.getId(),
                 student.getSubjectCode(), student.getExamNumber(), student.getSheetCount()));
     }
-    
+
     private void buildPackageUrl(ExamStudent student) {
         if (StringUtils.isNotBlank(student.getPackageCode())) {
             ExamPackage ep = packageService.find(student.getExamId(), student.getPackageCode());

+ 0 - 25
stmms-web/src/main/java/cn/com/qmth/stmms/admin/thread/ScoreCalculateThread.java

@@ -85,7 +85,6 @@ public class ScoreCalculateThread implements Runnable {
             // 删除原有统计数据
             reportService.deleteData(examId);
             context = new ReportContext(exam);
-            // checkStudentService.deleteByExamId(examId);
             long totalCount = studentService.countByExamId(examId);
 
             int pageNumber = 1;
@@ -106,21 +105,6 @@ public class ScoreCalculateThread implements Runnable {
                 pageNumber++;
                 list = studentService.findByExamId(examId, pageNumber, pageSize);
             }
-
-            // 统计识别缺考的试卷
-            // List<ExamStudent> students =
-            // studentService.findByExamIdAndUploadAndAbsent(examId, true, true,
-            // 1,
-            // Integer.MAX_VALUE);
-            // for (ExamStudent examStudent : students) {
-            // CheckStudent student = new CheckStudent(examStudent.getId(),
-            // examId, examStudent.getSubjectCode(),
-            // CheckType.SCAN_ABSENT);
-            // checkStudentService.save(student);
-            // }
-
-            // 生成报表数据
-            // reportService.generateReportData(examId);
             context.save();
             // 统分结束修改标记
             examService.updateNeedCalculate(examId, false);
@@ -151,15 +135,6 @@ public class ScoreCalculateThread implements Runnable {
             // 增加主观题总分统计
             markService.scoreCalculate(student, findMarkGroup(student.getSubjectCode()));
 
-            // 客观题0分主观题有分的考生
-            // ExamSubject subject = findExamSubject(student.getSubjectCode()) ;
-            // if (subject.getObjectiveScore()>0 && student.getObjectiveScore()
-            // == 0 && student.getSubjectiveScore() != 0) {
-            // CheckStudent cs = new CheckStudent(student.getId(), examId,
-            // student.getSubjectCode(),
-            // CheckType.EXCEPTION);
-            // checkStudentService.save(cs);
-            // }
         } catch (Exception e) {
             log.error("calculate error for studentId=" + student.getId(), e);
         }

+ 17 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/vo/ExamStudentVO.java

@@ -0,0 +1,17 @@
+package cn.com.qmth.stmms.admin.vo;
+
+import cn.com.qmth.stmms.common.annotation.ExcelField;
+
+public class ExamStudentVO {
+
+    @ExcelField(title = "准考证号", align = 2, sort = 10)
+    private String examNumber;
+
+    public String getExamNumber() {
+        return examNumber;
+    }
+
+    public void setExamNumber(String examNumber) {
+        this.examNumber = examNumber;
+    }
+}

+ 25 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ExamInfoController.java

@@ -5,6 +5,9 @@ import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -28,8 +31,6 @@ import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.common.enums.ExamStatus;
 import cn.com.qmth.stmms.common.utils.DateUtils;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
 
 @Controller("examInfoApiController")
 @RequestMapping("/api")
@@ -153,4 +154,26 @@ public class ExamInfoController extends BaseApiController {
         }
         return success;
     }
+
+    @AuthValidate({ "adminUser", "scanner" })
+    @RequestMapping(value = "/sliceConfig/{examId}/{subjectCode}", method = RequestMethod.POST)
+    @ResponseBody
+    public boolean updateSubjectSliceConfig(HttpServletRequest request, @PathVariable Integer examId,
+            @PathVariable String subjectCode, @RequestBody PictureConfigItem[] configs) {
+        User user = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(examId);
+        boolean success = false;
+        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
+            ExamSubject es = subjectService.find(examId, subjectCode);
+            if (configs != null && configs.length > 0 && es != null) {
+                subjectService.updateSliceConfig(examId, subjectCode, Arrays.asList(configs));
+                success = true;
+            } else {
+                success = false;
+            }
+        } else {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+        return success;
+    }
 }

+ 10 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ScanController.java

@@ -19,11 +19,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import cn.com.qmth.stmms.api.utils.ScanStudentParameter;
 import cn.com.qmth.stmms.biz.api.auth.annotation.AuthValidate;
 import cn.com.qmth.stmms.biz.api.auth.exception.ApiException;
+import cn.com.qmth.stmms.biz.exam.model.CheckStudent;
 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.service.CheckStudentService;
 import cn.com.qmth.stmms.biz.exam.service.ExamService;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.user.model.User;
+import cn.com.qmth.stmms.common.enums.CheckType;
 import cn.com.qmth.stmms.common.utils.DateUtils;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
 
@@ -39,6 +42,9 @@ public class ScanController extends BaseApiController {
     @Autowired
     private ExamService examService;
 
+    @Autowired
+    private CheckStudentService checkStudentService;
+
     /**
      * 上传考生识别结果
      * 
@@ -78,6 +84,10 @@ public class ScanController extends BaseApiController {
                         obj.accumulate("uploadTime", DateUtils.formatDateTime(student.getUploadTime()));
                         array.add(obj);
                     }
+                    // 增加人工审核数据
+                    if (sc.isManual()) {
+                        checkStudentService.save(new CheckStudent(student.getId(), examId, student.getSubjectCode(), CheckType.MANUAL));
+                    }
                 }
             }
         }

+ 11 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/utils/ScanStudentParameter.java

@@ -16,6 +16,8 @@ public class ScanStudentParameter {
 
     private String paperType;
 
+    private boolean manual;
+
     public String getExamNumber() {
         return examNumber;
     }
@@ -71,4 +73,13 @@ public class ScanStudentParameter {
     public void setPaperType(String paperType) {
         this.paperType = paperType;
     }
+
+    public boolean isManual() {
+        return manual;
+    }
+
+    public void setManualUpdate(boolean manual) {
+        this.manual = manual;
+    }
+
 }

+ 1 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkAnswer.jsp

@@ -12,7 +12,7 @@
 	    <li class="active"><a href="${ctx}/admin/exam/check/answer">识别结果检查</a></li>
 		<li><a href="${ctx}/admin/exam/check/image">图片检查</a></li>
 <%-- 		<li><a href="${ctx}/admin/exam/check/score">分数检查</a></li> --%>
-<%-- 		<li><a href="${ctx}/admin/exam/check/student">人工确认</a></li> --%>
+		<li><a href="${ctx}/admin/exam/check/student">人工确认</a></li>
 	</ul>
 	<form id="searchForm" action="${ctx}/admin/exam/check/answer/start" method="post" class="form-horizontal" target="_blank">
 	    <input type="hidden" class="hiddenField" id="examNumberIn" name="examNumberIn"/>

+ 1 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkImage.jsp

@@ -12,7 +12,7 @@
 		<li><a href="${ctx}/admin/exam/check/answer">识别结果检查</a></li>
 		<li class="active"><a href="${ctx}/admin/exam/check/image">图片检查</a></li>
 <%-- 		<li><a href="${ctx}/admin/exam/check/score">分数检查</a></li> --%>
-<%-- 		<li><a href="${ctx}/admin/exam/check/student">人工确认</a></li> --%>
+		<li><a href="${ctx}/admin/exam/check/student">人工确认</a></li>
 	</ul>
 	<form id="searchForm" action="${ctx}/admin/exam/check/image" method="post" class="breadcrumb form-search">
 		<input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>

+ 1 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkStudent.jsp

@@ -13,7 +13,7 @@
 		<li><a href="${ctx}/admin/exam/check/image">图片检查</a></li>
 		<li class="active"><a href="${ctx}/admin/exam/check/student">人工确认</a></li>
 	</ul>
-<form id="searchForm" action="${ctx}/admin/exam/check/student" method="post" class="breadcrumb form-search">
+	<form id="searchForm" action="${ctx}/admin/exam/check/student" 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>

+ 2 - 2
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkStudentEdit.jsp

@@ -42,7 +42,7 @@
             <div class="cont cl">
                 <div id="left" class="left">
                         <div class="form-m">
-                            <div class="form-t">
+                      <!--       <div class="form-t">
                                 <span class="b">是否缺考:</span>
                                 <label>
                                 <span class="radio"><input type="button" class="absent-select" data-absent="true"></span><span>是</span>
@@ -50,7 +50,7 @@
                                 <label>
                                 <span class="radio"><input type="button" class="absent-select" data-absent="false"></span><span>否</span>
                                 </label>
-                            </div>
+                            </div> -->
                             <div id="answer-content">
                             </div>
                         </div>

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

@@ -78,16 +78,21 @@
                     <a href="${ctx}/admin/exam/group/changeStatus?subjectCode=${result.subjectCode}&number=${result.number}&status=FINISH" data-number="${result.number}" class="edit-button">结束</a>
                     </c:if>
 					<c:if test="${result.currentCount>0}">
+					&nbsp;
 					<a href="${ctx}/admin/exam/group/release?subjectCode=${result.subjectCode}&number=${result.number}">回收</a>
 					</c:if>
 					<c:if test="${result.libraryCount>0}">
+					&nbsp;
 					<a href="${ctx}/admin/exam/group/reset?subjectCode=${result.subjectCode}&number=${result.number}" data-number="${result.number}" class="reset-button">重置</a>
 					</c:if>
+					&nbsp;
 					<a href="${ctx}/admin/exam/group/edit-simple?subjectCode=${result.subjectCode}&number=${result.number}" data-number="${result.number}" class="edit-button">修改</a>
+					&nbsp;
 					<a href="${ctx}/admin/exam/group/delete?subjectCode=${result.subjectCode}&number=${result.number}" data-number="${result.number}" class="delete-button">删除</a>
 					</c:if>
 					
 					<c:if test="${web_user.schoolAdmin==true && result.status.value==3}">
+					&nbsp;
 					<a href="${ctx}/admin/exam/group/changeStatus?subjectCode=${result.subjectCode}&number=${result.number}&status=FORMAL" data-number="${result.number}" class="edit-button">开始正评</a>
 					</c:if>
 				</td>

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

@@ -16,6 +16,22 @@
 			<a href="${ctx}/admin/exam/student/template">下载模板</a>
 		</form>
 	</div>
+	    <div id="breachImportBox" class="hide">
+        <form id="breachImportForm" action="${ctx}/admin/exam/student/breachImport" method="post" enctype="multipart/form-data"
+              style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+            <input id="breachUploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
+            <input id="breachBtnImportSubmit" class="btn btn-primary" type="submit" value="违纪考生导入"/>
+            <a href="${ctx}/admin/exam/student/breachTemplate">下载模板</a>
+        </form>
+    </div>
+    <div id="absentImportBox" class="hide">
+        <form id="absentImportForm" action="${ctx}/admin/exam/student/absentImport" method="post" enctype="multipart/form-data"
+              style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+            <input id="absentUploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
+            <input id="absentBtnImportSubmit" class="btn btn-primary" type="submit" value="缺考考生导入"/>
+            <a href="${ctx}/admin/exam/student/absentTemplate">下载模板</a>
+        </form>
+    </div>
 	<form id="searchForm"  action="${ctx}/admin/exam-param/student" 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}"/>
@@ -60,6 +76,17 @@
 				<option value="1" <c:if test="${query.absent!=null && query.absent==true}">selected</c:if>>缺考</option>
 				<option value="0" <c:if test="${query.absent!=null && query.absent==false}">selected</c:if>>正常</option>
 			</select>
+			<select id="breach" name="breach" class="input-small">
+				<option value="">不限</option>
+				<option value="1" <c:if test="${query.breach!=null && query.breach==true}">selected</c:if>>违纪</option>
+				<option value="0" <c:if test="${query.breach!=null && query.breach==false}">selected</c:if>>正常</option>
+			</select>
+			<select id="manualAbsent" name="manualAbsent" class="input-small">
+				<option value="">不限</option>
+				<option value="1" <c:if test="${query.manualAbsent!=null && query.manualAbsent==true}">selected</c:if>>人工指定缺考</option>
+				<option value="0" <c:if test="${query.manualAbsent!=null && query.manualAbsent==false}">selected</c:if>>正常</option>
+			</select>
+			<br><br>
 			<label>签到表编号</label>
 			<input type="text" name="packageCode" value="${query.packageCode}" maxlength="30" class="input-small"/>
 			<label>批次编号</label>
@@ -73,6 +100,8 @@
 			<c:if test="${query.totalCount>0 && query.totalCount<=10000}">
 			&nbsp;<input id="export-button" class="btn" type="button" value="导出"/>
 			</c:if>
+			&nbsp;<input id="breachBtnImport" class="btn" type="button" value="违纪名单导入"/>
+            &nbsp;<input id="absentBtnImport" class="btn" type="button" value="缺考名单导入"/>
 		</div>
 	</form>
 	<tags:message content="${message}"/>
@@ -86,7 +115,8 @@
 				<th>试卷类型</th>
 				<th>层次</th>
 				<th>专业类型</th>
-				<th>状态</th>
+				<th>扫描识别</th>
+				<th>人工指定</th>
 				<th>批次编号</th>
 				<th>签到表编号</th>
 				<th>考试备注信息</th>
@@ -107,9 +137,6 @@
 				<c:if test="${student.upload==true}">
 				<a class="sheet-link" href="##" data-sheet-url="${student.sheetUrlString}" data-answer-url="<c:if test="${student.answerUrl!=null}">${cardServer}${student.answerUrl}</c:if>" data-title="${student.examNumber}&nbsp;&nbsp;${student.name}&nbsp;&nbsp;客观总分${student.objectiveScoreString}&nbsp;&nbsp;主观总分${student.subjectiveScoreString}&nbsp;&nbsp;全卷总分${student.totalScoreString}">已上传</a>
 				&nbsp;
-				<c:if test="${student.manualAbsent==true}">
-				人工指定
-				</c:if>
 				<c:if test="${student.absent==true}">
 				缺考
 				</c:if>
@@ -123,6 +150,20 @@
 				</c:if>
 				
 				</td>
+				<td >
+                    <c:if test="${student.breach==true}">
+                        <a href="##" onclick="updateBreach(${student.id});">违纪</a>
+                    </c:if>
+                    <c:if test="${student.breach==false}">
+                        正常
+                    </c:if>
+                    <c:if test="${student.manualAbsent==true}">
+				    人工指定
+				    </c:if>
+				    <c:if test="${student.manualAbsent==false}">
+				    正常
+				    </c:if>
+                </td>
 				<td>${student.batchCode}</td>
 				<td>
 				<c:if test="${student.packageUrlString!=null && student.packageUrlString!=''}">
@@ -169,6 +210,14 @@ $("#btnImport").click(function(){
 	$.jBox($("#importBox").html(), {title:"导入数据", buttons:{"关闭":true}, 
 		bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
 });
+$("#breachBtnImport").click(function(){
+	$.jBox($("#breachImportBox").html(), {title:"导入数据", buttons:{"关闭":true},
+		bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
+});
+$("#absentBtnImport").click(function(){
+	$.jBox($("#absentImportBox").html(), {title:"导入数据", buttons:{"关闭":true},
+		bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
+});
 $("#export-button").click(function(){
 	$("#searchForm").attr("action","${ctx}/admin/exam/student/export");
 	$("#searchForm").submit();
@@ -187,6 +236,21 @@ function goSearch(){
 	$("#searchForm").submit();
 	return false;
 }
+function updateBreach(studentId) {
+	  top.$.jBox.confirm("确认要将该考生违纪重置为正常?","提示",function(v,h,f){
+	    if(v=="ok"){
+	      var url = '${ctx}/admin/exam/student/updateBreach?id='+studentId;
+	      $.ajax( {
+	        url : url,
+	        type : "POST",
+	        success : function(val) {
+	          if(val.success){
+	            window.location.href="${ctx}/admin/exam/student";
+	          }
+	        }})
+	    }
+	  });
+}
 </script>	
 </body>
 </html>