Explorar o código

分组管理、评卷管理

yin hai 11 horas
pai
achega
ef3b776039

+ 53 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/MarkInfoVo.java

@@ -0,0 +1,53 @@
+package cn.com.qmth.stmms.biz.exam.bean;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.common.enums.MarkMode;
+import io.swagger.annotations.ApiModelProperty;
+
+public class MarkInfoVo {
+
+    @ApiModelProperty("未评卷数量")
+    private long unMarkedCount;
+
+    @ApiModelProperty("评卷数量")
+    private long markedCount;
+
+    @ApiModelProperty("科目未完成数量")
+    private long unSubjectFinishCount;
+
+    @ApiModelProperty("科目完成数量")
+    private long subjectFinishCount;
+
+    public long getUnMarkedCount() {
+        return unMarkedCount;
+    }
+
+    public void setUnMarkedCount(long unMarkedCount) {
+        this.unMarkedCount = unMarkedCount;
+    }
+
+    public long getMarkedCount() {
+        return markedCount;
+    }
+
+    public void setMarkedCount(long markedCount) {
+        this.markedCount = markedCount;
+    }
+
+    public long getUnSubjectFinishCount() {
+        return unSubjectFinishCount;
+    }
+
+    public void setUnSubjectFinishCount(long unSubjectFinishCount) {
+        this.unSubjectFinishCount = unSubjectFinishCount;
+    }
+
+    public long getSubjectFinishCount() {
+        return subjectFinishCount;
+    }
+
+    public void setSubjectFinishCount(long subjectFinishCount) {
+        this.subjectFinishCount = subjectFinishCount;
+    }
+}

+ 592 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/MarkGroupController.java

@@ -0,0 +1,592 @@
+package cn.com.qmth.stmms.api.controller.admin;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+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.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Transactional;
+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.exception.StatusException;
+
+import cn.com.qmth.stmms.admin.thread.MarkGroupDeleteThread;
+import cn.com.qmth.stmms.api.controller.BaseApiController;
+import cn.com.qmth.stmms.biz.config.service.impl.SystemCache;
+import cn.com.qmth.stmms.biz.exam.bean.ResultMessage;
+import cn.com.qmth.stmms.biz.exam.dao.SelectiveStudentDao;
+import cn.com.qmth.stmms.biz.exam.model.*;
+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.MarkConfigItem;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
+import cn.com.qmth.stmms.biz.school.model.School;
+import cn.com.qmth.stmms.biz.school.service.SchoolService;
+import cn.com.qmth.stmms.common.annotation.Logging;
+import cn.com.qmth.stmms.common.domain.ApiUser;
+import cn.com.qmth.stmms.common.enums.*;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+import net.sf.json.JsonConfig;
+
+@Api(tags = "分组管理")
+@Controller("adminExamGroupController")
+@RequestMapping("/api/admin/exam/group")
+public class MarkGroupController extends BaseApiController {
+
+    protected static Logger log = LoggerFactory.getLogger(MarkGroupController.class);
+
+    public static final String SPLIT = ",";
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private ExamStudentService studentService;
+
+    @Autowired
+    private MarkService markService;
+
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private FileService fileService;
+
+    @Autowired
+    private SelectiveGroupService selectiveGroupService;
+
+    @Autowired
+    private InspectHistoryService inspectHistoryService;
+
+    @Autowired
+    private SchoolService schoolService;
+
+    @Qualifier("task-executor")
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
+    @Value("${mark.group.delete}")
+    private String markDeleteCode;
+
+    @Autowired
+    private SystemCache systemCache;
+
+    @Autowired
+    private SelectiveStudentDao selectiveStudentDao;
+
+    @ApiOperation(value = "分组查询")
+    @Logging(menu = "大题查询", type = LogType.QUERY)
+    @RequestMapping(value = "query", method = RequestMethod.POST)
+    @ResponseBody
+    public List<MarkGroup> query(@RequestParam String subjectCode) {
+        ApiUser wu = getApiUser();
+        int examId = getSessionExamId();
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        if (subject == null) {
+            throw new StatusException("科目不能为空");
+        }
+        List<MarkGroup> list = groupService.findByExamAndSubject(examId, subject.getCode());
+        for (MarkGroup group : list) {
+            List<ExamQuestion> qList = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
+                    subject.getCode(), false, group.getNumber());
+            group.setQuestionList(qList);
+            group.setMarkerCount(
+                    markerService.countByExamAndSubjectAndGroup(examId, subject.getCode(), group.getNumber()));
+            group.setCurrentCount(markService.applyCount(group));
+            int percent = group.getLibraryCount() > 0
+                    ? (int) (group.getMarkedCount() * 100.00 / group.getLibraryCount())
+                    : 0;
+            if (group.getMarkedCount() > 0 && percent == 0) {
+                percent = 1;
+            } else if (group.getLeftCount() > 0 && percent == 100) {
+                percent = 99;
+            }
+            group.setPercent(percent);
+            group.setDeleting(lockService.isLocked(LockType.GROUP_DELETE, group.getExamId(), group.getSubjectCode(),
+                    group.getNumber()));
+            if (!qList.isEmpty() && group.isSelective()) {
+                SelectiveGroup selectiveGroup = selectiveGroupService.findOne(examId, group.getSubjectCode(),
+                        qList.get(0).getMainNumber());
+                if (selectiveGroup != null) {
+                    group.setSelectiveIndex(selectiveGroup.getSelectiveIndex());
+                }
+            }
+        }
+        return list;
+    }
+
+    @ApiOperation(value = "分组下拉查询")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    @ResponseBody
+    public List<MarkGroup> list(@RequestParam String subjectCode, @RequestParam(required = false) Boolean withDouble,
+            @RequestParam(required = false) MarkStatus status) {
+        int examId = getSessionExamId();
+        List<MarkGroup> list = withDouble != null && withDouble
+                ? groupService.findByExamAndSubjectWithDouble(examId, subjectCode)
+                : (status != null ? groupService.findByExamAndSubjectAndStatus(examId, subjectCode, status)
+                        : groupService.findByExamAndSubject(examId, subjectCode));
+        for (MarkGroup group : list) {
+            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode,
+                    false, group.getNumber()));
+        }
+        return list;
+    }
+
+    @ApiOperation(value = "新增分组")
+    @Logging(menu = "新增大题", type = LogType.ADD)
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    @Transactional
+    @ResponseBody
+    public ResultMessage insert(@RequestParam String subjectCode, @RequestParam Integer number,
+            @RequestParam Integer[] questionIds, @RequestParam String picList,
+            @RequestParam(required = false) Double doubleRate,
+            @RequestParam(required = false) Double arbitrateThreshold,
+            @RequestParam(required = false) Integer thirdPolicy, @RequestParam(required = false) Integer scorePolicy,
+            @RequestParam(required = false) String arbitrateThresholdList,
+            @RequestParam(required = false) Integer arbitrateType, @RequestParam(required = false) String markMode,
+            @RequestParam(required = false) Integer trialCount,
+            @RequestParam(required = false, defaultValue = "false") boolean sheetView,
+            @RequestParam(defaultValue = "false") boolean enableAllZero) {
+        int examId = getSessionExamId();
+        Exam exam = examService.findById(examId);
+        MarkGroup group = groupService.findOne(examId, subjectCode, number);
+        if (group != null) {
+            throw new StatusException("评卷分组序号不能重复");
+        } else if (questionIds == null || questionIds.length <= 0) {
+            throw new StatusException("题目不能为空");
+        } else {
+            try {
+                // create group
+                // build picList
+                List<MarkConfigItem> picConfigList = null;
+                if (!exam.getType().equals(ExamType.MULTI_MEDIA)) {
+                    picList = StringEscapeUtils.unescapeHtml(StringUtils.trimToNull(picList));
+                    JSONArray array = JSONArray.fromObject(picList);
+                    picConfigList = JSONArray.toList(array, new MarkConfigItem(), new JsonConfig());
+                }
+                List<ExamQuestion> list = new ArrayList<ExamQuestion>();
+                BigDecimal totalScore = BigDecimal.ZERO;
+                boolean selective = false;
+                List<Double> arbitrateThresholds = buildDoubleList(arbitrateThresholdList);
+                for (int i = 0; i < questionIds.length; i++) {
+                    Integer questionId = questionIds[i];
+                    ExamQuestion question = questionService.findById(questionId);
+                    question.setGroupNumber(number);
+                    if (doubleRate != null && doubleRate > 0
+                            && ArbitrateType.QUESTION.equals(ArbitrateType.findByValue(arbitrateType))) {
+                        question.setArbitrateThreshold(arbitrateThresholds.get(i));
+                    } else {
+                        question.setArbitrateThreshold(null);
+                    }
+                    list.add(question);
+                    totalScore = totalScore.add(BigDecimal.valueOf(question.getTotalScore()));
+                    if (selective == false
+                            && selectiveGroupService.findOne(examId, subjectCode, question.getMainNumber()) != null) {
+                        selective = true;
+                    }
+                }
+                if (trialCount != null && trialCount > 0) {
+                    subjectService.updateTrialCount(examId, subjectCode, trialCount);
+                }
+                if (this.groupService.countByExamAndSubjectAndStatus(examId, subjectCode, MarkStatus.TRIAL) > 0) {
+                    ExamSubject subject = subjectService.find(examId, subjectCode);
+                    trialCount = subject.getTrialCount();
+                }
+                group = new MarkGroup(examId, subjectCode, number, picConfigList, totalScore.doubleValue(), doubleRate,
+                        arbitrateThreshold, scorePolicy, arbitrateType, markMode, trialCount, sheetView, enableAllZero,
+                        thirdPolicy, selective);
+                // clear and replace exam_question
+                questionService.save(list);
+                groupService.save(group);
+
+                studentService.updateSubjectiveStatusAndScore(examId, subjectCode, SubjectiveStatus.UNMARK, 0, null);
+                inspectHistoryService.deleteByExamIdAndSubjectCode(examId, subjectCode);
+            } catch (Exception e) {
+                log.error("add markgroup error", e.getMessage());
+                e.printStackTrace();
+                throw new StatusException("新增失败!失败信息:" + e.getMessage());
+            }
+        }
+        return resultOk();
+    }
+
+    @ApiOperation(value = "分组修改")
+    @Logging(menu = "分组修改", type = LogType.UPDATE)
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    @Transactional
+    @ResponseBody
+    public ResultMessage update(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer number, @RequestParam Boolean reset, @RequestParam(required = false) String picList,
+            @RequestParam(required = false) Double doubleRate,
+            @RequestParam(required = false) Double arbitrateThreshold,
+            @RequestParam(required = false) Integer thirdPolicy, @RequestParam(required = false) Integer scorePolicy,
+            @RequestParam(required = false) Integer arbitrateType, @RequestParam(required = false) MarkMode markMode,
+            @RequestParam(required = false) Integer trialCount,
+            @RequestParam(required = false, defaultValue = "false") Boolean sheetView,
+            @RequestParam(required = false, defaultValue = "false") Boolean enableAllZero,
+            @RequestParam(required = false) Integer[] questionIds,
+            @RequestParam(required = false) String intervalScoreList,
+            @RequestParam(required = false) String arbitrateThresholdList,
+            @RequestParam(required = false) String deleteCode) {
+        int examId = getSessionExamId();
+        Exam exam = examService.findById(examId);
+        MarkGroup group = groupService.findOne(examId, subjectCode, number);
+        if (group != null) {
+            try {
+                if (questionIds != null && reset.booleanValue()) {
+                    // advance update
+                    School school = schoolService.findById(exam.getSchoolId());
+                    boolean warn = systemCache.isGroupDeleteWarn() ? true : school.isGroupDeleteCheck();
+                    if (warn && group.getLibraryCount() != 0 && group.getLeftCount() == 0
+                            && !markDeleteCode.equals(deleteCode)) {
+                        throw new StatusException("分组授权码不正确");
+                    }
+                    List<ExamQuestion> questionList = new ArrayList<ExamQuestion>();
+                    ArbitrateType at = arbitrateType != null ? ArbitrateType.findByValue(arbitrateType)
+                            : ArbitrateType.GROUP;
+                    if (ArbitrateType.QUESTION.equals(at)) {
+                        arbitrateThreshold = null;
+                    }
+                    List<Double> arbitrateThresholds = buildDoubleList(arbitrateThresholdList);
+                    boolean selective = false;
+                    for (int i = 0; i < questionIds.length; i++) {
+                        ExamQuestion question = questionService.findById(questionIds[i]);
+                        if (doubleRate != null && doubleRate > 0 && ArbitrateType.QUESTION.equals(at)) {
+                            question.setArbitrateThreshold(arbitrateThresholds.get(i));
+                        } else {
+                            question.setArbitrateThreshold(null);
+                        }
+                        questionList.add(question);
+                        if (selective == false && selectiveGroupService.findOne(examId, subjectCode,
+                                question.getMainNumber()) != null) {
+                            selective = true;
+                        }
+                    }
+                    if (!questionList.isEmpty()) {
+                        ScorePolicy policy = scorePolicy != null ? ScorePolicy.findByValue(scorePolicy) : null;
+                        ThirdPolicy third = thirdPolicy != null ? ThirdPolicy.findByValue(thirdPolicy)
+                                : ThirdPolicy.DISABLE;
+                        try {
+                            lockService.waitlock(LockType.GROUP, true, group.getExamId(), group.getSubjectCode(),
+                                    group.getNumber());
+                            markService.updateGroup(group, questionList, policy, at, third, selective);
+                            RequestUtils.setLog(request, "重置分组,科目代码:" + subjectCode + " 分组号:" + number);
+                        } catch (Exception e) {
+                            log.error("update group error", e);
+                            throw new StatusException("重置更新大题失败" + e.getMessage());
+                        } finally {
+                            lockService.unlock(LockType.GROUP, true, group.getExamId(), group.getSubjectCode(),
+                                    group.getNumber());
+                        }
+                    }
+                } else {
+                    // simple update
+                    List<Double> intervalScores = buildDoubleList(intervalScoreList);
+                    List<Double> arbitrateThresholds = buildDoubleList(arbitrateThresholdList);
+                    List<ExamQuestion> questionList = questionService
+                            .findByExamAndSubjectAndObjectiveAndGroupNumber(examId, subjectCode, false, number);
+                    if (intervalScores.size() == questionList.size()) {
+                        for (int i = 0; i < questionList.size(); i++) {
+                            ExamQuestion q = questionList.get(i);
+                            q.setIntervalScore(intervalScores.get(i));
+                            if (doubleRate != null && doubleRate > 0
+                                    && ArbitrateType.QUESTION.equals(group.getArbitrateType())) {
+                                q.setArbitrateThreshold(arbitrateThresholds.get(i));
+                            } else {
+                                q.setArbitrateThreshold(null);
+                            }
+                            questionService.save(q);
+                        }
+                    }
+                }
+                // quick update
+                picList = StringEscapeUtils.unescapeHtml(picList);
+                JSONArray array = JSONArray.fromObject(picList);
+                List<MarkConfigItem> list = JSONArray.toList(array, new MarkConfigItem(), new JsonConfig());
+                if (list != null && !list.isEmpty()) {
+                    groupService.updatePicList(examId, subjectCode, number, list);
+                }
+                groupService.updateDoubleRate(examId, subjectCode, number, doubleRate);
+                groupService.updateArbitrateThreshold(examId, subjectCode, number, arbitrateThreshold);
+                groupService.updateMarkMode(examId, subjectCode, number, markMode);
+                if (sheetView != null) {
+                    groupService.updateSheetView(examId, subjectCode, number, sheetView);
+                }
+                if (enableAllZero != null) {
+                    groupService.updateEnableAllZero(examId, subjectCode, number, enableAllZero);
+                }
+                return resultOk();
+            } catch (Exception e) {
+                log.error("edit markgroup error", e);
+                e.printStackTrace();
+                throw new StatusException("更新分组!失败信息:" + e.getMessage());
+            }
+        } else {
+            throw new StatusException("找不到对应大题");
+        }
+    }
+
+    private List<Double> buildDoubleList(String content) {
+        List<Double> list = new ArrayList<Double>();
+        content = StringUtils.trimToNull(content);
+        if (content != null) {
+            String[] values = StringUtils.split(content, ",");
+            if (values != null) {
+                for (String value : values) {
+                    try {
+                        Double number = Double.valueOf(value);
+                        if (number != null) {
+                            list.add(number);
+                        }
+                    } catch (Exception e) {
+                        continue;
+                    }
+                }
+            }
+        }
+        return list;
+    }
+
+    @ApiOperation(value = "分组状态修改")
+    @Logging(menu = "大题状态修改", type = LogType.QUERY)
+    @RequestMapping(value = "/changeStatus", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage changeStatus(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer number, @RequestParam MarkStatus status) {
+        int examId = getSessionExamId(request);
+        MarkGroup markGroup = groupService.findOne(examId, subjectCode, number);
+        if (markGroup == null) {
+            throw new StatusException("找不到对应大题");
+        }
+        boolean allow = false;
+        if (markGroup.getStatus() == MarkStatus.TRIAL && status == MarkStatus.FORMAL) {
+            allow = true;
+        } else if (markGroup.getStatus() == MarkStatus.FORMAL && status == MarkStatus.FINISH
+                && markGroup.getLeftCount() == 0
+                && selectiveStudentDao.countByExamIdAndSubjectCodeAndLessSelectiveOrNotSelective(markGroup.getExamId(),
+                        markGroup.getSubjectCode(), true, true) == 0) {
+            allow = true;
+        } else if (markGroup.getStatus() == MarkStatus.FINISH && status == MarkStatus.FORMAL) {
+            allow = true;
+        }
+        if (!allow) {
+            throw new StatusException("不能切换到指定的评卷状态,评卷未完成或存在选做异常");
+        }
+        if (markGroup.getStatus() == MarkStatus.TRIAL && status == MarkStatus.FORMAL) {
+            List<MarkGroup> list = groupService.findByExamAndSubjectAndStatus(examId, subjectCode, MarkStatus.TRIAL);
+            for (MarkGroup group : list) {
+                updateStatus(group, status);
+            }
+            markService.groupTrialToFormal(examId, subjectCode);
+        } else {
+            updateStatus(markGroup, status);
+        }
+        return resultOk();
+    }
+
+    private void updateStatus(MarkGroup group, MarkStatus status) {
+        try {
+            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+            if (groupService.updateStatus(group.getExamId(), group.getSubjectCode(), group.getNumber(), status,
+                    group.getStatus())) {
+                if (status == MarkStatus.FORMAL) {
+                    // 切换到正评成功后刷新任务数量
+                    group.setStatus(status);
+                    markService.updateLibraryCount(group);
+                    markService.updateMarkedCount(group);
+                    markerService.logoutByExamIdAndSubjectCodeAndGroupNumber(group.getExamId(), group.getSubjectCode(),
+                            group.getNumber());
+                } else if (status == MarkStatus.FINISH) {
+                    // 结束时判断是否全部完成统分
+                    long unGroupQuestionCount = questionService.countByExamIdAndSubjectAndObjectiveAndGroupNumberIsNull(
+                            group.getExamId(), group.getSubjectCode(), false);
+                    // 考生整体状态与总分更新
+                    long groupCount = groupService.countByExamAndSubjectAndStatus(group.getExamId(),
+                            group.getSubjectCode(), MarkStatus.TRIAL, MarkStatus.FORMAL);
+                    if (unGroupQuestionCount > 0 || groupCount > 0) {
+                        return;
+                    }
+                    groupCount = groupService.countByExamAndSubject(group.getExamId(), group.getSubjectCode());
+                    List<Integer> studentList = studentService
+                            .findIdByExamIdAndSubjectCodeAndSubjectiveStatusAndUploadAndAbsentAndBreach(
+                                    group.getExamId(), group.getSubjectCode(), SubjectiveStatus.UNMARK, true, false,
+                                    false);
+                    for (Integer studentId : studentList) {
+                        lockService.waitlock(LockType.STUDENT, studentId);
+                        markService.checkStudentSubjective(studentId, groupCount, unGroupQuestionCount);
+                        lockService.unlock(LockType.STUDENT, studentId);
+                    }
+                }
+            }
+
+        } finally {
+            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+        }
+    }
+
+    @ApiOperation(value = "分组数量校对")
+    @Logging(menu = "大题数量校对", type = LogType.UPDATE)
+    @RequestMapping(value = "/checkCount", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage ckeckCount(@RequestParam String subjectCode) {
+        int examId = getSessionExamId();
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        if (subject == null) {
+            throw new StatusException("找不到对应科目");
+        }
+        markService.updateAllCount(examId, subjectCode);
+        return resultOk();
+    }
+
+    @ApiOperation(value = "分组任务回收")
+    @Logging(menu = "大题任务回收", type = LogType.UPDATE)
+    @RequestMapping(value = "/release", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage release(@RequestParam String subjectCode, @RequestParam Integer number) {
+        int examId = getSessionExamId();
+        MarkGroup group = groupService.findOne(examId, subjectCode, number);
+        if (group == null) {
+            throw new StatusException("找不到大题");
+        }
+        try {
+            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+            markService.releaseByGroup(group);
+        } finally {
+            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+        }
+        return resultOk();
+    }
+
+    @ApiOperation(value = "分组重置")
+    @Logging(menu = "分组重置", type = LogType.UPDATE)
+    @RequestMapping(value = "/reset", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage reset(@RequestParam String subjectCode, @RequestParam Integer number) {
+        int examId = getSessionExamId();
+        MarkGroup group = groupService.findOne(examId, subjectCode, number);
+        if (group == null) {
+            throw new StatusException("找不到大题");
+        }
+        try {
+            lockService.waitlock(LockType.EXAM_SUBJECT, group.getExamId(), group.getSubjectCode());
+            lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+            markService.resetByGroup(group);
+        } catch (Exception e) {
+            log.error("reset group error", e);
+            e.printStackTrace();
+            throw new StatusException("重置大题失败", e);
+        } finally {
+            lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+            lockService.unlock(LockType.EXAM_SUBJECT, group.getExamId(), group.getSubjectCode());
+        }
+        return resultOk();
+    }
+
+    @ApiOperation(value = "分组删除")
+    @Logging(menu = "分组重置-删除", type = LogType.DELETE)
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage delete(HttpServletRequest request, @RequestParam String subjectCode,
+            @RequestParam Integer number, @RequestParam(required = false) String deleteCode) {
+        int examId = getSessionExamId();
+        MarkGroup group = groupService.findOne(examId, subjectCode, number);
+        if (group == null) {
+            throw new StatusException("找不到大题");
+        }
+        Exam exam = examService.findById(examId);
+        School school = schoolService.findById(exam.getSchoolId());
+        boolean warn = systemCache.isGroupDeleteWarn() ? true : school.isGroupDeleteCheck();
+        if (warn && group.getLibraryCount() != 0 && group.getLeftCount() == 0 && !markDeleteCode.equals(deleteCode)) {
+            throw new StatusException("删除分组授权码不正确");
+        }
+        if (lockService.trylock(LockType.GROUP_DELETE, group.getExamId(), group.getSubjectCode(), group.getNumber())) {
+            taskExecutor.submit(new MarkGroupDeleteThread(group, markService, lockService));
+            RequestUtils.setLog(request, "删除分组,科目代码:" + subjectCode + " 分组号:" + number);
+        }
+        return resultOk();
+    }
+
+    @ApiOperation(value = "分组关闭")
+    @Logging(menu = "大题关闭", type = LogType.QUERY)
+    @RequestMapping(value = "/finish", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage finish(@RequestParam String subjectCode, @RequestParam Integer[] groupNumbers) {
+        int examId = getSessionExamId();
+        String messages = "";
+        for (Integer number : groupNumbers) {
+            MarkGroup group = groupService.findOne(examId, subjectCode, number);
+            if (group == null || group.getStatus() == MarkStatus.FINISH) {
+                continue;
+            }
+            try {
+                lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+                if (group.getStatus() == MarkStatus.FORMAL && group.getLeftCount() == 0
+                        && selectiveStudentDao.countByExamIdAndSubjectCodeAndLessSelectiveOrNotSelective(
+                                group.getExamId(), group.getSubjectCode(), true, true) == 0) {
+                    groupService.updateStatus(examId, subjectCode, number, MarkStatus.FINISH, group.getStatus());
+                } else {
+                    messages = "评卷未完成或选做题异常,无法关闭分组";
+                }
+            } finally {
+                lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+            }
+        }
+        if (StringUtils.isNotBlank(messages)) {
+            throw new StatusException(messages);
+        }
+        return resultOk();
+    }
+
+    @ApiOperation(value = "设置试评数量")
+    @Logging(menu = "设置试评数量", type = LogType.UPDATE)
+    @RequestMapping(value = "/updateTrialCount", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage updateTrialCount(@RequestParam String subjectCode, @RequestParam Integer trialCount) {
+        int examId = getSessionExamId();
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        JSONObject obj = new JSONObject();
+        if (subject == null) {
+            throw new StatusException("科目不能为空");
+        }
+        long groupCount = groupService.countByExamAndSubjectAndStatus(examId, subjectCode, MarkStatus.TRIAL);
+        if (groupCount == 0) {
+            throw new StatusException("试评分组不能为空");
+        }
+        if (subject.getTrialCount() > trialCount) {
+            throw new StatusException("设置数量请大于" + subject.getTrialCount());
+        } else {
+            subjectService.updateTrialCount(examId, subjectCode, trialCount);
+        }
+        return resultOk();
+    }
+}

+ 287 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/MarkInfoController.java

@@ -0,0 +1,287 @@
+package cn.com.qmth.stmms.api.controller.admin;
+
+import java.text.DecimalFormat;
+import java.util.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.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.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 com.qmth.boot.core.exception.StatusException;
+
+import cn.com.qmth.stmms.admin.dto.MarkInfoDTO;
+import cn.com.qmth.stmms.admin.dto.MarkerInfoDTO;
+import cn.com.qmth.stmms.admin.vo.SubjectLibraryVO;
+import cn.com.qmth.stmms.api.controller.BaseApiController;
+import cn.com.qmth.stmms.biz.exam.bean.MarkInfoVo;
+import cn.com.qmth.stmms.biz.exam.bean.ResultMessage;
+import cn.com.qmth.stmms.biz.exam.dao.SelectiveStudentDao;
+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.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.lock.LockService;
+import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
+import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
+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.utils.ExportExcel;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+@Api(tags = "评卷管理")
+@Controller("adminMarkInfoController")
+@RequestMapping("/api/admin/mark/info")
+public class MarkInfoController extends BaseApiController {
+
+    protected static Logger log = LoggerFactory.getLogger(MarkInfoController.class);
+
+    public static final String SPLIT = ",";
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private MarkLibraryService libraryService;
+
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private ExamStudentService studentService;
+
+    @Autowired
+    private SelectiveStudentDao selectiveStudentDao;
+
+    @ApiOperation(value = "评卷进度列表")
+    @RequestMapping(value = "query", method = RequestMethod.POST)
+    @ResponseBody
+    public PageResult<SubjectLibraryVO> query(ExamSubjectSearchQuery query) {
+        ApiUser user = getApiUser();
+        int examId = getSessionExamId();
+        query.setExamId(examId);
+        Set<String> unFinishSet = libraryService.findSubjectUnFinishByExamId(examId);
+        unFinishSet.addAll(questionService.FindSubjectCodeByExamIdAndObjectiveAndGroupNumberIsNull(examId, false));
+        if (query.getFinished() != null) {
+            String subjectCodeIn = org.apache.commons.lang.StringUtils.join(unFinishSet, ",");
+            if (query.getFinished()) {
+                query.setCodeNotIn(subjectCodeIn);
+            } else {
+                query.setCodeIn(subjectCodeIn);
+            }
+        }
+        if (user.isSubjectHeader()) {
+            String subjectCodeIn = org.apache.commons.lang.StringUtils.join(user.getSubjectCodeSet(), ",");
+            query.setCodeIn(subjectCodeIn);
+        }
+        query = subjectService.findByQuery(query);
+
+        List<SubjectLibraryVO> list = new LinkedList<SubjectLibraryVO>();
+        for (ExamSubject subject : query.getResult()) {
+            SubjectLibraryVO vo = new SubjectLibraryVO();
+            vo.setSubject(subject);
+            vo.setStudentCount(subject.getUploadCount());
+            vo.setGroupCount(groupService.countByExamAndSubject(examId, subject.getCode()));
+            MarkLibrarySearchQuery mQuery = new MarkLibrarySearchQuery();
+            mQuery.setExamId(examId);
+            mQuery.setSubjectCode(subject.getCode());
+            long libraryCount = libraryService.countByQuery(mQuery);
+            mQuery.addStatus(LibraryStatus.MARKED);
+            long markedCount = libraryService.countByQuery(mQuery);
+            vo.setMarkedCount(markedCount);
+            mQuery.addStatus(LibraryStatus.ARBITRATED);
+            mQuery.addStatus(LibraryStatus.INSPECTED);
+            long totalMarkedCount = libraryService.countByQuery(mQuery);
+            String percent = libraryCount > 0
+                    ? (new DecimalFormat("####.###").format(totalMarkedCount * 100.0 / libraryCount) + "%")
+                    : "0%";
+            vo.setPercent(percent);
+            long count = questionService.countByExamIdAndSubjectAndObjectiveAndGroupNumberIsNull(examId,
+                    subject.getCode(), false);
+            vo.setGroupFinish(count == 0);
+            vo.setSelectiveError(selectiveStudentDao.countByExamIdAndSubjectCodeAndLessSelectiveOrNotSelective(
+                    subject.getExamId(), subject.getCode(), true, true) != 0);
+            list.add(vo);
+        }
+        return PageUtil.of(list, query);
+    }
+
+    @ApiOperation(value = "评卷进度统计")
+    @RequestMapping(value = "statistic", method = RequestMethod.POST)
+    @ResponseBody
+    public MarkInfoVo statistic() {
+        int examId = getSessionExamId();
+        Set<String> unFinishSet = libraryService.findSubjectUnFinishByExamId(examId);
+        MarkLibrarySearchQuery mQuery = new MarkLibrarySearchQuery();
+        mQuery.setExamId(examId);
+        long total = libraryService.countByQuery(mQuery);
+        mQuery.addStatus(LibraryStatus.MARKED);
+        mQuery.addStatus(LibraryStatus.ARBITRATED);
+        mQuery.addStatus(LibraryStatus.INSPECTED);
+        long markedCount = libraryService.countByQuery(mQuery);
+        long subjectCount = subjectService.count(examId);
+        MarkInfoVo vo = new MarkInfoVo();
+        vo.setMarkedCount(markedCount);
+        vo.setUnMarkedCount(total - markedCount);
+        vo.setUnSubjectFinishCount(unFinishSet.size());
+        vo.setSubjectFinishCount(subjectCount - unFinishSet.size());
+        return vo;
+    }
+
+    @ApiOperation(value = "整体评卷进度导出")
+    @Logging(menu = "整体评卷进度导出", type = LogType.EXPORT)
+    @RequestMapping(value = "/export/progress", method = RequestMethod.POST)
+    public void exportProgress(HttpServletResponse response) {
+        ApiUser user = getApiUser();
+        int examId = getSessionExamId();
+        List<MarkInfoDTO> result = new LinkedList<MarkInfoDTO>();
+        List<ExamSubject> list = subjectService.list(examId);
+        if (user.isSubjectHeader()) {
+            list = getExamSubject(examId, user);
+        }
+        for (ExamSubject subject : list) {
+            MarkInfoDTO dto = new MarkInfoDTO(subject);
+            MarkLibrarySearchQuery mQuery = new MarkLibrarySearchQuery();
+            mQuery.setExamId(examId);
+            mQuery.setSubjectCode(subject.getCode());
+            long libraryCount = libraryService.countByQuery(mQuery);
+            mQuery.addStatus(LibraryStatus.MARKED);
+            long inspectedCount = libraryService.countByQuery(mQuery);
+            dto.setInspectedCount(inspectedCount);
+            mQuery.addStatus(LibraryStatus.ARBITRATED);
+            mQuery.addStatus(LibraryStatus.INSPECTED);
+            long totalMarkedCount = libraryService.countByQuery(mQuery);
+            String percent = libraryCount > 0
+                    ? (new DecimalFormat("####.###").format(totalMarkedCount * 100.0 / libraryCount) + "%")
+                    : "0%";
+            dto.setPercent(percent);
+            dto.setGroupCount(groupService.countByExamAndSubject(examId, subject.getCode()));
+            result.add(dto);
+        }
+
+        try {
+            String fileName = "整体评卷进度.xlsx";
+            new ExportExcel("整体评卷进度", MarkInfoDTO.class).setDataList(result).write(response, fileName).dispose();
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+            throw new StatusException("导出整体评卷进度失败!失败信息:" + e.getMessage());
+        }
+    }
+
+    @ApiOperation(value = "评卷员工作量导出")
+    @Logging(menu = "评卷员工作量导出", type = LogType.EXPORT)
+    @RequestMapping(value = "/export/marker", method = RequestMethod.POST)
+    public void exportMarker(HttpServletResponse response) {
+        ApiUser user = getApiUser();
+        int examId = getSessionExamId();
+        List<MarkerInfoDTO> result = new LinkedList<MarkerInfoDTO>();
+        List<Marker> list = markerService.getMarkCount(examId);
+        if (user.isSubjectHeader()) {
+            list = markerService.getMarkCount(examId, user.getSubjectCodeSet());
+        }
+        Map<String, ExamSubject> subjectMap = new HashMap<String, ExamSubject>();
+        Map<String, String> collegeMap = new HashMap<String, String>();
+        for (Marker marker : list) {
+            ExamSubject subject = subjectMap.get(marker.getSubjectCode());
+            if (subject == null) {
+                subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
+                subjectMap.put(marker.getSubjectCode(), subject);
+                collegeMap.put(marker.getSubjectCode(), StringUtils
+                        .join(studentService.findDistinctCollegeBySubjectCode(examId, marker.getSubjectCode()), SPLIT));
+            }
+            MarkGroup group = groupService.findOne(examId, marker.getSubjectCode(), marker.getGroupNumber());
+            group.setQuestionList(questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
+                    group.getSubjectCode(), false, group.getNumber()));
+            marker.setUser(userService.findById(marker.getUserId()));
+            MarkerInfoDTO dto = new MarkerInfoDTO(marker, subject, group);
+            dto.setTotalScore(questionService.sumTotalScoreByGroupNumber(examId, marker.getSubjectCode(), false,
+                    marker.getGroupNumber()));
+            dto.setCollege(collegeMap.get(marker.getSubjectCode()));
+            result.add(dto);
+        }
+
+        try {
+            String fileName = "评卷员工作量.xlsx";
+            new ExportExcel("评卷员工作量", MarkerInfoDTO.class).setDataList(result).write(response, fileName).dispose();
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+            throw new StatusException("导出评卷员工作量失败!失败信息:" + e.getMessage());
+        }
+    }
+
+    @ApiOperation(value = "大题关闭")
+    @Logging(menu = "大题关闭", type = LogType.UPDATE)
+    @RequestMapping(value = "/finish", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMessage finish(@RequestParam String[] codes) {
+        int examId = getSessionExamId();
+        String messages = "";
+        for (String code : codes) {
+            MarkLibrarySearchQuery mQuery = new MarkLibrarySearchQuery();
+            mQuery.setExamId(examId);
+            mQuery.setSubjectCode(code);
+            long libraryCount = libraryService.countByQuery(mQuery);
+            mQuery.addStatus(LibraryStatus.MARKED);
+            mQuery.addStatus(LibraryStatus.ARBITRATED);
+            mQuery.addStatus(LibraryStatus.INSPECTED);
+            long markedCount = libraryService.countByQuery(mQuery);
+            if (markedCount != libraryCount) {
+                continue;
+            }
+            List<MarkGroup> groups = groupService.findByExamAndSubject(examId, code);
+            for (MarkGroup group : groups) {
+                if (group == null || group.getStatus() == MarkStatus.FINISH) {
+                    continue;
+                }
+                try {
+                    lockService.waitlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+                    if (group.getStatus() == MarkStatus.FORMAL && group.getLeftCount() == 0
+                            && selectiveStudentDao.countByExamIdAndSubjectCodeAndLessSelectiveOrNotSelective(
+                                    group.getExamId(), group.getSubjectCode(), true, true) == 0) {
+                        groupService.updateStatus(examId, code, group.getNumber(), MarkStatus.FINISH,
+                                group.getStatus());
+                    } else {
+                        messages = " " + code;
+                    }
+                } finally {
+                    lockService.unlock(LockType.GROUP, group.getExamId(), group.getSubjectCode(), group.getNumber());
+                }
+            }
+        }
+        if (StringUtils.isNotBlank(messages)) {
+            throw new StatusException(messages + " 评卷未完成或选做题异常,无法关闭分组");
+        } else {
+            return resultOk();
+        }
+    }
+}

+ 3 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/QuestionController.java

@@ -155,6 +155,7 @@ public class QuestionController extends BaseApiController {
     @ApiOperation(value = "删除题目")
     @Logging(menu = "删除题目", type = LogType.DELETE)
     @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage delete(HttpServletRequest request, @RequestParam List<Integer> ids) {
         List<ExamQuestion> list = new ArrayList<ExamQuestion>();
         for (Integer id : ids) {
@@ -186,6 +187,7 @@ public class QuestionController extends BaseApiController {
     @ApiOperation(value = "编辑题目")
     @Logging(menu = "编辑题目", type = LogType.UPDATE)
     @RequestMapping(value = "/edit", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage update(HttpServletRequest request, ExamQuestion question) {
         int examId = getSessionExamId(request);
         ExamQuestion old = questionService.findById(question.getId());
@@ -291,6 +293,7 @@ public class QuestionController extends BaseApiController {
     @ApiOperation(value = "新增题目")
     @Logging(menu = "新增题目", type = LogType.ADD)
     @RequestMapping(value = "/question/save", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage save(HttpServletRequest request, ExamQuestion question) {
         int examId = getSessionExamId(request);
         ExamQuestion old = questionService.findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(examId,

+ 8 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/ReportController.java

@@ -156,6 +156,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "分段统计")
     @Logging(menu = "课程分段统计", type = LogType.QUERY)
     @RequestMapping(value="/range", method = RequestMethod.POST)
+    @ResponseBody
     public JSONArray rangeList(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();
@@ -245,6 +246,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "成绩分析计算")
     @Logging(menu = "科目成绩分析计算", type = LogType.UPDATE)
     @RequestMapping(value="/calculate", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage calculate(@RequestParam String subjectCode, @RequestParam Boolean objective) {
         int examId = getSessionExamId();
         Set<String> subjectSet = new HashSet<String>();
@@ -322,6 +324,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "课程学院分析")
     @Logging(menu = "课程学院分析", type = LogType.QUERY)
     @RequestMapping(value="/college", method = RequestMethod.POST)
+    @ResponseBody
     public PageResult<ReportSubjectCollege> collegeList(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();
@@ -368,6 +371,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "课程大题分析")
     @Logging(menu = "课程大题分析", type = LogType.QUERY)
     @RequestMapping(value="/group", method = RequestMethod.POST)
+    @ResponseBody
     public PageResult<ReportSubjectGroup> group(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();
@@ -415,6 +419,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "课程小题分析")
     @Logging(menu = "课程小题分析", type = LogType.QUERY)
     @RequestMapping(value="/question", method = RequestMethod.POST)
+    @ResponseBody
     public PageResult<ReportSubjectQuestion> questionList(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();
@@ -463,6 +468,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "班级分析")
     @Logging(menu = "课程班级分析", type = LogType.QUERY)
     @RequestMapping(value="/class", method = RequestMethod.POST)
+    @ResponseBody
     public PageResult<ReportSubjectClass> classList(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();
@@ -508,6 +514,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "课程老师分析")
     @Logging(menu = "课程老师分析", type = LogType.QUERY)
     @RequestMapping(value="/teacher", method = RequestMethod.POST)
+    @ResponseBody
     public PageResult<ReportSubjectTeacher> teacherList(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();
@@ -559,6 +566,7 @@ public class ReportController extends BaseApiController {
     @ApiOperation(value = "课程教师班级分析")
     @Logging(menu = "课程教师班级分析", type = LogType.QUERY)
     @RequestMapping(value="/teacher/class", method = RequestMethod.POST)
+    @ResponseBody
     public PageResult<ReportSubjectTeacherClass> teacherClassList(ReportSubjectQuery query) {
         ApiUser wu = getApiUser();
         int examId = getSessionExamId();

+ 3 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/SelectiveGroupController.java

@@ -119,6 +119,7 @@ public class SelectiveGroupController extends BaseApiController {
     @Logging(menu = "选做题新增", type = LogType.ADD)
     @RequestMapping(value = "/group/save", method = RequestMethod.POST)
     @Transactional
+    @ResponseBody
     public ResultMessage save(@RequestParam String subjectCode, @RequestParam Integer selectiveCount,
             @RequestParam Integer scorePolicy, @RequestParam Integer selectivePart,
             @RequestParam(required = true, defaultValue = "false") Boolean enableAllSelectiveAdd,
@@ -196,6 +197,7 @@ public class SelectiveGroupController extends BaseApiController {
     @Logging(menu = "删除选做题", type = LogType.DELETE)
     @RequestMapping(value = "/group/delete", method = RequestMethod.POST)
     @Transactional
+    @ResponseBody
     public ResultMessage delete(@RequestParam String subjectCode, @RequestParam Integer selectiveIndex) {
         int examId = getSessionExamId();
         List<MarkGroup> groups = groupService.findByExamAndSubject(examId, subjectCode);
@@ -210,6 +212,7 @@ public class SelectiveGroupController extends BaseApiController {
     @Logging(menu = "修改选做题取分规则", type = LogType.UPDATE)
     @RequestMapping(value = "/group/edit", method = RequestMethod.POST)
     @Transactional
+    @ResponseBody
     public ResultMessage edit(@RequestParam String subjectCode, @RequestParam Integer selectiveIndex,
             @RequestParam Integer policy,
             @RequestParam(required = true, defaultValue = "false") Boolean enableAllSelective) {

+ 3 - 7
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/StudentController.java

@@ -509,8 +509,7 @@ public class StudentController extends BaseApiController {
     @Logging(menu = "违纪重置", type = LogType.UPDATE)
     @RequestMapping(value = "/updateBreach", method = RequestMethod.POST)
     @ResponseBody
-    public JSONObject updateBreach(HttpServletRequest request, Integer id) {
-        JSONObject result = new JSONObject();
+    public ResultMessage updateBreach(HttpServletRequest request, Integer id) {
         ExamStudent student = studentService.findById(id);
         if (student != null && studentService.updateBreach(id, false)) {
             List<MarkGroup> groupList = groupService.findByExamAndSubjectAndStatus(student.getExamId(),
@@ -519,13 +518,10 @@ public class StudentController extends BaseApiController {
                 groupService.updateStatus(student.getExamId(), student.getSubjectCode(), markGroup.getNumber(),
                         MarkStatus.FORMAL, MarkStatus.FINISH);
             }
-            result.accumulate("message", "重置成功!");
-            result.accumulate("success", true);
+            return  resultOk();
         } else {
-            result.accumulate("message", "将违纪考生信息重置为正常时出错!");
-            result.accumulate("success", false);
+            throw new StatusException("将违纪考生信息重置为正常时出错!");
         }
-        return result;
     }
 
     @ApiOperation(value = "多媒体考生上传模版")

+ 6 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/SubjectController.java

@@ -237,6 +237,7 @@ public class SubjectController extends BaseApiController {
     @ApiOperation(value = "客观题统分")
     @Logging(menu = "客观题统分", type = LogType.UPDATE)
     @RequestMapping(value = "/calculate", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage calculate(HttpServletRequest request, @RequestParam(required = false) String subjectCode) {
         ApiUser wu = RequestUtils.getApiUser(request);
         Exam exam = examService.findById(getSessionExamId(request));
@@ -316,6 +317,7 @@ public class SubjectController extends BaseApiController {
     @ApiOperation(value = "导入客or主观题")
     @Logging(menu = "导入客/主观题", type = LogType.IMPORT_FILE)
     @RequestMapping(value = "/import", method = RequestMethod.POST)
+    @ResponseBody
     public JSONObject importFile(HttpServletRequest request, MultipartFile file, @RequestParam Boolean objective) {
         int examId = getSessionExamId(request);
 
@@ -437,6 +439,7 @@ public class SubjectController extends BaseApiController {
     @ApiOperation(value = "导入主观题评卷分组")
     @Logging(menu = "导入主观题分组", type = LogType.IMPORT_FILE)
     @RequestMapping(value = "/importGroup", method = RequestMethod.POST)
+    @ResponseBody
     public JSONObject importGroupFile(HttpServletRequest request, MultipartFile file) {
         int examId = getSessionExamId(request);
         List<String> error = new LinkedList<String>();
@@ -521,6 +524,7 @@ public class SubjectController extends BaseApiController {
     @ApiOperation(value = "科目成绩分析计算")
     @Logging(menu = "科目成绩分析计算", type = LogType.UPDATE)
     @RequestMapping(value = "/report", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage report(HttpServletRequest request, @RequestParam(required = false) String subjectCode) {
         ApiUser wu = RequestUtils.getApiUser(request);
         Exam exam = examService.findById(getSessionExamId(request));
@@ -554,6 +558,7 @@ public class SubjectController extends BaseApiController {
     @ApiOperation(value = "客观题分析计算")
     @Logging(menu = "客观题分析计算", type = LogType.UPDATE)
     @RequestMapping(value = "/report/objective", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage reportObjective(HttpServletRequest request) {
         ApiUser wu = RequestUtils.getApiUser(request);
         Exam exam = examService.findById(getSessionExamId(request));
@@ -581,6 +586,7 @@ public class SubjectController extends BaseApiController {
     @ApiOperation(value = "导入数据包")
     @Logging(menu = "导入数据包", type = LogType.IMPORT_FILE)
     @RequestMapping(value = "/importData", method = RequestMethod.POST)
+    @ResponseBody
     public ResultMessage importData(HttpServletRequest request, MultipartFile file) {
         int examId = getSessionExamId(request);
         List<String> error = new ArrayList<String>();