package cn.com.qmth.stmms.mark; import cn.com.qmth.stmms.admin.utils.SessionExamUtils; 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.service.*; import cn.com.qmth.stmms.biz.file.service.FileService; import cn.com.qmth.stmms.biz.lock.LockService; import cn.com.qmth.stmms.biz.mark.model.*; import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery; import cn.com.qmth.stmms.biz.mark.service.*; import cn.com.qmth.stmms.biz.user.model.User; import cn.com.qmth.stmms.biz.user.service.UserService; import cn.com.qmth.stmms.common.annotation.Logging; import cn.com.qmth.stmms.common.controller.BaseController; import cn.com.qmth.stmms.common.domain.WebUser; import cn.com.qmth.stmms.common.enums.*; import cn.com.qmth.stmms.common.session.model.StmmsSession; import cn.com.qmth.stmms.common.session.service.SessionService; import cn.com.qmth.stmms.common.utils.Md5EncryptUtils; import cn.com.qmth.stmms.common.utils.RequestUtils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import net.sf.json.JSONObject; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; @Controller @RequestMapping("/mark") public class MarkController extends BaseController { private static Logger log = LoggerFactory.getLogger(MarkController.class); @Autowired private ExamSubjectService subjectService; @Autowired private TrialService trialService; @Autowired private MarkerService markerService; @Autowired private MarkLibraryService libraryService; @Autowired private TaskService taskService; @Autowired private MarkService markService; @Autowired private ExamService examService; @Autowired private MarkGroupService groupService; @Autowired private LockService lockService; @Autowired private ProblemTypeService problemTypeService; @Autowired private UserService userService; @Autowired private MarkerClassService markerClassService; @Autowired private SessionService sessionService; @Autowired private FileService fileService; @Value("${marker.forceMode}") private String forceMarkMode; @RequestMapping(value = "/reset", method = RequestMethod.GET) public ModelAndView reset(HttpServletRequest request) { User user = RequestUtils.getWebUser(request).getUser(); ModelAndView modelAndView = new ModelAndView("modules/mark/reset"); modelAndView.addObject("user", user); return modelAndView; } @Logging(menu = "修改姓名密码", type = LogType.UPDATE) @RequestMapping(value = "/reset", method = RequestMethod.POST) public ModelAndView reset(HttpServletRequest request, User user) { User current = RequestUtils.getWebUser(request).getUser(); current.setName(user.getName()); current.setPassword(Md5EncryptUtils.md5(user.getPassword())); current.setLastLoginIp(request.getRemoteAddr()); current.setLastLoginTime(new Date()); userService.save(current); return new ModelAndView("redirect:/mark/subject-select"); } @RequestMapping(value = "/subject-select", method = RequestMethod.GET) public ModelAndView select(HttpServletRequest request) { ModelAndView modelAndView = new ModelAndView("modules/mark/subjectSelect"); User user = RequestUtils.getWebUser(request).getUser(); Calendar rightNow = Calendar.getInstance(); rightNow.setTime(new Date()); rightNow.add(Calendar.YEAR, -1); List examList = examService.findByMarkerUserId(user.getId(), rightNow.getTime()); modelAndView.addObject("examList", examList); return modelAndView; } @RequestMapping(value = "/subject-select", method = RequestMethod.POST) public ModelAndView select(HttpServletRequest request, HttpServletResponse response, @RequestParam Integer markerId) { User user = RequestUtils.getWebUser(request).getUser(); ModelAndView modelAndView = new ModelAndView("modules/mark/subjectSelectAp"); Calendar rightNow = Calendar.getInstance(); rightNow.setTime(new Date()); rightNow.add(Calendar.YEAR, -1); List examList = examService.findByMarkerUserId(user.getId(), rightNow.getTime()); modelAndView.addObject("examList", examList); Marker marker = markerService.findById(markerId); Exam exam = examService.findById(marker.getExamId()); modelAndView.addObject("exam", exam); MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); if (group == null) { modelAndView.addObject("message", "user.login.error.group"); return modelAndView; } if (group.getStatus() == MarkStatus.FINISH) { modelAndView.addObject("message", "user.login.error.finish"); return modelAndView; } StmmsSession session = RequestUtils.getSession(request); session.saveWebUser(new WebUser(user, null, markerId.toString())); sessionService.put(request, response, session); SessionExamUtils.setExamId(request, exam.getId(), exam.getName(), exam.isForbiddenInfo()); return new ModelAndView("redirect:/mark/index"); } @RequestMapping("/index") public ModelAndView index(HttpServletRequest request, @RequestParam(value = "mode", required = false) String mode) { Marker marker = RequestUtils.getWebUser(request).getMarker(); ModelAndView modelAndView = getMarkModeView(marker, MarkMode.findByName(mode)); preProcess(marker, modelAndView); return modelAndView; } private ModelAndView getMarkModeView(Marker marker, MarkMode mode) { // 多媒体阅卷 Exam exam = examService.findById(marker.getExamId()); boolean forceMode = false; MarkMode sysMode = MarkMode.findByName(forceMarkMode); MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); if (ExamType.MULTI_MEDIA.equals(exam.getType())) { ModelAndView view = new ModelAndView("modules/mark/markJson"); view.addObject("forceMode", false); view.addObject("sheetView", false); view.addObject("isFormal", group.getStatus() == MarkStatus.FORMAL); return view; } if (sysMode != null) { // 全局配置的强制评卷模式 mode = sysMode; forceMode = true; } else { // 没有全局配置,优先从大题配置取强制评卷模式 if (group != null && group.getMarkMode() != null) { mode = group.getMarkMode(); forceMode = true; } // 否则取评卷员当前记录的评卷模式 if (mode == null) { mode = marker.getMode(); } if (mode == null) { mode = MarkMode.COMMON; } if (marker.getMode() != mode) { marker.setMode(mode); markerService.save(marker); } } ModelAndView view = new ModelAndView(mode == MarkMode.TRACK ? "modules/mark/markTrack" : "modules/mark/markNew"); view.addObject("forceMode", forceMode); view.addObject("sheetView", group.isSheetView()); view.addObject("enableAllZero", group.isEnableAllZero()); view.addObject("isFormal", group.getStatus() == MarkStatus.FORMAL); return view; } @RequestMapping("/logout") public ModelAndView logout(HttpServletRequest request) { WebUser wu = RequestUtils.getWebUser(request); releaseMarker(wu.getMarker()); if (StringUtils.isNotBlank(wu.getLogoutUrl())) { return new ModelAndView("redirect:" + wu.getLogoutUrl()); } else { return new ModelAndView("redirect:/logout"); } } /** * 进入评卷界面后的通用预处理 * * @param marker * @param modelAndView */ private void preProcess(Marker marker, ModelAndView modelAndView) { modelAndView.addObject("fileServer", fileService.getFileServer()); modelAndView.addObject("marker", marker); ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode()); subject.setPaperAnswerUrl(fileService); modelAndView.addObject("subject", subject); Exam exam = examService.findById(marker.getExamId()); modelAndView.addObject("forceSpecialTag", exam.isForceSpecialTag()); modelAndView.addObject("defaultSetting", StringUtils.trimToNull(marker.getMarkSetting())); String sheetConfig = ""; if (StringUtils.isNotBlank(subject.getSheetConfig())) { sheetConfig = buildPictureConfig(subject.getSheetConfig()); } else if (StringUtils.isNotBlank(exam.getSheetConfig())) { sheetConfig = buildPictureConfig(exam.getSheetConfig()); } modelAndView.addObject("sheetConfig", sheetConfig); releaseMarker(marker); List problemTypes = problemTypeService.findByExamId(marker.getExamId()); ObjectMapper mapper = new ObjectMapper(); try { modelAndView.addObject("problemTypes", mapper.writeValueAsString(problemTypes)); } catch (JsonProcessingException e) { log.error("MarkController-问题类型获取出错", e); } } @RequestMapping("/clear") @ResponseBody public void clear(HttpServletRequest request) { releaseMarker(RequestUtils.getWebUser(request).getMarker()); } @RequestMapping("/status") @ResponseBody public JSONObject status(HttpServletRequest request) { JSONObject status = new JSONObject(); Marker marker = RequestUtils.getWebUser(request).getMarker(); ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode()); MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); if (subject == null || group == null || group.getStatus() == MarkStatus.FINISH) { status.accumulate("valid", false); return status; } long totalCount = 0; long personCount = 0; long markedCount = 0; long exceptionCount = 0; long topCount = 0; if (group.getStatus() == MarkStatus.FORMAL) { topCount = marker.getTopCount() != null ? marker.getTopCount() : 0; MarkLibrarySearchQuery query = new MarkLibrarySearchQuery(); query.setExamId(marker.getExamId()); query.setSubjectCode(marker.getSubjectCode()); query.setGroupNumber(marker.getGroupNumber()); totalCount = libraryService.countByQuery(query); query.setMarkerId(marker.getId()); personCount = libraryService.countByQuery(query); query.setMarkerId(0); query.addStatus(LibraryStatus.MARKED); query.addStatus(LibraryStatus.ARBITRATED); markedCount = libraryService.countByQuery(query); query.clearStatus(); query.addStatus(LibraryStatus.WAIT_ARBITRATE); query.addStatus(LibraryStatus.PROBLEM); exceptionCount = libraryService.countByQuery(query); } else if (group.getStatus() == MarkStatus.TRIAL) { totalCount = trialService.countLibrary(group.getExamId(), group.getSubjectCode(), group.getNumber()); personCount = trialService.countMarkerHistory(marker.getId()); markedCount = personCount; } status.accumulate("personCount", personCount); status.accumulate("totalCount", totalCount); status.accumulate("markedCount", markedCount); status.accumulate("exceptionCount", exceptionCount); status.accumulate("valid", totalCount > 0); status.accumulate("topCount", topCount); return status; } @RequestMapping("/gettask") @ResponseBody public Task getTask(HttpServletRequest request) { Marker marker = RequestUtils.getWebUser(request).getMarker(); Task task = null; try { lockService.watch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); lockService.watch(LockType.MARKER, marker.getId()); MarkGroup group = groupService .findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); if (group == null) { task = new Task(); task.setExist(false); task.setMessage("mark.control.task.not.exist"); } else if (group.getStatus() == MarkStatus.FINISH) { task = new Task(); task.setExist(false); task.setMessage("mark.control.task.finish"); } else if (group.getStatus() == MarkStatus.TRIAL) { task = getTrialTask(marker); } else if (group.getStatus() == MarkStatus.FORMAL) { task = getFormalTask(marker); } if (task == null) { task = new Task(); task.setExist(false); task.setMessage("mark.control.task.null"); } } catch (Exception e) { log.error("get task error", e); } finally { lockService.unwatch(LockType.MARKER, marker.getId()); lockService.unwatch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); } return task; } private Task getFormalTask(Marker marker) { int retry = 1; Task task = null; while (task == null) { List list = new ArrayList(); // 需要判断评卷员是否绑定了班级 long classCount = markerClassService.countByUserIdAndExamId(marker.getUserId(), marker.getExamId()); list = libraryService.findUnMarked(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber(), marker.getId(), marker.getUserId(), classCount > 0, retry, 20); if (list.isEmpty()) { break; } for (MarkLibrary library : list) { if (markService.applyLibrary(library, marker)) { task = taskService.build(library); break; } } if (task == null) { retry++; } } return task; } private Task getTrialTask(Marker marker) { int retry = 1; Task task = null; while (task == null) { List list = trialService.findUnMarkedLibrary(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber(), marker.getId(), retry, 10); if (list.isEmpty()) { break; } for (TrialLibrary library : list) { if (markService.applyLibrary(library, marker)) { task = taskService.build(library, null); break; } } retry++; } return task; } @Logging(menu = "评卷", type = LogType.UPDATE) @RequestMapping(value = "/savetask", method = RequestMethod.POST) @ResponseBody public JSONObject saveTask(HttpServletRequest request, @RequestBody MarkResult markResult) { JSONObject result = new JSONObject(); Marker marker = RequestUtils.getWebUser(request).getMarker(); boolean success = false; try { lockService.watch(LockType.EXAM_SUBJECT, marker.getExamId(), marker.getSubjectCode()); lockService.watch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); lockService.watch(LockType.STUDENT, markResult.getStudentId()); lockService.watch(LockType.MARKER, marker.getId()); lockService.waitlock(LockType.GROUP_LIBRARY, markResult.getStudentId(), marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); success = markService.submitTask(markResult, marker); } catch (Exception e) { success = false; log.error("save task error", e); } finally { lockService.unlock(LockType.GROUP_LIBRARY, markResult.getStudentId(), marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); lockService.unwatch(LockType.MARKER, marker.getId()); lockService.unwatch(LockType.STUDENT, markResult.getStudentId()); lockService.unwatch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); lockService.unwatch(LockType.EXAM_SUBJECT, marker.getExamId(), marker.getSubjectCode()); } result.accumulate("success", success); result.accumulate("status", status(request)); if (!success) { result.accumulate("message", "mark.control.tsak.error"); } return result; } @Logging(menu = "查询回评任务", type = LogType.QUERY) @RequestMapping("/gethistory") @ResponseBody public Object history(HttpServletRequest request, @RequestParam int pageNumber, @RequestParam int pageSize, @RequestParam String order, @RequestParam String sort, @RequestParam(required = false, defaultValue = "false") Boolean isTag, @RequestParam(required = false) String secretNumber) throws Exception { Marker marker = RequestUtils.getWebUser(request).getMarker(); List list = new ArrayList<>(); Direction d = Direction.DESC; Sort querySort = null; if (sort.equals("asc")) { d = Direction.ASC; } if (order.equals("time")) { querySort = new Sort(d, "markerTime"); } else if (order.equals("studentId")) { querySort = new Sort(d, "studentId"); } else if (order.equals("score")) { querySort = new Sort(d, "markerScore"); } MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber()); if (group != null && group.getStatus() == MarkStatus.FORMAL) { // 正评查找已给分的评卷任务 MarkLibrarySearchQuery query = new MarkLibrarySearchQuery(); query.setExamId(marker.getExamId()); query.setSubjectCode(marker.getSubjectCode()); query.setMarkerId(marker.getId()); query.addStatus(LibraryStatus.MARKED); query.setGroupNumber(marker.getGroupNumber()); query.setSecretNumber(secretNumber); query.setPageNumber(pageNumber); query.setPageSize(pageSize); if (querySort != null) { query.setSort(querySort); } else { query.orderByMarkerTimeDesc(); } list = taskService.findByQuery(query); for (Task task : list) { task.setPrevious(true); } } else if (group != null && group.getStatus() == MarkStatus.TRIAL) { // 试评查找给分历史记录 List historyList = new ArrayList(); if (secretNumber != null) { historyList = trialService.findHistory(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber(), marker.getId(), secretNumber, pageNumber, pageSize, querySort); } else { historyList = trialService.findHistory(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber(), marker.getId(), pageNumber, pageSize, querySort, null); } for (TrialHistory history : historyList) { TrialLibrary library = trialService.findLibrary(history.getLibraryId()); if (library != null) { Task task = taskService.build(library, history); task.setPrevious(true); list.add(task); } } } return list; } @Logging(menu = "修改密码", type = LogType.UPDATE) @RequestMapping("/change-name") @ResponseBody public JSONObject changeName(HttpServletRequest request, @RequestParam String name, @RequestParam(required = false) String password) { User user = userService.findById(RequestUtils.getWebUser(request).getId()); JSONObject result = new JSONObject(); user.setName(name); if (StringUtils.isNotEmpty(password)) { user.setPassword(Md5EncryptUtils.md5(password)); } try { user = userService.save(user); result.accumulate("success", true); result.accumulate("name", user.getName()); } catch (Exception e) { result.accumulate("success", false); log.error("MarkController-修改名字出错", e); } return result; } @RequestMapping("/update-setting") @ResponseBody public JSONObject updateSetting(HttpServletRequest request, @RequestParam String setting) { Marker marker = RequestUtils.getWebUser(request).getMarker(); JSONObject result = new JSONObject(); markerService .updateMarkSetting(marker.getId(), StringEscapeUtils.unescapeHtml(StringUtils.trimToNull(setting))); result.accumulate("success", true); return result; } private void releaseMarker(Marker marker) { if (marker == null) { return; } try { lockService.waitlock(LockType.MARKER, marker.getId()); markService.releaseByMarker(marker); } catch (Exception e) { log.error("release marker error", e); } finally { lockService.unlock(LockType.MARKER, marker.getId()); } } protected String buildPictureConfig(String sheetConfig) { String json = ""; if (StringUtils.isNotBlank(sheetConfig)) { try { ObjectMapper mapper = new ObjectMapper(); json = mapper.writeValueAsString(PictureConfigItem.parse(sheetConfig)); } catch (JsonProcessingException e) { e.printStackTrace(); } } return json; } }