1
0

MarkController.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. package cn.com.qmth.stmms.mark;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. import java.util.List;
  5. import javax.servlet.http.HttpServletRequest;
  6. import net.sf.json.JSONObject;
  7. import org.apache.commons.lang.StringEscapeUtils;
  8. import org.apache.commons.lang.StringUtils;
  9. import org.slf4j.Logger;
  10. import org.slf4j.LoggerFactory;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.beans.factory.annotation.Value;
  13. import org.springframework.data.domain.Sort;
  14. import org.springframework.data.domain.Sort.Direction;
  15. import org.springframework.stereotype.Controller;
  16. import org.springframework.web.bind.annotation.RequestBody;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RequestMethod;
  19. import org.springframework.web.bind.annotation.RequestParam;
  20. import org.springframework.web.bind.annotation.ResponseBody;
  21. import org.springframework.web.servlet.ModelAndView;
  22. import cn.com.qmth.stmms.biz.exam.model.Exam;
  23. import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
  24. import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
  25. import cn.com.qmth.stmms.biz.exam.model.Marker;
  26. import cn.com.qmth.stmms.biz.exam.service.ExamService;
  27. import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
  28. import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
  29. import cn.com.qmth.stmms.biz.exam.service.MarkerService;
  30. import cn.com.qmth.stmms.biz.lock.LockService;
  31. import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
  32. import cn.com.qmth.stmms.biz.mark.model.MarkResult;
  33. import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
  34. import cn.com.qmth.stmms.biz.mark.model.ProblemType;
  35. import cn.com.qmth.stmms.biz.mark.model.Task;
  36. import cn.com.qmth.stmms.biz.mark.model.TrialHistory;
  37. import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
  38. import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
  39. import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
  40. import cn.com.qmth.stmms.biz.mark.service.MarkService;
  41. import cn.com.qmth.stmms.biz.mark.service.ProblemTypeService;
  42. import cn.com.qmth.stmms.biz.mark.service.TaskService;
  43. import cn.com.qmth.stmms.biz.mark.service.TrialService;
  44. import cn.com.qmth.stmms.common.controller.BaseController;
  45. import cn.com.qmth.stmms.common.enums.ExamType;
  46. import cn.com.qmth.stmms.common.enums.LibraryStatus;
  47. import cn.com.qmth.stmms.common.enums.LockType;
  48. import cn.com.qmth.stmms.common.enums.MarkMode;
  49. import cn.com.qmth.stmms.common.enums.MarkStatus;
  50. import cn.com.qmth.stmms.common.utils.RequestUtils;
  51. import com.fasterxml.jackson.core.JsonProcessingException;
  52. import com.fasterxml.jackson.databind.ObjectMapper;
  53. @Controller
  54. @RequestMapping("/mark")
  55. public class MarkController extends BaseController {
  56. private static Logger log = LoggerFactory.getLogger(MarkController.class);
  57. @Autowired
  58. private ExamSubjectService subjectService;
  59. @Autowired
  60. private TrialService trialService;
  61. @Autowired
  62. private MarkerService markerService;
  63. @Autowired
  64. private MarkLibraryService libraryService;
  65. @Autowired
  66. private TaskService taskService;
  67. @Autowired
  68. private MarkService markService;
  69. @Autowired
  70. private ExamService examService;
  71. @Autowired
  72. private MarkGroupService groupService;
  73. @Autowired
  74. private LockService lockService;
  75. @Autowired
  76. private ProblemTypeService problemTypeService;
  77. @Value("${slice.image.server}")
  78. private String sliceServer;
  79. @Value("${sheet.image.server}")
  80. private String sheetServer;
  81. @Value("${card.server}")
  82. private String cardServer;
  83. @Value("${marker.forceMode}")
  84. private String forceMarkMode;
  85. @Value("${json.server}")
  86. private String jsonServer;
  87. @RequestMapping(value = "/reset", method = RequestMethod.GET)
  88. public ModelAndView reset(HttpServletRequest request) {
  89. Marker marker = RequestUtils.getWebUser(request).getMarker();
  90. ModelAndView modelAndView = new ModelAndView("modules/mark/reset");
  91. modelAndView.addObject("marker", marker);
  92. return modelAndView;
  93. }
  94. @RequestMapping(value = "/reset", method = RequestMethod.POST)
  95. public ModelAndView reset(HttpServletRequest request, Marker marker) {
  96. Marker current = RequestUtils.getWebUser(request).getMarker();
  97. current.setName(marker.getName());
  98. current.setPassword(marker.getPassword());
  99. current.setLastLoginIp(request.getRemoteAddr());
  100. current.setLastLoginTime(new Date());
  101. markerService.save(current);
  102. return new ModelAndView("redirect:/mark/index");
  103. }
  104. @RequestMapping("/index")
  105. public ModelAndView index(HttpServletRequest request, @RequestParam(value = "mode", required = false) String mode) {
  106. Marker marker = RequestUtils.getWebUser(request).getMarker();
  107. ModelAndView modelAndView = getMarkModeView(marker, MarkMode.findByName(mode));
  108. preProcess(marker, modelAndView);
  109. return modelAndView;
  110. }
  111. private ModelAndView getMarkModeView(Marker marker, MarkMode mode) {
  112. // 多媒体阅卷
  113. Exam exam = examService.findById(marker.getExamId());
  114. boolean forceMode = false;
  115. MarkMode sysMode = MarkMode.findByName(forceMarkMode);
  116. MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  117. if (ExamType.MULTI_MEDIA.equals(exam.getType())) {
  118. ModelAndView view = new ModelAndView("modules/mark/markJson");
  119. view.addObject("forceMode", false);
  120. view.addObject("sheetView", false);
  121. view.addObject("isFormal", group.getStatus() == MarkStatus.FORMAL);
  122. return view;
  123. }
  124. if (sysMode != null) {
  125. // 全局配置的强制评卷模式
  126. mode = sysMode;
  127. forceMode = true;
  128. } else {
  129. // 没有全局配置,优先从大题配置取强制评卷模式
  130. if (group != null && group.getMarkMode() != null) {
  131. mode = group.getMarkMode();
  132. forceMode = true;
  133. }
  134. // 否则取评卷员当前记录的评卷模式
  135. if (mode == null) {
  136. mode = marker.getMode();
  137. }
  138. if (mode == null) {
  139. mode = MarkMode.COMMON;
  140. }
  141. if (marker.getMode() != mode) {
  142. marker.setMode(mode);
  143. markerService.save(marker);
  144. }
  145. }
  146. ModelAndView view = new ModelAndView(mode == MarkMode.TRACK ? "modules/mark/markTrack" : "modules/mark/markNew");
  147. view.addObject("forceMode", forceMode);
  148. view.addObject("sheetView", group.isSheetView());
  149. view.addObject("isFormal", group.getStatus() == MarkStatus.FORMAL);
  150. return view;
  151. }
  152. @RequestMapping("/logout")
  153. public ModelAndView logout(HttpServletRequest request) {
  154. releaseMarker(RequestUtils.getWebUser(request).getMarker());
  155. return new ModelAndView("redirect:/logout");
  156. }
  157. /**
  158. * 进入评卷界面后的通用预处理
  159. *
  160. * @param marker
  161. * @param session
  162. * @param modelAndView
  163. * @param modelAndView
  164. */
  165. private void preProcess(Marker marker, ModelAndView modelAndView) {
  166. modelAndView.addObject("sliceServer", sliceServer);
  167. modelAndView.addObject("sheetServer", sheetServer);
  168. modelAndView.addObject("cardServer", cardServer);
  169. modelAndView.addObject("jsonServer", jsonServer);
  170. modelAndView.addObject("marker", marker);
  171. ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
  172. modelAndView.addObject("subject", subject);
  173. Exam exam = examService.findById(marker.getExamId());
  174. modelAndView.addObject("forceSpecialTag", exam.isForceSpecialTag());
  175. modelAndView.addObject("defaultSetting", StringUtils.trimToNull(marker.getMarkSetting()));
  176. String sheetConfig = "";
  177. if (StringUtils.isNotBlank(subject.getSheetConfig())) {
  178. sheetConfig = buildPictureConfig(subject.getSheetConfig());
  179. } else if (StringUtils.isNotBlank(exam.getSheetConfig())) {
  180. sheetConfig = buildPictureConfig(exam.getSheetConfig());
  181. }
  182. modelAndView.addObject("sheetConfig", sheetConfig);
  183. releaseMarker(marker);
  184. List<ProblemType> problemTypes = problemTypeService.findByExamId(marker.getExamId());
  185. ObjectMapper mapper = new ObjectMapper();
  186. try {
  187. modelAndView.addObject("problemTypes", mapper.writeValueAsString(problemTypes));
  188. } catch (JsonProcessingException e) {
  189. log.error("MarkController-问题类型获取出错", e);
  190. }
  191. }
  192. @RequestMapping("/clear")
  193. @ResponseBody
  194. public void clear(HttpServletRequest request) {
  195. releaseMarker(RequestUtils.getWebUser(request).getMarker());
  196. }
  197. @RequestMapping("/status")
  198. @ResponseBody
  199. public JSONObject status(HttpServletRequest request) {
  200. JSONObject status = new JSONObject();
  201. Marker marker = RequestUtils.getWebUser(request).getMarker();
  202. ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
  203. MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  204. if (subject == null || group == null || group.getStatus() == MarkStatus.FINISH) {
  205. status.accumulate("valid", false);
  206. return status;
  207. }
  208. long totalCount = 0;
  209. long personCount = 0;
  210. long markedCount = 0;
  211. long exceptionCount = 0;
  212. long topCount = 0;
  213. if (group.getStatus() == MarkStatus.FORMAL) {
  214. topCount = marker.getTopCount() != null ? marker.getTopCount() : 0;
  215. MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
  216. query.setExamId(marker.getExamId());
  217. query.setSubjectCode(marker.getSubjectCode());
  218. query.setGroupNumber(marker.getGroupNumber());
  219. totalCount = libraryService.countByQuery(query);
  220. query.setMarkerId(marker.getId());
  221. personCount = libraryService.countByQuery(query);
  222. query.setMarkerId(0);
  223. query.addStatus(LibraryStatus.MARKED);
  224. query.addStatus(LibraryStatus.INSPECTED);
  225. query.addStatus(LibraryStatus.ARBITRATED);
  226. markedCount = libraryService.countByQuery(query);
  227. query.clearStatus();
  228. query.addStatus(LibraryStatus.WAIT_ARBITRATE);
  229. query.addStatus(LibraryStatus.PROBLEM);
  230. exceptionCount = libraryService.countByQuery(query);
  231. } else if (group.getStatus() == MarkStatus.TRIAL) {
  232. totalCount = trialService.countLibrary(group.getExamId(), group.getSubjectCode(), group.getNumber());
  233. personCount = trialService.countMarkerHistory(marker.getId());
  234. markedCount = personCount;
  235. }
  236. status.accumulate("personCount", personCount);
  237. status.accumulate("totalCount", totalCount);
  238. status.accumulate("markedCount", markedCount);
  239. status.accumulate("exceptionCount", exceptionCount);
  240. status.accumulate("valid", totalCount > 0);
  241. status.accumulate("topCount", topCount);
  242. return status;
  243. }
  244. @RequestMapping("/gettask")
  245. @ResponseBody
  246. public Task getTask(HttpServletRequest request) {
  247. Marker marker = RequestUtils.getWebUser(request).getMarker();
  248. Task task = null;
  249. try {
  250. lockService.watch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  251. lockService.watch(LockType.MARKER, marker.getId());
  252. MarkGroup group = groupService
  253. .findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  254. if (group == null) {
  255. task = new Task();
  256. task.setExist(false);
  257. task.setMessage("mark.control.task.not.exist");
  258. } else if (group.getStatus() == MarkStatus.FINISH) {
  259. task = new Task();
  260. task.setExist(false);
  261. task.setMessage("mark.control.task.finish");
  262. } else if (group.getStatus() == MarkStatus.TRIAL) {
  263. task = getTrialTask(marker);
  264. } else if (group.getStatus() == MarkStatus.FORMAL) {
  265. task = getFormalTask(marker);
  266. }
  267. if (task == null) {
  268. task = new Task();
  269. task.setExist(false);
  270. task.setMessage("mark.control.task.null");
  271. }
  272. } catch (Exception e) {
  273. log.error("get task error", e);
  274. } finally {
  275. lockService.unwatch(LockType.MARKER, marker.getId());
  276. lockService.unwatch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  277. }
  278. return task;
  279. }
  280. private Task getFormalTask(Marker marker) {
  281. int retry = 1;
  282. Task task = null;
  283. while (task == null) {
  284. List<MarkLibrary> list = new ArrayList<MarkLibrary>();
  285. // 需要判断评卷员是否绑定了班级
  286. list = libraryService.findUnMarked(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber(),
  287. marker.getId(), marker.getClassCount() != null && marker.getClassCount() > 0, retry, 20);
  288. if (list.isEmpty()) {
  289. break;
  290. }
  291. for (MarkLibrary library : list) {
  292. if (markService.applyLibrary(library, marker)) {
  293. task = taskService.build(library);
  294. break;
  295. }
  296. }
  297. if (task == null) {
  298. retry++;
  299. }
  300. }
  301. return task;
  302. }
  303. private Task getTrialTask(Marker marker) {
  304. int retry = 1;
  305. Task task = null;
  306. while (task == null) {
  307. List<TrialLibrary> list = trialService.findUnMarkedLibrary(marker.getExamId(), marker.getSubjectCode(),
  308. marker.getGroupNumber(), marker.getId(), retry, 10);
  309. if (list.isEmpty()) {
  310. break;
  311. }
  312. for (TrialLibrary library : list) {
  313. if (markService.applyLibrary(library, marker)) {
  314. task = taskService.build(library, null);
  315. break;
  316. }
  317. }
  318. retry++;
  319. }
  320. return task;
  321. }
  322. @RequestMapping(value = "/savetask", method = RequestMethod.POST)
  323. @ResponseBody
  324. public JSONObject saveTask(HttpServletRequest request, @RequestBody MarkResult markResult) {
  325. JSONObject result = new JSONObject();
  326. Marker marker = RequestUtils.getWebUser(request).getMarker();
  327. boolean success = false;
  328. try {
  329. lockService.watch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  330. lockService.watch(LockType.STUDENT, markResult.getStudentId());
  331. lockService.watch(LockType.MARKER, marker.getId());
  332. lockService.waitlock(LockType.GROUP_LIBRARY, markResult.getStudentId(), marker.getExamId(),
  333. marker.getSubjectCode(), marker.getGroupNumber());
  334. success = markService.submitTask(markResult, marker);
  335. } catch (Exception e) {
  336. success = false;
  337. log.error("save task error", e);
  338. } finally {
  339. lockService.unlock(LockType.GROUP_LIBRARY, markResult.getStudentId(), marker.getExamId(),
  340. marker.getSubjectCode(), marker.getGroupNumber());
  341. lockService.unwatch(LockType.MARKER, marker.getId());
  342. lockService.unwatch(LockType.STUDENT, markResult.getStudentId());
  343. lockService.unwatch(LockType.GROUP, marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  344. }
  345. result.accumulate("success", success);
  346. result.accumulate("status", status(request));
  347. if (!success) {
  348. result.accumulate("message", "mark.control.tsak.error");
  349. }
  350. return result;
  351. }
  352. @RequestMapping("/gethistory")
  353. @ResponseBody
  354. public Object history(HttpServletRequest request, @RequestParam int pageNumber, @RequestParam int pageSize,
  355. @RequestParam String order, @RequestParam String sort,
  356. @RequestParam(required = false, defaultValue = "false") Boolean isTag,
  357. @RequestParam(required = false) Integer studentId) throws Exception {
  358. Marker marker = RequestUtils.getWebUser(request).getMarker();
  359. List<Task> list = new ArrayList<>();
  360. Direction d = Direction.DESC;
  361. Sort querySort = null;
  362. if (sort.equals("asc")) {
  363. d = Direction.ASC;
  364. }
  365. if (order.equals("time")) {
  366. querySort = new Sort(d, "markerTime");
  367. } else if (order.equals("studentId")) {
  368. querySort = new Sort(d, "studentId");
  369. } else if (order.equals("score")) {
  370. querySort = new Sort(d, "markerScore");
  371. }
  372. MarkGroup group = groupService.findOne(marker.getExamId(), marker.getSubjectCode(), marker.getGroupNumber());
  373. if (group != null && group.getStatus() == MarkStatus.FORMAL) {
  374. // 正评查找已给分的评卷任务
  375. MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
  376. query.setExamId(marker.getExamId());
  377. query.setSubjectCode(marker.getSubjectCode());
  378. query.setMarkerId(marker.getId());
  379. query.addStatus(LibraryStatus.MARKED);
  380. query.addStatus(LibraryStatus.INSPECTED);
  381. query.setGroupNumber(marker.getGroupNumber());
  382. query.setPageNumber(pageNumber);
  383. query.setPageSize(pageSize);
  384. if (querySort != null) {
  385. query.setSort(querySort);
  386. } else {
  387. query.orderByMarkerTimeDesc();
  388. }
  389. if (studentId != null) {
  390. query.setStudentId(studentId);
  391. }
  392. list = taskService.findByQuery(query);
  393. for (Task task : list) {
  394. task.setPrevious(true);
  395. }
  396. } else if (group != null && group.getStatus() == MarkStatus.TRIAL) {
  397. // 试评查找给分历史记录
  398. List<TrialHistory> historyList = new ArrayList<TrialHistory>();
  399. if (studentId != null) {
  400. historyList = trialService.findHistory(marker.getExamId(), marker.getSubjectCode(),
  401. marker.getGroupNumber(), marker.getId(), studentId, pageNumber, pageSize, querySort);
  402. } else {
  403. historyList = trialService.findHistory(marker.getExamId(), marker.getSubjectCode(),
  404. marker.getGroupNumber(), marker.getId(), pageNumber, pageSize, querySort, null);
  405. }
  406. for (TrialHistory history : historyList) {
  407. TrialLibrary library = trialService.findLibrary(history.getLibraryId());
  408. if (library != null) {
  409. Task task = taskService.build(library, history);
  410. task.setPrevious(true);
  411. list.add(task);
  412. }
  413. }
  414. }
  415. return list;
  416. }
  417. @RequestMapping("/change-name")
  418. @ResponseBody
  419. public JSONObject changeName(HttpServletRequest request, @RequestParam String name,
  420. @RequestParam(required = false) String password) {
  421. Marker marker = RequestUtils.getWebUser(request).getMarker();
  422. JSONObject result = new JSONObject();
  423. marker.setName(name);
  424. if (StringUtils.isNotEmpty(password)) {
  425. marker.setPassword(password);
  426. }
  427. marker = markerService.save(marker);
  428. result.accumulate("success", marker != null);
  429. if (marker != null) {
  430. result.accumulate("name", marker.getName());
  431. }
  432. return result;
  433. }
  434. @RequestMapping("/update-setting")
  435. @ResponseBody
  436. public JSONObject updateSetting(HttpServletRequest request, @RequestParam String setting) {
  437. Marker marker = RequestUtils.getWebUser(request).getMarker();
  438. JSONObject result = new JSONObject();
  439. markerService
  440. .updateMarkSetting(marker.getId(), StringEscapeUtils.unescapeHtml(StringUtils.trimToNull(setting)));
  441. result.accumulate("success", true);
  442. return result;
  443. }
  444. private void releaseMarker(Marker marker) {
  445. if (marker == null) {
  446. return;
  447. }
  448. try {
  449. lockService.waitlock(LockType.MARKER, marker.getId());
  450. markService.releaseByMarker(marker);
  451. } catch (Exception e) {
  452. log.error("release marker error", e);
  453. } finally {
  454. lockService.unlock(LockType.MARKER, marker.getId());
  455. }
  456. }
  457. protected String buildPictureConfig(String sheetConfig) {
  458. String json = "";
  459. if (StringUtils.isNotBlank(sheetConfig)) {
  460. try {
  461. ObjectMapper mapper = new ObjectMapper();
  462. json = mapper.writeValueAsString(PictureConfigItem.parse(sheetConfig));
  463. } catch (JsonProcessingException e) {
  464. e.printStackTrace();
  465. }
  466. }
  467. return json;
  468. }
  469. }