|
@@ -1,12 +1,282 @@
|
|
package com.qmth.cqb.paper.service.export;
|
|
package com.qmth.cqb.paper.service.export;
|
|
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.HashSet;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.Set;
|
|
|
|
+
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.common.dto.core.enums.CourseLevel;
|
|
|
|
+import cn.com.qmth.examcloud.common.dto.question.enums.QuesStructType;
|
|
|
|
+
|
|
|
|
+import com.qmth.cqb.paper.dao.PaperDetailRepo;
|
|
|
|
+import com.qmth.cqb.paper.dao.PaperDetailUnitRepo;
|
|
|
|
+import com.qmth.cqb.paper.dao.PaperRepo;
|
|
|
|
+import com.qmth.cqb.paper.dto.PaperDetailExp;
|
|
|
|
+import com.qmth.cqb.paper.dto.PaperDetailUnitExp;
|
|
|
|
+import com.qmth.cqb.paper.dto.PaperExp;
|
|
|
|
+import com.qmth.cqb.paper.model.Paper;
|
|
|
|
+import com.qmth.cqb.paper.model.PaperDetail;
|
|
|
|
+import com.qmth.cqb.paper.model.PaperDetailUnit;
|
|
|
|
+import com.qmth.cqb.paper.service.PaperService;
|
|
|
|
+import com.qmth.cqb.question.dao.QuesRepo;
|
|
|
|
+import com.qmth.cqb.question.model.QuesOption;
|
|
|
|
+import com.qmth.cqb.question.model.Question;
|
|
|
|
+import com.qmth.cqb.utils.BeanCopierUtil;
|
|
|
|
+import com.qmth.cqb.utils.CommonUtils;
|
|
|
|
+import com.qmth.cqb.utils.exception.PaperException;
|
|
|
|
+import com.qmth.cqb.utils.word.DocxProcessUtil;
|
|
|
|
+
|
|
|
|
+import freemarker.template.Configuration;
|
|
|
|
+import freemarker.template.Template;
|
|
|
|
|
|
-@Service("exportPaperService")
|
|
|
|
public abstract class ExportPaperAbstractService {
|
|
public abstract class ExportPaperAbstractService {
|
|
|
|
|
|
- public abstract void dzkdDownloadPaper(String id, HttpServletResponse response) throws Exception;
|
|
|
|
-
|
|
|
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(ExportPaperAbstractService.class);
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperRepo paperRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperService paperService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperDetailRepo paperDetailRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ PaperDetailUnitRepo paperDetailUnitRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ QuesRepo quesRepo;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ ExportPaperService exportPaperService;
|
|
|
|
+
|
|
|
|
+ public static Configuration CONFIGURATION;
|
|
|
|
+
|
|
|
|
+ public static final String ENCODING = "UTF-8";
|
|
|
|
+
|
|
|
|
+ protected static Template SXSF_TEMPLATE_PAPER;
|
|
|
|
+
|
|
|
|
+ protected static Template SXSF_TEMPLATE_ANSWER;
|
|
|
|
+
|
|
|
|
+ protected static Template DZKD_TEMPLATE_PAPER;
|
|
|
|
+
|
|
|
|
+ protected static Template DZKD_TEMPLATE_ANSWER;
|
|
|
|
+
|
|
|
|
+ protected static Template TEMPLATE_NORMAL;
|
|
|
|
+
|
|
|
|
+ static {
|
|
|
|
+ try {
|
|
|
|
+ logger.info("*********************试卷导出设置初始化start**************************");
|
|
|
|
+ CONFIGURATION = new Configuration(Configuration.VERSION_2_3_25);
|
|
|
|
+ // 设置编码
|
|
|
|
+ CONFIGURATION.setDefaultEncoding(ENCODING);
|
|
|
|
+ // 设置ftl模板路径
|
|
|
|
+ CONFIGURATION.setClassForTemplateLoading(DocxProcessUtil.class, "/");
|
|
|
|
+
|
|
|
|
+ //陕西师范模板
|
|
|
|
+ SXSF_TEMPLATE_PAPER = CONFIGURATION.getTemplate("sxsf_paper_template.ftl", ENCODING);
|
|
|
|
+ SXSF_TEMPLATE_ANSWER = CONFIGURATION.getTemplate("sxsf_answer_template.ftl", ENCODING);
|
|
|
|
+ //电子科大模板
|
|
|
|
+ DZKD_TEMPLATE_PAPER = CONFIGURATION.getTemplate("dzkd_paper_template.ftl", ENCODING);
|
|
|
|
+ DZKD_TEMPLATE_ANSWER = CONFIGURATION.getTemplate("dzkd_answer_template.ftl", ENCODING);
|
|
|
|
+
|
|
|
|
+ TEMPLATE_NORMAL = CONFIGURATION.getTemplate("paper_template.ftl", ENCODING);
|
|
|
|
+ logger.info("*********************试卷导出设置初始化end**************************");
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 下载试卷
|
|
|
|
+ * @param id
|
|
|
|
+ * @param response
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public abstract void downloadPaper(String id, HttpServletResponse response)throws Exception;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 初始化导出试卷DTO
|
|
|
|
+ *
|
|
|
|
+ * @param id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ protected Map<String,Object> initExportPaper(String id) throws Exception {
|
|
|
|
+ // 创建返回Map
|
|
|
|
+ Map<String,Object> returnMap = new HashMap<String,Object>();
|
|
|
|
+ // 获取paper
|
|
|
|
+ Paper paper = paperRepo.findOne(id);
|
|
|
|
+ paperService.formatPaper(paper, null);
|
|
|
|
+ if (paper == null) {
|
|
|
|
+ throw new PaperException("该试卷不存在");
|
|
|
|
+ }
|
|
|
|
+ // 创建paperDto
|
|
|
|
+ PaperExp paperExp = BeanCopierUtil.copyProperties(paper, PaperExp.class);
|
|
|
|
+ paperExp.setCourseLevel(paper.getLevel()==null?CourseLevel.ALL.name():paper.getLevel().name());
|
|
|
|
+ List<PaperDetailExp> objectiveDetails = new ArrayList<PaperDetailExp>();// 客观题
|
|
|
|
+ List<PaperDetailExp> subjectiveDetails = new ArrayList<PaperDetailExp>();// 主观题
|
|
|
|
+ double objectiveScore = 0;
|
|
|
|
+ double subjectiveScore = 0;
|
|
|
|
+ paperExp.setTitle(CommonUtils.PAPER_TITLE);
|
|
|
|
+ paperExp.setSubTitle(CommonUtils.PAPER_SUB_TITLE);
|
|
|
|
+ // 获取大题
|
|
|
|
+ List<PaperDetail> paperDetails = paperDetailRepo.findByPaper(paper);
|
|
|
|
+ int objectNumber = 1;// 客观题大题序号
|
|
|
|
+ int objetcUnitSum = 0;
|
|
|
|
+ for (int i = 0; i < paperDetails.size(); i++) {
|
|
|
|
+ PaperDetailExp paperDetailExp = BeanCopierUtil.copyProperties(paperDetails.get(i), PaperDetailExp.class);
|
|
|
|
+ List<PaperDetailUnit> paperDetailUnits = paperDetailUnitRepo.findByPaperDetail(paperDetails.get(i));
|
|
|
|
+ // 把大题分类 :客观题和主观题
|
|
|
|
+ List<PaperDetailUnitExp> paperDetailUnitExps = BeanCopierUtil.copyPropertiesOfList(paperDetailUnits,PaperDetailUnitExp.class);
|
|
|
|
+ // 选择题,套题下选择题 选项顺序重新排列
|
|
|
|
+ paperService.reorderChoicequestionOption(paperDetailUnitExps);
|
|
|
|
+ paperDetailExp.setPaperDetailUnits(paperDetailUnitExps);
|
|
|
|
+ boolean hasTextAnswer = false;// 判断主观题
|
|
|
|
+ if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
|
|
|
|
+ for (Question ques : paperDetailUnits.get(0).getQuestion().getSubQuestions()) {
|
|
|
|
+ if (ques.getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
|
|
|
|
+ hasTextAnswer = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.TEXT_ANSWER_QUESTION) {
|
|
|
|
+ hasTextAnswer = true;
|
|
|
|
+ } else if (paperDetailUnits.get(0).getQuestionType() == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
+ hasTextAnswer = true;
|
|
|
|
+ }
|
|
|
|
+ if (hasTextAnswer) {
|
|
|
|
+ subjectiveDetails.add(paperDetailExp);
|
|
|
|
+ subjectiveScore += paperDetailExp.getScore();
|
|
|
|
+ } else {
|
|
|
|
+ objectiveDetails.add(paperDetailExp);
|
|
|
|
+ paperDetailExp.setNumber(objectNumber);
|
|
|
|
+ paperDetailExp.setCnNum(CommonUtils.toCHNum(objectNumber));
|
|
|
|
+ objectiveScore += paperDetailExp.getScore();
|
|
|
|
+ objetcUnitSum += paperDetailExp.getUnitCount();
|
|
|
|
+ objectNumber++;
|
|
|
|
+ }
|
|
|
|
+ setExpTitle(paperDetailExp);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ paperExp.setObjectiveDetails(objectiveDetails);
|
|
|
|
+ paperExp.setSubjectiveDetails(subjectiveDetails);
|
|
|
|
+ paperExp.setObjectiveScore(objectiveScore);
|
|
|
|
+ paperExp.setSubjectiveScore(subjectiveScore);
|
|
|
|
+ if (objectiveDetails.size() > 0) {
|
|
|
|
+ setUnitExpNumber(objectiveDetails, 0);
|
|
|
|
+ }
|
|
|
|
+ if (subjectiveDetails.size() > 0) {
|
|
|
|
+ for (PaperDetailExp subDetail : subjectiveDetails) {
|
|
|
|
+ subDetail.setNumber(objectNumber);
|
|
|
|
+ subDetail.setCnNum(CommonUtils.toCHNum(objectNumber));
|
|
|
|
+ objectNumber++;
|
|
|
|
+ }
|
|
|
|
+ setUnitExpNumber(subjectiveDetails, objetcUnitSum);
|
|
|
|
+ }
|
|
|
|
+ returnMap.put("paper", paperExp);
|
|
|
|
+ returnMap.put("fileName", paperExp.getName());
|
|
|
|
+
|
|
|
|
+ return returnMap;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected void setExpTitle(PaperDetailExp paperDetailExp) {
|
|
|
|
+ String title = "";
|
|
|
|
+ String totalScore = BigDecimal.valueOf(paperDetailExp.getScore()).stripTrailingZeros().toPlainString();
|
|
|
|
+ String unitScore = BigDecimal.valueOf(paperDetailExp.getPaperDetailUnits().get(0).getScore()).stripTrailingZeros().toPlainString();
|
|
|
|
+ QuesStructType type = paperDetailExp.getPaperDetailUnits().get(0).getQuestionType();
|
|
|
|
+ String scoreString = "";
|
|
|
|
+ if (type == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
+ scoreString = checkPaperDetailUnitScore(paperDetailExp) ? "每空"+ unitScore + "分" : "";
|
|
|
|
+ } else {
|
|
|
|
+ scoreString = checkPaperDetailUnitScore(paperDetailExp) ? "每小题"+ unitScore + "分" : "";
|
|
|
|
+ }
|
|
|
|
+ if (type == QuesStructType.SINGLE_ANSWER_QUESTION) {
|
|
|
|
+ paperDetailExp.setName("单项选择题");
|
|
|
|
+
|
|
|
|
+ title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"
|
|
|
|
+ + scoreString + "共" + totalScore + "分)。"
|
|
|
|
+ + "在每小题列出的四个备选中只有一个符合题目要求的,请将其选出并将“答题卡”的相应代码涂黑,错涂、多涂或未涂均无分";
|
|
|
|
+ } else if (type == QuesStructType.BOOL_ANSWER_QUESTION) {
|
|
|
|
+ paperDetailExp.setName("判断题");
|
|
|
|
+ title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"+ scoreString + "共" + totalScore+ "分。正确的填涂A、错误填涂B。错涂、多涂或未涂均无分)";
|
|
|
|
+ } else if (type == QuesStructType.FILL_BLANK_QUESTION) {
|
|
|
|
+ paperDetailExp.setName("填空题");
|
|
|
|
+ int blankNum = 0;
|
|
|
|
+ for (PaperDetailUnitExp unit : paperDetailExp.getPaperDetailUnits()) {
|
|
|
|
+ String tempStr = unit.getQuestion().getQuesBody().replaceAll("###", "");
|
|
|
|
+ int lenTimes = (unit.getQuestion().getQuesBody().length() - tempStr.length()) / "###".length();// 出现的次数
|
|
|
|
+ blankNum += lenTimes;
|
|
|
|
+ }
|
|
|
|
+ title = "(本大题共" + blankNum + "个空格,将每空答在答题卡 “1—" + blankNum+ "”相应的序号上。" + scoreString + "共" + totalScore + "分)";
|
|
|
|
+ } else {
|
|
|
|
+ title = "(本大题共" + paperDetailExp.getUnitCount() + "小题,"+ scoreString + "共" + totalScore + "分)";
|
|
|
|
+ }
|
|
|
|
+ paperDetailExp.setTitle(title);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 校验大题下的小题分数是不是一样
|
|
|
|
+ *
|
|
|
|
+ * @param paperDetailExp
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ protected boolean checkPaperDetailUnitScore(PaperDetailExp paperDetailExp) {
|
|
|
|
+ List<PaperDetailUnitExp> paperDetailUnitExps = paperDetailExp.getPaperDetailUnits();
|
|
|
|
+ Set<Double> scoreSet = new HashSet<Double>();
|
|
|
|
+ for (PaperDetailUnitExp unitExp : paperDetailUnitExps) {
|
|
|
|
+ scoreSet.add(unitExp.getScore());
|
|
|
|
+ }
|
|
|
|
+ return scoreSet.size() == 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected void setUnitExpNumber(List<PaperDetailExp> paperDetails,int startIndxt) throws Exception {
|
|
|
|
+ int subNum = startIndxt;
|
|
|
|
+ for (PaperDetailExp paperDetail : paperDetails) {
|
|
|
|
+ for (PaperDetailUnitExp paperDetailUnit : paperDetail.getPaperDetailUnits()) {
|
|
|
|
+ List<QuesOption> optionList = paperDetailUnit.getQuestion().getQuesOptions();
|
|
|
|
+ if (optionList != null && optionList.size() > 0) {
|
|
|
|
+ int index = 0;
|
|
|
|
+ for (QuesOption quesOption : optionList) {
|
|
|
|
+ quesOption.setOptionBodyWord(exportPaperService.setOptionNum(quesOption.getOptionBodyWord(),exportPaperService.getOptionNum(index)));
|
|
|
|
+ index++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
|
|
|
|
+ Question question = paperDetailUnit.getQuestion();
|
|
|
|
+ // 套题序号
|
|
|
|
+ if (subQuesList != null && subQuesList.size() > 0) {
|
|
|
|
+ question.setQuesBodyWord(exportPaperService.replaceQuesBlank(question.getQuesBodyWord(),subNum + 1));
|
|
|
|
+ for (Question subQues : subQuesList) {
|
|
|
|
+ int curSubNum = ++subNum;
|
|
|
|
+ subQues.setQuesBodyWord(exportPaperService.setSubQuesNum(subQues.getQuesBodyWord(),curSubNum));
|
|
|
|
+ subQues.setQuesAnswerWord(exportPaperService.setSubQuesNum(subQues.getQuesAnswerWord(),curSubNum));
|
|
|
|
+ subQues.setQuesBodyWord(exportPaperService.replaceQuesBlank(subQues.getQuesBodyWord(),curSubNum));
|
|
|
|
+ List<QuesOption> subOptionList = subQues.getQuesOptions();
|
|
|
|
+ if (subOptionList != null && subOptionList.size() > 0) {
|
|
|
|
+ int sub_index = 0;
|
|
|
|
+ for (QuesOption quesOption : subOptionList) {
|
|
|
|
+ quesOption.setOptionBodyWord(exportPaperService.setOptionNum(quesOption.getOptionBodyWord(),exportPaperService.getOptionNum(sub_index)));
|
|
|
|
+ sub_index++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ int curSubNum = ++subNum;
|
|
|
|
+ question.setQuesBodyWord(exportPaperService.setSubQuesNum(question.getQuesBodyWord(), curSubNum));
|
|
|
|
+ question.setQuesAnswerWord(exportPaperService.setSubQuesNum(question.getQuesAnswerWord(),curSubNum));
|
|
|
|
+ question.setQuesBodyWord(exportPaperService.replaceQuesBlank(question.getQuesBodyWord(),curSubNum));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|