yin 1 年之前
父节点
当前提交
ca1ed3cbe8
共有 21 个文件被更改,包括 526 次插入401 次删除
  1. 29 28
      install/mysql/init/stmms_ft.sql
  2. 4 0
      install/mysql/upgrade/1.5.0.sql
  3. 14 4
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/config/service/impl/SystemCache.java
  4. 3 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/config/service/impl/SystemConfigServiceImpl.java
  5. 7 6
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamDao.java
  6. 18 13
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamStudentDao.java
  7. 16 13
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamStudentService.java
  8. 23 22
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamServiceImpl.java
  9. 100 60
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamStudentServiceImpl.java
  10. 2 1
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/ConfigType.java
  11. 2 2
      stmms-common/src/main/java/cn/com/qmth/stmms/common/utils/VersionInfo.java
  12. 10 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/MarkerInfoDTO.java
  13. 15 19
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectQuestionDTO.java
  14. 10 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectUserDTO.java
  15. 27 21
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkController.java
  16. 17 27
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ScoreController.java
  17. 24 24
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/StudentController.java
  18. 9 18
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/user/UserController.java
  19. 63 47
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/scoreList.jsp
  20. 104 69
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/studentList.jsp
  21. 29 27
      stmms-web/src/main/webapp/sql/stmms_ft.sql

+ 29 - 28
install/mysql/init/stmms_ft.sql

@@ -34,7 +34,7 @@ CREATE TABLE `b_school`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='学校表';
 
-  
+
 # Dump of table b_sys_config
 # ------------------------------------------------------------
 
@@ -49,7 +49,7 @@ CREATE TABLE `b_sys_config`
     UNIQUE KEY `index1` (`type`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='配置表';
-  
+
 LOCK TABLES `b_sys_config` WRITE;
 
 INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
@@ -58,7 +58,8 @@ INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
 VALUES (2, 'MARK_TIME', '30', '2021-08-09 15:38:58');
 INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
 VALUES (3, 'AUTO_REPORT', null, '2021-08-09 15:38:58');
-
+INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
+VALUES (4, 'STUDENT_SHEET_COUNT', null, '2021-08-09 15:38:58');
 UNLOCK TABLES;
 
 
@@ -76,7 +77,7 @@ CREATE TABLE `b_sys_auth` (
 ) ENGINE=InnoDB 
 	DEFAULT CHARSET = utf8mb4 COMMENT ='授权配置表';
 
-  
+
 # Dump of table b_user
 # ------------------------------------------------------------
 
@@ -136,7 +137,7 @@ CREATE TABLE `eb_user_exam`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='用户考试关联表';
 
-  
+
 # Dump of table eb_subject_user
 # ------------------------------------------------------------
 
@@ -348,7 +349,7 @@ CREATE TABLE `eb_exam_student`
 
 DROP TABLE IF EXISTS `eb_inspect_history`;
 
-CREATE TABLE `eb_inspect_history` 
+CREATE TABLE `eb_inspect_history`
 (
 	`id` 		INT (11) NOT NULL AUTO_INCREMENT COMMENT '主键',
 	`exam_id`	INT (11) NOT NULL COMMENT '考试ID',
@@ -513,7 +514,7 @@ CREATE TABLE `eb_subjective_score`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='主观题得分明细表';
 
-  
+
 # Dump of table eb_selective_group
 # ------------------------------------------------------------
 
@@ -549,8 +550,8 @@ CREATE TABLE `eb_selective_student`
     PRIMARY KEY (`student_id`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='选做题考生状态表';
-  
-  
+
+
 # Dump of table eb_operation_log
 # ------------------------------------------------------------
 
@@ -665,8 +666,8 @@ CREATE TABLE `m_reject_history`
     KEY `index2` (`library_id`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='打回记录表';
-  
-  
+
+
 # Dump of table m_special_tag
 # ------------------------------------------------------------
 
@@ -717,7 +718,7 @@ CREATE TABLE `m_track`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='轨迹给分表';
 
-  
+
 # Dump of table m_header_tag
 # ------------------------------------------------------------
 
@@ -1076,7 +1077,7 @@ CREATE TABLE `s_basic_subject_college`
     `subject_code`    varchar(32) DEFAULT NULL COMMENT '科目代码',
     `subject_name`    varchar(32) DEFAULT NULL COMMENT '科目名称',
     `college_name`    varchar(64) DEFAULT NULL COMMENT '学院名称',
-	`total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',    
+	`total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',
     `reality_count`      int(11)     DEFAULT NULL COMMENT '有效人数',
     `excellent_count` int(11)     DEFAULT NULL COMMENT '优秀人数',
     `excellent_rate`  double      DEFAULT NULL COMMENT '优秀率',
@@ -1109,7 +1110,7 @@ CREATE TABLE `s_basic_subject_teacher`
     `max_score`          double      DEFAULT NULL COMMENT '最高分',
     `min_score`          double      DEFAULT NULL COMMENT '最低分',
     `avg_score`          double      DEFAULT NULL COMMENT '平均分',
-    `total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',    
+    `total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',
     `reality_count`      int(11)     DEFAULT NULL COMMENT '有效人数',
     `relative_avg_score` double      DEFAULT NULL COMMENT '平均相对分',
     PRIMARY KEY (`id`),
@@ -1143,14 +1144,14 @@ CREATE TABLE `s_basic_subject_teacher_class`
     KEY `index1` (`exam_id`, `subject_code`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='任课老师班级统计表';
-  
+
 
 # Dump of table eb_import_query
 # ------------------------------------------------------------
 
 DROP TABLE IF EXISTS `eb_import_query`;
 
-CREATE TABLE `eb_import_query` 
+CREATE TABLE `eb_import_query`
 (
   `id` 			int(11) 	NOT NULL AUTO_INCREMENT COMMENT '主键',
   `create_time` datetime    NOT NULL COMMENT '创建时间',
@@ -1162,14 +1163,14 @@ CREATE TABLE `eb_import_query`
   KEY `index1` (`exam_id`, `user_id`, `type`)
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='导入查询表';
-  
-  
+
+
 # Dump of table eb_answer_card
 # ------------------------------------------------------------
 
 DROP TABLE IF EXISTS `eb_answer_card`;
 
-CREATE TABLE `eb_answer_card` 
+CREATE TABLE `eb_answer_card`
 (
     `exam_id`			int(11)     NOT NULL COMMENT '考试ID',
     `code`				varchar(64) DEFAULT NULL COMMENT '混扫代码',
@@ -1188,8 +1189,8 @@ CREATE TABLE `eb_answer_card`
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='题卡卡格式表';
 
-DROP TABLE IF EXISTS `eb_score_verify`;  
-CREATE TABLE `eb_score_verify` 
+DROP TABLE IF EXISTS `eb_score_verify`;
+CREATE TABLE `eb_score_verify`
 (
 	`id`			int(11)     NOT NULL AUTO_INCREMENT COMMENT '主键',
     `exam_id`		int(11)     NOT NULL COMMENT '考试ID',
@@ -1204,12 +1205,12 @@ CREATE TABLE `eb_score_verify`
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='成绩校验';
 
-  
+
 # Dump of table eb_answer_card_subject
 # ------------------------------------------------------------
 
 DROP TABLE IF EXISTS `eb_answer_card_subject`;
-CREATE TABLE `eb_answer_card_subject` 
+CREATE TABLE `eb_answer_card_subject`
 (
 	`id`           		int(11)     	NOT NULL AUTO_INCREMENT COMMENT '主键',
     `exam_id`			int(11)     	NOT NULL COMMENT '考试ID',
@@ -1219,7 +1220,7 @@ CREATE TABLE `eb_answer_card_subject`
   UNIQUE KEY `index1` (`exam_id`,`card_number`,`subject_code`)
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='卡格式科目关联关系';
-  
+
 DROP TABLE IF EXISTS `eb_user_student`;
 CREATE TABLE `eb_user_student`
 (
@@ -1230,7 +1231,7 @@ CREATE TABLE `eb_user_student`
     UNIQUE KEY `index1` (`user_id`, `exam_number`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='用户考生关联表';
-  
+
 DROP TABLE IF EXISTS `b_role_info`;
 CREATE TABLE `b_role_info`
 (
@@ -1240,12 +1241,12 @@ CREATE TABLE `b_role_info`
     `name`           varchar(64) NOT NULL COMMENT '名称',
     `seq`            int(11)     NOT NULL COMMENT '排序',
     `updater_id` 	 int(11)	 DEFAULT NULL COMMENT '更新人ID',
-    `update_time`	 datetime    DEFAULT NULL COMMENT '更新时间', 
+    `update_time`	 datetime    DEFAULT NULL COMMENT '更新时间',
     PRIMARY KEY (`id`),
     UNIQUE KEY `IDX_ROLE_INFO_01` (`school_id`,`code`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='角色表';
-  
+
 DROP TABLE IF EXISTS `b_privilege`;
 CREATE TABLE `b_privilege`
 (
@@ -1279,7 +1280,7 @@ CREATE TABLE `b_role_privilege`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='角色权限关联表';
 
-LOCK TABLES `b_privilege` WRITE;  
+LOCK TABLES `b_privilege` WRITE;
 INSERT INTO `b_privilege` ( `code`, `name`, `parent_code`, `privilege_type`, `privilege_uri`, `seq`,`level`,`icon`,`i18n`)
 VALUES ('user_list', '用户管理', 'root_code', 'MENU', '/admin/user/list', 10,1,'icon-user','index.user');
 INSERT INTO `b_privilege` ( `code`, `name`, `parent_code`, `privilege_type`, `privilege_uri`, `seq`,`level`,`icon`,`i18n`)

+ 4 - 0
install/mysql/upgrade/1.5.0.sql

@@ -0,0 +1,4 @@
+-- 1.5.0
+USE `stmms_ft`;
+INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
+VALUES (4, 'STUDENT_SHEET_COUNT', null, '2021-08-09 15:38:58');

+ 14 - 4
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/config/service/impl/SystemCache.java

@@ -4,12 +4,12 @@ import java.util.List;
 
 import javax.annotation.PostConstruct;
 
-import net.sf.json.JSONObject;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
+import com.qmth.boot.tools.models.ByteArray;
+
 import cn.com.qmth.stmms.biz.config.model.SystemAuth;
 import cn.com.qmth.stmms.biz.config.service.SystemAuthService;
 import cn.com.qmth.stmms.biz.config.service.SystemConfigService;
@@ -20,8 +20,7 @@ import cn.com.qmth.stmms.biz.utils.SolarHttpUtil;
 import cn.com.qmth.stmms.common.enums.ConfigType;
 import cn.com.qmth.stmms.common.enums.SystemAuthType;
 import cn.com.qmth.stmms.common.utils.AesUtils;
-
-import com.qmth.boot.tools.models.ByteArray;
+import net.sf.json.JSONObject;
 
 @Component
 public class SystemCache {
@@ -47,6 +46,8 @@ public class SystemCache {
 
     private Long markTime;
 
+    private boolean enableStudentSheetCount;
+
     @Value("${qmth.solar.host}")
     private String host;
 
@@ -75,6 +76,7 @@ public class SystemCache {
         }
         fileServer = configService.findByType(ConfigType.FILE_SERVER);
         markTime = Long.parseLong(configService.findByType(ConfigType.MARK_TIME));
+        enableStudentSheetCount = Boolean.parseBoolean(configService.findByType(ConfigType.STUDENT_SHEET_COUNT));
     }
 
     public boolean isAuth() {
@@ -125,6 +127,14 @@ public class SystemCache {
         this.groupDeleteWarn = groupDeleteWarn;
     }
 
+    public boolean isEnableStudentSheetCount() {
+        return enableStudentSheetCount;
+    }
+
+    public void setEnableStudentSheetCount(boolean enableStudentSheetCount) {
+        this.enableStudentSheetCount = enableStudentSheetCount;
+    }
+
     public void parseJson(JSONObject json) {
         if (json != null) {
             Auth = true;

+ 3 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/config/service/impl/SystemConfigServiceImpl.java

@@ -33,6 +33,9 @@ public class SystemConfigServiceImpl extends BaseQueryService<SystemConfig> impl
         if (ConfigType.MARK_TIME.equals(s.getType())) {
             systemCache.setMarkTime(Long.parseLong(value));
         }
+        if (ConfigType.STUDENT_SHEET_COUNT.equals(s.getType())) {
+            systemCache.setEnableStudentSheetCount(Boolean.parseBoolean(value));
+        }
         return s;
     }
 

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

@@ -17,6 +17,7 @@ import cn.com.qmth.stmms.common.enums.ObjectiveStatus;
 
 public interface ExamDao extends PagingAndSortingRepository<Exam, Integer>, JpaSpecificationExecutor<Exam> {
 
+    @Override
     public Page<Exam> findAll(Pageable pageable);
 
     List<Exam> findByStatus(ExamStatus status);
@@ -38,21 +39,21 @@ public interface ExamDao extends PagingAndSortingRepository<Exam, Integer>, JpaS
 
     public Exam findFirstBySchoolIdAndCode(Integer schoolId, String code);
 
-    @Query(value = "select * from eb_exam e where e.id in (select DISTINCT m.exam_id from eb_marker m where m.user_id=?1) and e.create_time >?2 "
+    @Query(value = "select * from eb_exam e where e.id in (select DISTINCT m.exam_id from eb_marker m where m.user_id=?1) and e.create_time >?2  and e.status = ?3"
             + "order by e.id desc", nativeQuery = true)
-    public List<Exam> findByMarkerUserId(Integer userId, Date time);
+    public List<Exam> findByMarkerUserId(Integer userId, Date time, ExamStatus status);
 
-    @Query(value = "select * from eb_exam e where e.school_id = ?1 and e.id in (select s.exam_id from eb_exam_subject s where s.code in (select su.subject_code from eb_subject_user su where su.user_id=?2) )"
+    @Query(value = "select * from eb_exam e where e.school_id = ?1 and e.id in (select s.exam_id from eb_exam_subject s where s.code in (select su.subject_code from eb_subject_user su where su.user_id=?2) ) and e.status = ?3 "
             + "order by e.id desc", nativeQuery = true)
-    public List<Exam> findBySubjectHeaderUserId(Integer schoolId, Integer userId);
+    public List<Exam> findBySubjectHeaderUserId(Integer schoolId, Integer userId, ExamStatus status);
 
     @Modifying
     @Query("update Exam e set e.objectiveStatus=?2 where e.id=?1")
     public int updateObjectiveStatus(int examId, ObjectiveStatus status);
 
-    @Query(value = "select * from eb_exam e where e.school_id = ?1 and e.id in (select s.exam_id from eb_user_exam s where s.user_id=?2 )"
+    @Query(value = "select * from eb_exam e where e.school_id = ?1 and e.id in (select s.exam_id from eb_user_exam s where s.user_id=?2 ) and e.status =?3 "
             + "order by e.id desc", nativeQuery = true)
-    public List<Exam> findBySchoolViewUserId(Integer schoolId, Integer userId);
+    public List<Exam> findBySchoolViewUserId(Integer schoolId, Integer userId, ExamStatus status);
 
     @Modifying
     @Query("update Exam e set e.updateTime=?2 where e.id=?1")

+ 18 - 13
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamStudentDao.java

@@ -1,7 +1,9 @@
 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 java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
 
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -9,13 +11,11 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.PagingAndSortingRepository;
 
-import java.math.BigDecimal;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
+import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
+import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
 
-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);
 
@@ -72,11 +72,12 @@ public interface ExamStudentDao extends PagingAndSortingRepository<ExamStudent,
 
     @Modifying
     @Query("update ExamStudent s set s.subjectiveStatus=?3, s.subjectiveScore=?4, s.subjectiveScoreList=?5 where s.examId=?1 and s.subjectCode=?2")
-    public void updateSubjectiveStatusAndScore(Integer examId, String subjetCode, SubjectiveStatus status,
-            double score, String scoreList);
+    public void updateSubjectiveStatusAndScore(Integer examId, String subjetCode, SubjectiveStatus status, double score,
+            String scoreList);
 
     // @Modifying
-    // @Query("update ExamStudent s set s.subjectiveStatus=?3, s.subjectiveScore=?4, s.subjectiveScoreList=?5, s.inspectTime=?6, s.inspectorId=?7 "
+    // @Query("update ExamStudent s set s.subjectiveStatus=?3, s.subjectiveScore=?4,
+    // s.subjectiveScoreList=?5, s.inspectTime=?6, s.inspectorId=?7 "
     // +
     // " where s.examId=?1 and s.subjectCode=?2 and s.subjectiveStatus not in (?8)")
     // public void updateSubjectiveStatusAndScoreWithoutStatus(Integer examId,
@@ -162,7 +163,8 @@ public interface ExamStudentDao extends PagingAndSortingRepository<ExamStudent,
 
     @Query("select s from ExamStudent s where s.examId=?1 and s.subjectCode=?2 and s.upload=true and s.absent=false and s.breach=false "
             + " and not exists (select l.id from MarkLibrary l where l.studentId=s.id and l.groupNumber=?3)")
-    public List<ExamStudent> findUnLibraryStudent(Integer examId, String subjectCode, Integer groupNumber, Pageable page);
+    public List<ExamStudent> findUnLibraryStudent(Integer examId, String subjectCode, Integer groupNumber,
+            Pageable page);
 
     @Query("select s from ExamStudent s where s.examId=?1 and s.subjectCode=?2 and s.upload=true and s.absent=false and s.breach=false "
             + "and s.trial=?4 and not exists (select l.id from TrialLibrary l where l.studentId=s.id and l.groupNumber=?3)")
@@ -208,7 +210,8 @@ public interface ExamStudentDao extends PagingAndSortingRepository<ExamStudent,
     public void updateSubjectiveStatusAndTimeAndInspectorId(Integer studentId, SubjectiveStatus status,
             Date inspectTime, Integer inspectorId);
 
-    public List<ExamStudent> findByExamIdAndStudentCodeAndSubjectCode(int examId, String studentCode, String subjectCode);
+    public List<ExamStudent> findByExamIdAndStudentCodeAndSubjectCode(int examId, String studentCode,
+            String subjectCode);
 
     @Query("select sum(s.sheetCount) from ExamStudent s where s.examId=?1 ")
     public Long sumSheetCountByExamId(Integer examId);
@@ -272,4 +275,6 @@ public interface ExamStudentDao extends PagingAndSortingRepository<ExamStudent,
     @Query("select sum(s.sheetCount) from ExamStudent s where s.examId=?1 and s.examSite=?2 ")
     public Long sumSheetCountByExamIdAndExamSite(int examId, String examSite);
 
+    @Query("select distinct m.college from ExamStudent m where m.examId=?1 and m.subjectCode=?2 ")
+    List<String> findDistinctCollegeBySubjectCode(int examId, String subjectCode);
 }

+ 16 - 13
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamStudentService.java

@@ -1,5 +1,10 @@
 package cn.com.qmth.stmms.biz.exam.service;
 
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 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;
@@ -9,11 +14,6 @@ import cn.com.qmth.stmms.biz.utils.OriginTag;
 import cn.com.qmth.stmms.biz.utils.PictureTag;
 import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
 
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 public interface ExamStudentService {
 
     public ExamStudent findById(int id);
@@ -35,7 +35,7 @@ public interface ExamStudentService {
     List<ExamStudent> findByExamId(int examId);
 
     List<ExamStudent> findByExamIdAndUploadAndAbsent(int examId, boolean upload, boolean absent, int pageNumber,
-            int pageSize);
+                                                     int pageSize);
 
     ExamStudent findByExamIdAndExamNumber(int examId, String examNumber);
 
@@ -67,7 +67,7 @@ public interface ExamStudentService {
     void updateSubjectInfo(ExamSubject subject);
 
     void updateSubjectiveStatusAndScore(Integer examId, String subjectCode, SubjectiveStatus status, double score,
-            String scoreList);
+                                        String scoreList);
 
     void updateSubjectiveStatusAndScore(Integer id, SubjectiveStatus status, double score, String scoreList);
 
@@ -86,10 +86,10 @@ public interface ExamStudentService {
     void updateException(int id, boolean exception);
 
     public ExamStudent findBySchoolIdAndSubjectCodeAndStudentCode(Integer schoolId, String subjectCode,
-            String studentCode);
+                                                                  String studentCode);
 
     public ExamStudent findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(Integer schoolId, String subjectCode,
-            String studentCode, String examSeqCode);
+                                                                           String studentCode, String examSeqCode);
 
     public ExamStudent findByExamIdAndSubjectCodeAndUploadTimeAfter(int examId, String code, Date date);
 
@@ -104,7 +104,7 @@ public interface ExamStudentService {
     List<ExamStudent> findAbsentOrBreachLibraryStudent(int examId, String subjectCode);
 
     public Long countByExamIdAndSubjectCodeAndCampus(Integer examId, String code, String campusName, boolean upload,
-            boolean absent);
+                                                     boolean absent);
 
     public long countByNoAbsentAndBreach(int examId, String subjectCode, boolean upload, boolean absent, boolean breach);
 
@@ -119,14 +119,14 @@ public interface ExamStudentService {
     List<ExamStudent> findByExamIdAndSubjectCode(int examId, String subjectCode, int pageNumber, int pageSize);
 
     List<Integer> findIdByExamIdAndSubjectCodeAndSubjectiveStatus(Integer examId, String subjectCode,
-            SubjectiveStatus... status);
+                                                                  SubjectiveStatus... status);
 
     List<PictureTag> buildSheetTags(ExamStudent student, int index, boolean withGroupScore);
 
     Map<Integer, List<PictureTag>> buildSheetTags(ExamStudent student, boolean withGroupScore, boolean sliceConfigFix);
 
     Map<MarkGroup, List<OriginTag>> getSliceTags(ExamStudent student, boolean withGroupScore,
-            List<PictureConfigItem> sliceConfig);
+                                                 List<PictureConfigItem> sliceConfig);
 
     boolean updateScanInfo(ExamStudent student);
 
@@ -147,7 +147,7 @@ public interface ExamStudentService {
     public List<String> findDistinctClassName(Integer examId);
 
     public void updateSubjectiveStatusAndTimeAndInspectorId(Integer studentId, SubjectiveStatus status,
-            Date inspectTime, Integer inspectorId);
+                                                            Date inspectTime, Integer inspectorId);
 
     public void inspect(Integer studentId, Date inspectTime, Integer inspectorId);
 
@@ -203,4 +203,7 @@ public interface ExamStudentService {
 
     public long countSheetCountByExamIdAndExamSite(int examId, String examSite);
 
+    List<String> findDistinctCollegeBySubjectCode(int examId, String subjectCode);
+
+    long countSheetCountByQuery(ExamStudentSearchQuery query);
 }

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

@@ -1,5 +1,22 @@
 package cn.com.qmth.stmms.biz.exam.service.impl;
 
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Page;
+import org.springframework.data.jpa.domain.Specification;
+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.ExamDao;
 import cn.com.qmth.stmms.biz.exam.model.Exam;
@@ -12,23 +29,6 @@ import cn.com.qmth.stmms.common.enums.ExamStatus;
 import cn.com.qmth.stmms.common.enums.ExamType;
 import cn.com.qmth.stmms.common.enums.ObjectiveStatus;
 
-import org.apache.commons.lang.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.domain.Page;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
-import javax.persistence.criteria.Root;
-
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
 @Service
 public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamService {
 
@@ -65,6 +65,7 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
     }
 
     // @Cacheable(value = "exam_cache", key = "#id", condition = "#id!=null")
+    @Override
     public Exam findById(Integer id) {
         return examDao.findOne(id);
     }
@@ -113,8 +114,8 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
                     predicates.add(cb.equal(root.get("code"), query.getCode()));
                 }
 
-                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()]));
             }
         }, query);
         fillResult(result, query);
@@ -138,12 +139,12 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
 
     @Override
     public List<Exam> findByMarkerUserId(Integer id, Date time) {
-        return examDao.findByMarkerUserId(id, time);
+        return examDao.findByMarkerUserId(id, time, ExamStatus.START);
     }
 
     @Override
     public List<Exam> findBySubjectHeaderUserId(Integer schoolId, Integer userId) {
-        return examDao.findBySubjectHeaderUserId(schoolId, userId);
+        return examDao.findBySubjectHeaderUserId(schoolId, userId, ExamStatus.START);
     }
 
     @Override
@@ -154,7 +155,7 @@ public class ExamServiceImpl extends BaseQueryService<Exam> implements ExamServi
 
     @Override
     public List<Exam> findBySchoolViewUserId(Integer schoolId, Integer userId) {
-        return examDao.findBySchoolViewUserId(schoolId, userId);
+        return examDao.findBySchoolViewUserId(schoolId, userId, ExamStatus.START);
     }
 
     @Override

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

@@ -1,5 +1,28 @@
 package cn.com.qmth.stmms.biz.exam.service.impl;
 
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.criteria.*;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.hibernate.SQLQuery;
+import org.hibernate.transform.Transformers;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.jpa.domain.Specification;
+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.ExamStudentDao;
 import cn.com.qmth.stmms.biz.exam.model.*;
@@ -18,29 +41,6 @@ import cn.com.qmth.stmms.biz.utils.ScoreItem;
 import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
 
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.RandomUtils;
-import org.hibernate.SQLQuery;
-import org.hibernate.transform.Transformers;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.domain.Sort.Direction;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.Query;
-import javax.persistence.criteria.*;
-
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
-
 @Service
 public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implements ExamStudentService {
 
@@ -90,6 +90,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
 
     public static final String USER_PASSWORD = "123456";
 
+    @Override
     public ExamStudent findById(int id) {
         return studentDao.findOne(id);
     }
@@ -100,6 +101,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
      * @param list
      * @return
      */
+    @Override
     @Transactional
     public int batchSave(List<ExamStudent> list) {
         if (list == null || list.isEmpty()) {
@@ -180,8 +182,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             student.setSubjectCategory(subject.getCategory());
             if (student.getSecretNumber() == null) {
                 student.randomSecretNumber();
-                while (secretNumberSet.contains(student.getSecretNumber())
-                        || studentDao.countByExamIdAndSecretNumber(student.getExamId(), student.getSecretNumber()) > 0) {
+                while (secretNumberSet.contains(student.getSecretNumber()) || studentDao
+                        .countByExamIdAndSecretNumber(student.getExamId(), student.getSecretNumber()) > 0) {
                     student.randomSecretNumber();
                 }
             }
@@ -191,6 +193,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return success;
     }
 
+    @Override
     @Transactional
     public ExamStudent save(ExamStudent student) {
         student.setSubjectCode(StringUtils.trimToNull(student.getSubjectCode()));
@@ -238,6 +241,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return studentDao.save(student);
     }
 
+    @Override
     @Transactional
     public void deleteById(int id) {
         checkStudentService.deleteByStudentId(id);
@@ -247,16 +251,19 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         }
     }
 
+    @Override
     @Transactional
     public void delete(ExamStudent student) {
         studentDao.delete(student);
     }
 
+    @Override
     @Transactional
     public void deleteByExamId(int examId) {
         studentDao.deleteByExamId(examId);
     }
 
+    @Override
     public ExamStudentSearchQuery findByQuery(final ExamStudentSearchQuery query) {
         checkQuery(query);
         query.addSort("examNumber", Direction.ASC);
@@ -271,6 +278,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return query;
     }
 
+    @Override
     public long countByQuery(final ExamStudentSearchQuery query) {
         return studentDao.count(buildSpecification(query));
     }
@@ -331,6 +339,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return list != null && list.size() > 0 ? list.get(0) : null;
     }
 
+    @Override
     public long countByExamId(int examId) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
@@ -355,6 +364,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return studentDao.countUploaded(examId);
     }
 
+    @Override
     public long countByExamIdAndSubjectCode(int examId, String subjectCode) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
@@ -362,6 +372,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return countByQuery(query);
     }
 
+    @Override
     public long countByExamIdAndSubjectCode(int examId, String subjectCode, boolean upload) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
@@ -370,6 +381,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return countByQuery(query);
     }
 
+    @Override
     public long countByExamIdAndSubjectCode(int examId, String subjectCode, boolean upload, boolean absent) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
@@ -588,8 +600,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                 if (query.getObjectiveScore() != null) {
                     predicates.add(cb.equal(root.get("objectiveScore"), query.getObjectiveScore()));
                 } else if (query.getObjectiveScoreGt() != null) {
-                    predicates.add(cb.greaterThan(root.get("objectiveScore").as(Double.class),
-                            query.getObjectiveScoreGt()));
+                    predicates.add(
+                            cb.greaterThan(root.get("objectiveScore").as(Double.class), query.getObjectiveScoreGt()));
                 } else if (query.getObjectiveScoreLt() != null) {
                     predicates
                             .add(cb.lessThan(root.get("objectiveScore").as(Double.class), query.getObjectiveScoreLt()));
@@ -604,11 +616,11 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                 if (query.getSubjectiveScore() != null) {
                     predicates.add(cb.equal(root.get("subjectiveScore"), query.getSubjectiveScore()));
                 } else if (query.getSubjectiveScoreGt() != null) {
-                    predicates.add(cb.greaterThan(root.get("subjectiveScore").as(Double.class),
-                            query.getSubjectiveScoreGt()));
+                    predicates.add(
+                            cb.greaterThan(root.get("subjectiveScore").as(Double.class), query.getSubjectiveScoreGt()));
                 } else if (query.getSubjectiveScoreLt() != null) {
-                    predicates.add(cb.lessThan(root.get("subjectiveScore").as(Double.class),
-                            query.getSubjectiveScoreLt()));
+                    predicates.add(
+                            cb.lessThan(root.get("subjectiveScore").as(Double.class), query.getSubjectiveScoreLt()));
                 }
                 if (query.getUpload() != null) {
                     predicates.add(cb.equal(root.get("upload"), query.getUpload()));
@@ -729,8 +741,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                 if (query.getSheetCount() != null) {
                     predicates.add(cb.equal(root.get("sheetCount"), query.getSheetCount()));
                 }
-                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()]));
             }
         };
     }
@@ -823,7 +835,9 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return countByQuery(query);
     }
 
-    public long countByNoAbsentAndBreach(int examId, String subjectCode, boolean upload, boolean absent, boolean breach) {
+    @Override
+    public long countByNoAbsentAndBreach(int examId, String subjectCode, boolean upload, boolean absent,
+            boolean breach) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
         query.setSubjectCode(subjectCode);
@@ -833,6 +847,7 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         return countByQuery(query);
     }
 
+    @Override
     public long countByAbsentAndBreach(int examId, String subjectCode, Boolean absent, Boolean breach) {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
@@ -876,8 +891,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             sliceConfig = exam.getSliceConfigList();
         }
         if (!sliceConfig.isEmpty()) {
-            List<PictureTag> tags = PictureConfigTransform.process(sliceConfig,
-                    getSliceTags(student, withGroupScore, sliceConfig)).get(index);
+            List<PictureTag> tags = PictureConfigTransform
+                    .process(sliceConfig, getSliceTags(student, withGroupScore, sliceConfig)).get(index);
             if (tags != null) {
                 list.addAll(tags);
             }
@@ -964,8 +979,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                 + format.format(student.getSubjectiveScore() != null ? student.getSubjectiveScore() : 0));
         // 客观题得分明细
         List<String> objectives = new LinkedList<>();
-        List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndPaperType(
-                student.getExamId(), student.getSubjectCode(), true, student.getPaperType());
+        List<ExamQuestion> questions = questionService.findByExamAndSubjectAndObjectiveAndPaperType(student.getExamId(),
+                student.getSubjectCode(), true, student.getPaperType());
         List<ScoreItem> scoreList = student.getScoreList(true);
         List<String> details = new ArrayList<>();
         int i = 0;
@@ -1049,9 +1064,9 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                 if (config.getX() <= 1 && config.getY() <= 1 && config.getI() <= sliceConfig.size()
                         && sliceConfig.get(config.getI() - 1).getW() > 0
                         && sliceConfig.get(config.getI() - 1).getH() > 0) {
-                    tag = new OriginTag(0, "", group.getNumber(), format.format(score), config.getI(), config.getX()
-                            * sliceConfig.get(config.getI() - 1).getW(), config.getY()
-                            * sliceConfig.get(config.getI() - 1).getH());
+                    tag = new OriginTag(0, "", group.getNumber(), format.format(score), config.getI(),
+                            config.getX() * sliceConfig.get(config.getI() - 1).getW(),
+                            config.getY() * sliceConfig.get(config.getI() - 1).getH());
                 }
                 originTags.add(tag);
             }
@@ -1094,8 +1109,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             for (MarkTrack markTrack : tracks) {
                 // 未作答时只显示汉字"空"
                 originTags.add(new OriginTag(library.getMarkerId(), Role.MARKER.toString(), library.getGroupNumber(),
-                        markTrack.isUnanswered() ? "空" : format.format(markTrack.getScore()), markTrack
-                                .getOffsetIndex(), markTrack.getOffsetX(), markTrack.getOffsetY()));
+                        markTrack.isUnanswered() ? "空" : format.format(markTrack.getScore()),
+                        markTrack.getOffsetIndex(), markTrack.getOffsetX(), markTrack.getOffsetY()));
             }
             // 添加特殊标记
             List<MarkSpecialTag> specialTags = specialTagService.findByLibraryId(library.getId());
@@ -1109,16 +1124,17 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         List<HeaderTag> headerTags = headerTagDao.findByStudentIdAndGroupNumberOrderByIdAsc(student.getId(),
                 group.getNumber());
         for (HeaderTag headerTag : headerTags) {
-            originTags.add(new OriginTag(headerTag.getUserId(), Role.SUBJECT_HEADER.toString(), headerTag
-                    .getGroupNumber(), headerTag.getTagName(), headerTag.getOffsetIndex(), headerTag.getOffsetX(),
-                    headerTag.getOffsetY()));
+            originTags.add(new OriginTag(headerTag.getUserId(), Role.SUBJECT_HEADER.toString(),
+                    headerTag.getGroupNumber(), headerTag.getTagName(), headerTag.getOffsetIndex(),
+                    headerTag.getOffsetX(), headerTag.getOffsetY()));
         }
         List<HeaderTrack> headerTracks = headerTrackDao.findByPkStudentIdAndGroupNumber(student.getId(),
                 group.getNumber());
         for (HeaderTrack headerTrack : headerTracks) {
-            originTags.add(new OriginTag(headerTrack.getUserId(), Role.SUBJECT_HEADER.toString(), headerTrack
-                    .getGroupNumber(), headerTrack.isUnanswered() ? "空" : format.format(headerTrack.getScore()),
-                    headerTrack.getOffsetIndex(), headerTrack.getOffsetX(), headerTrack.getOffsetY()));
+            originTags.add(
+                    new OriginTag(headerTrack.getUserId(), Role.SUBJECT_HEADER.toString(), headerTrack.getGroupNumber(),
+                            headerTrack.isUnanswered() ? "空" : format.format(headerTrack.getScore()),
+                            headerTrack.getOffsetIndex(), headerTrack.getOffsetX(), headerTrack.getOffsetY()));
         }
         return originTags;
     }
@@ -1165,7 +1181,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     }
 
     @Override
-    public List<ExamStudent> findByExamIdAndStudentCodeAndSubjectCode(int examId, String studentCode, String subjectCode) {
+    public List<ExamStudent> findByExamIdAndStudentCodeAndSubjectCode(int examId, String studentCode,
+            String subjectCode) {
         return studentDao.findByExamIdAndStudentCodeAndSubjectCode(examId, studentCode, subjectCode);
     }
 
@@ -1317,9 +1334,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     public int batchUpdate(List<ExamStudent> updateList) {
         int i = 0;
         for (ExamStudent student : updateList) {
-            i = i
-                    + this.studentDao.updateInfo(student.getId(), student.getCollege(), student.getClassName(),
-                            student.getTeacher(), student.getExamRoom(), student.getExamSite(), student.getRemark());
+            i = i + this.studentDao.updateInfo(student.getId(), student.getCollege(), student.getClassName(),
+                    student.getTeacher(), student.getExamRoom(), student.getExamSite(), student.getRemark());
         }
         return i;
     }
@@ -1376,10 +1392,14 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
     private List<ExamStudent> findByQuerySql(ExamStudentSearchQuery req) {
         int offset = (req.getPageNumber() - 1) * req.getPageSize();
         StringBuilder sql = new StringBuilder();
-        sql.append(" select s.sheet_count sheetCount,s.exam_number examNumber,s.exam_id examId,s.id,s.student_code studentCode,s.name");
-        sql.append(" ,s.subject_code subjectCode,s.subject_name subjectName,s.is_upload upload,s.is_breach breach,s.is_absent absent,s.subjective_score subjectiveScore ");
-        sql.append(" ,s.score_verify_time scoreVerifyTime,s.subjective_score_list subjectiveScoreList,s.objective_score objectiveScore,s.objective_score_list objectiveScoreList  ");
-        sql.append(" ,s.subject_level subjectLevel,s.subject_category subjectCategory,s.college,s.class_name className,s.teacher ");
+        sql.append(
+                " select s.sheet_count sheetCount,s.exam_number examNumber,s.exam_id examId,s.id,s.student_code studentCode,s.name");
+        sql.append(
+                " ,s.subject_code subjectCode,s.subject_name subjectName,s.is_upload upload,s.is_breach breach,s.is_absent absent,s.subjective_score subjectiveScore ");
+        sql.append(
+                " ,s.score_verify_time scoreVerifyTime,s.subjective_score_list subjectiveScoreList,s.objective_score objectiveScore,s.objective_score_list objectiveScoreList  ");
+        sql.append(
+                " ,s.subject_level subjectLevel,s.subject_category subjectCategory,s.college,s.class_name className,s.teacher ");
         sql.append(" ,s.exam_site examSite,s.exam_room examRoom,s.package_code packageCode");
         sql.append(" from eb_exam_student s ");
         sql.append(getWhereSql(req));
@@ -1492,7 +1512,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
             sql.append(" and s.upload_time is not null");
         }
         if (StringUtils.isNotBlank(query.getSubjectCodeIn())) {
-            sql.append(" and s.subject_code in('" + StringUtils.join(query.getSubjectCodeIn().split(","), "','") + "')");
+            sql.append(
+                    " and s.subject_code in('" + StringUtils.join(query.getSubjectCodeIn().split(","), "','") + "')");
         }
         if (StringUtils.isNotBlank(query.getCampusNameIn())) {
             sql.append(" and s.campus_name in('" + StringUtils.join(query.getCampusNameIn().split(","), "','") + "')");
@@ -1509,8 +1530,8 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
                     + "')");
         }
         if (StringUtils.isNotBlank(query.getExamSiteNotIn())) {
-            sql.append(" and s.exam_site not in('" + StringUtils.join(query.getExamSiteNotIn().split(","), "','")
-                    + "')");
+            sql.append(
+                    " and s.exam_site not in('" + StringUtils.join(query.getExamSiteNotIn().split(","), "','") + "')");
         }
         if (StringUtils.isNotBlank(query.getPaperType())) {
             sql.append(" and s.paper_type='" + query.getPaperType() + "'");
@@ -1588,4 +1609,23 @@ public class ExamStudentServiceImpl extends BaseQueryService<ExamStudent> implem
         Long count = studentDao.sumSheetCountByExamIdAndExamSite(examId, examSite);
         return count == null ? 0 : count;
     }
+
+    @Override
+    public List<String> findDistinctCollegeBySubjectCode(int examId, String subjectCode) {
+        return studentDao.findDistinctCollegeBySubjectCode(examId, subjectCode);
+    }
+
+    @Override
+    public long countSheetCountByQuery(ExamStudentSearchQuery studentSearchQuery) {
+        checkQuery(studentSearchQuery);
+        if (studentSearchQuery.getSheetCount() != null) {
+            studentSearchQuery.setSheetCount(studentSearchQuery.getSheetCount() * 2);
+        }
+        StringBuilder sql = new StringBuilder();
+        sql.append("select sum(s.sheet_count) ");
+        sql.append("from eb_exam_student s ");
+        sql.append(getWhereSql(studentSearchQuery));
+        Query query = entityManager.createNativeQuery(sql.toString());
+        return Integer.valueOf(query.getResultList().get(0).toString()) / 2;
+    }
 }

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

@@ -1,7 +1,8 @@
 package cn.com.qmth.stmms.common.enums;
 
 public enum ConfigType {
-    FILE_SERVER("图片服务", 1), MARK_TIME("评卷时长", 2), AUTO_REPORT("自动统计", 3);
+
+    FILE_SERVER("图片服务", 1), MARK_TIME("评卷时长", 2), AUTO_REPORT("自动统计", 3), STUDENT_SHEET_COUNT("计算扫描提卡张数", 4);
 
     private String name;
 

+ 2 - 2
stmms-common/src/main/java/cn/com/qmth/stmms/common/utils/VersionInfo.java

@@ -5,7 +5,7 @@ package cn.com.qmth.stmms.common.utils;
  */
 public class VersionInfo {
 
-    public static final String NAME = "1.3.15";
+    public static final String NAME = "1.5.0";
 
-    public static final String DATE = "20231228";
+    public static final String DATE = "20240501";
 }

+ 10 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/MarkerInfoDTO.java

@@ -34,6 +34,9 @@ public class MarkerInfoDTO {
     @ExcelField(title = "评卷数量", align = 2, sort = 90)
     private long markedCount;
 
+    @ExcelField(title = "学院", align = 2, sort = 100)
+    private String college;
+
     public MarkerInfoDTO(Marker marker, ExamSubject subject, MarkGroup group) {
         setSubjectCode(subject.getCode());
         setSubjectName(subject.getName());
@@ -117,4 +120,11 @@ public class MarkerInfoDTO {
         this.empno = empno;
     }
 
+    public String getCollege() {
+        return college;
+    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
 }

+ 15 - 19
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectQuestionDTO.java

@@ -1,20 +1,15 @@
 package cn.com.qmth.stmms.admin.dto;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.mark.model.MarkConfigItem;
+import cn.com.qmth.stmms.biz.utils.DoubleUtil;
 import cn.com.qmth.stmms.common.enums.QuestionType;
 import cn.com.qmth.stmms.common.utils.BigDecimalUtils;
 
@@ -68,16 +63,17 @@ public class SubjectQuestionDTO {
             } else {
                 MarkGroup group = groups.get(question.getGroupNumber());
                 if (group == null) {
-                    group = new MarkGroup(examId, subjectCode, question.getGroupNumber(), MarkConfigItem.parse(question
-                            .getPicList()), 0d, question.getDoubleRate(), question.getArbitrateThreshold(),
-                            question.getScorePolicy(), question.getMarkMode(), question.getTrialCount(), false, false,
-                            1, false);
+                    group = new MarkGroup(examId, subjectCode, question.getGroupNumber(),
+                            MarkConfigItem.parse(question.getPicList()), 0d, question.getDoubleRate(),
+                            question.getArbitrateThreshold(), question.getScorePolicy(), question.getMarkMode(),
+                            question.getTrialCount(), false, false, 1, false);
                     group.setImportQuestionList(new LinkedList<>());
                     groups.put(question.getGroupNumber(), group);
                 }
                 group.getImportQuestionList().add(question);
-                this.trialCount = question.getTrialCount() != null && question.getTrialCount() > 0 ? question
-                        .getTrialCount() : 0;
+                this.trialCount = question.getTrialCount() != null && question.getTrialCount() > 0
+                        ? question.getTrialCount()
+                        : 0;
                 // group.setTotalScore(group.getTotalScore() +
                 // question.getTotalScore());
                 // totalScore += question.getTotalScore();
@@ -136,13 +132,13 @@ public class SubjectQuestionDTO {
                         error.add("[" + subjectCode + "] 有满分为空的记录");
                         return false;
                     }
-                    int score = (int) (question.getTotalScore() * 100);
-                    if ((question.getTotalScore() * 100) - score > 0) {
+                    int score = (int) DoubleUtil.mul(question.getTotalScore(), 100);
+                    if (DoubleUtil.mul(question.getTotalScore(), 100) - score > 0) {
                         error.add("[" + subjectCode + "] 有满分为小数超2位的记录");
                         return false;
                     }
-                    if (!objective
-                            && (question.getIntervalScore() * 100) - (int) (question.getIntervalScore() * 100) > 0) {
+                    if (!objective && DoubleUtil.mul(question.getIntervalScore(), 100)
+                            - (int) DoubleUtil.mul(question.getIntervalScore(), 100) > 0) {
                         error.add("[" + subjectCode + "] 有间隔分为小数超2位的记录");
                         return false;
                     }
@@ -250,8 +246,8 @@ public class SubjectQuestionDTO {
                 if (subCount != null) {
                     subCountMap.put(question.getMainNumber(), subCount + 1);
                     Double mainScore = mainScoreMap.get(question.getMainNumber());
-                    mainScoreMap
-                            .put(question.getMainNumber(), BigDecimalUtils.add(mainScore, question.getTotalScore()));
+                    mainScoreMap.put(question.getMainNumber(),
+                            BigDecimalUtils.add(mainScore, question.getTotalScore()));
                 } else {
                     subCountMap.put(question.getMainNumber(), 1);
                     mainScoreMap.put(question.getMainNumber(), question.getTotalScore());

+ 10 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectUserDTO.java

@@ -10,6 +10,9 @@ public class SubjectUserDTO {
     @ExcelField(title = "课程名称", align = 2, sort = 20)
     private String subjectName;
 
+    @ExcelField(title = "学院", align = 2, sort = 30)
+    private String college;
+
     @ExcelField(title = "角色", align = 2, sort = 50)
     private String role;
 
@@ -62,4 +65,11 @@ public class SubjectUserDTO {
         this.randomPassword = randomPassword;
     }
 
+    public String getCollege() {
+        return college;
+    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
 }

+ 27 - 21
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkController.java

@@ -1,9 +1,7 @@
 package cn.com.qmth.stmms.admin.exam;
 
 import java.text.DecimalFormat;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -25,10 +23,7 @@ import cn.com.qmth.stmms.admin.vo.SubjectLibraryVO;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
-import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.exam.service.*;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
 import cn.com.qmth.stmms.biz.lock.LockService;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
@@ -37,11 +32,7 @@ import cn.com.qmth.stmms.biz.user.service.UserService;
 import cn.com.qmth.stmms.common.annotation.Logging;
 import cn.com.qmth.stmms.common.annotation.RoleRequire;
 import cn.com.qmth.stmms.common.domain.WebUser;
-import cn.com.qmth.stmms.common.enums.LibraryStatus;
-import cn.com.qmth.stmms.common.enums.LockType;
-import cn.com.qmth.stmms.common.enums.LogType;
-import cn.com.qmth.stmms.common.enums.MarkStatus;
-import cn.com.qmth.stmms.common.enums.Role;
+import cn.com.qmth.stmms.common.enums.*;
 import cn.com.qmth.stmms.common.utils.ExportExcel;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
 
@@ -51,6 +42,8 @@ public class MarkController extends BaseExamController {
 
     protected static Logger log = LoggerFactory.getLogger(MarkController.class);
 
+    public static final String SPLIT = ",";
+
     @Autowired
     private ExamSubjectService subjectService;
 
@@ -72,6 +65,9 @@ public class MarkController extends BaseExamController {
     @Autowired
     private LockService lockService;
 
+    @Autowired
+    private ExamStudentService studentService;
+
     /**
      * 评卷进度
      *
@@ -118,8 +114,9 @@ public class MarkController extends BaseExamController {
             mQuery.addStatus(LibraryStatus.ARBITRATED);
             mQuery.addStatus(LibraryStatus.INSPECTED);
             long totalMarkedCount = libraryService.countByQuery(mQuery);
-            String percent = libraryCount > 0 ? (new DecimalFormat("####.###").format(totalMarkedCount * 100.0
-                    / libraryCount) + "%") : "0%";
+            String percent = libraryCount > 0
+                    ? (new DecimalFormat("####.###").format(totalMarkedCount * 100.0 / libraryCount) + "%")
+                    : "0%";
             vo.setPercent(percent);
             long count = questionService.countByExamIdAndSubjectAndObjectiveAndGroupNumberIsNull(examId,
                     subject.getCode(), false);
@@ -169,8 +166,9 @@ public class MarkController extends BaseExamController {
             mQuery.addStatus(LibraryStatus.ARBITRATED);
             mQuery.addStatus(LibraryStatus.INSPECTED);
             long totalMarkedCount = libraryService.countByQuery(mQuery);
-            String percent = libraryCount > 0 ? (new DecimalFormat("####.###").format(totalMarkedCount * 100.0
-                    / libraryCount) + "%") : "0%";
+            String percent = libraryCount > 0
+                    ? (new DecimalFormat("####.###").format(totalMarkedCount * 100.0 / libraryCount) + "%")
+                    : "0%";
             dto.setPercent(percent);
             dto.setGroupCount(groupService.countByExamAndSubject(examId, subject.getCode()));
             result.add(dto);
@@ -197,15 +195,24 @@ public class MarkController extends BaseExamController {
         if (wu.isSubjectHeader()) {
             list = markerService.getMarkCount(examId, wu.getSubjectCodeSet());
         }
+        Map<String, ExamSubject> subjectMap = new HashMap<String, ExamSubject>();
+        Map<String, String> collegeMap = new HashMap<String, String>();
         for (Marker marker : list) {
+            ExamSubject subject = subjectMap.get(marker.getSubjectCode());
+            if (subject == null) {
+                subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
+                subjectMap.put(marker.getSubjectCode(), subject);
+                collegeMap.put(marker.getSubjectCode(), StringUtils
+                        .join(studentService.findDistinctCollegeBySubjectCode(examId, marker.getSubjectCode()), SPLIT));
+            }
             MarkGroup group = groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber());
             group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
                     group.getSubjectCode(), false, group.getNumber()));
             marker.setUser(userService.findById(marker.getUserId()));
-            MarkerInfoDTO dto = new MarkerInfoDTO(marker, subjectService.find(marker.getExamId(),
-                    marker.getSubjectCode()), group);
+            MarkerInfoDTO dto = new MarkerInfoDTO(marker, subject, group);
             dto.setTotalScore(questionService.sumTotalScoreByGroupNumber(examId, marker.getSubjectCode(), false,
                     marker.getGroupNumber()));
+            dto.setCollege(collegeMap.get(marker.getSubjectCode()));
             result.add(dto);
         }
 
@@ -245,8 +252,8 @@ public class MarkController extends BaseExamController {
                 try {
                     lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
                     if (group.getStatus() == MarkStatus.FORMAL && group.getLeftCount() == 0) {
-                        groupService
-                                .updateStatus(examId, code, group.getNumber(), MarkStatus.FINISH, group.getStatus());
+                        groupService.updateStatus(examId, code, group.getNumber(), MarkStatus.FINISH,
+                                group.getStatus());
                     }
                 } finally {
                     lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
@@ -255,6 +262,5 @@ public class MarkController extends BaseExamController {
         }
         return "redirect:/admin/exam/mark";
     }
-    
 
 }

+ 17 - 27
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ScoreController.java

@@ -2,17 +2,11 @@ package cn.com.qmth.stmms.admin.exam;
 
 import java.io.ByteArrayInputStream;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import net.sf.json.JSONObject;
-
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,20 +17,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import com.qmth.boot.tools.io.ZipWriter;
+
 import cn.com.qmth.stmms.admin.dto.ExamStudentDTO;
 import cn.com.qmth.stmms.admin.dto.ScoreEditDTO;
 import cn.com.qmth.stmms.admin.utils.ExportStudentExcel;
-import cn.com.qmth.stmms.biz.exam.model.Exam;
-import cn.com.qmth.stmms.biz.exam.model.ExamPackage;
-import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
-import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
-import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.*;
 import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
-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;
-import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
+import cn.com.qmth.stmms.biz.exam.service.*;
 import cn.com.qmth.stmms.biz.file.service.FileService;
 import cn.com.qmth.stmms.biz.utils.ScoreItem;
 import cn.com.qmth.stmms.common.annotation.Logging;
@@ -47,8 +35,7 @@ import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.utils.Encodes;
 import cn.com.qmth.stmms.common.utils.ExportExcel;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
-
-import com.qmth.boot.tools.io.ZipWriter;
+import net.sf.json.JSONObject;
 
 @Controller
 @RequestMapping("/admin/exam/score")
@@ -104,8 +91,9 @@ public class ScoreController extends BaseExamController {
         String logMessage = getLogMessage(query, filter);
         RequestUtils.setLog(request, logMessage);
         Exam exam = examService.findById(examId);
-        String exportMessage = StringUtils.isNotBlank(query.getSubjectCode()) ? subjectService.enableExport(exam,
-                query.getSubjectCode()) : null;
+        String exportMessage = StringUtils.isNotBlank(query.getSubjectCode())
+                ? subjectService.enableExport(exam, query.getSubjectCode())
+                : null;
         if (exportMessage != null) {
             view.addObject("exportMessage", exportMessage);
             view.addObject("enableExport", false);
@@ -117,6 +105,8 @@ public class ScoreController extends BaseExamController {
         view.addObject("query", query);
         view.addObject("filter", filter);
         view.addObject("fileServer", fileService.getFileServer());
+        view.addObject("classList", studentService.findDistinctClassName(examId));
+        view.addObject("collegeList", studentService.findDistinctCollege(examId));
         return view;
     }
 
@@ -285,8 +275,8 @@ public class ScoreController extends BaseExamController {
                         student.setSubjectiveScore(0d);
                     }
                     if (student.getSubjectiveScoreList() != null) {
-                        student.setSubjectiveScoreList(student.getSubjectiveScoreList()
-                                .replace(UN_SELECTIVE_SCORE, "/"));
+                        student.setSubjectiveScoreList(
+                                student.getSubjectiveScoreList().replace(UN_SELECTIVE_SCORE, "/"));
                     }
                     list.add(new ExamStudentDTO(student));
                 }
@@ -394,8 +384,8 @@ public class ScoreController extends BaseExamController {
         // student.setSheetUrls(PictureUrlBuilder
         // .getInnerSheetUrls(student.getExamId(), student.getExamNumber(),
         // student.getSheetCount()));
-        student.setSheetUrls(fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1,
-                student.getSheetCount()));
+        student.setSheetUrls(
+                fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1, student.getSheetCount()));
     }
 
     private void buildPackageUrl(ExamStudent student) {
@@ -410,8 +400,8 @@ public class ScoreController extends BaseExamController {
     private void buildAnswerUrl(ExamStudent student) {
         ExamSubject subject = subjectService.find(student.getExamId(), student.getSubjectCode());
         if (subject != null && subject.getAnswerFileType() != null) {
-            student.setAnswerUrl(fileService.getAnswerUri(subject.getExamId(), subject.getCode(),
-                    subject.getAnswerFileType()));
+            student.setAnswerUrl(
+                    fileService.getAnswerUri(subject.getExamId(), subject.getCode(), subject.getAnswerFileType()));
         }
         if (subject != null) {
             student.setSubjectRemark(StringUtils.trimToEmpty(subject.getRemark()));

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

@@ -8,8 +8,6 @@ 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;
@@ -24,19 +22,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import com.google.common.collect.Lists;
+
 import cn.com.qmth.stmms.admin.vo.ExamStudentVO;
 import cn.com.qmth.stmms.admin.vo.UploadStudentVO;
-import cn.com.qmth.stmms.biz.exam.model.Exam;
-import cn.com.qmth.stmms.biz.exam.model.ExamPackage;
-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.config.service.impl.SystemCache;
+import cn.com.qmth.stmms.biz.exam.model.*;
 import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
-import cn.com.qmth.stmms.biz.exam.service.ExamPackageService;
-import cn.com.qmth.stmms.biz.exam.service.ExamService;
-import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.*;
 import cn.com.qmth.stmms.biz.file.service.FileService;
 import cn.com.qmth.stmms.biz.mark.service.MarkService;
 import cn.com.qmth.stmms.common.annotation.Logging;
@@ -49,8 +42,7 @@ import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
 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.google.common.collect.Lists;
+import net.sf.json.JSONObject;
 
 @Controller("examStudentController")
 @RequestMapping("/admin/exam/student")
@@ -79,6 +71,9 @@ public class StudentController extends BaseExamController {
     @Autowired
     private MarkGroupService groupService;
 
+    @Autowired
+    private SystemCache authCache;
+
     private static final String NULL_PAPER_TYPE_PLACEHOLDER = "#";
 
     private static final String PAPER_TYPES_REGEX = "[a-zA-Z#]";
@@ -109,6 +104,11 @@ public class StudentController extends BaseExamController {
         model.addAttribute("fileServer", fileService.getFileServer());
         Exam exam = examService.findById(examId);
         model.addAttribute("examType", exam.getType());
+        model.addAttribute("classList", studentService.findDistinctClassName(examId));
+        model.addAttribute("collegeList", studentService.findDistinctCollege(examId));
+        if (authCache.isEnableStudentSheetCount()) {
+            model.addAttribute("studentSheetCount", studentService.countSheetCountByQuery(query));
+        }
         return "modules/exam/studentList";
     }
 
@@ -226,11 +226,8 @@ 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, "删除考生成功");
             RequestUtils.setLog(request, "删除成功,id:" + id);
         } else {
@@ -381,7 +378,8 @@ public class StudentController extends BaseExamController {
 
     @Logging(menu = "导入缺考名单", type = LogType.IMPORT_FILE)
     @RequestMapping(value = "/absentImport", method = RequestMethod.POST)
-    public String absentImportFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+    public String absentImportFile(HttpServletRequest request, MultipartFile file,
+            RedirectAttributes redirectAttributes) {
         int examId = getSessionExamId(request);
         try {
             int successNum = 0;
@@ -433,7 +431,8 @@ public class StudentController extends BaseExamController {
 
     @Logging(menu = "导入违纪名单", type = LogType.IMPORT_FILE)
     @RequestMapping(value = "/breachImport", method = RequestMethod.POST)
-    public String breachImportFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+    public String breachImportFile(HttpServletRequest request, MultipartFile file,
+            RedirectAttributes redirectAttributes) {
         int examId = getSessionExamId(request);
         // Exam exam = examService.findById(examId);
         try {
@@ -506,7 +505,8 @@ public class StudentController extends BaseExamController {
     }
 
     @RequestMapping(value = "/uploadImport", method = RequestMethod.POST)
-    public String uploadImportFile(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
+    public String uploadImportFile(HttpServletRequest request, MultipartFile file,
+            RedirectAttributes redirectAttributes) {
         int examId = getSessionExamId(request);
         // Exam exam = examService.findById(examId);
         try {
@@ -586,8 +586,8 @@ public class StudentController extends BaseExamController {
     }
 
     private void buildSheetUrl(ExamStudent student) {
-        student.setSheetUrls(fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1,
-                student.getSheetCount()));
+        student.setSheetUrls(
+                fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1, student.getSheetCount()));
     }
 
     private void buildPackageUrl(ExamStudent student) {

+ 9 - 18
stmms-web/src/main/java/cn/com/qmth/stmms/admin/user/UserController.java

@@ -1,12 +1,6 @@
 package cn.com.qmth.stmms.admin.user;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -35,15 +29,7 @@ import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.model.Marker;
 import cn.com.qmth.stmms.biz.exam.model.SubjectUser;
 import cn.com.qmth.stmms.biz.exam.query.MarkerSearchQuery;
-import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
-import cn.com.qmth.stmms.biz.exam.service.ExamService;
-import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
-import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
-import cn.com.qmth.stmms.biz.exam.service.MarkerService;
-import cn.com.qmth.stmms.biz.exam.service.SubjectUserService;
-import cn.com.qmth.stmms.biz.exam.service.UserExamService;
-import cn.com.qmth.stmms.biz.exam.service.UserStudentService;
+import cn.com.qmth.stmms.biz.exam.service.*;
 import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.biz.user.service.UserService;
 import cn.com.qmth.stmms.biz.user.service.query.UserSearchQuery;
@@ -444,6 +430,7 @@ public class UserController extends BaseExamController {
                     && (query.getRole().equals(Role.SUBJECT_HEADER) || query.getRole().equals(Role.INSPECTOR))) {
                 List<SubjectUserDTO> list = new ArrayList<SubjectUserDTO>();
                 Map<String, ExamSubject> subjectMap = new HashMap<String, ExamSubject>();
+                Map<String, String> collegeMap = new HashMap<String, String>();
                 query = userService.findByQuery(query);
                 for (User u : query.getResult()) {
                     List<SubjectUser> subjectUsers = subjectUserService.findByUserId(u.getId());
@@ -456,11 +443,15 @@ public class UserController extends BaseExamController {
                             ExamSubject subject = subjectMap.get(subjectUser.getSubjectCode());
                             if (subject == null) {
                                 subject = subjectService.find(examId, subjectUser.getSubjectCode());
+                                List<String> colleges = studentService.findDistinctCollegeBySubjectCode(examId,
+                                        subjectUser.getSubjectCode());
                                 subjectMap.put(subjectUser.getSubjectCode(), subject);
+                                collegeMap.put(subjectUser.getSubjectCode(), StringUtils.join(colleges, SPLIT));
                             }
                             if (subject != null) {
                                 s.setSubjectCode(subjectUser.getSubjectCode());
                                 s.setSubjectName(subject.getName());
+                                s.setCollege(collegeMap.get(subjectUser.getSubjectCode()));
                                 list.add(s);
                             }
                         }
@@ -530,8 +521,8 @@ public class UserController extends BaseExamController {
             @RequestParam String subjectCodeString, @RequestParam(required = false) Boolean random) {
         int examId = getSessionExamId(request);
         if (Role.MARKER.equals(role)) {
-            int successNum = userService.batchSaveMarker(examId, getSubjectCodeSet(subjectCodeString), number,
-                    password, random == null ? false : random);
+            int successNum = userService.batchSaveMarker(examId, getSubjectCodeSet(subjectCodeString), number, password,
+                    random == null ? false : random);
             String message = "已成功新增 " + successNum + " 条用户";
             addMessage(redirectAttributes, message);
         } else {

+ 63 - 47
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/scoreList.jsp

@@ -25,7 +25,8 @@
         <select class="input-large" name="subjectCode" id="subject-select">
             <option value="">请选择</option>
             <c:forEach items="${subjectList}" var="subject">
-                <option value="${subject.code}" <c:if test="${subject.code==query.subjectCode}">selected</c:if>>${subject.code}-${subject.name}</option>
+                <option value="${subject.code}"
+                        <c:if test="${subject.code==query.subjectCode}">selected</c:if>>${subject.code}-${subject.name}</option>
             </c:forEach>
         </select>
         <label>筛选</label>
@@ -55,14 +56,25 @@
         <br/><br/>
         <!--     总分 > startScore and 总分 <=endScore             -->
         <label>总分:从</label>
-        <input type="text" number="true" id="startScore" name="startScore" value="${query.startScore}" class="input-mini"/>
+        <input type="text" number="true" id="startScore" name="startScore" value="${query.startScore}"
+               class="input-mini"/>
         <label> 到&nbsp;&nbsp;&nbsp;</label>
         <input type="text" number="true" id="endScore" name="endScore" value="${query.endScore}" class="input-mini"/>
-        
+
         <label>学院</label>
-        <input type="text" name="college" value="${query.college}" maxlength="64" class="input-mini"/>
+        <select class="input-small studentQuery" id="college" name="college">
+            <option value="">请选择</option>
+            <c:forEach items="${collegeList }" var="c">
+                <option value="${c}" <c:if test="${query.college eq c }">selected</c:if>>${c}</option>
+            </c:forEach>
+        </select>
         <label>班级</label>
-        <input type="text" name="className" value="${query.className}" maxlength="64" class="input-mini"/>
+        <select class="input-small" id="className" name="className">
+            <option value="">请选择</option>
+            <c:forEach items="${classList }" var="c">
+                <option value="${c}" <c:if test="${query.className eq c }">selected</c:if>>${c}</option>
+            </c:forEach>
+        </select>
         <label>任课老师</label>
         <input type="text" name="teacher" value="${query.teacher}" maxlength="64" class="input-mini"/>
         <label>考点</label>
@@ -79,21 +91,21 @@
     </div>
 </form>
 <form id="exportForm" action="${ctx}/admin/exam/score/export" method="post" class="breadcrumb form-search hide">
-		<input type="text" name="name" value="${query.name}" maxlength="10" class="input-mini"/>
-        <input type="text" name="examNumber" value="${query.examNumber}" maxlength="50" class="input-small"/>
-        <input type="text" name="studentCode" value="${query.studentCode}" maxlength="30" class="input-small"/>
-        <input type="text" name="subjectCode" value="${query.subjectCode}"  class="input-small"/>
-   		<input type="text" name="upload" value="${query.upload}" class="input-small"/>
-		<input type="text" name="absent" value="${query.absent}" class="input-small"/>
-		<input type="text" name="breach" value="${query.breach}" class="input-small"/>
-		<input type="text" name="filter" value="${filter}" class="input-small"/>
-		<input type="text" name="startScore" value="${query.startScore}" class="input-small"/>
-		<input type="text" name="endScore" value="${query.endScore}" class="input-small"/>
-		<input type="text" name="college" value="${query.college}" class="input-small"/>
-		<input type="text" name="className" value="${query.className}" class="input-small"/>
-		<input type="text" name="teacher" value="${query.teacher}" class="input-small"/>
-        <input type="text" name="examSite" value="${query.examSite}" maxlength="64" class="input-mini"/>
-        <input type="text" name="examRoom" value="${query.examRoom}" maxlength="64" class="input-mini"/>
+    <input type="text" name="name" value="${query.name}" maxlength="10" class="input-mini"/>
+    <input type="text" name="examNumber" value="${query.examNumber}" maxlength="50" class="input-small"/>
+    <input type="text" name="studentCode" value="${query.studentCode}" maxlength="30" class="input-small"/>
+    <input type="text" name="subjectCode" value="${query.subjectCode}" class="input-small"/>
+    <input type="text" name="upload" value="${query.upload}" class="input-small"/>
+    <input type="text" name="absent" value="${query.absent}" class="input-small"/>
+    <input type="text" name="breach" value="${query.breach}" class="input-small"/>
+    <input type="text" name="filter" value="${filter}" class="input-small"/>
+    <input type="text" name="startScore" value="${query.startScore}" class="input-small"/>
+    <input type="text" name="endScore" value="${query.endScore}" class="input-small"/>
+    <input type="text" name="college" value="${query.college}" class="input-small"/>
+    <input type="text" name="className" value="${query.className}" class="input-small"/>
+    <input type="text" name="teacher" value="${query.teacher}" class="input-small"/>
+    <input type="text" name="examSite" value="${query.examSite}" maxlength="64" class="input-mini"/>
+    <input type="text" name="examRoom" value="${query.examRoom}" maxlength="64" class="input-mini"/>
 </form>
 <tags:message content="${message}"/>
 <table id="contentTable" class="table table-striped table-bordered table-condensed">
@@ -123,29 +135,29 @@
     <c:forEach items="${query.result}" var="student">
         <tr>
             <td>
-                <%--    <a href="##" class="detail-link" data-exam-number="${student.examNumber}">${student.examNumber}</a>  --%>
-	            <c:if test="${(web_user.subjectHeader==true||web_user.schoolViewer==true) && forbiddenInfo==true}">
-	            ***
-	            </c:if>
-	            <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
-	            ${student.examNumber}
-	            </c:if>
+                    <%--    <a href="##" class="detail-link" data-exam-number="${student.examNumber}">${student.examNumber}</a>  --%>
+                <c:if test="${(web_user.subjectHeader==true||web_user.schoolViewer==true) && forbiddenInfo==true}">
+                    ***
+                </c:if>
+                <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
+                    ${student.examNumber}
+                </c:if>
             </td>
             <td>
-	            <c:if test="${(web_user.subjectHeader==true||web_user.schoolViewer==true) && forbiddenInfo==true}">
-	            ***
-	            </c:if>
-	            <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
-	            ${student.name}
-	            </c:if>
+                <c:if test="${(web_user.subjectHeader==true||web_user.schoolViewer==true) && forbiddenInfo==true}">
+                    ***
+                </c:if>
+                <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
+                    ${student.name}
+                </c:if>
             </td>
             <td>
-            	<c:if test="${(web_user.subjectHeader==true||web_user.schoolViewer==true) && forbiddenInfo==true}">
-	            ***
-	            </c:if>
-	            <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
-	            ${student.studentCode}
-	            </c:if>
+                <c:if test="${(web_user.subjectHeader==true||web_user.schoolViewer==true) && forbiddenInfo==true}">
+                    ***
+                </c:if>
+                <c:if test="${web_user.schoolAdmin==true || forbiddenInfo==false}">
+                    ${student.studentCode}
+                </c:if>
             </td>
             <td>${student.subjectCode}-${student.subjectName}&nbsp;${student.subjectRemark}</td>
             <td>${student.subjectLevel}</td>
@@ -218,20 +230,24 @@
             <td>
                 <c:if test="${student.upload==true}">
                     <c:if test="${examType!='MULTI_MEDIA'}">
-                    	<c:if test='${web_user.schoolAdmin==true}'>
-                        <a class="sheet-link" href="##" data-id="${student.id}" data-sheet-url="${student.sheetUrlString}"
-                           data-answer-url="<c:if test="${student.answerUrl!=null}">${fileServer}${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>
+                        <c:if test='${web_user.schoolAdmin==true}'>
+                            <a class="sheet-link" href="##" data-id="${student.id}"
+                               data-sheet-url="${student.sheetUrlString}"
+                               data-answer-url="<c:if test="${student.answerUrl!=null}">${fileServer}${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>
                         </c:if>
-                        <a href="${ctx}/web/admin/exam/track/student?studentId=${student.id}&subjectCode=${student.subjectCode}" target="_blank">轨迹图</a>
+                        <a href="${ctx}/web/admin/exam/track/student?studentId=${student.id}&subjectCode=${student.subjectCode}"
+                           target="_blank">轨迹图</a>
                     </c:if>
                     <c:if test="${examType=='MULTI_MEDIA'}">
-                       <%--  <a class="json-link" href="${ctx}/admin/exam/library/getJson?studentId=${student.id}" target="_blank">原图</a> --%>
-                        <a href="${ctx}/web/admin/exam/track/student?studentId=${student.id}&subjectCode=${student.subjectCode}" target="_blank">原卷</a>
+                        <%--  <a class="json-link" href="${ctx}/admin/exam/library/getJson?studentId=${student.id}" target="_blank">原图</a> --%>
+                        <a href="${ctx}/web/admin/exam/track/student?studentId=${student.id}&subjectCode=${student.subjectCode}"
+                           target="_blank">原卷</a>
                     </c:if>
                 </c:if>
                 <c:if test="${student.packageUrlString!=null && student.packageUrlString!=''}">
-                    <a class="package-link" href="##" data-image-url="${student.packageUrlString}" data-title="${student.packageCode}">签到表</a>
+                    <a class="package-link" href="##" data-image-url="${student.packageUrlString}"
+                       data-title="${student.packageCode}">签到表</a>
                 </c:if>
             </td>
         </tr>

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

@@ -13,31 +13,38 @@
 <body>
 <div id="importBox" class="hide">
     <form id="importForm" action="${ctx}/admin/exam/student/import" method="post" enctype="multipart/form-data"
-          style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+          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/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/>
+    <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/>
+    <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>
 <div id="uploadImportBox" class="hide">
-    <form id="uploadImportForm" action="${ctx}/admin/exam/student/uploadImport" method="post" enctype="multipart/form-data"
-          style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');"><br/>
+    <form id="uploadImportForm" action="${ctx}/admin/exam/student/uploadImport" method="post"
+          enctype="multipart/form-data"
+          style="padding-left:20px;text-align:center;" class="form-search" onsubmit="loading('正在导入,请稍等...');">
+        <br/>
         <input id="studentUploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
         <input id="uploadBtnImportSubmit" class="btn btn-primary" type="submit" value="多媒体考生上传导入"/>
         <a href="${ctx}/admin/exam/student/uploadTemplate">下载模板</a>
@@ -50,16 +57,20 @@
         <label>姓名</label>
         <input type="text" name="name" value="${query.name}" maxlength="10" class="input-mini studentQuery"/>
         <label>准考证号</label>
-        <input type="text" name="examNumber" value="${query.examNumber}" maxlength="50" class="input-small studentQuery"/>
+        <input type="text" name="examNumber" value="${query.examNumber}" maxlength="50"
+               class="input-small studentQuery"/>
         <label>密号</label>
-        <input type="text" name="secretNumber" value="${query.secretNumber}" maxlength="50" class="input-small studentQuery"/>
+        <input type="text" name="secretNumber" value="${query.secretNumber}" maxlength="50"
+               class="input-small studentQuery"/>
         <label>学号</label>
-        <input type="text" name="studentCode" value="${query.studentCode}" maxlength="30" class="input-small studentQuery"/>
+        <input type="text" name="studentCode" value="${query.studentCode}" maxlength="30"
+               class="input-small studentQuery"/>
         <label>科目</label>
         <select class="input-large studentQuery" id="subjectCode" name="subjectCode">
             <option value="">请选择</option>
             <c:forEach items="${subjectList }" var="subject">
-                <option value="${subject.code }" <c:if test="${query.subjectCode eq subject.code }">selected</c:if>>${subject.code}-${subject.name}</option>
+                <option value="${subject.code }"
+                        <c:if test="${query.subjectCode eq subject.code }">selected</c:if>>${subject.code}-${subject.name}</option>
             </c:forEach>
         </select>
         <br><br>
@@ -74,10 +85,11 @@
         <select class="input-small studentQuery" id="subjectCategory" name="subjectCategory">
             <option value="">请选择</option>
             <c:forEach items="${categoryList }" var="category">
-                <option value="${category}" <c:if test="${query.subjectCategory eq category }">selected</c:if>>${category}</option>
+                <option value="${category}"
+                        <c:if test="${query.subjectCategory eq category }">selected</c:if>>${category}</option>
             </c:forEach>
         </select>
-        
+
         <label>状态</label>
         <select id="upload" name="upload" class="input-small studentQuery">
             <option value="">不限</option>
@@ -96,18 +108,33 @@
         </select>
         <select id="manualAbsent" name="manualAbsent" class="input-small studentQuery">
             <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>
+            <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-mini studentQuery"/>
+        <input type="text" name="packageCode" value="${query.packageCode}" maxlength="30"
+               class="input-mini studentQuery"/>
         <label>批次编号</label>
         <input type="text" name="batchCode" value="${query.batchCode}" maxlength="30" class="input-mini studentQuery"/>
         <label>学院</label>
-        <input type="text" name="college" value="${query.college}" maxlength="64" class="input-mini studentQuery"/>
+        <select class="input-small studentQuery" id="college" name="college">
+            <option value="">请选择</option>
+            <c:forEach items="${collegeList }" var="c">
+                <option value="${c}" <c:if test="${query.college eq c }">selected</c:if>>${c}</option>
+            </c:forEach>
+        </select>
         <label>班级</label>
-        <input type="text" name="className" value="${query.className}" maxlength="64" class="input-mini studentQuery"/>
+        <select class="input-small studentQuery" id="className" name="className">
+            <option value="">请选择</option>
+            <c:forEach items="${classList }" var="c">
+                <option value="${c}" <c:if test="${query.className eq c }">selected</c:if>>${c}</option>
+            </c:forEach>
+        </select>
         <label>任课老师</label>
         <input type="text" name="teacher" value="${query.teacher}" maxlength="64" class="input-mini studentQuery"/>
         <label>考点</label>
@@ -115,7 +142,8 @@
         <label>考场</label>
         <input type="text" name="examRoom" value="${query.examRoom}" maxlength="64" class="input-mini studentQuery"/>
         <label>扫描张数</label>
-        <input type="number" name="sheetCount" value="${query.sheetCount}" maxlength="64" class="input-mini digits studentQuery"/>
+        <input type="number" name="sheetCount" value="${query.sheetCount}" maxlength="64"
+               class="input-mini digits studentQuery"/>
         <br><br>
         &nbsp;<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
         <c:if test="${web_user.schoolAdmin==true}">
@@ -134,31 +162,34 @@
                 </div>
             </c:if>
         </c:if>
-       <%--  <c:if test="${query.totalCount>0 && query.totalCount<=10000}"> --%>
-            &nbsp;<input id="export-button" class="btn" type="button" value="导出"/>
-      <%--   </c:if> --%>
+        <%--  <c:if test="${query.totalCount>0 && query.totalCount<=10000}"> --%>
+        &nbsp;<input id="export-button" class="btn" type="button" value="导出"/>
+        <%--   </c:if> --%>
+        <c:if test="${studentSheetCount!=null}">
+            &nbsp;<input class="btn left" type="button" value="扫描张数:${studentSheetCount}"/>
+        </c:if>
     </div>
 </form>
 <form id="exportForm" action="${ctx}/admin/exam/student/export" method="post" class="breadcrumb form-search hide">
-		<input type="text" name="name" value="${query.name}" maxlength="10" class="input-mini"/>
-        <input type="text" name="examNumber" value="${query.examNumber}" maxlength="50" class="input-small"/>
-        <input type="text" name="secretNumber" value="${query.secretNumber}" maxlength="50" class="input-small"/>
-        <input type="text" name="studentCode" value="${query.studentCode}" maxlength="30" class="input-small"/>
-        <input type="text" name="subjectCode" value="${query.subjectCode}"  class="input-small"/>
-        <input type="text" name="subjectLevel" value="${query.subjectLevel}"  class="input-small"/>
-		<input type="text" name="subjectCategory" value="${query.subjectCategory}" maxlength="20" class="input-small"/>
-   		<input type="text" name="upload" value="${query.upload}" class="input-small"/>
-		<input type="text" name="absent" value="${query.absent}" class="input-small"/>
-		<input type="text" name="breach" value="${query.breach}" class="input-small"/>
-		<input type="text" name="manualAbsent" value="${query.manualAbsent}" class="input-small"/>
-		<input type="text" name="packageCode" value="${query.packageCode}" class="input-mini"/>
-		<input type="text" name="batchCode" value="${query.batchCode}" class="input-mini"/>
-        <input type="text" name="college" value="${query.college}" maxlength="64" class="input-mini"/>
-        <input type="text" name="className" value="${query.className}" maxlength="64" class="input-mini"/>
-        <input type="text" name="teacher" value="${query.teacher}" maxlength="64" class="input-mini"/>
-        <input type="text" name="examSite" value="${query.examSite}" maxlength="64" class="input-mini"/>
-        <input type="text" name="examRoom" value="${query.examRoom}" maxlength="64" class="input-mini"/>
-        <input type="number" name="sheetCount" value="${query.sheetCount}" maxlength="64" class="input-mini"/>
+    <input type="text" name="name" value="${query.name}" maxlength="10" class="input-mini"/>
+    <input type="text" name="examNumber" value="${query.examNumber}" maxlength="50" class="input-small"/>
+    <input type="text" name="secretNumber" value="${query.secretNumber}" maxlength="50" class="input-small"/>
+    <input type="text" name="studentCode" value="${query.studentCode}" maxlength="30" class="input-small"/>
+    <input type="text" name="subjectCode" value="${query.subjectCode}" class="input-small"/>
+    <input type="text" name="subjectLevel" value="${query.subjectLevel}" class="input-small"/>
+    <input type="text" name="subjectCategory" value="${query.subjectCategory}" maxlength="20" class="input-small"/>
+    <input type="text" name="upload" value="${query.upload}" class="input-small"/>
+    <input type="text" name="absent" value="${query.absent}" class="input-small"/>
+    <input type="text" name="breach" value="${query.breach}" class="input-small"/>
+    <input type="text" name="manualAbsent" value="${query.manualAbsent}" class="input-small"/>
+    <input type="text" name="packageCode" value="${query.packageCode}" class="input-mini"/>
+    <input type="text" name="batchCode" value="${query.batchCode}" class="input-mini"/>
+    <input type="text" name="college" value="${query.college}" maxlength="64" class="input-mini"/>
+    <input type="text" name="className" value="${query.className}" maxlength="64" class="input-mini"/>
+    <input type="text" name="teacher" value="${query.teacher}" maxlength="64" class="input-mini"/>
+    <input type="text" name="examSite" value="${query.examSite}" maxlength="64" class="input-mini"/>
+    <input type="text" name="examRoom" value="${query.examRoom}" maxlength="64" class="input-mini"/>
+    <input type="number" name="sheetCount" value="${query.sheetCount}" maxlength="64" class="input-mini"/>
 </form>
 <tags:message content="${message}"/>
 <table id="contentTable" class="table table-striped table-bordered table-condensed">
@@ -199,7 +230,8 @@
             <td>
                 <c:if test="${student.upload==true}">
                     <c:if test="${examType!='MULTI_MEDIA'}">
-                        <a class="sheet-link" href="##" data-sheet-url="${student.sheetUrlString}" data-answer-url="<c:if test="${student.answerUrl!=null}">${fileServer}${student.answerUrl}</c:if>"
+                        <a class="sheet-link" href="##" data-sheet-url="${student.sheetUrlString}"
+                           data-answer-url="<c:if test="${student.answerUrl!=null}">${fileServer}${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>
                     </c:if>
                     <c:if test="${examType=='MULTI_MEDIA'}">
@@ -213,11 +245,11 @@
                         正常
                     </c:if>
                 </c:if>
-                
+
                 <c:if test="${student.upload==false}">
                     未上传
                 </c:if>
-            
+
             </td>
             <td><fmt:formatNumber value="${student.sheetCount/2}" type="number" maxFractionDigits="0"/></td>
             <td>
@@ -240,7 +272,8 @@
             <td>${student.batchCode}</td>
             <td>
                 <c:if test="${student.packageUrlString!=null && student.packageUrlString!=''}">
-                    <a class="package-link" href="##" data-image-url="${student.packageUrlString}" data-title="${student.packageCode}">${student.packageCode}</a>
+                    <a class="package-link" href="##" data-image-url="${student.packageUrlString}"
+                       data-title="${student.packageCode}">${student.packageCode}</a>
                 </c:if>
                 <c:if test="${student.packageUrlString==null || student.packageUrlString==''}">
                     ${student.packageCode}
@@ -256,7 +289,8 @@
                     <a href="${ctx}/admin/exam/student/update?id=${student.id}" class="update-btn">修改</a>
                     <c:if test="${examType!='MULTI_MEDIA'}">
                         &nbsp;
-                        <a href="${ctx}/admin/exam/student/delete?id=${student.id}" onclick="return confirmx('确认要删除该考生吗?', this.href)">删除</a>
+                        <a href="${ctx}/admin/exam/student/delete?id=${student.id}"
+                           onclick="return confirmx('确认要删除该考生吗?', this.href)">删除</a>
                     </c:if>
                 </c:if>
             </td>
@@ -270,27 +304,28 @@
 <script type="text/javascript">
 
     $(document).ready(function () {
-    	var s=localStorage.getItem("studentQuery");
-    	if(s!="" && s!=null && s!=undefined){
-    		var studentQuery = JSON.parse(s);
-    		var pageN =1;
-    		var pageS =20;
-    		 for (var i = 0; i < studentQuery.length; i++) {
-    			var value = studentQuery[i].value;
-    			if(value!="" && value!=null && value!=undefined){
-	    			var name = studentQuery[i].name;
-    				$('[name='+name+']').attr('value',value);
-    				if(name=='pageNumber'){
-    					pageN = value;
-    				}
-    				if(name=='pageSize'){
-    					pageS = value;
-    				}
-    			} 
-    		};
-    		localStorage.setItem("studentQuery","");
-    		page(pageN, pageS);
-    	}
+        var s = localStorage.getItem("studentQuery");
+        if (s != "" && s != null && s != undefined) {
+            var studentQuery = JSON.parse(s);
+            var pageN = 1;
+            var pageS = 20;
+            for (var i = 0; i < studentQuery.length; i++) {
+                var value = studentQuery[i].value;
+                if (value != "" && value != null && value != undefined) {
+                    var name = studentQuery[i].name;
+                    $('[name=' + name + ']').attr('value', value);
+                    if (name == 'pageNumber') {
+                        pageN = value;
+                    }
+                    if (name == 'pageSize') {
+                        pageS = value;
+                    }
+                }
+            }
+            ;
+            localStorage.setItem("studentQuery", "");
+            page(pageN, pageS);
+        }
         $('.sheet-link').click(function () {
             initSheetPopover($(this).attr('data-title'), '${fileServer}', $(this).attr('data-sheet-url'), $(this).attr('data-answer-url'));
             return false;
@@ -381,9 +416,9 @@
             }
         });
     }
-    
+
     $('.update-btn').click(function () {
-    	localStorage.setItem("studentQuery", JSON.stringify($("#searchForm").serializeArray()));
+        localStorage.setItem("studentQuery", JSON.stringify($("#searchForm").serializeArray()));
     });
 </script>
 </body>

+ 29 - 27
stmms-web/src/main/webapp/sql/stmms_ft.sql

@@ -34,7 +34,7 @@ CREATE TABLE `b_school`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='学校表';
 
-  
+
 # Dump of table b_sys_config
 # ------------------------------------------------------------
 
@@ -49,7 +49,7 @@ CREATE TABLE `b_sys_config`
     UNIQUE KEY `index1` (`type`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='配置表';
-  
+
 LOCK TABLES `b_sys_config` WRITE;
 
 INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
@@ -58,6 +58,8 @@ INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
 VALUES (2, 'MARK_TIME', '30', '2021-08-09 15:38:58');
 INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
 VALUES (3, 'AUTO_REPORT', null, '2021-08-09 15:38:58');
+INSERT INTO `b_sys_config` (`id`, `type`, `description`, `update_time`)
+VALUES (4, 'STUDENT_SHEET_COUNT', null, '2021-08-09 15:38:58');
 
 UNLOCK TABLES;
 
@@ -76,7 +78,7 @@ CREATE TABLE `b_sys_auth` (
 ) ENGINE=InnoDB 
 	DEFAULT CHARSET = utf8mb4 COMMENT ='授权配置表';
 
-  
+
 # Dump of table b_user
 # ------------------------------------------------------------
 
@@ -136,7 +138,7 @@ CREATE TABLE `eb_user_exam`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='用户考试关联表';
 
-  
+
 # Dump of table eb_subject_user
 # ------------------------------------------------------------
 
@@ -348,7 +350,7 @@ CREATE TABLE `eb_exam_student`
 
 DROP TABLE IF EXISTS `eb_inspect_history`;
 
-CREATE TABLE `eb_inspect_history` 
+CREATE TABLE `eb_inspect_history`
 (
 	`id` 		INT (11) NOT NULL AUTO_INCREMENT COMMENT '主键',
 	`exam_id`	INT (11) NOT NULL COMMENT '考试ID',
@@ -513,7 +515,7 @@ CREATE TABLE `eb_subjective_score`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='主观题得分明细表';
 
-  
+
 # Dump of table eb_selective_group
 # ------------------------------------------------------------
 
@@ -548,8 +550,8 @@ CREATE TABLE `eb_selective_student`
     PRIMARY KEY (`student_id`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='选做题考生状态表';
-  
-  
+
+
 # Dump of table eb_operation_log
 # ------------------------------------------------------------
 
@@ -663,8 +665,8 @@ CREATE TABLE `m_reject_history`
     KEY `index1` (`exam_id`, `subject_code`, `group_number`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='打回记录表';
-  
-  
+
+
 # Dump of table m_special_tag
 # ------------------------------------------------------------
 
@@ -715,7 +717,7 @@ CREATE TABLE `m_track`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='轨迹给分表';
 
-  
+
 # Dump of table m_header_tag
 # ------------------------------------------------------------
 
@@ -1074,7 +1076,7 @@ CREATE TABLE `s_basic_subject_college`
     `subject_code`    varchar(32) DEFAULT NULL COMMENT '科目代码',
     `subject_name`    varchar(32) DEFAULT NULL COMMENT '科目名称',
     `college_name`    varchar(64) DEFAULT NULL COMMENT '学院名称',
-	`total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',    
+	`total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',
     `reality_count`      int(11)     DEFAULT NULL COMMENT '有效人数',
     `excellent_count` int(11)     DEFAULT NULL COMMENT '优秀人数',
     `excellent_rate`  double      DEFAULT NULL COMMENT '优秀率',
@@ -1107,7 +1109,7 @@ CREATE TABLE `s_basic_subject_teacher`
     `max_score`          double      DEFAULT NULL COMMENT '最高分',
     `min_score`          double      DEFAULT NULL COMMENT '最低分',
     `avg_score`          double      DEFAULT NULL COMMENT '平均分',
-    `total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',    
+    `total_count`      	 int(11)     DEFAULT NULL COMMENT '报考人数',
     `reality_count`      int(11)     DEFAULT NULL COMMENT '有效人数',
     `relative_avg_score` double      DEFAULT NULL COMMENT '平均相对分',
     PRIMARY KEY (`id`),
@@ -1141,14 +1143,14 @@ CREATE TABLE `s_basic_subject_teacher_class`
     KEY `index1` (`exam_id`, `subject_code`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='任课老师班级统计表';
-  
+
 
 # Dump of table eb_import_query
 # ------------------------------------------------------------
 
 DROP TABLE IF EXISTS `eb_import_query`;
 
-CREATE TABLE `eb_import_query` 
+CREATE TABLE `eb_import_query`
 (
   `id` 			int(11) 	NOT NULL AUTO_INCREMENT COMMENT '主键',
   `create_time` datetime    NOT NULL COMMENT '创建时间',
@@ -1160,14 +1162,14 @@ CREATE TABLE `eb_import_query`
   KEY `index1` (`exam_id`, `user_id`, `type`)
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='导入查询表';
-  
-  
+
+
 # Dump of table eb_answer_card
 # ------------------------------------------------------------
 
 DROP TABLE IF EXISTS `eb_answer_card`;
 
-CREATE TABLE `eb_answer_card` 
+CREATE TABLE `eb_answer_card`
 (
     `exam_id`			int(11)     NOT NULL COMMENT '考试ID',
     `code`				varchar(64) DEFAULT NULL COMMENT '混扫代码',
@@ -1186,8 +1188,8 @@ CREATE TABLE `eb_answer_card`
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='题卡卡格式表';
 
-DROP TABLE IF EXISTS `eb_score_verify`;  
-CREATE TABLE `eb_score_verify` 
+DROP TABLE IF EXISTS `eb_score_verify`;
+CREATE TABLE `eb_score_verify`
 (
 	`id`			int(11)     NOT NULL AUTO_INCREMENT COMMENT '主键',
     `exam_id`		int(11)     NOT NULL COMMENT '考试ID',
@@ -1202,12 +1204,12 @@ CREATE TABLE `eb_score_verify`
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='成绩校验';
 
-  
+
 # Dump of table eb_answer_card_subject
 # ------------------------------------------------------------
 
 DROP TABLE IF EXISTS `eb_answer_card_subject`;
-CREATE TABLE `eb_answer_card_subject` 
+CREATE TABLE `eb_answer_card_subject`
 (
 	`id`           		int(11)     	NOT NULL AUTO_INCREMENT COMMENT '主键',
     `exam_id`			int(11)     	NOT NULL COMMENT '考试ID',
@@ -1217,7 +1219,7 @@ CREATE TABLE `eb_answer_card_subject`
   UNIQUE KEY `index1` (`exam_id`,`card_number`,`subject_code`)
 )  ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='卡格式科目关联关系';
-  
+
 DROP TABLE IF EXISTS `eb_user_student`;
 CREATE TABLE `eb_user_student`
 (
@@ -1228,7 +1230,7 @@ CREATE TABLE `eb_user_student`
     UNIQUE KEY `index1` (`user_id`, `exam_number`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='用户考生关联表';
-  
+
 DROP TABLE IF EXISTS `b_role_info`;
 CREATE TABLE `b_role_info`
 (
@@ -1238,12 +1240,12 @@ CREATE TABLE `b_role_info`
     `name`           varchar(64) NOT NULL COMMENT '名称',
     `seq`            int(11)     NOT NULL COMMENT '排序',
     `updater_id` 	 int(11)	 DEFAULT NULL COMMENT '更新人ID',
-    `update_time`	 datetime    DEFAULT NULL COMMENT '更新时间', 
+    `update_time`	 datetime    DEFAULT NULL COMMENT '更新时间',
     PRIMARY KEY (`id`),
     UNIQUE KEY `IDX_ROLE_INFO_01` (`school_id`,`code`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='角色表';
-  
+
 DROP TABLE IF EXISTS `b_privilege`;
 CREATE TABLE `b_privilege`
 (
@@ -1277,7 +1279,7 @@ CREATE TABLE `b_role_privilege`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='角色权限关联表';
 
-LOCK TABLES `b_privilege` WRITE;  
+LOCK TABLES `b_privilege` WRITE;
 INSERT INTO `b_privilege` ( `code`, `name`, `parent_code`, `privilege_type`, `privilege_uri`, `seq`,`level`,`icon`,`i18n`)
 VALUES ('user_list', '用户管理', 'root_code', 'MENU', '/admin/user/list', 10,1,'icon-user','index.user');
 INSERT INTO `b_privilege` ( `code`, `name`, `parent_code`, `privilege_type`, `privilege_uri`, `seq`,`level`,`icon`,`i18n`)