Ver código fonte

导入报错提示优化(总分较验可配置 、小题数量核对 、答案核对)

chenken 8 anos atrás
pai
commit
4100d1be86

+ 152 - 56
cqb-paper/src/main/java/com/qmth/cqb/paper/service/ImportPaperService.java

@@ -4,6 +4,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -93,11 +94,10 @@ public class ImportPaperService {
      * @param file
      * @return
      */
-    public Paper ImportPaper(String paperName, String courseNo, String courseName, AccessUser user,
+    public Paper ImportPaper(Paper paper, AccessUser user,
             File file) throws Exception {
-        paperService.checkPaperNameNew(paperName, user.getRootOrgId().toString());
-        Paper paper = processImportPaper(paperName,courseNo,courseName,user,file);
-        return paper;
+        paperService.checkPaperNameNew(paper.getName(), user.getRootOrgId().toString());
+        return processImportPaper(paper,user,file);
     }
 
     /**
@@ -107,16 +107,23 @@ public class ImportPaperService {
      * @param paperDetails
      * @param paperDetailUnits
      * @param importPaperCheck
+     * @throws PaperException 
      */
-    public Paper savePaper(Paper paper, List paperDetails, List paperDetailUnits, List questions,
-            ImportPaperCheck importPaperCheck) {
-
+    public Paper savePaper(Paper paper, List<PaperDetail> paperDetails, 
+    									List<PaperDetailUnit> paperDetailUnits, 
+    									List<Question> questions,
+    									ImportPaperCheck importPaperCheck) throws Exception {
         Paper tempPaper = null;
-
         if (!StringUtils.isEmpty(importPaperCheck.errorInfo))
             return null;
-
         if (paper != null) {
+        	//总分校验
+        	checkTotalScore(paper,paperDetailUnits,importPaperCheck);
+        	//大题下小题数量校验
+        	checkUnitNum(paperDetailUnits,importPaperCheck);
+        	//校验答案是否不全
+        	checkAnswerISfull(paperDetailUnits,importPaperCheck);
+        	
             tempPaper = paperRepo.save(paper);
         }
 
@@ -171,9 +178,7 @@ public class ImportPaperService {
      * @param file
      * @return
      */
-    public Paper processImportPaper(String paperName, String courseNo, String courseName, AccessUser user,
-            File file) throws Exception {
-        Map<String, Object> msgMap = new HashMap<String, Object>();
+    public Paper processImportPaper(Paper paper,AccessUser user,File file) throws Exception {
         WordprocessingMLPackage wordMLPackage;
         WordprocessingMLPackage tmpWordMlPackage;
         WordprocessingMLPackage writePkg;
@@ -186,89 +191,57 @@ public class ImportPaperService {
         tmpWordMlPackage = DocxProcessUtil.getTmpPackage(wordMLPackage);
         writePkg = DocxProcessUtil.getTmpPackage(wordMLPackage);
         byte[] writeByte = DocxProcessUtil.getPkgByte(writePkg);
-
         // 获取word文档中所有段落
         List<Object> pList = DocxProcessUtil.getAllElementFromObject(wordMLPackage.getMainDocumentPart(), P.class);
-
-        // 创建试卷类
-        Paper paper = new Paper();
-
-        paper.setCourseNo(courseNo);
-
-        paper.setCourseName(courseName);
-
         paper.setOrgId(user.getRootOrgId().toString());
-
         paper.setCreator(user.getName());
-
         // 设置试卷
-        initPaper(paper, paperName);
-
+        initPaper(paper, paper.getName());
         // 创建空大题类
         PaperDetail paperDetail = null;
-
         // 创建大题集合
         List<PaperDetail> paperDetails = new ArrayList<PaperDetail>();
-
         // 创建小题集合
         List<PaperDetailUnit> paperDetailUnits = new ArrayList<PaperDetailUnit>();
-
         // 创建试题集合
         List<Question> questions = new ArrayList<Question>();
-
         // 大题号
         int mainQuesNum = 0;
-
         // 小题号
         int subQuesNum = 0;
-
         for (int i = 0; i < pList.size(); i++) {
             P p = (P) pList.get(i);
             String pText = DocxProcessUtil.getPText(p);
-
             if (StringUtils.isEmpty(pText)) {
                 // 跳过空白段落
                 continue;
-
             } else if (isQuesHeader(pText)) {
                 // 处理大题头信息
                 processMainQuesHeader(pList, importPaperCheck.index, importPaperCheck);
-
                 // 校验大题头信息
                 if (!checkQuesHeader(importPaperCheck)) {
                     throw new PaperException(importPaperCheck.errorInfo);
                 }
-
                 // 创建大题类
                 paperDetail = new PaperDetail();
-
                 // 设置大题类
                 initQuesHeader(paper, paperDetail, paperDetails, ++mainQuesNum, importPaperCheck);
-
                 // 设置当前索引,防止多余循环
                 i = importPaperCheck.index - 1;
-
             } else if (pText.matches("^\\d{1,}\\.[\\s\\S]*")
                     || (isNested(importPaperCheck) && !pText.startsWith("["))) {
-
                 if(paperDetail == null){
                     throw new PaperException("导入文件格式有误,必须有大题头信息,且以 [ 开头!");
                 }
-
                 ++subQuesNum;
-
                 // 处理试题
-
                 // 创建小题类和试题类
                 PaperDetailUnit paperDetailUnit = new PaperDetailUnit();
                 Question question = new Question();
-
                 // 初始化小题类和试题类
                 initPaperDetail(paper, paperDetail, paperDetailUnit, question, subQuesNum , importPaperCheck);
-
                 // 处理客观题
                 if (importPaperCheck.quesType.equals("单选") || importPaperCheck.quesType.equals("多选")) {
-
                     // 处理题干
                     processQuesBody(pList, importPaperCheck.index, subQuesNum, question, importPaperCheck, tmpWordMlPackage);
                     // 处理选项
@@ -297,7 +270,6 @@ public class ImportPaperService {
                 question.setOrgId(user.getRootOrgId().toString());
                 questions.add(question);
                 paperDetailUnits.add(paperDetailUnit);
-
                 // 设置当前索引,防止多余循环
                 i = importPaperCheck.index - 1;
             }else if(paperDetail == null){
@@ -635,12 +607,15 @@ public class ImportPaperService {
                 // 检测到答案开始段落
                 pAnswer = DocxProcessUtil.formatP(pAnswer, QuesUnit.QUES_ANSWER);
                 String tmpWordMl = DocxProcessUtil.getPWordMl(pAnswer);
-
                 if (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
-                        || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION
-                        || question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION) {
+                        || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
+                	//校验单选多选答案
+                	checkAnswer(question,pList.get(i).toString(),importPaperCheck,subQuesNum);
                     answerWordML.append(DocxProcessUtil.formatPWordMl(tmpWordMl));
                     answerHTML.append(tmpText.replaceAll("\\[答案\\]", "").replaceAll("[:|:]", "").trim());
+                }else if(question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION){
+                	answerWordML.append(DocxProcessUtil.formatPWordMl(tmpWordMl));
+                    answerHTML.append(tmpText.replaceAll("\\[答案\\]", "").replaceAll("[:|:]", "").trim());
                 }else{
                     answerWordML.append(DocxProcessUtil.formatPWordMl(tmpWordMl));
                     answerHTML.append(DocxProcessUtil.docx2Html(tmpWordMl, wordMLPackage));
@@ -662,14 +637,10 @@ public class ImportPaperService {
             }
         }
         importPaperCheck.setIndex(i);
-        // 校验答案
+        // 设置答案
         if (StringUtils.isNotEmpty(answerHTML)) {
             question.setQuesAnswer(answerHTML.toString());
             question.setQuesAnswerWord(answerWordML.toString());
-        } else {
-            importPaperCheck.setErrorInfo(getQuesNumInfo(importPaperCheck.quesName, subQuesNum)
-                    + "答案为空或格式不正确\n");
-            throw new PaperException(importPaperCheck.errorInfo);
         }
 
         // 设置预设分数
@@ -700,8 +671,6 @@ public class ImportPaperService {
                     quesOption.setIsCorrect((short) 0);
                 }
             }
-            // 选择题答案不持久化
-            //question.setQuesAnswer(null);
         }
     }
 
@@ -956,4 +925,131 @@ public class ImportPaperService {
         returnMap.put("msg", "success");
         return returnMap;
     }
+    /**
+     * 校验试卷总分是否与设定一致
+     * @param paper
+     * @param paperDetailUnits
+     * @param importPaperCheck
+     * @throws PaperException
+     */
+    private void checkTotalScore(Paper paper,List<PaperDetailUnit> paperDetailUnits,ImportPaperCheck importPaperCheck) throws PaperException{
+    	double totalScore = 0;
+        for (PaperDetailUnit unit : paperDetailUnits) {
+            if (unit.getScore() != null) {
+                totalScore += unit.getScore();
+            }
+        }
+    	if(paper.getTotalScore()!=null&&paper.getTotalScore()!=totalScore){
+    		importPaperCheck.setErrorInfo("试卷总分("+totalScore+")与设置总分("+paper.getTotalScore()+")不符");
+    		throw new PaperException(importPaperCheck.errorInfo);
+    	}
+    }
+    
+    /**
+     * 校验大题下小题数量是否与标识数量一致
+     * @throws PaperException 
+     */
+    private void checkUnitNum(List<PaperDetailUnit> paperDetailUnits,ImportPaperCheck importPaperCheck) throws PaperException{
+    	Map<PaperDetail, Integer> unitNumMap = new HashMap<PaperDetail, Integer>();
+    	Collections.sort(paperDetailUnits);
+    	for(PaperDetailUnit paperDetailUnit:paperDetailUnits){
+    		PaperDetail key = paperDetailUnit.getPaperDetail();
+    		if(unitNumMap.containsKey(key)){
+    			int value = unitNumMap.get(key);
+    			if(paperDetailUnit.getQuestionType()==QuesStructType.NESTED_ANSWER_QUESTION){
+    				unitNumMap.put(key,value+paperDetailUnit.getSubScoreList().size());
+    			}else{
+    				unitNumMap.put(key, value+1);
+    			}
+    		}else{
+    			if(paperDetailUnit.getQuestionType()==QuesStructType.NESTED_ANSWER_QUESTION){
+    				unitNumMap.put(key,paperDetailUnit.getSubScoreList().size());
+    			}else{
+    				unitNumMap.put(key, 1);
+    			}
+    		}
+    	}
+    	for (Map.Entry<PaperDetail, Integer> entry : unitNumMap.entrySet()) {
+    		PaperDetail paperDetail = entry.getKey();
+    		if(paperDetail.getUnitCount()!=entry.getValue()){
+    			importPaperCheck.setErrorInfo("大题:"+paperDetail.getName()
+    												+"标识小题数量("+paperDetail.getUnitCount()
+    												+")与实际小题数量("+entry.getValue()+")不符 ");
+        		throw new PaperException(importPaperCheck.errorInfo);
+    		}
+    	}
+    }
+    /**
+     * 校验选择题答案
+     * 1.判断答案格式,选择题答案必须以","分隔,且都为字母
+     * 2.判断答案在选项中是否不存在,例如选项为A,B,C,D,答案为E
+     * @param question
+     * @param answerWord
+     * @param importPaperCheck
+     * @throws PaperException 
+     */
+    private void checkAnswer(Question question,String answerWord,ImportPaperCheck importPaperCheck,int subQuesNum) throws PaperException{
+    	if(!StringUtils.isBlank(answerWord)){
+    		String[] pAnswerArray = answerWord.split(",");
+    		List<QuesOption> options = question.getQuesOptions();
+        	List<String> optionNumList = new ArrayList<String>();
+        	for(QuesOption quesOption:options){
+        		Integer numInteger = Integer.parseInt(quesOption.getNumber());
+        		char word = (char)(numInteger+64);
+        		optionNumList.add(word+"");
+    		}
+        	for(String answer:pAnswerArray){
+        		String reg="([A-Z]|[a-z])";
+        		if(!answer.matches(reg)){
+        			importPaperCheck.setErrorInfo(getQuesNumInfo(importPaperCheck.quesName, subQuesNum)+
+       					 "中,答案格式不正确,答案为:"+answerWord);
+       	         	throw new PaperException(importPaperCheck.errorInfo);
+        		}
+        		if(!optionNumList.contains(answer)){
+        			 importPaperCheck.setErrorInfo(getQuesNumInfo(importPaperCheck.quesName, subQuesNum)+
+        					 "中,选项为:"+optionNumList.toString()+",答案为:"+answerWord);
+        	         throw new PaperException(importPaperCheck.errorInfo);
+        		}
+        	}
+    	}
+    }
+    /**
+     * 校验客观题答案完整性
+     * 客观题答案要么全有,要么全没有
+     * @throws PaperException 
+     */
+    private void checkAnswerISfull(List<PaperDetailUnit> paperDetailUnits,ImportPaperCheck importPaperCheck) throws PaperException{
+    	List<PaperDetailUnit> paperDetailUnitList = new ArrayList<PaperDetailUnit>();
+    	for(PaperDetailUnit paperDetailUnit:paperDetailUnits){
+    		Question question = paperDetailUnit.getQuestion();
+    		if(question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
+                        || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION
+                        || question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION){
+    			paperDetailUnitList.add(paperDetailUnit);
+    		}
+    	}
+    	boolean isNull = false;
+    	boolean isNotNull = false;
+    	PaperDetailUnit paperDetailUnit = new PaperDetailUnit();
+    	for(PaperDetailUnit pdu:paperDetailUnitList){
+    		Question question = pdu.getQuestion();
+    		if(StringUtils.isBlank(question.getQuesAnswer())){
+    			isNull = true;
+    			paperDetailUnit = pdu;
+    			break;
+    		}
+    	}
+    	for(PaperDetailUnit pdu:paperDetailUnitList){
+    		Question question = pdu.getQuestion();
+    		if(StringUtils.isNotBlank(question.getQuesAnswer())){
+    			isNotNull = true;
+    			break;
+    		}
+    	}
+    	//不满足(客观题答案要么全有,要么全没有)条件
+    	if(isNull&&isNotNull){
+    		importPaperCheck.setErrorInfo("第"+paperDetailUnit.getNumber()+"小题答案缺失,请检查");
+	        throw new PaperException(importPaperCheck.errorInfo);
+    	}
+    }
 }

+ 11 - 4
cqb-paper/src/main/java/com/qmth/cqb/paper/service/PaperService.java

@@ -110,10 +110,17 @@ public class PaperService {
      * @return
      */
     public Page<Paper> getImportPapers(PaperSearchInfo paperSearchInfo, int curPage, int pageSize) {
-        formatPaperSearchInfo(paperSearchInfo);
-        Paper importPaper = BeanCopierUtil.copyProperties(paperSearchInfo, Paper.class);
-        importPaper.setPaperType(PaperType.IMPORT);
-        return paperRepo.findAll(Example.of(importPaper), new PageRequest(curPage - 1, pageSize));
+        Query query = new Query();
+        query.addCriteria(Criteria.where("paperType").is(PaperType.IMPORT));
+        if(StringUtils.isNotBlank(paperSearchInfo.getCourseNo())){
+        	query.addCriteria(Criteria.where("courseNo").is(paperSearchInfo.getCourseNo()));
+        }
+        long count = this.mongoTemplate.count(query, Paper.class);
+        query.with(new Sort(new Order(Direction.DESC,"createTime")));
+        query.limit(pageSize);
+        query.skip((curPage - 1) * pageSize);
+        List<Paper> paperList = this.mongoTemplate.find(query, Paper.class);
+        return new PageImpl<Paper>(paperList, new PageRequest(curPage - 1, pageSize), count);
     }
 
     /**

+ 7 - 5
cqb-paper/src/main/java/com/qmth/cqb/paper/web/ImportPaperController.java

@@ -7,14 +7,18 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 
 import cn.com.qmth.examcloud.common.util.ErrorMsg;
+
 import com.qmth.cqb.paper.model.Paper;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
@@ -60,17 +64,15 @@ public class ImportPaperController {
     @Uac(roles={RoleMeta.QUESTION_ADMIN,RoleMeta.SUPER_ADMIN},policy=UacPolicy.IN)
     @PostMapping(value = "/importPaper")
     public ResponseEntity importPaper(HttpServletRequest request, 
-                                        @RequestParam String paperName,
-                                        @RequestParam String courseNo, 
-                                        @RequestParam String courseName,
+                                        @ModelAttribute  Paper paper,
                                         @RequestParam("file") CommonsMultipartFile file) {
         AccessUser user = (AccessUser) request.getAttribute("accessUser");
         log.info("导入开始");
         File tempFile = null;
         try {
             tempFile = importPaperService.getUploadFile(file);
-            Paper paper = importPaperService.ImportPaper(paperName, courseNo, courseName, user, tempFile);
-            return new ResponseEntity(paper, HttpStatus.OK);
+            Paper newPaper = importPaperService.ImportPaper(paper, user, tempFile);
+            return new ResponseEntity(newPaper, HttpStatus.OK);
         } catch (Exception e) {
             e.printStackTrace();
             log.error("导入异常:" + e.getMessage());