Kaynağa Gözat

提交通用题库BUG

chenken 7 yıl önce
ebeveyn
işleme
61ec7b782d

+ 57 - 0
cqb-comm-utils/src/main/java/com/qmth/cqb/utils/CommonUtils.java

@@ -9,8 +9,16 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
 import cn.com.qmth.examcloud.common.dto.question.enums.QuesStructType;
 
 /**
@@ -191,6 +199,55 @@ public final class CommonUtils {
             return null;  
         } 
     }
+    
+    /**
+     * 从A标签中获取属性值
+     * 例如从:
+     * <a id=\"123456\" name=\"1_1_1.mp3\">
+     * 中获取id的属性值为:123456
+     * 获取name的属性值为:1_1_1.mp3
+     * @param questionStr
+     * @param attrName
+     * @return
+     */
+    public static String getAttrValue(String questionStr,String attrName){
+    	Pattern pattern = Pattern.compile("a.*");
+		Matcher matcher = pattern.matcher(questionStr);
+		while(matcher.find()){
+		      String result = matcher.group();
+		      String idstr = attrName+"=\".*?\"";
+		      Pattern pattern02 = Pattern.compile(idstr);
+		      Matcher matcher02 = pattern02.matcher(result);
+		      while(matcher02.find()){
+		    	  return matcher02.group().replaceAll(attrName+"=\"", "").replaceAll("\"", "");
+		      }
+		}
+		return "";
+    }
+    
+    /**
+     * 从一段HTML字符串中取出标签中的属性值
+     * @param htmlString
+     * @return
+     * @throws DocumentException
+     */
+    public static List<String> getAttrValueFromString(String htmlString,String flagName,String attrName){
+    	List<String> idValues = new ArrayList<String>();
+		try {
+			Document document = DocumentHelper.parseText(htmlString);
+			Element rootElement = document.getRootElement();
+			List<Element> nodes = rootElement.elements(flagName);
+			for(Iterator<Element> itr = nodes.iterator();itr.hasNext();){
+				Element element = (Element) itr.next();
+				Attribute attr = element.attribute(attrName);  
+				idValues.add(attr.getValue());
+			}
+		} catch (DocumentException e) {
+			e.printStackTrace();
+		}
+		return idValues;
+    }
+    
 
     public static void main(String[] args) {
         // QuesStructType quesStructType = getEnum(QuesStructType.class,"单选");

+ 3 - 18
cqb-paper/src/main/java/com/qmth/cqb/paper/service/export/ExportPaperAbstractService.java

@@ -702,7 +702,8 @@ public abstract class ExportPaperAbstractService {
 				if("audio".equals(block.getType())){
 					computerTestPaper.setHasVideo(1);
 					PaperDetailUnit paperDetailUnit = paperDetailUnitRepo.findById(computerTestQuestion.getId());
-					QuestionAudio audio = questionAudioService.findByQuestionIdAndFileName(paperDetailUnit.getQuestion().getId(),block.getValue());
+					QuestionAudio audio = questionAudioService.findAudioById(block.getValue());
+					block.setValue(block.getValue()+"."+audio.getFileSuffixes());
 					if(audio!=null){
 						AudioTimeConfig audioTime = new AudioTimeConfig();
 						audioTime.setCourseCode(computerTestPaper.getCourseCode());
@@ -730,7 +731,6 @@ public abstract class ExportPaperAbstractService {
     	List<ComputerTestPaper> computerTestPapers = new ArrayList<ComputerTestPaper>();
     	//循环得到试卷
     	for(ExamPaper examPaper:examPapers){
-    		
     		Paper paper = examPaper.getPaper();
     		//得到所有旧对象的大题对象
     		List<PaperDetail> paperDetails = paperService.findPaperDetailsById(paper.getId());
@@ -869,7 +869,7 @@ public abstract class ExportPaperAbstractService {
 					&&questionRowStrings[i].contains("name")){	//处理音频
 				questionRowStrings[i] = "<"+questionRowStrings[i]+">";
 				block.setType("audio");
-				block.setValue(getAudioName(questionRowStrings[i]));
+				block.setValue(CommonUtils.getAttrValue(questionRowStrings[i],"id"));
 				blocks.add(block);
 			}else{
 				block.setType("text");
@@ -901,21 +901,6 @@ public abstract class ExportPaperAbstractService {
         return list;
     }
 
-    private String getAudioName(String questionStr){
-    	Pattern pattern = Pattern.compile("a.*");
-		Matcher matcher = pattern.matcher(questionStr);
-		while(matcher.find()){
-		      String result = matcher.group();
-		      String idstr = "id=\".*?\"";
-		      Pattern pattern02 = Pattern.compile(idstr);
-		      Matcher matcher02 = pattern02.matcher(result);
-		      while(matcher02.find()){
-		    	  return matcher02.group().replaceAll("id=\"", "").replaceAll("\"", "");
-		      }
-		}
-		return "";
-    }
-    
 	/**
      * 生成试卷或答案Word,上传至又拍云
      * @param orgName

+ 71 - 29
cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/ExtractConfigFileServiceImpl.java

@@ -11,9 +11,6 @@ import java.util.Set;
 
 import javax.servlet.http.HttpServletResponse;
 
-
-
-
 import main.java.com.UpYun;
 
 import org.apache.commons.io.FileUtils;
@@ -50,8 +47,11 @@ import com.qmth.cqb.paper.service.ExportStructureService;
 import com.qmth.cqb.paper.service.ExtractConfigFileService;
 import com.qmth.cqb.paper.service.ExtractConfigService;
 import com.qmth.cqb.paper.service.export.ExportPaperAbstractService;
+import com.qmth.cqb.question.model.QuesOption;
+import com.qmth.cqb.question.model.Question;
 import com.qmth.cqb.question.model.QuestionAudio;
 import com.qmth.cqb.question.service.QuestionAudioService;
+import com.qmth.cqb.utils.CommonUtils;
 import com.qmth.cqb.utils.FileDisposeUtil;
 import com.qmth.cqb.utils.SpringContextUtils;
 import com.qmth.cqb.utils.enums.ExamFileType;
@@ -171,26 +171,8 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
 		FileDisposeUtil.createDirectory(downloadDirectory);
 		//创建压缩文件的文件夹
 		FileDisposeUtil.createDirectory(zipDirectory);
-		//如果是批量导出,首先检查该考试下的所有课程是否都制定了调卷规则
-		List<String> paperIds = new ArrayList<String>();
-		ExportStructure exportStructure = exportStructureService.findStructureByExamId(exportModel.getExamId()+"");
-		//如果是普通类型的批量导出,并且选择了导出试卷结构
-		if(exportModel.getExportContentList().contains(ExamFileType.PAPER_STRUCTURE_OBJECTIVE.name())
-				&&exportModel.getExportWay()==ExportWay.BATCH){
-			if(exportStructure!=null&&exportStructure.getExportType()==ExportType.NORMAL){
-				paperIds = checkAllCourseByExamId(exportModel.getExamId(),exportStructure.getExportType());
-				if(paperIds.size()>0){
-					//创建试卷结构Excel文件到downloadDirectory目录
-					makePaperStructure(exportStructure.getExamName(),paperIds,exportStructure);
-				}
-			}			
-		}
-		//如果是普通类型的单个导出
-		if(exportModel.getExportWay()==ExportWay.SINGLE){
-			if(exportStructure==null||exportStructure.getExportType()==ExportType.NORMAL){
-				paperIds = getFinishPaperIds(exportModel);
-			}
-		}
+		//得到所有锁定的试卷ID
+		List<String> paperIds = getFinishPaperIds(exportModel);
 		//根据条件获取到文件下载路径,下载文件到服务器的downloadDirectory文件夹
 		List<ExamFile> examFiles = examFileService.findExamFileListByExportPaperInfoModel(exportModel);
 		if(examFiles!=null&&examFiles.size()>0){
@@ -224,12 +206,9 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
 					List<PaperDetailUnit> paperDetailUnits = paperDetailUnitRepo.findByPaperOrderByNumber(paper);
 					for(PaperDetailUnit unit:paperDetailUnits){
 						if(unit.getQuestion().getHasAudio()!=null&&unit.getQuestion().getHasAudio()){
-							String questionNumber = unit.getNumber()+"";
 							List<QuestionAudio> questionAudios = questionAudioService.findQuestionAudiosByQuestionId(unit.getQuestion().getId());
 							for(QuestionAudio audio:questionAudios){
-								//名称与题号保持一致
-								int index = audio.getFileName().indexOf("_");
-								String fileName = questionNumber+audio.getFileName().substring(index, audio.getFileName().length());
+								String fileName = getAudioFileName(audio,unit);
 								String audioFileName = examFile.getFileName().split("\\.")[0]+"_"+fileName;
 								UpYun upyun = new UpYun(bucketName,userName,password);
 								File file = new File(downloadDirectory+File.separator+audioFileName);
@@ -243,12 +222,76 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
 		}
 	}
 	
+	/**
+	 * 计算取得音频文件名称
+	 * @param audio
+	 * @param unit
+	 * @return
+	 */
+	private String getAudioFileName(QuestionAudio audio,PaperDetailUnit unit){
+		String questionAudioId = audio.getId();
+		StringBuffer audioFileName = new StringBuffer(unit.getNumber()+"_");
+		Question question = unit.getQuestion();
+		List<String> idvaluesBody = CommonUtils.getAttrValueFromString(question.getQuesBody(),"a","id");
+		if(idvaluesBody.contains(questionAudioId)){
+			audioFileName.append("1");//题干
+			audioFileName.append("_");
+			int index = idvaluesBody.indexOf(questionAudioId);
+			audioFileName.append(index+1);
+		}else{
+			List<QuesOption> options = question.getQuesOptions();
+			if(options!=null&&options.size()>0){
+				for(QuesOption option:options){
+					List<String> idvaluesOption = CommonUtils.getAttrValueFromString(option.getOptionBody(),"a","id");
+					if(idvaluesOption.contains(questionAudioId)){
+						audioFileName.append("2");//选项
+						audioFileName.append("_");
+						audioFileName.append(CommonUtils.getOptionNum(Integer.parseInt(option.getNumber())-1));
+						audioFileName.append("_");
+						int index = idvaluesOption.indexOf(questionAudioId);
+						audioFileName.append(index+1);
+						break;
+					}
+				}
+			}
+		}
+		audioFileName.append(".");
+		audioFileName.append(audio.getFileSuffixes());
+		return audioFileName.toString();
+	}
+	
 	/**
 	 * 得到调卷规则中已完成的试卷的ID集合
 	 * @param exportModel
 	 * @return
+	 * @throws Exception 
 	 */
-	private List<String> getFinishPaperIds(ExportPaperInfoModel exportModel) {
+	private List<String> getFinishPaperIds(ExportPaperInfoModel exportModel) throws Exception {
+		List<String> paperIds = new ArrayList<String>();
+		ExportStructure exportStructure = exportStructureService.findStructureByExamId(exportModel.getExamId()+"");
+		if(exportStructure==null){
+			exportStructure = new ExportStructure();
+			exportStructure.setExportType(ExportType.NORMAL);
+		}
+		//如果是普通类型的批量导出
+		if(exportModel.getExportWay()==ExportWay.BATCH){
+			paperIds = checkAllCourseByExamId(exportModel.getExamId(),exportStructure.getExportType());
+			if(exportStructure.getExportType()==ExportType.NORMAL){
+				if(paperIds.size()>0&&exportModel.getExportContentList().contains(ExamFileType.PAPER_STRUCTURE_OBJECTIVE.name())){
+					makePaperStructure(exportStructure.getExamName(),paperIds,exportStructure);
+				}
+			}
+		}
+		//如果是普通类型的单个导出
+		if(exportModel.getExportWay()==ExportWay.SINGLE){
+			if(exportStructure.getExportType()==ExportType.NORMAL){
+				paperIds = getSinglePaperFinishPaperIds(exportModel);
+			}
+		}
+		return paperIds;
+	}
+	
+	private List<String> getSinglePaperFinishPaperIds(ExportPaperInfoModel exportModel){
 		List<String> paperIds = new ArrayList<String>();
  		ExtractConfig condition = new ExtractConfig();
 		condition.setExamId(Long.parseLong(exportModel.getExamId()));
@@ -380,5 +423,4 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
     	logger.info("批量生成试卷结构完成");
 	}
 
-	
 }

+ 12 - 7
cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/ExtractConfigServiceImpl.java

@@ -9,7 +9,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
-import java.util.Map.Entry;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -61,10 +60,10 @@ import com.qmth.cqb.paper.service.ExtractConfigService;
 import com.qmth.cqb.paper.service.PaperDetailUnitService;
 import com.qmth.cqb.paper.service.PaperService;
 import com.qmth.cqb.question.dao.QuesRepo;
-import com.qmth.cqb.question.dao.QuestionAudioRepo;
 import com.qmth.cqb.question.model.QuesOption;
 import com.qmth.cqb.question.model.Question;
 import com.qmth.cqb.question.model.QuestionAudio;
+import com.qmth.cqb.question.service.QuestionAudioService;
 import com.qmth.cqb.utils.BeanCopierUtil;
 import com.qmth.cqb.utils.CommonUtils;
 import com.qmth.cqb.utils.enums.PaperType;
@@ -106,7 +105,7 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
     private QuesRepo quesRepo;
     
     @Autowired
-    private QuestionAudioRepo questionAudioRepo;
+    private QuestionAudioService questionAudioService;
 
     @Autowired
     private MongoTemplate mongoTemplate;
@@ -141,6 +140,13 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 
 	@Override
 	public Map<String, String> saveExtractConfig(ExtractConfig extractConfig,AccessUser accessUser) throws Exception {
+		List<ExamPaper> examPapers = extractConfig.getExamPaperList();
+		for(int i=0;i<examPapers.size();i++){
+			ExamPaper examPaper = examPapers.get(i);
+			Paper paper = examPaper.getPaper();
+			paper = paperRepo.findOne(paper.getId());
+			examPaper.setPaper(paper);
+		}
 		Course course = courseRepo.findFirstByCodeAndOrgId(extractConfig.getCourseCode(),extractConfig.getOrgId());
 		extractConfig.setCourse(course);
 		Map<String,String> newFinishedPaperIdMap = makePaperByConfig(extractConfig);
@@ -549,9 +555,8 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
         reorderChoicequestionOption(paperDetailUnit);
         Question ques = paperDetailUnit.getQuestion();
         QuestionDto dto = BeanCopierUtil.copyProperties(ques, QuestionDto.class);
-        
+        dto.setScore(paperDetailUnit.getScore());
         dto.setQuesOptions(buildQuestionOptionDto(ques.getQuesOptions()));
-        
         if (ques.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
             List<Question> subQuesList = ques.getSubQuestions();
             List<SubQuestionDto> subQuesDtos = BeanCopierUtil.copyPropertiesOfList(subQuesList, SubQuestionDto.class);
@@ -619,8 +624,8 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 			for(int i = 0;i<bodyStrings.length;i++){
 				String containAStr = bodyStrings[i];
 				if(containAStr.indexOf("<a")>-1){
-					String fileName = matchAudioName(containAStr, "a", "id");
-					QuestionAudio questionAudio = questionAudioRepo.findByQuestionIdAndFileName(questionDto.getId(),fileName);
+					String questionAudioId = matchAudioName(containAStr, "a", "id");
+					QuestionAudio questionAudio = questionAudioService.findAudioById(questionAudioId);
 					String url = downloadUrl + questionAudio.getFileUrl();
 					if(questionDto.getPlayTime()!=null){
 						containAStr += " question-audio url=\""+url+"\" playTime=\""+questionDto.getPlayTime()+"\""+"></a>";

+ 3 - 3
cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/PaperServiceImpl.java

@@ -1081,7 +1081,7 @@ public class PaperServiceImpl implements PaperService{
 				String quesBody = question.getQuesBody();
 				if(!quesBody.contains(fileName)){
 					String quesBodyNew = quesBody.substring(0, quesBody.lastIndexOf("</p>")) 
-							+ "<a id=\"" + fileName + "\" name=\"" + fileName + "\"></a></p>";
+							+ "<a id=\"" + questionAudio.getId() + "\" name=\"" + fileName + "\"></a></p>";
 					question.setQuesBody(quesBodyNew);
 				}
 			}else {
@@ -1093,10 +1093,10 @@ public class PaperServiceImpl implements PaperService{
 						if(!optionBody.contains(fileName)){
 							String optionBodyNew = "";
 							if(StringUtils.isBlank(optionBody)){
-								optionBodyNew = "<p><a id=\""+fileName+"\" name=\""+fileName+"\"></a></p>";
+								optionBodyNew = "<p><a id=\""+questionAudio.getId()+"\" name=\""+fileName+"\"></a></p>";
 							}else{
 								optionBodyNew = optionBody.substring(0, optionBody.lastIndexOf("</p>")) 
-										+ "<a id=\""+fileName+"\" name=\""+fileName+"\"></a></p>";
+										+ "<a id=\""+questionAudio.getId()+"\" name=\""+fileName+"\"></a></p>";
 							}
 							quesOption.setOptionBody(optionBodyNew);
 						}

+ 17 - 0
cqb-question-resource/src/main/java/com/qmth/cqb/question/model/QuestionAudio.java

@@ -3,6 +3,8 @@ package com.qmth.cqb.question.model;
 import java.io.Serializable;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
+
 /**
  * @author  	chenken
  * @date    	2017年8月1日 上午10:56:23
@@ -30,6 +32,10 @@ public class QuestionAudio implements Serializable{
 	 * 文件名称
 	 */
 	private String fileName;
+	/**
+	 * 文件后缀
+	 */
+	private String fileSuffixes;
 	/**
 	 * 存放路径
 	 */
@@ -48,6 +54,9 @@ public class QuestionAudio implements Serializable{
 	public QuestionAudio(String questionId,String fileName,String fileUrl){
 		this.questionId = questionId;
 		this.fileName = fileName;
+		if(StringUtils.isNotBlank(fileName)){
+			this.fileSuffixes = fileName.substring(fileName.indexOf(".")+1,fileName.length());
+		}
 		this.fileUrl = fileUrl;
 	}
 	
@@ -88,4 +97,12 @@ public class QuestionAudio implements Serializable{
 		this.createUser = createUser;
 	}
 
+	public String getFileSuffixes() {
+		return fileSuffixes;
+	}
+
+	public void setFileSuffixes(String fileSuffixes) {
+		this.fileSuffixes = fileSuffixes;
+	}
+	
 }

+ 7 - 0
cqb-question-resource/src/main/java/com/qmth/cqb/question/service/QuestionAudioService.java

@@ -14,6 +14,13 @@ import com.qmth.cqb.question.model.QuestionAudio;
  * @description QuestionRadioService.java
  */
 public interface QuestionAudioService {
+	
+	/**
+	 * 使用ID查询音频
+	 * @param id
+	 * @return
+	 */
+	public QuestionAudio findAudioById(String id);
 	/**
 	 * 保存试题音频文件记录
 	 * @param questionRadio

+ 8 - 0
cqb-question-resource/src/main/java/com/qmth/cqb/question/service/impl/QuestionAudioServiceImpl.java

@@ -96,5 +96,13 @@ public class QuestionAudioServiceImpl implements QuestionAudioService{
 		}
 	}
 
+	@Override
+	public QuestionAudio findAudioById(String id) {
+		if(StringUtils.isNotBlank(id)){
+			return questionAudioRepo.findOne(id);
+		}
+		return null;
+	}
+
 }
 

+ 7 - 0
cqb-question-resource/src/main/java/com/qmth/cqb/question/web/QuestionAudioController.java

@@ -32,5 +32,12 @@ public class QuestionAudioController {
 		QuestionAudio questionAudio = questionAudioService.findByQuestionIdAndFileName(questionId, fileName);
 		return new ResponseEntity(questionAudio, HttpStatus.OK);
 	}
+	
+	@ApiOperation(value = "通过ID获取试题音频文件", notes = "通过ID获取试题音频文件")
+    @GetMapping(value = "/questionAudio/{questionAudioId}")
+	public ResponseEntity findQuestionAudioById(@PathVariable String questionAudioId){
+		QuestionAudio questionAudio = questionAudioService.findAudioById(questionAudioId);
+		return new ResponseEntity(questionAudio, HttpStatus.OK);
+	} 
 }
 

+ 4 - 4
cqb-starter/src/test/java/com/qmth/cqb/ExtractConfigServiceTest.java

@@ -151,10 +151,10 @@ public class ExtractConfigServiceTest {
 	}
 	@Test
 	public void testGetQuestionById(){
-		String examId = "117";
-		String paperDetailUnitId = "59ace6ec0fe2d25e666b1a08";
-		String courseCode = "000008";
-		String groupCode = "O";
+		String examId = "189";
+		String paperDetailUnitId = "59b8d7200fe2d22f92f48bdc";
+		String courseCode = "000001";
+		String groupCode = "A";
 		QuestionDto dto = extractConfigService.extractExamQuestion(examId,courseCode,groupCode,paperDetailUnitId);
 		System.out.println(dto.getQuesAnswer());
 	}