1
0
yin 4 дней назад
Родитель
Сommit
258be03574

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

@@ -0,0 +1,329 @@
+package cn.com.qmth.stmms.api.controller.admin;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+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.ui.Model;
+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.QuestionDeleteThread;
+import cn.com.qmth.stmms.api.controller.BaseApiController;
+import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
+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.SelectiveGroup;
+import cn.com.qmth.stmms.biz.exam.service.*;
+import cn.com.qmth.stmms.biz.exam.service.query.ExamQuestionSearchQuery;
+import cn.com.qmth.stmms.biz.file.service.FileService;
+import cn.com.qmth.stmms.biz.lock.LockService;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
+import cn.com.qmth.stmms.biz.report.service.ReportService;
+import cn.com.qmth.stmms.common.annotation.Logging;
+import cn.com.qmth.stmms.common.enums.*;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+import net.sf.json.JSONObject;
+
+@Controller("adminQuestionController")
+@RequestMapping("/api/admin/question")
+public class QuestionController extends BaseApiController {
+
+    protected static final Logger log = LoggerFactory.getLogger(QuestionController.class);
+
+    private static final String NULL_PAPER_TYPE_PLACEHOLDER = "#";
+
+    @Autowired
+    private ExamStudentService studentService;
+
+    @Autowired
+    private ExamSubjectService subjectService;
+
+    @Autowired
+    private ExamService examService;
+
+    @Autowired
+    private ExamQuestionService questionService;
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private InspectHistoryService inspectHistoryService;
+
+    @Qualifier("task-executor")
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private MarkService markService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private SelectiveGroupService selectiveGroupService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    @ResponseBody
+    public List<ExamQuestion> list(ExamQuestionSearchQuery query) {
+        int examId = getSessionExamId();
+        ExamSubject subject = subjectService.find(examId, query.getSubjectCode());
+        if (subject == null) {
+            throw new StatusException("没有找到科目");
+        }
+        List<ExamQuestion> list = questionService.findByQuery(query).getResult();
+        List<MarkGroup> groups = groupService.findByExamAndSubject(examId, query.getSubjectCode());
+        Map<Integer, MarkGroup> maps = new HashMap<Integer, MarkGroup>();
+        for (MarkGroup markGroup : groups) {
+            maps.put(markGroup.getNumber(), markGroup);
+        }
+        List<SelectiveGroup> selectiveGroups = selectiveGroupService.findByExamIdAndSubjectCode(examId,
+                query.getSubjectCode());
+        Map<Integer, SelectiveGroup> selectiveMap = new HashMap<Integer, SelectiveGroup>();
+        for (SelectiveGroup selectiveGroup : selectiveGroups) {
+            selectiveMap.put(selectiveGroup.getMainNumber(), selectiveGroup);
+        }
+        for (ExamQuestion examQuestion : list) {
+            if (examQuestion.getGroupNumber() != null && maps.get(examQuestion.getGroupNumber()).getMarkedCount() > 0) {
+                examQuestion.setEnableUpdate(false);
+            } else {
+                examQuestion.setEnableUpdate(true);
+            }
+            // 选做题判分策略
+            if (selectiveMap.containsKey(examQuestion.getMainNumber())) {
+                examQuestion.setEnableUpdate(false);
+                examQuestion.setSelective(true);
+                examQuestion.setSelectiveIndex(selectiveMap.get(examQuestion.getMainNumber()).getSelectiveIndex());
+                examQuestion.setSelectivePart(selectiveMap.get(examQuestion.getMainNumber()).getSelectivePart());
+                examQuestion.setScorePolicy(selectiveMap.get(examQuestion.getMainNumber()).getScorePolicy().getValue());
+            } else {
+                examQuestion.setSelective(false);
+            }
+            examQuestion.setDeleting(lockService.isLocked(LockType.QUESTION_DELETE, examQuestion.getExamId(),
+                    examQuestion.getSubjectCode(), examQuestion.getMainNumber(), examQuestion.getSubNumber()));
+        }
+        return list;
+    }
+
+    @RequestMapping(value = "/main/list", method = RequestMethod.POST)
+    @ResponseBody
+    public List<ExamQuestion> mainList(ExamQuestionSearchQuery query) {
+        int examId = getSessionExamId();
+        ExamSubject subject = subjectService.find(examId, query.getSubjectCode());
+        if (subject == null) {
+            throw new StatusException("没有找到科目");
+        }
+        List<ExamQuestion> mainList = new LinkedList<ExamQuestion>();
+        mainList.addAll(questionService.findMainByExamAndSubjectAndObjective(examId, query.getSubjectCode(), true));
+        mainList.addAll(questionService.findMainByExamAndSubjectAndObjective(examId, query.getSubjectCode(), false));
+        return mainList;
+    }
+
+    @RequestMapping(value = "/objectivePolicy/list", method = RequestMethod.POST)
+    @ResponseBody
+    public List<ObjectivePolicy> roleList() {
+        return Arrays.asList(ObjectivePolicy.values());
+    }
+
+    @RequestMapping(value = "/type/list", method = RequestMethod.POST)
+    @ResponseBody
+    public List<QuestionType> typeList() {
+        return Arrays.asList(QuestionType.values());
+    }
+
+    @Logging(menu = "删除题目", type = LogType.DELETE)
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public JSONObject delete(HttpServletRequest request, @RequestParam List<Integer> ids) {
+        List<ExamQuestion> list = new ArrayList<ExamQuestion>();
+        for (Integer id : ids) {
+            ExamQuestion question = questionService.findById(id);
+            if (question == null) {
+                throw new StatusException("没有找到题目");
+            }
+            SelectiveGroup selectiveGroup = selectiveGroupService.findOne(question.getExamId(),
+                    question.getSubjectCode(), question.getMainNumber());
+            if (selectiveGroup != null) {
+                throw new StatusException("删除失败,该题目已有分组或选做题存在选做题分组");
+            }
+            if (!question.isObjective() && question.getGroupNumber() != null) {
+                throw new StatusException("删除失败,该题目已有分组或选做题存在选做题分组");
+            }
+            if (lockService.trylock(LockType.QUESTION_DELETE, question.getExamId(), question.getSubjectCode(),
+                    question.getMainNumber(), question.getSubNumber())) {
+                list.add(question);
+                RequestUtils.setLog(request, "删除题目,科目代码:" + question.getSubjectCode() + " 大题号:"
+                        + question.getMainNumber() + " 小题号:" + question.getSubNumber());
+            }
+        }
+        if (!list.isEmpty()) {
+            taskExecutor.submit(new QuestionDeleteThread(list, markService, lockService));
+        }
+        return result(true);
+    }
+
+    @Logging(menu = "编辑题目", type = LogType.UPDATE)
+    @RequestMapping(value = "/edit", method = RequestMethod.POST)
+    public JSONObject update(HttpServletRequest request, ExamQuestion question) {
+        int examId = getSessionExamId(request);
+        ExamQuestion old = questionService.findById(question.getId());
+        ExamQuestion newQ = questionService.findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(examId,
+                question.getSubjectCode(), question.isObjective(), question.getMainNumber(), question.getSubNumber());
+        if (old == null || ((old.getMainNumber() != question.getMainNumber()
+                || !old.getSubNumber().equals(question.getSubNumber())) && newQ != null)) {
+            throw new StatusException("编辑失败,编辑题目不存在或编辑后的题号已存在");
+        }
+        questionService.updateMainName(question.getId(), question.getName());
+        questionService.updateTrackCount(question.getId(),
+                question.getTrackCount() == null ? 0 : question.getTrackCount());
+        if (!old.isObjective() && old.getGroupNumber() != null) {
+            MarkGroup group = groupService.findOne(examId, old.getSubjectCode(), old.getGroupNumber());
+            if (group.getMarkedCount() > 0) {
+                throw new StatusException("编辑失败,已经开始评卷");
+            }
+        }
+        SelectiveGroup selectiveGroup = selectiveGroupService.findOne(examId, old.getSubjectCode(),
+                old.getMainNumber());
+        if (!old.isObjective() && selectiveGroup != null) {
+            throw new StatusException("编辑失败,已经存在选做题分组");
+        }
+        List<String> error = new LinkedList<String>();
+        if (validate(question, error, new HashMap<Integer, String>())) {
+            throw new StatusException(StringUtils.join(error, " "));
+        }
+        old.setMainNumber(question.getMainNumber());
+        old.setSubNumber(question.getSubNumber());
+        old.setMainTitle(question.getMainTitle());
+        old.setName(question.getName());
+        old.setTotalScore(question.getTotalScore());
+        old.setIntervalScore(question.getIntervalScore());
+        old.setObjectivePolicy(question.getObjectivePolicy());
+        old.setAnswer(question.getAnswer().toUpperCase());
+        old.setPaperType(question.getPaperType());
+        old.setType(question.getType());
+        old.setTrackCount(question.getTrackCount() == null ? 0 : question.getTrackCount());
+        questionService.saveAndFlush(old);
+        questionService.updateMainTitle(examId, question.getSubjectCode(), question.isObjective(),
+                question.getMainNumber(), question.getMainTitle());
+        subjectService.updateScore(examId, question.getSubjectCode(), question.isObjective(),
+                questionService.sumTotalScore(examId, question.getSubjectCode(), question.isObjective()));
+        // 更新分组总分
+        if (!old.isObjective() && old.getGroupNumber() != null) {
+            markerService.logoutByExamIdAndSubjectCodeAndGroupNumber(examId, old.getSubjectCode(),
+                    old.getGroupNumber());
+            MarkGroup group = groupService.findOne(examId, old.getSubjectCode(), old.getGroupNumber());
+            List<ExamQuestion> questionGroup = questionService.findByExamAndSubjectAndObjectiveAndGroupNumber(examId,
+                    question.getSubjectCode(), false, old.getGroupNumber());
+            BigDecimal totalScore = BigDecimal.ZERO;
+            for (ExamQuestion q : questionGroup) {
+                totalScore = totalScore.add(BigDecimal.valueOf(q.getTotalScore()));
+            }
+            group.setTotalScore(totalScore.doubleValue());
+            groupService.save(group);
+        }
+        return result(true);
+    }
+
+    private boolean validate(ExamQuestion question, List<String> error, Map<Integer, String> titleMap) {
+        if (countDecimalPlaces(question.getTotalScore()) > 2) {
+            error.add("有满分为小数超2位的记录");
+            return false;
+        }
+        if (question.isObjective() && StringUtils.isBlank(question.getAnswer())) {
+            error.add("有答案为空的记录");
+            return false;
+        }
+        if (question.isObjective() && question.getType() == null) {
+            error.add("有题型为空的记录");
+            return false;
+        }
+        if (QuestionType.TRUE_OR_FALSE.equals(question.getType())
+                && (!question.getAnswer().contains("A") && !question.getAnswer().contains("B"))) {
+            error.add("有判断题标答不为A或B的记录");
+            return false;
+        }
+        if (QuestionType.SINGLE.equals(question.getType()) && question.getAnswer().length() > 1) {
+            error.add("有单选题标答大于一个的记录");
+            return false;
+        }
+        String title = titleMap.get(question.getMainNumber());
+        if (title != null && !title.equals(question.getMainTitle())) {
+            error.add("有名称不一致的记录");
+            return false;
+        }
+        if (question.isObjective()) {
+            question.setAnswer(question.getAnswer().toUpperCase());
+        }
+        return true;
+    }
+
+    public int countDecimalPlaces(double number) {
+        String num = Double.toString(number);
+        int decimalPointIndex = num.indexOf('.');
+        if (decimalPointIndex == -1) {
+            return 0;
+        }
+        return num.length() - decimalPointIndex - 1;
+    }
+
+    @Logging(menu = "新增题目", type = LogType.ADD)
+    @RequestMapping(value = "/question/save", method = RequestMethod.POST)
+    public JSONObject save(HttpServletRequest request,
+                       ExamQuestion question) {
+        int examId = getSessionExamId(request);
+        ExamQuestion old = questionService.findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(examId,
+                question.getSubjectCode(), question.isObjective(), question.getMainNumber(), question.getSubNumber());
+        if (old != null) {
+            throw new StatusException("新增失败,题号已存在");
+        }
+        question.setExamId(examId);
+        if (StringUtils.isBlank(question.getPaperType())) {
+            question.setPaperType(NULL_PAPER_TYPE_PLACEHOLDER);
+        }
+        if (question.isObjective()) {
+            question.setGroupNumber(0);
+        } else {
+            question.setObjectivePolicy(null);
+            question.setAnswer(null);
+            question.setType(null);
+        }
+        if(question.getTrackCount()==null ){
+            question.setTrackCount(0);
+        }
+        Map<Integer, String> titleMap = new HashMap<>();
+        List<ExamQuestion> current = questionService.findByExamAndSubjectAndObjective(examId, question.getSubjectCode(),
+                question.isObjective());
+        for (ExamQuestion q : current) {
+            titleMap.put(q.getMainNumber(), q.getMainTitle());
+        }
+        List<String> error = new LinkedList<String>();
+        if (validate(question, error, titleMap)) {
+            return result(StringUtils.join(error, " "));
+        }
+        questionService.save(question);
+        subjectService.updateScore(examId, question.getSubjectCode(), question.isObjective(),
+                questionService.sumTotalScore(examId, question.getSubjectCode(), question.isObjective()));
+        if (!question.isObjective()) {
+            studentService.updateSubjectiveStatusAndScore(examId, question.getSubjectCode(),
+                    SubjectiveStatus.UNMARK, 0, null);
+            inspectHistoryService.deleteByExamIdAndSubjectCode(examId, question.getSubjectCode());
+        }
+        return result(true);
+    }
+}

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

@@ -141,7 +141,7 @@ public class ScanController extends BaseApiController {
     }
 
     @Logging(menu = "扫描进度-按考点查询", type = LogType.QUERY)
-    @RequestMapping("/examSite")
+    @RequestMapping(value="/examSite", method = RequestMethod.POST)
     @ResponseBody
     public PageResult<ScanInfoVO> examSite(HttpServletRequest request, ExamStudentSearchQuery query) {
         int examId = getSessionExamId(request);

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

@@ -254,7 +254,7 @@ public class StudentController extends BaseApiController {
         return result("删除考生成功");
     }
 
-    @RequestMapping(value = "/template")
+    @RequestMapping(value = "/template", method = RequestMethod.POST)
     public void importFileTemplate(HttpServletResponse response) {
         try {
             String fileName = "考生数据导入模板.xlsx";
@@ -382,7 +382,7 @@ public class StudentController extends BaseApiController {
         }
     }
 
-    @RequestMapping(value = "/absentTemplate")
+    @RequestMapping(value = "/absentTemplate", method = RequestMethod.POST)
     public void absentTemplate(HttpServletResponse response) {
         try {
             String fileName = "缺考考生导入模板.xlsx";
@@ -435,7 +435,7 @@ public class StudentController extends BaseApiController {
         }
     }
 
-    @RequestMapping(value = "/breachTemplate")
+    @RequestMapping(value = "/breachTemplate", method = RequestMethod.POST)
     public void breachTemplate(HttpServletResponse response) {
         try {
             String fileName = "违纪考生导入模板.xlsx";
@@ -509,7 +509,7 @@ public class StudentController extends BaseApiController {
         return result;
     }
 
-    @RequestMapping(value = "/uploadTemplate")
+    @RequestMapping(value = "/uploadTemplate", method = RequestMethod.POST)
     public void uploadTemplate(HttpServletResponse response) {
         try {
             String fileName = "多媒体考生上传导入模板.xlsx";
@@ -578,7 +578,7 @@ public class StudentController extends BaseApiController {
         }
     }
 
-    @RequestMapping(value = "/collationLabelTemplate")
+    @RequestMapping(value = "/collationLabelTemplate", method = RequestMethod.POST)
     public void collationLabelTemplate(HttpServletResponse response) {
         try {
             String fileName = "整理异常导入模板.xlsx";

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

@@ -1,16 +1,13 @@
 package cn.com.qmth.stmms.api.controller.admin;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.io.*;
+import java.math.BigDecimal;
+import java.util.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
-import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
-import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
-import cn.com.qmth.stmms.common.domain.ApiUser;
-import cn.com.qmth.stmms.common.domain.WebUser;
-import cn.com.qmth.stmms.common.enums.LockType;
-import cn.com.qmth.stmms.common.enums.MarkStatus;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -18,28 +15,49 @@ 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.data.domain.Sort;
 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 org.springframework.web.servlet.mvc.support.RedirectAttributes;
+import org.springframework.web.multipart.MultipartFile;
 
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.qmth.boot.core.collection.PageResult;
 import com.qmth.boot.core.exception.StatusException;
-
+import com.qmth.boot.tools.io.ZipReader;
+
+import cn.com.qmth.stmms.admin.dto.ObjectiveQuestionDTO;
+import cn.com.qmth.stmms.admin.dto.QuestionDTO;
+import cn.com.qmth.stmms.admin.dto.SubjectQuestionDTO;
+import cn.com.qmth.stmms.admin.dto.SubjectiveQuestionDTO;
+import cn.com.qmth.stmms.admin.thread.ScoreCalculateThread;
+import cn.com.qmth.stmms.admin.thread.ScoreReportObjectiveThread;
+import cn.com.qmth.stmms.admin.thread.ScoreReportThread;
+import cn.com.qmth.stmms.admin.vo.StructFile;
+import cn.com.qmth.stmms.admin.vo.StructQuestion;
 import cn.com.qmth.stmms.api.controller.BaseApiController;
-import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.common.domain.card.AnswerCardSubjectFile;
+import cn.com.qmth.stmms.biz.common.domain.card.AnswerCardSubjectItem;
+import cn.com.qmth.stmms.biz.common.domain.card.CardFile;
+import cn.com.qmth.stmms.biz.exam.model.*;
 import cn.com.qmth.stmms.biz.exam.service.*;
+import cn.com.qmth.stmms.biz.exam.service.query.ExamQuestionSearchQuery;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.file.enums.FormatType;
 import cn.com.qmth.stmms.biz.file.service.FileService;
 import cn.com.qmth.stmms.biz.lock.LockService;
 import cn.com.qmth.stmms.biz.mark.service.MarkService;
 import cn.com.qmth.stmms.biz.report.service.ReportService;
 import cn.com.qmth.stmms.biz.utils.PageUtil;
 import cn.com.qmth.stmms.common.annotation.Logging;
-import cn.com.qmth.stmms.common.enums.LogType;
+import cn.com.qmth.stmms.common.domain.ApiUser;
+import cn.com.qmth.stmms.common.enums.*;
+import cn.com.qmth.stmms.common.utils.ExportExcel;
+import cn.com.qmth.stmms.common.utils.ImportExcel;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
+import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;
 
 @Controller("adminSubjectController")
@@ -149,7 +167,7 @@ public class SubjectController extends BaseApiController {
     @Logging(menu = "科目设置修改", type = LogType.UPDATE)
     @RequestMapping(value = "/update", method = RequestMethod.POST)
     @ResponseBody
-    public JSONObject save(RedirectAttributes redirectAttributes, HttpServletRequest request, ExamSubject subject) {
+    public JSONObject save(HttpServletRequest request, ExamSubject subject) {
         ExamSubject previous = subjectService.find(getSessionExamId(request), subject.getCode());
         if (previous == null) {
             throw new StatusException("科目不存在");
@@ -178,4 +196,559 @@ public class SubjectController extends BaseApiController {
         }
         return result(true);
     }
+
+    @RequestMapping(value = "/getPaperType", method = RequestMethod.POST)
+    @ResponseBody
+    public List<String> query(HttpServletRequest request, @RequestParam String subjectCode) {
+        int examId = getSessionExamId(request);
+        JSONArray array = new JSONArray();
+        List<String> list = this.questionService.getPaperType(examId, subjectCode);
+        return list;
+    }
+
+    @RequestMapping(value = "/template", method = RequestMethod.POST)
+    public void importTemplate(HttpServletResponse response, @RequestParam Boolean objective) {
+        try {
+            String fileName = objective ? "客观题导入模板.xlsx" : "主观题导入模板.xlsx";
+            String title = objective ? "客观题数据" : "主观题数据";
+            List<QuestionDTO> list = new LinkedList<QuestionDTO>();
+            list.add(objective ? new ObjectiveQuestionDTO() : new SubjectiveQuestionDTO());
+            new ExportExcel(title, objective ? ObjectiveQuestionDTO.class : SubjectiveQuestionDTO.class, 2)
+                    .setDataList(list).write(response, fileName).dispose();
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+            throw new StatusException("导入模板下载失败!失败信息:" + e.getMessage());
+        }
+    }
+
+    @Logging(menu = "客观题统分", type = LogType.UPDATE)
+    @RequestMapping(value = "/calculate", method = RequestMethod.POST)
+    public JSONObject calculate(HttpServletRequest request, @RequestParam(required = false) String subjectCode) {
+        ApiUser wu = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(getSessionExamId(request));
+        if (exam == null || !exam.getSchoolId().equals(wu.getUser().getSchoolId())) {
+            throw new StatusException("请选择正确的考试");
+        } else {
+            Set<String> subjectSet = new HashSet<String>();
+            // 整个考试加锁
+            boolean examLock = false;
+            if (subjectCode == null) {
+                subjectSet = getCalculateSubjectCodes(exam.getId());
+                examLock = true;
+            } else if (!lockService.isLocked(LockType.SCORE_CALCULATE, exam.getId(), subjectCode)) {
+                subjectSet.add(subjectCode);
+            }
+            if (!subjectSet.isEmpty()) {
+                ScoreCalculateThread thread = new ScoreCalculateThread(exam.getId(), subjectSet, lockService,
+                        studentService, questionService, examService, subjectService, fileService, examLock);
+                taskExecutor.submit(thread);
+            }
+        }
+        return result(true);
+    }
+
+    private Set<String> getCalculateSubjectCodes(Integer examId) {
+        List<ExamSubject> list = subjectService.list(examId);
+        Set<String> set = new HashSet<>();
+        for (ExamSubject subject : list) {
+            if (!lockService.isLocked(LockType.SCORE_CALCULATE, subject.getExamId(), subject.getCode())) {
+                set.add(subject.getCode());
+            }
+        }
+        return set;
+    }
+
+    @Logging(menu = "导出客/主观题", type = LogType.EXPORT)
+    @RequestMapping(value = "/export", method = RequestMethod.POST)
+    public void exportFile(HttpServletRequest request, HttpServletResponse response, @RequestParam Boolean objective) {
+        int examId = getSessionExamId(request);
+
+        Map<String, ExamSubject> subjectMap = new HashMap<String, ExamSubject>();
+        List<ExamSubject> subjectList = subjectService.list(examId);
+        for (ExamSubject subject : subjectList) {
+            subjectMap.put(subject.getCode(), subject);
+        }
+
+        Map<String, MarkGroup> groupMap = new HashMap<String, MarkGroup>();
+        List<MarkGroup> groupList = groupService.findByExam(examId);
+        for (MarkGroup group : groupList) {
+            groupMap.put(group.getSubjectCode() + "_" + group.getNumber(), group);
+        }
+        List<QuestionDTO> list = new LinkedList<QuestionDTO>();
+        ExamQuestionSearchQuery query = new ExamQuestionSearchQuery();
+        query.setExamId(examId);
+        query.setObjective(objective);
+        query.setSort(new Sort(Sort.Direction.ASC, "subjectCode", "paperType", "mainNumber", "subNumber"));
+        query.setPageNumber(1);
+        query.setPageSize(Integer.MAX_VALUE);
+        query = questionService.findByQuery(query);
+        for (ExamQuestion q : query.getResult()) {
+            list.add(objective ? new ObjectiveQuestionDTO(q, subjectMap.get(q.getSubjectCode()))
+                    : new SubjectiveQuestionDTO(q, subjectMap.get(q.getSubjectCode()),
+                            groupMap.get(q.getSubjectCode() + "_" + q.getGroupNumber())));
+        }
+        try {
+            String fileName = objective ? "客观题数据.xlsx" : "主观题数据.xlsx";
+            String title = objective ? "客观题数据" : "主观题数据";
+            new ExportExcel(title, objective ? ObjectiveQuestionDTO.class : SubjectiveQuestionDTO.class, 2)
+                    .setDataList(list).write(response, fileName).dispose();
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            e.printStackTrace();
+            throw new StatusException("导出数据失败!失败信息:" + e.getMessage());
+        }
+    }
+
+    @Logging(menu = "导入客/主观题", type = LogType.IMPORT_FILE)
+    @RequestMapping(value = "/import", method = RequestMethod.POST)
+    public JSONObject importFile(HttpServletRequest request, MultipartFile file, @RequestParam Boolean objective) {
+        int examId = getSessionExamId(request);
+
+        List<String> error = new LinkedList<String>();
+        Map<String, SubjectQuestionDTO> map = parseQuestion(file, examId, objective, error);
+        if (error.size() > 0) {
+            return result(StringUtils.join(error, "<br\\>"));
+        }
+        int success = 0;
+        for (SubjectQuestionDTO dto : map.values()) {
+            // 每次导入都需要重新统分
+            examService.updateObjectiveStatus(examId, ObjectiveStatus.WAITING);
+            ExamSubject subject = subjectService.find(examId, dto.getSubjectCode());
+            if (subject != null) {
+                Map<Integer, String> titleMap = new HashMap<>();
+                List<ExamQuestion> current = questionService.findByExamAndSubjectAndObjective(examId, subject.getCode(),
+                        objective);
+                for (ExamQuestion question : current) {
+                    titleMap.put(question.getMainNumber(), question.getMainTitle());
+                }
+                if (dto.validate(error, titleMap)) {
+                    if (objective) {
+                        questionService.deleteByExamAndSubjectAndObjective(examId, dto.getSubjectCode(), objective);
+                        for (ExamQuestion question : dto.getQuestionList()) {
+                            questionService.save(question);
+                        }
+                        subjectService.updateScore(examId, subject.getCode(), objective, dto.getTotalScore());
+                    } else {
+                        int questionCount = 0;
+                        List<SelectiveGroup> list = selectiveGroupService.findByExamIdAndSubjectCode(examId,
+                                subject.getCode());
+                        Map<Integer, SelectiveGroup> selectiveMap = new HashMap<Integer, SelectiveGroup>();
+                        for (SelectiveGroup selectiveGroup : list) {
+                            selectiveMap.put(selectiveGroup.getMainNumber(), selectiveGroup);
+                        }
+                        for (ExamQuestion question : dto.getQuestionList()) {
+                            ExamQuestion old = questionService
+                                    .findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(examId,
+                                            subject.getCode(), objective, question.getMainNumber(),
+                                            question.getSubNumber());
+                            if (old != null) {
+                                if (old.getGroupNumber() != null) {
+                                    error.add("[" + subject.getCode() + "] 大题号" + question.getMainNumber() + " 小题号"
+                                            + question.getSubNumber() + "已有分组");
+                                    continue;
+                                }
+                                if (selectiveMap.containsKey(question.getMainNumber())) {
+                                    error.add("[" + subject.getCode() + "] 大题号" + question.getMainNumber() + " 小题号"
+                                            + question.getSubNumber() + "已有选做题分组");
+                                    continue;
+                                }
+                                old.setName(question.getName());
+                                old.setTotalScore(question.getTotalScore());
+                                old.setIntervalScore(question.getIntervalScore());
+                                old.setTrackCount(question.getTrackCount());
+                                questionService.save(old);
+                            } else {
+                                question.setGroupNumber(null);
+                                questionService.save(question);
+                                questionCount++;
+                            }
+                        }
+                        if (questionCount > 0) {
+                            studentService.updateSubjectiveStatusAndScore(examId, subject.getCode(),
+                                    SubjectiveStatus.UNMARK, 0, null);
+                            inspectHistoryService.deleteByExamIdAndSubjectCode(examId, subject.getCode());
+                        }
+                        subjectService.updateScore(examId, subject.getCode(), objective,
+                                questionService.sumTotalScore(examId, subject.getCode(), objective));
+                    }
+                    success++;
+                }
+            } else {
+                error.add("[" + dto.getSubjectCode() + "] 科目代码不存在;");
+            }
+        }
+        error.add(0, success + "个科目导入成功;");
+        if (success > 0) {
+            subjectService.updateTotalScore(examId);
+        }
+        RequestUtils.setLog(request, success + "个科目导入成功;");
+        return result(StringUtils.join(error, "<br\\>"));
+    }
+
+    private Map<String, SubjectQuestionDTO> parseQuestion(MultipartFile file, int examId, boolean objective,
+            List<String> error) {
+        Map<String, SubjectQuestionDTO> map = new HashMap<String, SubjectQuestionDTO>();
+        try {
+            ImportExcel excel = new ImportExcel(file, 1, 0);
+            Class<? extends QuestionDTO> clazz = objective ? ObjectiveQuestionDTO.class : SubjectiveQuestionDTO.class;
+            if (!objective && !Arrays.equals(SUBJECTIVE_EXCEL_HEADER, excel.getHeaderName())) {
+                error.add("Excel表头错误");
+                return map;
+            }
+            if (objective && !Arrays.equals(OBJECTIVE_EXCEL_HEADER, excel.getHeaderName())) {
+                error.add("Excel表头错误");
+                return map;
+            }
+            List<? extends QuestionDTO> list = excel.getDataList(clazz);
+            if (list != null) {
+                for (QuestionDTO dto : list) {
+                    String subjectCode = StringUtils.trimToNull(dto.getSubjectCode());
+                    if (subjectCode != null) {
+                        SubjectQuestionDTO subject = map.get(subjectCode);
+                        if (subject == null) {
+                            subject = new SubjectQuestionDTO(examId, subjectCode, objective);
+                            map.put(subjectCode, subject);
+                        }
+                        subject.addQuestion(dto.transform());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("parse question excel error", e);
+            error.add("Excel文件解析失败");
+        }
+        return map;
+    }
+
+    @Logging(menu = "导入主观题分组", type = LogType.IMPORT_FILE)
+    @RequestMapping(value = "/importGroup", method = RequestMethod.POST)
+    public JSONObject importGroupFile(HttpServletRequest request, MultipartFile file) {
+        int examId = getSessionExamId(request);
+        List<String> error = new LinkedList<String>();
+        Map<String, SubjectQuestionDTO> map = parseQuestion(file, examId, false, error);
+        if (error.size() > 0) {
+            return result(StringUtils.join(error, " "));
+        }
+        int success = 0;
+        for (SubjectQuestionDTO dto : map.values()) {
+            ExamSubject subject = subjectService.find(examId, dto.getSubjectCode());
+            if (subject != null) {
+                // 验证是否存在分组
+                List<MarkGroup> groups = groupService.findByExamAndSubject(examId, subject.getCode());
+                if (groups != null && groups.size() > 0) {
+                    error.add("[" + subject.getCode() + "] 已存在分组");
+                    continue;
+                }
+                if (subject.isSelective()) {
+                    error.add("[" + subject.getCode() + "] 已存在选做题分组");
+                    continue;
+                }
+                Map<Integer, String> titleMap = new HashMap<>();
+                List<ExamQuestion> current = questionService.findByExamAndSubjectAndObjective(examId, subject.getCode(),
+                        false);
+                for (ExamQuestion question : current) {
+                    titleMap.put(question.getMainNumber(), question.getMainTitle());
+                }
+                if (dto.validate(error, titleMap) && dto.validateGroupNumber(error)
+                        && dto.getQuestionList().size() == current.size()) {
+                    int successGroup = 0;
+                    for (MarkGroup group : dto.getGroups().values()) {
+                        if (group.getImportQuestionList() != null) {
+                            boolean validate = true;
+                            List<ExamQuestion> questionGroup = new ArrayList<ExamQuestion>();
+                            for (ExamQuestion question : group.getImportQuestionList()) {
+                                ExamQuestion old = questionService
+                                        .findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(examId,
+                                                subject.getCode(), false, question.getMainNumber(),
+                                                question.getSubNumber());
+                                if (old == null) {
+                                    error.add("[" + group.getSubjectCode() + "_" + group.getNumber() + "] 分组有小题不存在");
+                                    validate = false;
+                                    break;
+                                }
+                                old.setGroupNumber(group.getNumber());
+                                old.setArbitrateThreshold(question.getArbitrateThreshold());
+                                questionGroup.add(old);
+                            }
+                            // 校验通过小题才保存
+                            if (validate && !questionGroup.isEmpty()) {
+                                questionService.save(questionGroup);
+                            }
+                            // 有题目的分组才保存
+                            if (questionService.countByExamAndSubjectAndObjectiveAndGroupNumber(examId,
+                                    group.getSubjectCode(), false, group.getNumber()) != 0) {
+                                BigDecimal totalScore = BigDecimal.ZERO;
+                                for (ExamQuestion q : questionGroup) {
+                                    totalScore = totalScore.add(BigDecimal.valueOf(q.getTotalScore()));
+                                }
+                                group.setTotalScore(totalScore.doubleValue());
+                                groupService.save(group);
+                                studentService.updateSubjectiveStatusAndScore(examId, group.getSubjectCode(),
+                                        SubjectiveStatus.UNMARK, 0, null);
+                                inspectHistoryService.deleteByExamIdAndSubjectCode(examId, subject.getCode());
+                                successGroup++;
+                            }
+                        }
+                    }
+                    if (successGroup > 0) {
+                        success++;
+                        subjectService.updateTrialCount(examId, subject.getCode(), dto.getTrialCount());
+                    }
+                }
+            } else {
+                error.add("[" + dto.getSubjectCode() + "] 科目代码不存在;");
+            }
+        }
+        error.add(0, success + "个科目导入成功;");
+        RequestUtils.setLog(request, success + "个科目导入成功;");
+        return result(StringUtils.join(error, " "));
+    }
+
+    @Logging(menu = "科目成绩分析计算", type = LogType.UPDATE)
+    @RequestMapping(value = "/report", method = RequestMethod.POST)
+    public JSONObject report(HttpServletRequest request, @RequestParam(required = false) String subjectCode) {
+        ApiUser wu = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(getSessionExamId(request));
+        if (exam == null || !exam.getSchoolId().equals(wu.getUser().getSchoolId())) {
+            throw new StatusException("请选择正确的考试");
+        } else {
+            Set<String> subjectSet = new HashSet<String>();
+            // 整个考试加锁
+            boolean examLock = false;
+            if (subjectCode == null) {
+                examLock = true;
+                List<ExamSubject> list = subjectService.list(exam.getId());
+                for (ExamSubject subject : list) {
+                    if (!lockService.isLocked(LockType.SCORE_CALCULATE, subject.getExamId(), subject.getCode())) {
+                        subjectSet.add(subject.getCode());
+                    }
+                }
+            } else if (!lockService.isLocked(LockType.SCORE_CALCULATE, exam.getId(), subjectCode)) {
+                subjectSet.add(subjectCode);
+            }
+            if (!subjectSet.isEmpty()) {
+                Map<Integer, Set<String>> map = new HashMap<Integer, Set<String>>();
+                map.put(exam.getId(), subjectSet);
+                ScoreReportThread thread = new ScoreReportThread(map, reportService, examLock);
+                taskExecutor.submit(thread);
+            }
+        }
+        return result(true);
+    }
+
+    @Logging(menu = "客观题分析计算", type = LogType.UPDATE)
+    @RequestMapping(value = "/report/objective", method = RequestMethod.POST)
+    public JSONObject reportObjective(HttpServletRequest request) {
+        ApiUser wu = RequestUtils.getApiUser(request);
+        Exam exam = examService.findById(getSessionExamId(request));
+        if (exam == null || !exam.getSchoolId().equals(wu.getUser().getSchoolId())) {
+            throw new StatusException("请选择正确的考试");
+        } else {
+            Set<String> subjectSet = new HashSet<String>();
+            // 整个考试加锁
+            boolean examLock = true;
+            List<ExamSubject> list = subjectService.list(exam.getId());
+            for (ExamSubject subject : list) {
+                if (!lockService.isLocked(LockType.SCORE_CALCULATE, subject.getExamId(), subject.getCode())) {
+                    subjectSet.add(subject.getCode());
+                }
+            }
+            if (!subjectSet.isEmpty()) {
+                Map<Integer, Set<String>> map = new HashMap<Integer, Set<String>>();
+                map.put(exam.getId(), subjectSet);
+                ScoreReportObjectiveThread thread = new ScoreReportObjectiveThread(map, reportService, examLock);
+                taskExecutor.submit(thread);
+            }
+        }
+        return result(true);
+    }
+
+    @Logging(menu = "导入数据包", type = LogType.IMPORT_FILE)
+    @RequestMapping(value = "/importData", method = RequestMethod.POST)
+    public JSONObject importData(HttpServletRequest request, MultipartFile file) {
+        int examId = getSessionExamId(request);
+        List<String> error = new ArrayList<String>();
+        try {
+            byte[] data = IOUtils.toByteArray(file.getInputStream());
+            File target = new File(tempFile + File.separator + "temp.zip");
+            target.getParentFile().mkdirs();
+            FileOutputStream ous = new FileOutputStream(target);
+            ous.write(data);
+            IOUtils.closeQuietly(ous);
+
+            ZipReader zipReader = new ZipReader(target);
+            for (String subjectCode : zipReader.list(false)) {
+                try {
+                    if (subjectCode.equalsIgnoreCase("cards")) {
+                        error = this.parseCard(examId, error, zipReader);
+                    } else {
+                        error = this.parseSubject(examId, subjectCode, error, zipReader);
+                    }
+                } catch (Exception e) {
+                    log.error("parse zip data error", e);
+                    error.add("[" + subjectCode + "] 科目代码导入失败;");
+                }
+            }
+            subjectService.updateCardType(examId);
+            target.delete();
+        } catch (Exception e) {
+            log.error("parse question excel error", e);
+            error.add("zip文件解析失败");
+        }
+        if (error.size() > 0) {
+            return result(StringUtils.join(error, " "));
+        }
+        return result(true);
+    }
+
+    private List<String> parseCard(int examId, List<String> error, ZipReader zipReader) throws IOException {
+        InputStream ins = zipReader.read("cards", "description.json");
+        List<AnswerCardSubjectFile> courseList = AnswerCardSubjectFile.parse(ins);
+        for (AnswerCardSubjectFile answerCardSubjectFile : courseList) {
+            try {
+                InputStream cardIns = zipReader.read("cards", answerCardSubjectFile.getCode() + ".json");
+                CardFile cardFile = CardFile.parse(cardIns);
+                if (cardFile.getPages().size() != 1 && cardFile.getPages().size() % 2 != 0) {
+                    error.add("[" + answerCardSubjectFile.getCode() + "] 科目代码卡格式解析有误;");
+                    return error;
+                }
+                byte[] out = cardFile.output();
+                String md5 = BinaryUtil.encodeMD5(out);
+                AnswerCard card = answerCardService.findByExamIdAndCode(examId, answerCardSubjectFile.getCode());
+                if (card == null) {
+                    card = new AnswerCard();
+                    card.setExamId(examId);
+                    Integer number = answerCardService.findMaxNumberByExamId(examId) + 1;
+                    card.setNumber(number);
+                    card.setCode(answerCardSubjectFile.getCode());
+                }
+                card.setMd5(md5);
+                card.setNeedAdapte(true);
+                card.setSliceConfig(cardFile.getSliceConfig().toString());
+                card.setSinglePage(cardFile.getPages().size() == 1);
+                card.setPaperCount(card.getSinglePage() ? 1 : cardFile.getPages().size() / 2);
+                card.setSource(CardSource.WEB);
+                card.setUpdateTime(new Date());
+                List<String> asList = new ArrayList<String>();
+                List<ExamSubject> subjects = new ArrayList<ExamSubject>();
+                for (AnswerCardSubjectItem item : answerCardSubjectFile.getCourses()) {
+                    ExamSubject subject = subjectService.find(examId, item.getCode());
+                    if (subject == null) {
+                        error.add("[" + item.getCode() + "] 科目代码不存在;");
+                        return error;
+                    }
+                    if (answerCardService.hasSubject(examId, item.getCode(), item.getCode())) {
+                        error.add("[" + item.getCode() + "] 科目代码已经绑定卡格式;");
+                        return error;
+                    } else {
+                        asList.add(item.getCode());
+                        subject.setSliceConfig(cardFile.getSliceConfig().toString());
+                        subject.setCardType(FormatType.JSON);
+                        subjects.add(subject);
+                    }
+                }
+                answerCardService.save(card, asList);
+                fileService.uploadAnswerCard(new ByteArrayInputStream(out), md5, examId, card.getNumber());
+                for (ExamSubject examSubject : subjects) {
+                    subjectService.save(examSubject);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                log.error("parse zip data error", e);
+                error.add("[" + answerCardSubjectFile.getCode() + "] 科目代码卡格式解析有误;");
+                return error;
+            }
+        }
+        return error;
+    }
+
+    private List<String> parseSubject(int examId, String subjectCode, List<String> error, ZipReader zipReader)
+            throws Exception {
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        if (subject == null) {
+            error.add("[" + subjectCode + "] 科目代码不存在;");
+            return error;
+        }
+        if (subject.getTotalScore() != 0) {
+            error.add("[" + subjectCode + "] 科目代码已经存在题目;");
+            return error;
+        }
+        InputStream cardIns = zipReader.read(subjectCode, "card.json");
+        CardFile cardFile = CardFile.parse(cardIns);
+        if (cardFile.getPages().size() != 1 && cardFile.getPages().size() % 2 != 0) {
+            error.add("[" + subjectCode + "] 科目代码卡格式解析有误;");
+            return error;
+        }
+        byte[] out = cardFile.output();
+        String md5 = BinaryUtil.encodeMD5(out);
+        AnswerCard card = answerCardService.findByExamIdAndSubjectCode(examId, subject.getCode(), CardSource.WEB);
+        if (card == null) {
+            card = new AnswerCard();
+            card.setExamId(examId);
+            Integer number = answerCardService.findMaxNumberByExamId(examId) + 1;
+            card.setNumber(number);
+        }
+        card.setMd5(md5);
+        card.setNeedAdapte(true);
+        card.setSliceConfig(cardFile.getSliceConfig().toString());
+        card.setSinglePage(cardFile.getPages().size() == 1);
+        card.setPaperCount(card.getSinglePage() ? 1 : cardFile.getPages().size() / 2);
+        card.setSource(CardSource.WEB);
+        card.setUpdateTime(new Date());
+        answerCardService.save(card, subjectCode);
+
+        fileService.uploadAnswerCard(new ByteArrayInputStream(out), md5, examId, card.getNumber());
+        subject.setSliceConfig(cardFile.getSliceConfig().toString());
+        subject.setCardType(FormatType.JSON);
+        subjectService.save(subject);
+
+        InputStream structIns = zipReader.read(subjectCode, "struct.json");
+        StructFile structFile = StructFile.parse(structIns);
+        if (!structFile.getObjective().isEmpty()) {
+            List<ExamQuestion> oList = new ArrayList<ExamQuestion>();
+            for (StructQuestion structQuestion : structFile.getObjective()) {
+                ExamQuestion q = structQuestion.transform();
+                q.setPaperType(structFile.getPaperType());
+                q.setExamId(examId);
+                q.setSubjectCode(subject.getCode());
+                q.setObjective(true);
+                oList.add(q);
+            }
+            questionService.save(oList);
+            examService.updateObjectiveStatus(examId, ObjectiveStatus.WAITING);
+            subjectService.updateScore(examId, subject.getCode(), true,
+                    questionService.sumTotalScore(examId, subject.getCode(), true));
+        }
+        if (!structFile.getSubjective().isEmpty()) {
+            List<ExamQuestion> sList = new ArrayList<ExamQuestion>();
+            Map<Integer, Double> mainMap = new HashMap<Integer, Double>();
+            for (StructQuestion structQuestion : structFile.getSubjective()) {
+                ExamQuestion q = structQuestion.transform();
+                q.setPaperType(structFile.getPaperType());
+                q.setExamId(examId);
+                q.setSubjectCode(subject.getCode());
+                q.setObjective(false);
+                q.setGroupNumber(q.getMainNumber());
+                sList.add(q);
+                Double totalScore = mainMap.get(q.getMainNumber());
+                if (totalScore == null) {
+                    mainMap.put(q.getMainNumber(), q.getTotalScore());
+                } else {
+                    mainMap.put(q.getMainNumber(), totalScore + q.getTotalScore());
+                }
+            }
+            questionService.save(sList);
+            for (Integer number : mainMap.keySet()) {
+                MarkGroup group = new MarkGroup(examId, subject.getCode(), number, null, mainMap.get(number), null,
+                        null, null, null, null, 0, false, false, null, false);
+                group.setPicList(cardFile.getMarkConfigAdd(cardFile.getMarkConfig(number), 0.015));
+                groupService.save(group);
+            }
+            subjectService.updateScore(examId, subject.getCode(), false,
+                    questionService.sumTotalScore(examId, subject.getCode(), false));
+        }
+        return error;
+    }
+
 }

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

@@ -143,7 +143,7 @@ public class UserController extends BaseApiController {
         } catch (Exception e) {
             log.error(e.getMessage());
             e.printStackTrace();
-            throw new StatusException("导出用户数据失败");
+            throw new StatusException("导出数据失败!失败信息:"+e.getMessage());
         }
     }
 
@@ -235,7 +235,7 @@ public class UserController extends BaseApiController {
         } catch (Exception e) {
             log.error(e.getMessage());
             e.printStackTrace();
-            throw new StatusException("导出用户数据失败");
+            throw new StatusException("导出数据失败!失败信息:"+e.getMessage());
         }
     }
 
@@ -338,12 +338,12 @@ public class UserController extends BaseApiController {
         } catch (Exception e) {
             log.error(e.getMessage());
             e.printStackTrace();
-            throw new StatusException("导出用户数据失败");
+            throw new StatusException("导出用户数据失败"+e.getMessage());
         }
     }
 
     @Logging(menu = "用户启用/禁用", type = LogType.UPDATE)
-    @RequestMapping("/enable")
+    @RequestMapping(value="/enable", method = RequestMethod.POST)
     @ResponseBody
     public JSONObject toggle(HttpServletRequest request, @RequestParam List<Integer> ids,
             @RequestParam Boolean enable) {
@@ -422,7 +422,7 @@ public class UserController extends BaseApiController {
         return set;
     }
 
-    @RequestMapping(value = "/student/template")
+    @RequestMapping(value = "/student/template", method = RequestMethod.POST)
     public void importStudentTemplate(HttpServletResponse response) {
         try {
             String fileName = "绑定考生导入模板.xlsx";
@@ -437,14 +437,14 @@ public class UserController extends BaseApiController {
         }
     }
 
-    @RequestMapping(value = "/student/clear")
+    @RequestMapping(value = "/student/clear", method = RequestMethod.POST)
     @ResponseBody
     public JSONObject studentClear(@RequestParam Integer id) {
         userStudentService.clear(id);
         return result(true);
     }
 
-    @RequestMapping(value = "/subject/template")
+    @RequestMapping(value = "/subject/template", method = RequestMethod.POST)
     public void importFileTemplate(HttpServletResponse response, @RequestParam Boolean isHeader) {
         try {
             String fileName = isHeader ? "科组长数据导入模板.xlsx" : "复核员数据导入模板.xlsx";
@@ -551,7 +551,7 @@ public class UserController extends BaseApiController {
         return user;
     }
 
-    @RequestMapping(value = "/class/template")
+    @RequestMapping(value = "/class/template", method = RequestMethod.POST)
     public void importFileTemplate(HttpServletResponse response) {
         try {
             String fileName = "评卷员班级导入模板.xlsx";