Sfoglia il codice sorgente

新增学院管理员

ting.yin 2 anni fa
parent
commit
bb306323ea
22 ha cambiato i file con 412 aggiunte e 72 eliminazioni
  1. 8 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/user/service/UserService.java
  2. 210 15
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/user/service/impl/UserServiceImpl.java
  3. 1 1
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/Role.java
  4. 8 8
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ArbitrateController.java
  5. 2 2
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ExamController.java
  6. 4 4
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/InspectedController.java
  7. 4 4
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/LibraryController.java
  8. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkController.java
  9. 11 11
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkGroupController.java
  10. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkQualityController.java
  11. 4 4
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/PaperController.java
  12. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ProblemHistoryController.java
  13. 2 2
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/TrialController.java
  14. 3 2
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/interceptor/AdminInterceptor.java
  15. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/report/ReportSubjectRangeController.java
  16. 41 5
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/user/UserController.java
  17. 6 6
      stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/CoreController.java
  18. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/LoginController.java
  19. 4 2
      stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/LoginController.java
  20. 1 1
      stmms-web/src/main/java/cn/com/qmth/stmms/common/domain/WebUser.java
  21. 96 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/user/userAdd.jsp
  22. 2 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/user/userList.jsp

+ 8 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/user/service/UserService.java

@@ -28,4 +28,12 @@ public interface UserService {
 
     User findByAccount(Integer schoolId, String account);
 
+    void batchSaveMarker(int examId, String[] subjectCodes, Integer number, String password);
+
+    void batchSaveSubjectUser(int examId, Role role, String[] subjectCodes, Integer number);
+
+    void batchSaveCollegeUser(int examId, Integer number);
+
+    public int findMaxNumberByLoginNameStart(String prefix);
+
 }

+ 210 - 15
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/user/service/impl/UserServiceImpl.java

@@ -1,12 +1,14 @@
 package cn.com.qmth.stmms.biz.user.service.impl;
 
-import cn.com.qmth.stmms.biz.user.dao.UserDao;
-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;
-import cn.com.qmth.stmms.common.enums.Role;
-import cn.com.qmth.stmms.common.enums.UserSource;
-import cn.com.qmth.stmms.common.utils.EncryptUtils;
+import java.util.ArrayList;
+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.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -16,14 +18,24 @@ 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;
+import cn.com.qmth.stmms.biz.exam.model.Exam;
+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.model.SubjectUser;
+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.user.dao.UserDao;
+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;
+import cn.com.qmth.stmms.common.enums.Role;
+import cn.com.qmth.stmms.common.enums.UserSource;
+import cn.com.qmth.stmms.common.utils.EncryptUtils;
 
 /**
  * 用户Service
@@ -33,9 +45,29 @@ import java.util.List;
 @Service("userService")
 public class UserServiceImpl implements UserService {
 
+    public static final String USER_PASSWORD = "123456";
+
     @Autowired
     private UserDao userDao;
 
+    @Autowired
+    private SubjectUserService subjectUserService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private ExamStudentService studentService;
+
     @Override
     @Transactional
     public User save(User user) {
@@ -201,4 +233,167 @@ public class UserServiceImpl implements UserService {
         return userDao.findFirstBySchoolIdAndRelatedAccount(schoolId, account);
     }
 
+    @Transactional
+    @Override
+    public void batchSaveMarker(int examId, String[] subjectCodes, Integer number, String password) {
+        if (subjectCodes.length == 0) {
+            List<ExamSubject> subjects = subjectService.list(examId, 0);
+            for (ExamSubject subject : subjects) {
+                saveMarkerBySubject(examId, number, password, subject.getCode());
+            }
+        } else {
+            for (String subjectCode : subjectCodes) {
+                saveMarkerBySubject(examId, number, password, subjectCode);
+            }
+        }
+
+    }
+
+    private void saveMarkerBySubject(int examId, Integer number, String password, String subjectCode) {
+        Exam exam = examService.findById(examId);
+        List<MarkGroup> groups = groupService.findByExamAndSubject(examId, subjectCode);
+        List<Marker> saveList = new ArrayList<Marker>();
+        for (MarkGroup group : groups) {
+            String prefix = exam.getSchoolId() + "-" + subjectCode + "-" + group.getNumber();
+            int maxNumber = this.findMaxNumberByLoginNameStart(prefix);
+            for (int j = 0; j < number; j++) {
+                String loginName = prefix + "-" + (maxNumber + j + 1);
+                User user = userDao.findFirstByLoginName(loginName);
+                if (user == null) {
+                    user = new User();
+                    user.setLoginName(loginName);
+                    user.setName(loginName);
+                    user.setPassword(EncryptUtils.md5(USER_PASSWORD));
+                    user.setRole(Role.MARKER);
+                    user.setSource(UserSource.INTERNAL);
+                    user.setEnable(true);
+                    user.setSchoolId(exam.getSchoolId());
+                    user.setCreatedTime(new Date());
+                }
+                if (StringUtils.isNotBlank(password)) {
+                    user.setPassword(EncryptUtils.md5(password));
+                }
+                userDao.save(user);
+                Marker marker = markerService.findByExamAndSubjectAndNumberAndUserId(examId, subjectCode,
+                        group.getNumber(), user.getId());
+                if (marker == null) {
+                    marker = new Marker();
+                    marker.setSubjectCode(subjectCode);
+                    marker.setGroupNumber(group.getNumber());
+                    marker.setUserId(user.getId());
+                    marker.setExamId(examId);
+                    marker.setEnable(true);
+                    saveList.add(marker);
+                }
+            }
+        }
+        markerService.batchSave(saveList);
+    }
+
+    @Transactional
+    @Override
+    public void batchSaveSubjectUser(int examId, Role role, String[] subjectCodes, Integer number) {
+        if (subjectCodes.length == 0) {
+            List<ExamSubject> subjects = subjectService.list(examId);
+            for (ExamSubject subject : subjects) {
+                saveSubjectUserBySubject(examId, number, role, subject.getCode());
+            }
+        } else {
+            for (String subjectCode : subjectCodes) {
+                saveSubjectUserBySubject(examId, number, role, subjectCode);
+            }
+        }
+    }
+
+    private void saveSubjectUserBySubject(int examId, Integer number, Role role, String subjectCode) {
+        Exam exam = examService.findById(examId);
+        List<SubjectUser> saveList = new ArrayList<SubjectUser>();
+        for (int i = 0; i < number; i++) {
+            String prefix = exam.getSchoolId() + "-" + subjectCode;
+            if (role.equals(Role.INSPECTOR)) {
+                prefix = exam.getSchoolId() + "-FH-" + subjectCode;
+            }
+            int maxNumber = this.findMaxNumberByLoginNameStart(prefix);
+            String loginName = prefix + "-" + (maxNumber + i + 1);
+            User user = userDao.findFirstByLoginName(loginName);
+            if (user == null) {
+                user = new User();
+                user.setLoginName(loginName);
+                user.setName(loginName);
+                user.setPassword(EncryptUtils.md5(USER_PASSWORD));
+                user.setRole(role);
+                user.setSource(UserSource.INTERNAL);
+                user.setEnable(true);
+                user.setSchoolId(exam.getSchoolId());
+                user.setCreatedTime(new Date());
+                userDao.save(user);
+            }
+            SubjectUser subjectUser = subjectUserService.findBySubjectCodeAndUserId(subjectCode, user.getId());
+            if (subjectUser == null) {
+                subjectUser = new SubjectUser();
+                subjectUser.setSubjectCode(subjectCode);
+                subjectUser.setUserId(user.getId());
+                saveList.add(subjectUser);
+            }
+        }
+        subjectUserService.batchSave(saveList);
+    }
+
+    @Override
+    public void batchSaveCollegeUser(int examId, Integer number) {
+        Exam exam = examService.findById(examId);
+        List<String> collegeList = studentService.findDistinctCollege(examId);
+        List<SubjectUser> saveList = new ArrayList<SubjectUser>();
+        for (String college : collegeList) {
+            List<String> subjectList = studentService.findDistinctSubjectCodeByCollege(examId, college);
+            for (int i = 0; i < number; i++) {
+                String prefix = exam.getSchoolId() + "-XY-";
+                int maxNumber = this.findMaxNumberByLoginNameStart(prefix);
+                String loginName = prefix + "-" + (maxNumber + i + 1);
+                User user = userDao.findFirstByLoginName(loginName);
+                if (user == null) {
+                    user = new User();
+                    user.setLoginName(loginName);
+                    user.setName(loginName);
+                    user.setPassword(EncryptUtils.md5(USER_PASSWORD));
+                    user.setRole(Role.COLLEGE_ADMIN);
+                    user.setSource(UserSource.INTERNAL);
+                    user.setEnable(true);
+                    user.setSchoolId(exam.getSchoolId());
+                    user.setCreatedTime(new Date());
+                    userDao.save(user);
+                }
+                for (String subjectCode : subjectList) {
+                    SubjectUser subjectUser = subjectUserService.findBySubjectCodeAndUserId(subjectCode, user.getId());
+                    if (subjectUser == null) {
+                        subjectUser = new SubjectUser();
+                        subjectUser.setSubjectCode(subjectCode);
+                        subjectUser.setUserId(user.getId());
+                        saveList.add(subjectUser);
+                    }
+                }
+                subjectUserService.batchSave(saveList);
+            }
+        }
+
+    }
+
+    @Override
+    public int findMaxNumberByLoginNameStart(String prefix) {
+        List<User> list = userDao.findStartWithLoginName(prefix);
+        int number = 1;
+        for (User user : list) {
+            String userNumber = user.getLoginName().substring(prefix.length() + 1, user.getLoginName().length() - 1);
+            try {
+                int no = Integer.parseInt(userNumber);
+                if (number < no) {
+                    number = no;
+                }
+            } catch (Exception e) {
+
+            }
+        }
+        return number;
+    }
+
 }

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

@@ -3,7 +3,7 @@ package cn.com.qmth.stmms.common.enums;
 public enum Role {
 
     SYS_ADMIN("系统管理员", 1), SCHOOL_ADMIN("学校管理员", 2), SCANNER("扫描员", 3), SUBJECT_HEADER("科组长", 4), MARKER("评卷员", 5), SCHOOL_VIEWER(
-            "学校查询员", 6), SCHOOL_DEV("学校接口调用", 7), INSPECTOR("复核员", 8), SCAN_ADMIN("扫描管理员", 2);
+            "学校查询员", 6), SCHOOL_DEV("学校接口调用", 7), INSPECTOR("复核员", 8), SCAN_ADMIN("扫描管理员", 9), COLLEGE_ADMIN("扫描管理员", 10);
 
     private String name;
 

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

@@ -145,7 +145,7 @@ public class ArbitrateController extends BaseExamController {
     }
 
     @RequestMapping("/getSetting")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     @ResponseBody
     public JSONObject getSetting(Model model, HttpServletRequest request,
             @RequestParam(required = false) String subjectCode, @RequestParam(required = false) Integer groupNumber,
@@ -195,7 +195,7 @@ public class ArbitrateController extends BaseExamController {
     @Logging(menu = "打回仲裁任务", type = LogType.UPDATE)
     @RequestMapping(value = "/back", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject back(HttpServletRequest request, @RequestParam Integer historyId) {
         JSONObject obj = new JSONObject();
         ArbitrateHistory history = arbitrateService.findById(historyId);
@@ -221,7 +221,7 @@ public class ArbitrateController extends BaseExamController {
 
     @RequestMapping(value = "/getHistory", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public List<Task> getHistory(HttpServletRequest request, @RequestParam String subjectCode,
             @RequestParam Integer groupNumber, @RequestParam(required = false) Integer pageNumber,
             @RequestParam(required = false) Integer pageSize, @RequestParam String order, @RequestParam String sort,
@@ -269,7 +269,7 @@ public class ArbitrateController extends BaseExamController {
 
     @RequestMapping("/getTask")
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public Task getTask(HttpServletRequest request, @RequestParam(required = false) String subjectCode,
             @RequestParam(required = false) Integer groupNumber, @RequestParam(required = false) Integer historyId) {
         int examId = getSessionExamId(request);
@@ -314,7 +314,7 @@ public class ArbitrateController extends BaseExamController {
     @Logging(menu = "处理仲裁", type = LogType.UPDATE)
     @RequestMapping(value = "/saveTask", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject saveTask(HttpServletRequest request, @RequestBody MarkResult markResult) {
         WebUser wu = RequestUtils.getWebUser(request);
         JSONObject result = new JSONObject();
@@ -351,7 +351,7 @@ public class ArbitrateController extends BaseExamController {
 
     @RequestMapping("/getStatus")
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject status(HttpServletRequest request, @RequestParam String subjectCode,
             @RequestParam Integer groupNumber) {
         JSONObject status = new JSONObject();
@@ -381,7 +381,7 @@ public class ArbitrateController extends BaseExamController {
 
     @RequestMapping("/getArbitrationList")
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public Object getList(HttpServletRequest request, @RequestParam Integer historyId) {
         ArbitrateHistory history = arbitrateService.findById(historyId);
         List<ArbitrationDTO> list = new ArrayList<ArbitrationDTO>();
@@ -399,7 +399,7 @@ public class ArbitrateController extends BaseExamController {
 
     @RequestMapping("/clear")
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public Object clear(HttpServletRequest request, @RequestParam(required = false) Integer libraryId) {
         WebUser wu = RequestUtils.getWebUser(request);
         JSONObject obj = new JSONObject();

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

@@ -251,7 +251,7 @@ public class ExamController extends BaseExamController {
         return fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1, student.getSheetCount());
     }
 
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.SCHOOL_VIEWER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.SCHOOL_VIEWER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     @RequestMapping(value = "/select")
     public String select(Model model, HttpServletRequest request) {
         WebUser wu = RequestUtils.getWebUser(request);
@@ -267,7 +267,7 @@ public class ExamController extends BaseExamController {
         return "modules/exam/examSelect";
     }
 
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.SCHOOL_VIEWER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.SCHOOL_VIEWER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     @RequestMapping(value = "/select", method = RequestMethod.POST)
     public String selectExam(HttpServletRequest request, @RequestParam Integer examId) {
         Exam exam = examService.findById(examId);

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

@@ -224,7 +224,7 @@ public class InspectedController extends BaseExamController {
 
     @RequestMapping(value = "/clear", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     public JSONObject clear(HttpServletRequest request, @RequestParam(required = false) String subjectCode,
             @RequestParam(required = false) Integer studentId) {
         JSONObject obj = new JSONObject();
@@ -244,7 +244,7 @@ public class InspectedController extends BaseExamController {
     @Logging(menu = "取消复核", type = LogType.UPDATE)
     @RequestMapping(value = "/cancel", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     public JSONObject cancel(HttpServletRequest request, @RequestParam Integer studentId) {
         JSONObject obj = new JSONObject();
         ExamStudent student = studentService.findById(studentId);
@@ -281,7 +281,7 @@ public class InspectedController extends BaseExamController {
     @Logging(menu = "打回", type = LogType.UPDATE)
     @RequestMapping(value = "/rejected", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     public JSONObject rejected(HttpServletRequest request, @RequestBody RejectResult rejectResult) {
         JSONObject obj = new JSONObject();
         ExamStudent student = studentService.findById(rejectResult.getStudentId());
@@ -420,7 +420,7 @@ public class InspectedController extends BaseExamController {
 
     @Logging(menu = "取消复核", type = LogType.UPDATE)
     @RequestMapping(value = "/batchCancel", method = RequestMethod.POST)
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     public String batchCancel(HttpServletRequest request, @RequestParam Integer[] ids) {
         WebUser wu = RequestUtils.getWebUser(request);
         for (Integer id : ids) {

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

@@ -155,7 +155,7 @@ public class LibraryController extends BaseExamController {
     @Logging(menu = "打回或重置评卷任务", type = LogType.UPDATE)
     @RequestMapping(value = "/reject", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject reject(HttpServletRequest request, @RequestParam Integer id,
             @RequestParam(required = false, defaultValue = "false") boolean isRest) {
         JSONObject obj = new JSONObject();
@@ -197,7 +197,7 @@ public class LibraryController extends BaseExamController {
     }
 
     @RequestMapping(value = "/getJson", method = RequestMethod.GET)
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.SCHOOL_VIEWER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.SCHOOL_VIEWER, Role.COLLEGE_ADMIN })
     public String getJson(Model model, HttpServletRequest request, @RequestParam Integer studentId,
             @RequestParam(required = false) Integer groupNumber) {
         int examId = getSessionExamId(request);
@@ -289,7 +289,7 @@ public class LibraryController extends BaseExamController {
 
     @RequestMapping(value = "/clear", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public Object clear(HttpServletRequest request, @RequestParam String subjectCode,
             @RequestParam Integer groupNumber, @RequestParam(required = false) Integer libraryId) {
         WebUser wu = RequestUtils.getWebUser(request);
@@ -338,7 +338,7 @@ public class LibraryController extends BaseExamController {
     @Logging(menu = "打回", type = LogType.UPDATE)
     @RequestMapping(value = "/rejected", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.INSPECTOR, Role.COLLEGE_ADMIN })
     public JSONObject rejected(HttpServletRequest request, @RequestBody RejectResult rejectResult) {
         JSONObject obj = new JSONObject();
         WebUser wu = RequestUtils.getWebUser(request);

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

@@ -225,7 +225,7 @@ public class MarkController extends BaseExamController {
 
     @Logging(menu = "大题关闭", type = LogType.QUERY)
     @RequestMapping("/finish")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String finish(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String[] codes) {
         int examId = getSessionExamId(request);

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

@@ -164,7 +164,7 @@ public class MarkGroupController extends BaseExamController {
 
     @Logging(menu = "大题数量校对", type = LogType.UPDATE)
     @RequestMapping("/check-count")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String ckeckCount(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode) {
         int examId = getSessionExamId(request);
@@ -180,7 +180,7 @@ public class MarkGroupController extends BaseExamController {
 
     @Logging(menu = "大题任务回收", type = LogType.UPDATE)
     @RequestMapping("/release")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String release(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number) {
         int examId = getSessionExamId(request);
@@ -200,7 +200,7 @@ public class MarkGroupController extends BaseExamController {
 
     @Logging(menu = "大题重置", type = LogType.UPDATE)
     @RequestMapping("/reset")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String reset(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number) {
         int examId = getSessionExamId(request);
@@ -226,7 +226,7 @@ public class MarkGroupController extends BaseExamController {
 
     @Logging(menu = "大题状态修改", type = LogType.QUERY)
     @RequestMapping("/changeStatus")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String changeStatus(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number, @RequestParam MarkStatus status) {
         int examId = getSessionExamId(request);
@@ -281,7 +281,7 @@ public class MarkGroupController extends BaseExamController {
     }
 
     @RequestMapping("/add")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String add(HttpServletRequest request, Model model, @RequestParam String subjectCode) {
         int examId = getSessionExamId(request);
         ExamSubject subject = subjectService.find(examId, subjectCode);
@@ -315,7 +315,7 @@ public class MarkGroupController extends BaseExamController {
     }
 
     @RequestMapping("/edit-simple")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String editSimple(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number) {
         int examId = getSessionExamId(request);
@@ -343,7 +343,7 @@ public class MarkGroupController extends BaseExamController {
     }
 
     @RequestMapping("/edit-full")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String editFull(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number) {
         int examId = getSessionExamId(request);
@@ -378,7 +378,7 @@ public class MarkGroupController extends BaseExamController {
 
     @Logging(menu = "删除大题", type = LogType.DELETE)
     @RequestMapping("/delete")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String delete(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number) {
         int examId = getSessionExamId(request);
@@ -418,7 +418,7 @@ public class MarkGroupController extends BaseExamController {
     @Logging(menu = "修改大题", type = LogType.UPDATE)
     @SuppressWarnings("unchecked")
     @RequestMapping("/update")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     @Transactional
     public String update(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number, @RequestParam Boolean reset,
@@ -557,7 +557,7 @@ public class MarkGroupController extends BaseExamController {
     @Logging(menu = "新增大题", type = LogType.ADD)
     @SuppressWarnings("unchecked")
     @RequestMapping("/insert")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     @Transactional
     public String insert(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer number, @RequestParam Integer[] questionIds,
@@ -700,7 +700,7 @@ public class MarkGroupController extends BaseExamController {
 
     @Logging(menu = "大题关闭", type = LogType.QUERY)
     @RequestMapping("/finish")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String finish(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode, @RequestParam Integer[] groupNumbers) {
         int examId = getSessionExamId(request);

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

@@ -227,7 +227,7 @@ public class MarkQualityController extends BaseExamController {
     @Logging(menu = "质量监控查询给分记录详情", type = LogType.QUERY)
     @RequestMapping(value = "/history", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public List<Task> getTask(HttpServletRequest request, @RequestParam Integer markerId,
             @RequestParam Double markerScore, @RequestParam(required = false) Integer pageNumber,
             @RequestParam(required = false) Integer pageSize) {

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

@@ -521,8 +521,6 @@ public class PaperController extends BaseExamController {
         }
         List<String> error = new LinkedList<String>();
         if (validate(question, error, new HashMap<Integer, String>())) {
-            markerService
-                    .logoutByExamIdAndSubjectCodeAndGroupNumber(examId, old.getSubjectCode(), old.getGroupNumber());
             old.setMainNumber(question.getMainNumber());
             old.setSubNumber(question.getSubNumber());
             old.setMainTitle(question.getMainTitle());
@@ -537,6 +535,8 @@ public class PaperController extends BaseExamController {
                     questionService.sumTotalScore(examId, question.getSubjectCode(), question.isObjective()));
             // 更新分组总分
             if (!old.isObjective() && old.getGroupNumber() != null) {
+                markerService.logoutByExamIdAndSubjectCodeAndGroupNumber(examId, old.getSubjectCode(),
+                        old.getGroupNumber());
                 MarkGroup group = groupService.findOne(examId, old.getSubjectCode(), old.getGroupNumber());
                 List<ExamQuestion> questionGroup = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(
                         examId, question.getSubjectCode(), false, old.getGroupNumber());
@@ -578,7 +578,7 @@ public class PaperController extends BaseExamController {
 
     @Logging(menu = "客观题统分", type = LogType.UPDATE)
     @RequestMapping("/calculate")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public ModelAndView calculate(HttpServletRequest request, RedirectAttributes redirectAttributes,
             @RequestParam(required = false) String subjectCode) {
         WebUser wu = RequestUtils.getWebUser(request);
@@ -668,7 +668,7 @@ public class PaperController extends BaseExamController {
 
     @Logging(menu = "批量删除题目", type = LogType.DELETE)
     @RequestMapping("/question/delete")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String delete(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam Integer[] ids, ExamSubjectSearchQuery query, @RequestParam(required = false) Boolean upload) {
         for (Integer id : ids) {

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

@@ -160,7 +160,7 @@ public class ProblemHistoryController extends BaseExamController {
 
     @Logging(menu = "任务批量重置", type = LogType.QUERY)
     @RequestMapping("/restBatch")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String restBatch(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam Integer[] libraryIds) {
         WebUser wu = RequestUtils.getWebUser(request);

+ 2 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/TrialController.java

@@ -127,7 +127,7 @@ public class TrialController extends BaseExamController {
     @Logging(menu = "重置试评任务", type = LogType.UPDATE)
     @RequestMapping(value = "/reset", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject reset(HttpServletRequest request, @RequestParam Integer libraryId) {
         JSONObject obj = new JSONObject();
         int examId = getSessionExamId(request);
@@ -168,7 +168,7 @@ public class TrialController extends BaseExamController {
     @Logging(menu = "试评详情", type = LogType.QUERY)
     @RequestMapping(value = "/detail")
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject detail(HttpServletRequest request, @RequestParam Integer libraryId) {
         JSONObject obj = new JSONObject();
         TrialLibrary library = trialService.findById(libraryId);

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

@@ -37,7 +37,7 @@ public class AdminInterceptor extends SessionInterceptor {
         }
         if (wu != null
                 && (wu.getRole() == Role.SCHOOL_ADMIN || wu.getRole() == Role.SUBJECT_HEADER
-                        || wu.getRole() == Role.SCHOOL_VIEWER || wu.getRole() == Role.INSPECTOR)) {
+                        || wu.getRole() == Role.SCHOOL_VIEWER || wu.getRole() == Role.INSPECTOR || wu.getRole() == Role.COLLEGE_ADMIN)) {
             Integer examId = SessionExamUtils.getExamId(request);
             String uri = request.getRequestURI();
             if (examId > 0 || uri.startsWith("/admin/exam/select") || uri.startsWith("/admin/home")
@@ -53,7 +53,8 @@ public class AdminInterceptor extends SessionInterceptor {
     private WebUser buildWebUser(HttpServletRequest request) {
         WebUser wu = WebUser.buildFromSession(RequestUtils.getSession(request), userService);
         if (wu != null) {
-            if (wu.getRole() == Role.SUBJECT_HEADER || wu.getRole() == Role.INSPECTOR) {
+            if (wu.getRole() == Role.SUBJECT_HEADER || wu.getRole() == Role.INSPECTOR
+                    || wu.getRole() == Role.COLLEGE_ADMIN) {
                 wu.setSubjectCodeSet(subjectUserService.findSubjectCode(wu.getId()));
             }
             RequestUtils.setWebUser(request, wu);

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/report/ReportSubjectRangeController.java

@@ -185,7 +185,7 @@ public class ReportSubjectRangeController extends BaseExamController {
 
     @Logging(menu = "科目成绩分析计算", type = LogType.UPDATE)
     @RequestMapping("/report")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String calculate(HttpServletRequest request, RedirectAttributes redirectAttributes,
             @RequestParam String subjectCode) {
         int examId = getSessionExamId(request);

+ 41 - 5
stmms-web/src/main/java/cn/com/qmth/stmms/admin/user/UserController.java

@@ -34,6 +34,7 @@ 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.ExamSubjectService;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
 import cn.com.qmth.stmms.biz.exam.service.MarkerService;
@@ -57,7 +58,7 @@ public class UserController extends BaseExamController {
     public static final String SUBJECT_CODE_SPLIT = ",";
 
     public static Role[] ROLE_LIST = { Role.SCANNER, Role.SUBJECT_HEADER, Role.INSPECTOR, Role.MARKER,
-            Role.SCHOOL_VIEWER, Role.SCHOOL_ADMIN };
+            Role.SCHOOL_VIEWER, Role.SCHOOL_ADMIN, Role.COLLEGE_ADMIN };
 
     @Autowired
     private UserService userService;
@@ -77,6 +78,9 @@ public class UserController extends BaseExamController {
     @Autowired
     private ExamQuestionService questionService;
 
+    @Autowired
+    private ExamService examService;
+
     @Logging(menu = "查询用户", type = LogType.QUERY)
     @RequestMapping("/list")
     @RoleRequire(Role.SCHOOL_ADMIN)
@@ -111,7 +115,8 @@ public class UserController extends BaseExamController {
         if (user != null && user.getSchoolId().equals(current.getSchoolId())) {
             ModelAndView view = new ModelAndView("modules/user/userEdit");
             view.addObject("user", user);
-            if (user.getRole() == Role.SUBJECT_HEADER || user.getRole() == Role.INSPECTOR) {
+            if (user.getRole() == Role.SUBJECT_HEADER || user.getRole() == Role.INSPECTOR
+                    || user.getRole() == Role.COLLEGE_ADMIN) {
                 view.addObject("subjectCodeString",
                         StringUtils.join(subjectUserService.findSubjectCode(user.getId()), SUBJECT_CODE_SPLIT));
             }
@@ -141,7 +146,8 @@ public class UserController extends BaseExamController {
                 user.setCreatedTime(new Date());
                 user.setUpdatedTime(new Date());
                 userService.save(user);
-                if (user.getRole() == Role.SUBJECT_HEADER || user.getRole() == Role.INSPECTOR) {
+                if (user.getRole() == Role.SUBJECT_HEADER || user.getRole() == Role.INSPECTOR
+                        || user.getRole() == Role.COLLEGE_ADMIN) {
                     subjectUserService.updateByUserId(user.getId(), getSubjectCodeSet(subjectCodeString));
                 }
             } else {
@@ -189,6 +195,8 @@ public class UserController extends BaseExamController {
             message = "科组长必须绑定科目代码";
         } else if (user.getRole() == Role.INSPECTOR && StringUtils.isBlank(subjectCodeString)) {
             message = "复核员必须绑定科目代码";
+        } else if (user.getRole() == Role.COLLEGE_ADMIN && StringUtils.isBlank(subjectCodeString)) {
+            message = "学院管理员必须绑定科目代码";
         }
         return message;
     }
@@ -204,7 +212,7 @@ public class UserController extends BaseExamController {
                 }
             }
         } catch (Exception e) {
-
+            e.printStackTrace();
         }
         return set;
     }
@@ -303,7 +311,7 @@ public class UserController extends BaseExamController {
 
     @Logging(menu = "用户启用/禁用", type = LogType.UPDATE)
     @RequestMapping("/toggle")
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public String toggle(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
             @RequestParam Integer[] ids, @RequestParam Boolean enable) {
         for (Integer id : ids) {
@@ -334,4 +342,32 @@ public class UserController extends BaseExamController {
         obj.accumulate("success", true);
         return obj;
     }
+
+    @RequestMapping(value = "/batchAdd", method = RequestMethod.GET)
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public ModelAndView batchAdd(HttpServletRequest request) {
+        ModelAndView view = new ModelAndView("modules/user/userAdd");
+        Role[] roleList = { Role.SUBJECT_HEADER, Role.INSPECTOR, Role.MARKER, Role.COLLEGE_ADMIN };
+        view.addObject("roleList", roleList);
+        int examId = getSessionExamId(request);
+        view.addObject("exam", examService.findById(examId));
+        return view;
+    }
+
+    @Logging(menu = "批量新增用户", type = LogType.ADD)
+    @RequestMapping(value = "/batchSave", method = RequestMethod.POST)
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public String batchSave(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
+            @RequestParam Role role, @RequestParam String password, @RequestParam Integer number,
+            @RequestParam String[] subejctCodes) {
+        int examId = getSessionExamId(request);
+        if (Role.MARKER.equals(role)) {
+            userService.batchSaveMarker(examId, subejctCodes, number, password);
+        } else if (Role.COLLEGE_ADMIN.equals(role)) {
+            userService.batchSaveCollegeUser(examId, number);
+        } else {
+            userService.batchSaveSubjectUser(examId, role, subejctCodes, number);
+        }
+        return "redirect:/admin/user/list";
+    }
 }

+ 6 - 6
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/CoreController.java

@@ -612,7 +612,7 @@ public class CoreController extends BaseApiController {
 
     @RequestMapping(value = "/exam/paper/query", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONArray paperQuery(HttpServletRequest request, @RequestParam Integer examId,
             @RequestParam String subjectCode, @RequestParam(required = false, defaultValue = "#") String paperType) {
         ApiUser user = RequestUtils.getApiUser(request);
@@ -666,7 +666,7 @@ public class CoreController extends BaseApiController {
 
     @RequestMapping(value = "/exam/mark_group/delete", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject groupDelete(HttpServletRequest request, @RequestParam Integer examId,
             @RequestParam String subjectCode) {
         ApiUser user = RequestUtils.getApiUser(request);
@@ -699,7 +699,7 @@ public class CoreController extends BaseApiController {
 
     @RequestMapping(value = "/exam/mark_group/count", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject groupCount(HttpServletRequest request, @RequestParam Integer examId,
             @RequestParam String subjectCode) {
         ApiUser user = RequestUtils.getApiUser(request);
@@ -720,7 +720,7 @@ public class CoreController extends BaseApiController {
 
     @RequestMapping(value = "/exam/mark_group/save", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject groupSave(HttpServletRequest request, @RequestBody PaperStructureDTO dto) {
         ApiUser user = RequestUtils.getApiUser(request);
         JSONObject result = new JSONObject();
@@ -769,7 +769,7 @@ public class CoreController extends BaseApiController {
 
     @RequestMapping(value = "/exam/marker/save", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     public JSONObject markerSave(HttpServletRequest request, @RequestParam Integer examId,
             @RequestParam String subjectCode, @RequestParam Integer groupNumber, @RequestParam String account) {
         ApiUser user = RequestUtils.getApiUser(request);
@@ -810,7 +810,7 @@ public class CoreController extends BaseApiController {
 
     @RequestMapping(value = "/exam/subject_header/save", method = RequestMethod.POST)
     @ResponseBody
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.COLLEGE_ADMIN })
     public JSONObject subjectHeaderSave(HttpServletRequest request, @RequestParam String subjectCode,
             @RequestParam String account) {
         ApiUser user = RequestUtils.getApiUser(request);

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/LoginController.java

@@ -43,7 +43,7 @@ public class LoginController extends BaseApiController {
     @Autowired
     private SchoolService schoolService;
 
-    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER, Role.SUBJECT_HEADER })
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER, Role.SUBJECT_HEADER, Role.COLLEGE_ADMIN })
     @RequestMapping(value = "/user/login", method = RequestMethod.GET)
     @ResponseBody
     public JSONObject login(HttpServletRequest request) {

+ 4 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/LoginController.java

@@ -94,9 +94,11 @@ public class LoginController {
         }
         if (ADMIN_LOGIN.equals(loginType)) {
             if (u.getRole() == Role.SYS_ADMIN || u.getRole() == Role.SCHOOL_ADMIN || u.getRole() == Role.SUBJECT_HEADER
-                    || u.getRole() == Role.SCHOOL_VIEWER || u.getRole() == Role.INSPECTOR) {
+                    || u.getRole() == Role.SCHOOL_VIEWER || u.getRole() == Role.INSPECTOR
+                    || u.getRole() == Role.COLLEGE_ADMIN) {
                 if (u.getLastLoginTime() == null
-                        && (u.getRole() == Role.SUBJECT_HEADER || u.getRole() == Role.SCHOOL_VIEWER || u.getRole() == Role.INSPECTOR)) {
+                        && (u.getRole() == Role.SUBJECT_HEADER || u.getRole() == Role.SCHOOL_VIEWER
+                                || u.getRole() == Role.INSPECTOR || u.getRole() == Role.COLLEGE_ADMIN)) {
                     u.refreshAccessToken();
                     userService.save(u);
                     WebUser wu = new WebUser(u);

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/common/domain/WebUser.java

@@ -96,7 +96,7 @@ public class WebUser {
     }
 
     public boolean isSubjectHeader() {
-        return role == Role.SUBJECT_HEADER;
+        return (role == Role.SUBJECT_HEADER) || (role == Role.COLLEGE_ADMIN);
     }
 
     public boolean isSchoolAdmin() {

+ 96 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/user/userAdd.jsp

@@ -0,0 +1,96 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp" %>
+<html>
+<head>
+    <title>用户管理</title>
+    <meta name="decorator" content="default"/>
+    <%@include file="/WEB-INF/views/include/head.jsp" %>
+    <script type="text/javascript">
+        $(document).ready(function () {
+            $("#loginName").focus();
+            $("#inputForm").validate({
+                submitHandler: function (form) {
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function (error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+            $('#role-select').change(function () {
+                var role = $('#role-select').val();
+                if (role == '4' || role == '8') {
+                    $('#subject-code-div').show();
+                } else {
+                    $('#subject-code-div').hide();
+                }
+            });
+            $('#role-select').trigger('change');
+        });
+    </script>
+</head>
+<body>
+<ul class="nav nav-tabs">
+    <li><a href="${ctx}/admin/user/list">用户列表</a></li>
+    <li class="active"><a href="##">用户新增</a></li>
+</ul>
+<form:form id="inputForm" modelAttribute="user" action="${ctx}/admin/user/batchSave" method="post" class="form-horizontal">
+    <form:hidden path="id"/>
+    <tags:message content="${message}"/>
+    <div class="control-group">
+        <label class="control-label">考试名称</label>
+        <div class="controls">
+            ${exam.id }-${exam.name }
+        </div>
+    </div>
+    <div class="control-group">
+        <label class="control-label">角色</label>
+        <div class="controls">
+            <select name="role" id="role-select">
+                <c:if test="${roleList != null}">
+                    <c:forEach items="${roleList}" var="role">
+                        <option value="${role.value}"
+                                <c:if test="${role.value==user.role.value}">selected</c:if>>${role.name}</option>
+                    </c:forEach>
+                </c:if>
+                <c:if test="${user.role!=null && roleList==null}">
+                    <option value="${user.role.value}" selected>${user.role.name}</option>
+                </c:if>
+            </select>
+        </div>
+    </div>
+    <div class="control-group">
+        <label class="control-label">每分组账号数</label>
+        <div class="controls">
+            <form:password path="number" htmlEscape="false" maxlength="20"/>
+        </div>
+    </div>
+    <div class="control-group">
+        <label class="control-label">密码</label>
+        <div class="controls">
+            <form:password path="password" htmlEscape="false" maxlength="20"/>
+        </div>
+    </div>
+    <c:if test="${user.role==null || user.role.value==4|| user.role.value==8}">
+        <div class="control-group" id="subject-code-div">
+            <label class="control-label">绑定科目代码</label>
+            <div class="controls">
+            <textarea name="subjectCodeString" rows="4" maxlength="200" class="input-xxlarge"
+                      >${subjectCodeString}</textarea>
+            </div>
+        </div>
+    </c:if>
+    <div class="form-actions">
+        <input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/>
+        &nbsp;
+        <a href="javascript:" onclick="history.go(-1);"  class="btn">返回</a>
+    </div>
+</form:form>
+</body>
+</html>

+ 2 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/user/userList.jsp

@@ -104,6 +104,8 @@
 					<li><a href="##" onclick="goExportExam()">按考试导出</a></li>
 				</ul>
 			</div>
+			 &nbsp;
+            <a href="${ctx}/admin/user/batchAdd" class="btn">批量创建</a>
             &nbsp;
             <input id="btnEnable" class="btn" type="button" value="启用" onclick="goEnable(true)"/>
             &nbsp;