|
@@ -0,0 +1,427 @@
|
|
|
+package cn.com.qmth.stmms.api.controller.admin;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Controller;
|
|
|
+import org.springframework.web.bind.annotation.RequestBody;
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
+import org.springframework.web.bind.annotation.RequestParam;
|
|
|
+import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
+
|
|
|
+import com.qmth.boot.core.collection.PageResult;
|
|
|
+
|
|
|
+import cn.com.qmth.stmms.admin.dto.RejectResult;
|
|
|
+import cn.com.qmth.stmms.api.controller.BaseApiController;
|
|
|
+import cn.com.qmth.stmms.biz.exam.bean.LibraryStatusInfo;
|
|
|
+import cn.com.qmth.stmms.biz.exam.bean.MarkLibraryVo;
|
|
|
+import cn.com.qmth.stmms.biz.exam.bean.ResultMessage;
|
|
|
+import cn.com.qmth.stmms.biz.exam.bean.TaskVo;
|
|
|
+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.ExamService;
|
|
|
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
|
|
|
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
|
|
|
+import cn.com.qmth.stmms.biz.exception.StatusException;
|
|
|
+import cn.com.qmth.stmms.biz.lock.LockService;
|
|
|
+import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
|
|
|
+import cn.com.qmth.stmms.biz.mark.model.Task;
|
|
|
+import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
|
|
|
+import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
|
|
|
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
|
|
|
+import cn.com.qmth.stmms.biz.mark.service.TaskService;
|
|
|
+import cn.com.qmth.stmms.biz.user.model.User;
|
|
|
+import cn.com.qmth.stmms.biz.user.service.UserService;
|
|
|
+import cn.com.qmth.stmms.biz.utils.PageUtil;
|
|
|
+import cn.com.qmth.stmms.common.annotation.Logging;
|
|
|
+import cn.com.qmth.stmms.common.domain.ApiUser;
|
|
|
+import cn.com.qmth.stmms.common.enums.LibraryStatus;
|
|
|
+import cn.com.qmth.stmms.common.enums.LockType;
|
|
|
+import cn.com.qmth.stmms.common.enums.LogType;
|
|
|
+import cn.com.qmth.stmms.common.enums.MarkStatus;
|
|
|
+import cn.com.qmth.stmms.common.enums.Role;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import io.swagger.annotations.ApiParam;
|
|
|
+
|
|
|
+@Api(tags = "任务管理")
|
|
|
+@Controller("adminLibraryController")
|
|
|
+@RequestMapping("/api/admin/exam/library")
|
|
|
+public class LibraryController extends BaseApiController {
|
|
|
+
|
|
|
+ protected static Logger log = LoggerFactory.getLogger(LibraryController.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkGroupService groupService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkLibraryService libraryService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkerService markerService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private MarkService markService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private LockService lockService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExamService examService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private UserService userService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TaskService taskService;
|
|
|
+
|
|
|
+ public static final String UN_SELECTIVE_SCORE = "-1";
|
|
|
+
|
|
|
+ private static final String DEFAULT_SECRET_NUMBER = "***";
|
|
|
+
|
|
|
+ @ApiOperation(value = "待复核任务数")
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping(value = "inspected/count", method = RequestMethod.POST)
|
|
|
+ public Long inspectedCount(MarkLibrarySearchQuery query) {
|
|
|
+ long inspectedCount = 0;
|
|
|
+ LibraryStatus status = query.getStatus();
|
|
|
+ if (LibraryStatus.MARKED.equals(status) || status == null) {
|
|
|
+ query.addStatus(LibraryStatus.MARKED);
|
|
|
+ inspectedCount = libraryService.countByQuery(query);
|
|
|
+ }
|
|
|
+ return inspectedCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "任务分页查询")
|
|
|
+ @Logging(menu = "评卷任务查询", type = LogType.QUERY)
|
|
|
+ @ResponseBody
|
|
|
+ @RequestMapping(value = "list", method = RequestMethod.POST)
|
|
|
+ public PageResult<MarkLibraryVo> list(MarkLibrarySearchQuery query) {
|
|
|
+
|
|
|
+ LibraryStatus status = query.getStatus();
|
|
|
+ int examId = getSessionExamId();
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ List<ExamSubject> subjectList = getExamSubject(examId, wu);
|
|
|
+ if (subjectList.isEmpty()) {
|
|
|
+ return PageUtil.emptyPage();
|
|
|
+ }
|
|
|
+ query.setExamId(examId);
|
|
|
+ if (status != null) {
|
|
|
+ query.addStatus(status);
|
|
|
+ }
|
|
|
+ if (status != LibraryStatus.REJECTED) {
|
|
|
+ query.setRejectReason(null);
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(query.getSubjectCode()) && !subjectList.isEmpty()) {
|
|
|
+ query.setSubjectCode(subjectList.get(0).getCode());
|
|
|
+ }
|
|
|
+ query = libraryService.findByQuery(query);
|
|
|
+ List<MarkLibraryVo> ret = new ArrayList<>();
|
|
|
+ for (MarkLibrary library : query.getResult()) {
|
|
|
+ if (library.getMarkerId() != null) {
|
|
|
+ User marker = userService.findByMarkerId(library.getMarkerId());
|
|
|
+ library.setMarkerLoginName(marker.getLoginName() + "/" + marker.getName());
|
|
|
+ if (library.getHeaderId() != null) {
|
|
|
+ User header = userService.findById(library.getHeaderId());
|
|
|
+ library.setHeaderLoginName(header.getLoginName() + "/" + header.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (library.getMarkerScoreList() != null) {
|
|
|
+ library.setMarkerScoreList(library.getMarkerScoreList().replace(UN_SELECTIVE_SCORE, "/"));
|
|
|
+ }
|
|
|
+ ret.add(MarkLibraryVo.of(library));
|
|
|
+ }
|
|
|
+ return PageUtil.of(ret, query);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "打回或重置")
|
|
|
+ @Logging(menu = "打回或重置评卷任务", type = LogType.UPDATE)
|
|
|
+ @RequestMapping(value = "reject", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public ResultMessage reject(@ApiParam("任务id") @RequestParam Integer id,
|
|
|
+ @ApiParam("是否重置") @RequestParam(required = false, defaultValue = "false") boolean isRest,
|
|
|
+ @ApiParam("打回原因") @RequestParam(required = false) String reason) {
|
|
|
+ MarkLibrary library = libraryService.findById(id);
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ if (library != null) {
|
|
|
+ if (subjectCheck(library.getSubjectCode(), wu)) {
|
|
|
+ try {
|
|
|
+ lockService.watch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
|
|
|
+ lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
|
|
|
+ library.getGroupNumber());
|
|
|
+ lockService.waitlock(LockType.STUDENT, library.getStudentId());
|
|
|
+ if ((library.getStatus().equals(LibraryStatus.MARKED)
|
|
|
+ || library.getStatus().equals(LibraryStatus.PROBLEM)
|
|
|
+ || library.getStatus().equals(LibraryStatus.INSPECTED))
|
|
|
+ && markService.rejectLibrary(library, wu.getUser().getId(), reason, isRest)) {
|
|
|
+ return resultOk();
|
|
|
+ } else {
|
|
|
+ throw new StatusException("无法打回该评卷任务");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("back library error", e);
|
|
|
+ throw new StatusException("打回评卷任务失败");
|
|
|
+ } finally {
|
|
|
+ lockService.unlock(LockType.STUDENT, library.getStudentId());
|
|
|
+ lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
|
|
|
+ library.getGroupNumber());
|
|
|
+ lockService.unwatch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new StatusException("没有操作该评卷任务的权限");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new StatusException("该评卷任务不存在");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "获取复核任务")
|
|
|
+ @Logging(menu = "开始任务复核", type = LogType.QUERY)
|
|
|
+ @RequestMapping(value = "get-task", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public TaskVo getTask(MarkLibrarySearchQuery query) {
|
|
|
+ int examId = getSessionExamId();
|
|
|
+ MarkGroup group = groupService.findOne(examId, query.getSubjectCode(), query.getGroupNumber());
|
|
|
+ Exam exam = examService.findById(examId);
|
|
|
+ if (group == null) {
|
|
|
+ return null;
|
|
|
+ } else if (group.getStatus() == MarkStatus.FINISH) {
|
|
|
+ return null;
|
|
|
+ } else if (group.getStatus() == MarkStatus.TRIAL) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Task task = null;
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ int retry = 1;
|
|
|
+ while (task == null) {
|
|
|
+ query.setExamId(examId);
|
|
|
+ query.addStatus(LibraryStatus.MARKED);
|
|
|
+ query.setPageNumber(retry);
|
|
|
+ query.setPageSize(20);
|
|
|
+ query = libraryService.findByQuery(query);
|
|
|
+ if (query.getResult().isEmpty()) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ for (MarkLibrary library : query.getResult()) {
|
|
|
+ if (libraryService.applyLibrary(library, wu.getUser().getId())) {
|
|
|
+ task = taskService.build(library);
|
|
|
+ if (exam.isForbiddenInfo() && !Role.SCHOOL_ADMIN.equals(wu.getRole())) {
|
|
|
+ task.setSecretNumber(DEFAULT_SECRET_NUMBER);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (task == null) {
|
|
|
+ retry++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return TaskVo.of(task);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "复核")
|
|
|
+ @Logging(menu = "考生评卷复核", type = LogType.UPDATE)
|
|
|
+ @RequestMapping(value = "inspected/save", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public ResultMessage save(@RequestParam Integer libraryId) {
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ MarkLibrary library = libraryService.findById(libraryId);
|
|
|
+ try {
|
|
|
+ if (libraryId != null && library.getStatus().equals(LibraryStatus.MARKED)
|
|
|
+ && libraryService.hasApplied(library, wu.getUser().getId())) {
|
|
|
+ library.setHeaderId(wu.getUser().getId());
|
|
|
+ library.setHeaderTime(new Date());
|
|
|
+ library.setStatus(LibraryStatus.INSPECTED);
|
|
|
+ libraryService.save(library);
|
|
|
+ libraryService.releaseByLibrary(library);
|
|
|
+ return resultOk();
|
|
|
+ } else {
|
|
|
+ throw new StatusException("无法复核,请刷新页面");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("inspected library save error", e);
|
|
|
+ throw new StatusException("无法复核,请刷新页面");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "任务释放")
|
|
|
+ @RequestMapping(value = "clear", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public ResultMessage clear(@RequestParam String subjectCode, @RequestParam Integer groupNumber,
|
|
|
+ @RequestParam(required = false) Integer libraryId) {
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ if (libraryId != null) {
|
|
|
+ releaseLibrary(libraryId);
|
|
|
+ return resultOk();
|
|
|
+ } else {
|
|
|
+ int examId = getSessionExamId();
|
|
|
+ releaseUser(examId, subjectCode, groupNumber, wu.getUser().getId());
|
|
|
+ return resultOk();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "获取状态信息")
|
|
|
+ @RequestMapping(value = "get-status", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public LibraryStatusInfo status(MarkLibrarySearchQuery query) {
|
|
|
+ LibraryStatusInfo status = new LibraryStatusInfo();
|
|
|
+ int examId = getSessionExamId();
|
|
|
+ query.setExamId(examId);
|
|
|
+ query.addStatus(LibraryStatus.MARKED);
|
|
|
+ long inspectedCount = libraryService.countByQuery(query);
|
|
|
+ status.setTotalCount(inspectedCount);
|
|
|
+ status.setValid(true);
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void releaseUser(Integer examId, String subjectCode, Integer groupNumber, Integer userId) {
|
|
|
+ try {
|
|
|
+ libraryService.releaseByUserId(examId, subjectCode, groupNumber, userId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("release user error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void releaseLibrary(Integer libraryId) {
|
|
|
+ try {
|
|
|
+ MarkLibrary library = libraryService.findById(libraryId);
|
|
|
+ libraryService.releaseByLibrary(library);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("release library error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "打回")
|
|
|
+ @Logging(menu = "打回", type = LogType.UPDATE)
|
|
|
+ @RequestMapping(value = "rejected", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public ResultMessage rejected(@RequestBody RejectResult rejectResult) {
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ MarkLibrary library = libraryService.findById(rejectResult.getLibraryId());
|
|
|
+ if (library != null) {
|
|
|
+ if (subjectCheck(library.getSubjectCode(), wu)) {
|
|
|
+ try {
|
|
|
+ lockService.watch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
|
|
|
+ lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
|
|
|
+ library.getGroupNumber());
|
|
|
+ lockService.waitlock(LockType.STUDENT, library.getStudentId());
|
|
|
+ if (((libraryService.hasApplied(library, wu.getUser().getId())
|
|
|
+ && (library.getStatus().equals(LibraryStatus.MARKED))
|
|
|
+ || library.getStatus().equals(LibraryStatus.INSPECTED))
|
|
|
+ && markService.rejectLibrary(library, rejectResult.getQuestionList(), wu.getUser().getId(),
|
|
|
+ rejectResult.getReason()))) {
|
|
|
+ libraryService.releaseByLibrary(library);
|
|
|
+ return resultOk();
|
|
|
+ } else {
|
|
|
+ throw new StatusException("无法打回该评卷任务");
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("back library error", e);
|
|
|
+ throw new StatusException("打回评卷任务失败");
|
|
|
+ } finally {
|
|
|
+ lockService.unlock(LockType.STUDENT, library.getStudentId());
|
|
|
+ lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
|
|
|
+ library.getGroupNumber());
|
|
|
+ lockService.unwatch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new StatusException("没有操作该评卷任务的权限");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new StatusException("该评卷任务不存在");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "回看评卷复核任务")
|
|
|
+ @Logging(menu = "回看评卷复核任务", type = LogType.QUERY)
|
|
|
+ @RequestMapping(value = "get-history", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public List<TaskVo> getHistory(@RequestParam String subjectCode, @RequestParam Integer groupNumber,
|
|
|
+ @RequestParam int pageNumber, @RequestParam int pageSize) {
|
|
|
+ int examId = getSessionExamId();
|
|
|
+ Exam exam = examService.findById(examId);
|
|
|
+ ApiUser wu = getApiUser();
|
|
|
+ List<TaskVo> list = new ArrayList<>();
|
|
|
+ MarkLibrarySearchQuery query = new MarkLibrarySearchQuery();
|
|
|
+ query.setExamId(examId);
|
|
|
+ query.setSubjectCode(subjectCode);
|
|
|
+ query.setGroupNumber(groupNumber);
|
|
|
+ query.addStatus(LibraryStatus.INSPECTED);
|
|
|
+ query.setHeaderId(wu.getUser().getId());
|
|
|
+ query.setPageNumber(pageNumber);
|
|
|
+ query.setPageSize(pageSize);
|
|
|
+ query.orderByHeaderTimeDesc();
|
|
|
+ query = libraryService.findByQuery(query);
|
|
|
+ for (MarkLibrary library : query.getResult()) {
|
|
|
+ Task task = taskService.build(library);
|
|
|
+ if (exam.isForbiddenInfo() && !Role.SCHOOL_ADMIN.equals(wu.getRole())) {
|
|
|
+ task.setSecretNumber(DEFAULT_SECRET_NUMBER);
|
|
|
+ }
|
|
|
+ task.setPrevious(true);
|
|
|
+ list.add(TaskVo.of(task));
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "评卷员任务指定")
|
|
|
+ @Logging(menu = "评卷员任务指定", type = LogType.UPDATE)
|
|
|
+ @RequestMapping(value = "assigned", method = RequestMethod.POST)
|
|
|
+ @ResponseBody
|
|
|
+ public ResultMessage assigned(@RequestParam Integer libraryId, @RequestParam String marker) {
|
|
|
+ User user = userService.findByLoginName(marker);
|
|
|
+ if (user == null || !Role.MARKER.equals(user.getRole())) {
|
|
|
+ throw new StatusException("指定失败,未找到评卷员");
|
|
|
+ }
|
|
|
+ MarkLibrary library = libraryService.findById(libraryId);
|
|
|
+ if (library == null) {
|
|
|
+ throw new StatusException("指定失败,未找到评卷任务");
|
|
|
+ }
|
|
|
+ MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
|
|
|
+ try {
|
|
|
+ lockService.watch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
|
|
|
+ lockService.watch(LockType.GROUP, library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
|
|
|
+ lockService.waitlock(LockType.STUDENT, library.getStudentId());
|
|
|
+ Marker mk = markerService.findByExamAndSubjectAndNumberAndUserId(library.getExamId(),
|
|
|
+ library.getSubjectCode(), library.getGroupNumber(), user.getId());
|
|
|
+ if (mk == null) {
|
|
|
+ throw new StatusException("指定失败,评卷员不在该任务分组");
|
|
|
+ }
|
|
|
+ if (library.getMarkerId().equals(mk.getId())) {
|
|
|
+ throw new StatusException("指定失败,当前任务已属于该评卷员");
|
|
|
+ }
|
|
|
+ if (group.getDoubleRate() != null && group.getDoubleRate() > 0) {
|
|
|
+ List<MarkLibrary> libraryList = libraryService.findByStudentAndGroup(library.getStudentId(),
|
|
|
+ library.getGroupNumber());
|
|
|
+ for (MarkLibrary l : libraryList) {
|
|
|
+ if (mk.getId().equals(l.getMarkerId())) {
|
|
|
+ throw new StatusException("指定失败,当前任务已属于该评卷员");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ markService.releaseByLibrary(library);
|
|
|
+ if (markService.applyLibrary(library, mk)) {
|
|
|
+ library = libraryService.findById(libraryId);
|
|
|
+ if (!LibraryStatus.WAITING.equals(library.getStatus())
|
|
|
+ && !LibraryStatus.REJECTED.equals(library.getStatus())) {
|
|
|
+ throw new StatusException("指定失败,当前任务已评");
|
|
|
+ }
|
|
|
+ libraryService.assigned(library.getId(), mk.getId());
|
|
|
+ return resultOk();
|
|
|
+ } else {
|
|
|
+ throw new StatusException("指定失败,请更换评卷员重试");
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ lockService.unlock(LockType.STUDENT, library.getStudentId());
|
|
|
+ lockService.unwatch(LockType.GROUP, library.getExamId(), library.getSubjectCode(),
|
|
|
+ library.getGroupNumber());
|
|
|
+ lockService.unwatch(LockType.EXAM_SUBJECT, library.getExamId(), library.getSubjectCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|