|
@@ -1,7 +1,13 @@
|
|
|
package cn.com.qmth.stmms.admin.exam;
|
|
|
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.LinkedList;
|
|
@@ -15,9 +21,11 @@ import javax.servlet.http.HttpServletResponse;
|
|
|
import net.sf.json.JSONArray;
|
|
|
import net.sf.json.JSONObject;
|
|
|
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
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.data.domain.Sort.Direction;
|
|
@@ -38,11 +46,16 @@ 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.ScoreReportThread;
|
|
|
+import cn.com.qmth.stmms.admin.vo.StructFile;
|
|
|
+import cn.com.qmth.stmms.admin.vo.StructQuestion;
|
|
|
+import cn.com.qmth.stmms.biz.common.domain.card.CardFile;
|
|
|
+import cn.com.qmth.stmms.biz.exam.model.AnswerCard;
|
|
|
import cn.com.qmth.stmms.biz.exam.model.Exam;
|
|
|
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.AnswerCardService;
|
|
|
import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
|
|
|
import cn.com.qmth.stmms.biz.exam.service.ExamService;
|
|
|
import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
|
|
@@ -52,6 +65,7 @@ import cn.com.qmth.stmms.biz.exam.service.MarkerService;
|
|
|
import cn.com.qmth.stmms.biz.exam.service.SelectiveGroupService;
|
|
|
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;
|
|
@@ -65,6 +79,7 @@ import cn.com.qmth.stmms.biz.report.service.ReportSubjectTeacherService;
|
|
|
import cn.com.qmth.stmms.common.annotation.Logging;
|
|
|
import cn.com.qmth.stmms.common.annotation.RoleRequire;
|
|
|
import cn.com.qmth.stmms.common.domain.WebUser;
|
|
|
+import cn.com.qmth.stmms.common.enums.CardSource;
|
|
|
import cn.com.qmth.stmms.common.enums.LockType;
|
|
|
import cn.com.qmth.stmms.common.enums.LogType;
|
|
|
import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
|
|
@@ -76,6 +91,9 @@ 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 com.aliyun.oss.common.utils.BinaryUtil;
|
|
|
+import com.qmth.boot.tools.io.ZipReader;
|
|
|
+
|
|
|
@Controller("examPaperController")
|
|
|
@RequestMapping("/admin/exam/paper")
|
|
|
public class PaperController extends BaseExamController {
|
|
@@ -137,6 +155,12 @@ public class PaperController extends BaseExamController {
|
|
|
@Autowired
|
|
|
private SelectiveGroupService selectiveGroupService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private AnswerCardService answerCardService;
|
|
|
+
|
|
|
+ @Value("${file.store}")
|
|
|
+ private String fileStore;
|
|
|
+
|
|
|
@Logging(menu = "试卷管理查询", type = LogType.QUERY)
|
|
|
@RequestMapping
|
|
|
public String list(Model model, HttpServletRequest request, ExamSubjectSearchQuery query,
|
|
@@ -805,4 +829,117 @@ public class PaperController extends BaseExamController {
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
+ @Logging(menu = "导入数据包", type = LogType.IMPORT_FILE)
|
|
|
+ @RequestMapping(value = "/importData", method = RequestMethod.POST)
|
|
|
+ @RoleRequire(Role.SCHOOL_ADMIN)
|
|
|
+ public String importData(HttpServletRequest request, MultipartFile file, RedirectAttributes redirectAttributes) {
|
|
|
+ int examId = getSessionExamId(request);
|
|
|
+ List<String> error = new ArrayList<String>();
|
|
|
+ try {
|
|
|
+ byte[] data = IOUtils.toByteArray(file.getInputStream());
|
|
|
+ File target = new File(fileStore, "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 {
|
|
|
+ ExamSubject subject = subjectService.find(examId, subjectCode);
|
|
|
+ if (subject == null) {
|
|
|
+ error.add("[" + subjectCode + "] 科目代码不存在;");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (subject.getTotalScore() != 0) {
|
|
|
+ error.add("[" + subjectCode + "] 科目代码已经存在题目;");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ 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 + "] 科目代码卡格式解析有误;");
|
|
|
+ }
|
|
|
+ byte[] out = cardFile.output();
|
|
|
+ String md5 = BinaryUtil.encodeMD5(out);
|
|
|
+ AnswerCard card = answerCardService.findByExamIdAndSubjectCode(examId, subject.getCode());
|
|
|
+ if (card == null) {
|
|
|
+ card = new AnswerCard();
|
|
|
+ card.setExamId(examId);
|
|
|
+ Integer number = answerCardService.findMaxNumberByExamId(examId) + 1;
|
|
|
+ card.setNumber(number);
|
|
|
+ card.setSubjectCode(subject.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());
|
|
|
+ answerCardService.save(card);
|
|
|
+
|
|
|
+ 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.getSubjective()) {
|
|
|
+ ExamQuestion q = structQuestion.transform();
|
|
|
+ q.setPaperType(structFile.getPaperType());
|
|
|
+ q.setExamId(examId);
|
|
|
+ q.setSubjectCode(subject.getCode());
|
|
|
+ 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.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, 0, false, false, null, false);
|
|
|
+ groupService.save(group);
|
|
|
+ }
|
|
|
+ subjectService.updateScore(examId, subject.getCode(), false,
|
|
|
+ questionService.sumTotalScore(examId, subject.getCode(), false));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("parse zip data error", e);
|
|
|
+ error.add("[" + subjectCode + "] 科目代码导入失败;");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ target.delete();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("parse question excel error", e);
|
|
|
+ error.add("zip文件解析失败");
|
|
|
+ }
|
|
|
+ if (error.size() > 0) {
|
|
|
+ addMessage(redirectAttributes, StringUtils.join(error, "<br\\>"));
|
|
|
+ }
|
|
|
+ return "redirect:/admin/exam/paper";
|
|
|
+ }
|
|
|
}
|