Эх сурвалжийг харах

Merge remote-tracking branch 'origin/dev0410' into dev1130

# Conflicts:
#	cqb-comm-utils/src/main/java/com/qmth/cqb/utils/FileDisposeUtil.java
#	cqb-gen-paper/src/main/java/com/qmth/cqb/genpaper/web/GenPaperController.java
#	cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/PaperServiceImpl.java
宋悦 7 жил өмнө
parent
commit
da8f913826
16 өөрчлөгдсөн 450 нэмэгдсэн , 57 устгасан
  1. 38 1
      cqb-comm-utils/src/main/java/com/qmth/cqb/utils/CommonUtils.java
  2. 2 2
      cqb-comm-utils/src/main/java/com/qmth/cqb/utils/FileDisposeUtil.java
  3. 26 2
      cqb-gen-paper/src/main/java/com/qmth/cqb/genpaper/web/GenPaperController.java
  4. 33 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/PaperDetailDtoAssembler.java
  5. 35 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/PaperDetailUnitDtoAssembler.java
  6. 30 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/PaperDtoAssembler.java
  7. 48 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/SubQuestionDtoAssembler.java
  8. 8 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/model/PaperDetailUnit.java
  9. 9 3
      cqb-paper/src/main/java/com/qmth/cqb/paper/service/export/ExportPaperAbstractService.java
  10. 4 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/service/export/SddxExportPaperService.java
  11. 2 0
      cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/ExportPaperServiceImpl.java
  12. 123 40
      cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/ExtractConfigServiceImpl.java
  13. 1 1
      cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/PaperServiceImpl.java
  14. 5 5
      cqb-starter/src/main/resources/application-dev.properties
  15. 3 3
      cqb-starter/src/main/resources/application-test.properties
  16. 83 0
      cqb-starter/src/test/java/com/qmth/cqb/ExtractConfigServiceTest.java

+ 38 - 1
cqb-comm-utils/src/main/java/com/qmth/cqb/utils/CommonUtils.java

@@ -6,14 +6,15 @@ import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
-import com.qmth.cqb.utils.word.DocxProcessUtil;
 import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.dom4j.Attribute;
@@ -23,6 +24,7 @@ import org.dom4j.DocumentHelper;
 import org.dom4j.Element;
 
 import cn.com.qmth.examcloud.common.dto.question.enums.QuesStructType;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -413,6 +415,41 @@ public final class CommonUtils {
         }
         return str.replaceAll("[\\t\\r\\f]*","");
     }
+    
+    /**
+	 * 替换掉字符串的Unicode字符为中文字符
+	 * 如下所示
+	 * \u0026ldquo;=“
+	 * \u0026mdash;=—
+	 * \u0026lt;=<
+	 * \u0026hellip;=… 
+	 * \u0026rdquo;=”
+	 * \u0026gt;=>
+	 */
+	public static String replaceUnicodeStr(String content){
+		try {
+			Pattern pattern = Pattern.compile("\\\\u\\w+;");
+			Matcher matcher = pattern.matcher(content);
+			Map<String,String> unicodeMap = new HashMap<String, String>();
+			while(matcher.find()){
+			      String unicodeStr = matcher.group();
+			      byte[] unicodeStrByte = unicodeStr.getBytes();
+				  String resultByte = new String(unicodeStrByte,"utf-8");
+				  String escapeStr = StringEscapeUtils.unescapeHtml4(StringEscapeUtils.unescapeEcmaScript(resultByte));
+				  unicodeMap.put(unicodeStr, escapeStr);
+			}
+			System.out.println(unicodeMap);
+			if(unicodeMap.size()>0){
+				for(String key:unicodeMap.keySet()){
+					 //replace函数替换时忽略正则表达式符号,replaceAll和replaceFirst函数替换时是使用正则表达式匹配的。
+					content = content.replace(key, unicodeMap.get(key));
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return content;
+	}
 
     public static void main(String[] args) throws Exception{
         // QuesStructType quesStructType = getEnum(QuesStructType.class,"单选");

+ 2 - 2
cqb-comm-utils/src/main/java/com/qmth/cqb/utils/FileDisposeUtil.java

@@ -106,8 +106,8 @@ public class FileDisposeUtil {
 	        //设置Content-Disposition,名称强制为UTF-8
 			//String fileEncode = System.getProperty("file.encoding");
 	        //response.setHeader("Content-Disposition", "attachment;filename="+new String(filename.getBytes(fileEncode),"UTF-8"));
-			response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8")); 
-			// 设置强制下载不打开
+	        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename,"UTF-8"));
+	         // 设置强制下载不打开
 	         response.setContentType("application/octet-stream;charset=utf-8");
 	        //读取目标文件,通过response将目标文件写到客户端  
 	        //获取目标文件的绝对路径  

+ 26 - 2
cqb-gen-paper/src/main/java/com/qmth/cqb/genpaper/web/GenPaperController.java

@@ -35,7 +35,7 @@ public class GenPaperController {
 
     @Autowired
     GenPaperService genPaperService;
-    
+
     @Autowired
     PaperService paperService;
 
@@ -48,6 +48,18 @@ public class GenPaperController {
         genPaperDto.setCreator(user.getName());
         Map<String, Object> paperMap = new HashMap<String, Object>();
         String paperName = genPaperDto.getPaperName();
+        //判断试卷名称是否一样
+        try {
+			boolean result;
+			result = paperService.checkPaperName(paperName, PaperType.GENERATE,user.getRootOrgId()+"");
+			if(!result){
+				String msg = "考试试卷:"+paperName+"已经存在";
+				paperMap.put("msg", msg);
+	            return new ResponseEntity(paperMap, HttpStatus.INTERNAL_SERVER_ERROR);
+			}
+		} catch (Exception e) {
+			return new ResponseEntity(e.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
+		}
         if (genPaperDto.getGenNumber() == 1) {
             if (genPaperDto.getSimpleGenPaperPolicy().getKey() == 1L) {
                 paperMap = genPaperService.genPaperByQuestionNum(genPaperDto);
@@ -93,6 +105,18 @@ public class GenPaperController {
         genPaperDto.setCreator(user.getName());
         Map<String, Object> paperMap = new HashMap<String, Object>();
         String paperName = genPaperDto.getPaperName();
+        //判断试卷名称是否一样
+        try {
+			boolean result;
+			result = paperService.checkPaperName(paperName, PaperType.GENERATE,user.getRootOrgId()+"");
+			if(!result){
+				String msg = "考试试卷:"+paperName+"已经存在";
+				paperMap.put("msg", msg);
+	            return new ResponseEntity(paperMap, HttpStatus.INTERNAL_SERVER_ERROR);
+			}
+		} catch (Exception e) {
+			return new ResponseEntity(e.getMessage(),HttpStatus.INTERNAL_SERVER_ERROR);
+		}
         if (genPaperDto.getGenNumber() > 1) {
             for (int i = 1; i <= genPaperDto.getGenNumber(); i++) {
                 genPaperDto.setPaperName(paperName + "_" + i);
@@ -110,7 +134,7 @@ public class GenPaperController {
             return new ResponseEntity(paperMap, HttpStatus.INTERNAL_SERVER_ERROR);
         }
     }
-    
+
     @ApiOperation(value = "蓝图组卷", notes = "蓝图组卷")
     @Uac(roles={RoleMeta.QUESTION_ADMIN,RoleMeta.SUPER_ADMIN},policy=UacPolicy.IN)
     @PostMapping("/genPaper/blue")

+ 33 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/PaperDetailDtoAssembler.java

@@ -0,0 +1,33 @@
+package com.qmth.cqb.paper.assemble;
+
+import cn.com.qmth.examcloud.common.dto.question.PaperDetailDto;
+import com.qmth.cqb.paper.model.PaperDetail;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by songyue on 18/1/5.
+ */
+@Component
+public class PaperDetailDtoAssembler {
+
+    public PaperDetailDto toDto(PaperDetail paperDetail){
+        PaperDetailDto paperDetailDto = new PaperDetailDto();
+        paperDetailDto.setId(paperDetail.getId());
+        paperDetailDto.setName(paperDetail.getName());
+        paperDetailDto.setNumber(paperDetail.getNumber());
+        paperDetailDto.setScore(paperDetail.getScore());
+        return paperDetailDto;
+    }
+
+    public List<PaperDetailDto> toDtoList(List<PaperDetail> paperDetailList){
+        List<PaperDetailDto> paperDetailDtos = new ArrayList<>();
+        for(PaperDetail paperDetail:paperDetailList){
+            paperDetailDtos.add(toDto(paperDetail));
+        }
+        return paperDetailDtos;
+    }
+}

+ 35 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/PaperDetailUnitDtoAssembler.java

@@ -0,0 +1,35 @@
+package com.qmth.cqb.paper.assemble;
+
+import cn.com.qmth.examcloud.common.dto.question.PaperDetailUnitDto;
+import com.qmth.cqb.paper.model.PaperDetailUnit;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by songyue on 18/1/5.
+ */
+@Component
+public class PaperDetailUnitDtoAssembler {
+
+    public PaperDetailUnitDto toDto(PaperDetailUnit paperDetailUnit){
+        PaperDetailUnitDto paperDetailUnitDto = new PaperDetailUnitDto();
+        paperDetailUnitDto.setId(paperDetailUnit.getId());
+        paperDetailUnitDto.setNumber(paperDetailUnit.getNumber());
+        paperDetailUnitDto.setScore(paperDetailUnit.getScore());
+        paperDetailUnitDto.setOptionOrder(paperDetailUnit.getOptionOrder());
+        paperDetailUnitDto.setQuestionType(paperDetailUnit.getQuestionType());
+        paperDetailUnitDto.setSubScoreList(paperDetailUnit.getSubScoreList());
+        return paperDetailUnitDto;
+    }
+
+    public List<PaperDetailUnitDto> toDtoList(List<PaperDetailUnit> paperDetailUnitList){
+        List<PaperDetailUnitDto> paperDetailUnitDtos = new ArrayList<>();
+        for(PaperDetailUnit pdu:paperDetailUnitList){
+            paperDetailUnitDtos.add(toDto(pdu));
+        }
+        return paperDetailUnitDtos;
+    }
+}

+ 30 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/PaperDtoAssembler.java

@@ -0,0 +1,30 @@
+package com.qmth.cqb.paper.assemble;
+
+import cn.com.qmth.examcloud.common.dto.question.PaperDto;
+import com.qmth.cqb.paper.model.Paper;
+import org.springframework.stereotype.Component;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by songyue on 18/1/5.
+ */
+@Component
+public class PaperDtoAssembler {
+
+    public PaperDto toDto(Paper paper){
+        PaperDto paperDto = new PaperDto();
+        paperDto.setId(paper.getId());
+        paperDto.setName(paper.getName());
+        paperDto.setTitle(paper.getTitle());
+        paperDto.setParams(paper.getParams());
+        paperDto.setTotalScore(paper.getTotalScore());
+        return paperDto;
+    }
+
+    public List<PaperDto> toDtoList(List<Paper> paperList){
+        return paperList.stream()
+                .map(paper -> toDto(paper))
+                .collect(Collectors.toList());
+    }
+}

+ 48 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/assemble/SubQuestionDtoAssembler.java

@@ -0,0 +1,48 @@
+package com.qmth.cqb.paper.assemble;
+
+import cn.com.qmth.examcloud.common.dto.question.QuesOptionDto;
+import cn.com.qmth.examcloud.common.dto.question.SubQuestionDto;
+import com.qmth.cqb.question.model.QuesOption;
+import com.qmth.cqb.question.model.Question;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by songyue on 18/1/5.
+ */
+@Component
+public class SubQuestionDtoAssembler {
+
+    public SubQuestionDto toDto(Question question){
+        SubQuestionDto subQuestionDto = new SubQuestionDto();
+        subQuestionDto.setQuestionType(question.getQuestionType());
+        subQuestionDto.setNumber(question.getNumber());
+        subQuestionDto.setScore(question.getScore());
+        subQuestionDto.setQuesAnswer(question.getQuesAnswer());
+        subQuestionDto.setQuesBody(question.getQuesBody());
+        subQuestionDto.setQuesParams(question.getQuesParams());
+        subQuestionDto.setQuesOptions(toOptionDtoList(question.getQuesOptions()));
+        return subQuestionDto;
+    }
+
+    public QuesOptionDto toOptionDto(QuesOption quesOption){
+        QuesOptionDto quesOptionDto = new QuesOptionDto();
+        quesOptionDto.setNumber(quesOption.getNumber());
+        quesOptionDto.setOptionBody(quesOption.getOptionBody());
+        return quesOptionDto;
+    }
+
+    public List<SubQuestionDto> toDtoList(List<Question> questionList){
+        return questionList.stream()
+                .map(question -> toDto(question))
+                .collect(Collectors.toList());
+    }
+
+    public List<QuesOptionDto> toOptionDtoList(List<QuesOption> quesOptionList){
+        return quesOptionList.stream()
+                .map(quesOption -> toOptionDto(quesOption))
+                .collect(Collectors.toList());
+    }
+}

+ 8 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/model/PaperDetailUnit.java

@@ -264,4 +264,12 @@ public class PaperDetailUnit implements Serializable, Comparable<PaperDetailUnit
         }
         return CommonUtils.formatDouble(totalScore);
     }
+
+    public int getDetailNumber(){
+        return this.paperDetail.getNumber();
+    }
+
+    public String getDetailId(){
+        return this.paperDetail.getId();
+    }
 }

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

@@ -262,8 +262,9 @@ public abstract class ExportPaperAbstractService {
     	sortPaperDetailUnitExps(paperExp.getPaperDetails());
     	//如果每个小题分数不一样,题干后面添加分数
     	appendScoreToQuestionBody(paperExp.getPaperDetails());
-    	//给每个小题选项排序
+    	//1.设置题号 2.给小题选项进行排序 3.设置选项号 4.替换题干中的##为____
     	setUnitExpNumber(paperExp.getPaperDetails());
+    	//设置大题标题
     	setExpDtoTitle(paperExp.getPaperDetails());
     	return paperExp;
     }
@@ -423,7 +424,10 @@ public abstract class ExportPaperAbstractService {
     }
     
     /**
-	 * 给小题选项进行排序
+     * 1.设置题号
+	 * 2.给小题选项进行排序
+	 * 3.设置选项号
+	 * 4.替换题干中的##为____
 	 * @param paperDetails
 	 * @throws Exception
 	 */
@@ -441,10 +445,11 @@ public abstract class ExportPaperAbstractService {
 				}
 				List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
 				Question question = paperDetailUnit.getQuestion();
-				// 套题序号
 				if (subQuesList != null && subQuesList.size() > 0) {
+					//套题主题干
 					question.setQuesBodyWord(replaceQuesBlank(question.getQuesBodyWord(),subQuesList.get(0).getNumber()));
 					for (Question subQues : subQuesList) {
+						//处理子题题干,答案
 						subQues.setQuesBodyWord(setSubQuesNum(subQues.getQuesBodyWord(),subQues.getNumber()));
 						subQues.setQuesAnswerWord(setSubQuesNum(subQues.getQuesAnswerWord(),subQues.getNumber()));
 						subQues.setQuesBodyWord(replaceQuesBlank(subQues.getQuesBodyWord(),subQues.getNumber()));
@@ -458,6 +463,7 @@ public abstract class ExportPaperAbstractService {
 						}
 					}
 				} else {
+					//处理非套题题干、答案
 					question.setQuesBodyWord(setSubQuesNum(question.getQuesBodyWord(), paperDetailUnit.getNumber()));
 					question.setQuesAnswerWord(setSubQuesNum(question.getQuesAnswerWord(),paperDetailUnit.getNumber()));
 					question.setQuesBodyWord(replaceQuesBlank(question.getQuesBodyWord(),paperDetailUnit.getNumber()));

+ 4 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/service/export/SddxExportPaperService.java

@@ -32,6 +32,10 @@ public class SddxExportPaperService extends ExportPaperAbstractService{
 		PaperExp paperExp = initPaperExp(paperId);
 		if(paperExp!=null){
 			String paperfileName = paperExp.getName()+"_"+paperExp.getCourseNo()+"_"+ExamFileType.PAPER.getName()+DOCX_SUFFIX;
+			File firectory = new File(TEMP_FILE_EXP+File.separator+zipFileName);
+			if(!firectory.exists()){
+				firectory.mkdirs();
+			}
 			File file = new File(TEMP_FILE_EXP+File.separator+zipFileName+File.separator+paperfileName);
 			DocxProcessUtil.exportWordNew(paperExp, file,SDDX_TEMPLATE_PAPER);
 			DocxProcessUtil.processImage(zipFileName+File.separator+paperfileName,getPkgList(paperId));

+ 2 - 0
cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/ExportPaperServiceImpl.java

@@ -306,6 +306,8 @@ public class ExportPaperServiceImpl implements ExportPaperService{
 		//将对象转成 json对象
 		Gson gson = new Gson();
 		String strJSON = gson.toJson(computerTestPaper);
+		
+		strJSON = CommonUtils.replaceUnicodeStr(strJSON);
 		//生成文件流写入JSON文件
 		FileOutputStream outputStream = null;
 		try {

+ 123 - 40
cqb-paper/src/main/java/com/qmth/cqb/paper/service/impl/ExtractConfigServiceImpl.java

@@ -1,18 +1,18 @@
 package com.qmth.cqb.paper.service.impl;
 
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
+import com.qmth.cqb.paper.assemble.PaperDetailDtoAssembler;
+import com.qmth.cqb.paper.assemble.PaperDetailUnitDtoAssembler;
+import com.qmth.cqb.paper.assemble.PaperDtoAssembler;
+import com.qmth.cqb.paper.assemble.SubQuestionDtoAssembler;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.SystemUtils;
+import org.bson.types.ObjectId;
 import org.nlpcn.commons.lang.util.StringUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -129,6 +129,18 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 	@Value("${upyun.downloadUrl}")
 	private String downloadUrl;
 
+	@Autowired
+	private PaperDtoAssembler paperDtoAssembler;
+
+	@Autowired
+	private PaperDetailDtoAssembler paperDetailDtoAssembler;
+
+	@Autowired
+	private PaperDetailUnitDtoAssembler paperDetailUnitDtoAssembler;
+
+	@Autowired
+	private SubQuestionDtoAssembler subQuestionDtoAssembler;
+
     
 	@Override
 	public ExtractConfig findConfig(ExtractConfig condition) {
@@ -172,37 +184,68 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 	public Map<String, Object> extractExamPaper(Long exam_id,String course_code,String group_code){
 		Map<String, Object> returnMap = new HashMap<String,Object>();
 		logger.info("调卷开始...");
+		long beginTime = System.currentTimeMillis();
 		logger.info("开始根据examId:"+exam_id+"和courseCode:"+course_code+"获取调卷规则");
 		ExtractConfig extractConfig = this.findConfig(new ExtractConfig(exam_id,course_code));
 		if(extractConfig==null){
-			 logger.info("该考试和课程下调卷规则未制定,请先制定调卷规则,调卷程序退出");
+			 logger.error("该考试和课程下调卷规则未制定,请先制定调卷规则,调卷程序退出");
 			 returnMap.put("errorMsg","该考试和课程下调卷规则未制定,请先制定调卷规则");
 			 return returnMap;
 		}
+		long configFinishTime = System.currentTimeMillis();
+		logger.info("获取调卷规则共耗时:"+(configFinishTime - beginTime)+"ms");
 		logger.info("根据调卷规则中设置的概率获取类型为"+group_code+"的试卷");
 		Map<String,Paper> paperMap = this.getExamPaperByProbability(extractConfig.getExamPaperList());
 		if(paperMap.isEmpty()){
-			logger.info("该考试和课程下调卷规则中试卷不存在,请检查调卷规则,调卷程序退出");
+			logger.error("该考试和课程下调卷规则中试卷不存在,请检查调卷规则,调卷程序退出");
 			returnMap.put("errorMsg","该考试和课程下调卷规则中试卷不存在,请重新制定调卷规则");
 			return returnMap;
 		}
+
+		long paperMapFinishTime = System.currentTimeMillis();
+		logger.info("获取类型为"+group_code+"的试卷共耗时:"+(paperMapFinishTime - configFinishTime)+"ms");
+
 		Paper basePaper = paperMap.get(group_code);
 		if(basePaper==null){
-			logger.info("该考试和课程下调卷规则中该类型试卷不存在,请检查调卷规则,调卷程序退出");
+			logger.error("该考试和课程下调卷规则中该类型试卷不存在,请检查调卷规则,调卷程序退出");
 			returnMap.put("errorMsg","该考试和课程下调卷规则中该类型试卷不存在,请重新制定调卷规则");
 			return returnMap;
 		}
 		String basePaperId = basePaper.getId();
 		logger.info("将原始试卷:"+basePaperId+"根据规则重新组卷");
-    	Paper newPaper = this.recombinationPaper(basePaper,PaperType.STUDENT_EXAM,
-						        				 extractConfig.getScrambling_the_question_order(), 
-						        				 extractConfig.getScrambling_the_option_order());
-    	logger.info("根据新试卷 paperId:"+newPaper.getId()+"组装PaperDto后返回");
-    	PaperDto paperDto = getPaperDtoByPaper(newPaper);
-    	paperDto.setBasePaperId(basePaperId);
-    	paperDto.setAllQbjectiveQuestion(checkIsAllQbjectiveQuestion(basePaperId));
-		returnMap.put("paperDto",paperDto);
-		logger.info("调卷完成");
+		int upSetQuestionOrder = extractConfig.getScrambling_the_question_order();
+		int upSetOptionOrder = extractConfig.getScrambling_the_option_order();
+		//不乱序直接调卷
+		if(upSetQuestionOrder == 0 && upSetOptionOrder == 0){
+			PaperDto paperDto = getPaperDtoByPaper(basePaper);
+			long paperDtoFinishTime = System.currentTimeMillis();
+			logger.info("获取试卷Dto共耗时:"+(paperDtoFinishTime - paperMapFinishTime)+"ms");
+			paperDto.setBasePaperId(basePaperId);
+			paperDto.setAllQbjectiveQuestion(checkIsAllQbjectiveQuestion(basePaperId));
+			returnMap.put("paperDto",paperDto);
+			logger.info("调卷完成");
+			logger.info("总共耗时:"+(System.currentTimeMillis() - beginTime)+"ms");
+		}else{
+			//乱序重新生成试卷
+			Paper newPaper = this.recombinationPaper(basePaper,PaperType.STUDENT_EXAM,
+					upSetQuestionOrder,
+					upSetOptionOrder);
+			logger.info("根据新试卷 paperId:"+newPaper.getId()+"组装PaperDto后返回");
+
+			long genPaperFinishTime = System.currentTimeMillis();
+			logger.info("组卷共耗时:"+(genPaperFinishTime - paperMapFinishTime)+"ms");
+
+			PaperDto paperDto = getPaperDtoByPaper(newPaper);
+
+			long paperDtoFinishTime = System.currentTimeMillis();
+			logger.info("获取试卷Dto共耗时:"+(paperDtoFinishTime - genPaperFinishTime)+"ms");
+
+			paperDto.setBasePaperId(basePaperId);
+			paperDto.setAllQbjectiveQuestion(checkIsAllQbjectiveQuestion(basePaperId));
+			returnMap.put("paperDto",paperDto);
+			logger.info("调卷完成");
+			logger.info("总共耗时:"+(System.currentTimeMillis() - beginTime)+"ms");
+		}
 		return returnMap;
 	}
 	
@@ -261,20 +304,35 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 	 * @return
 	 */
 	public Paper recombinationPaper(Paper paper,PaperType paperType,int upSetQuestionOrder,int upSetOptionOrder){
+
+		//将小题全部取出来,只取一次
+		List<PaperDetailUnit> allPaperDetailUnits = paperDetailUnitRepo.findByPaperOrderByNumber(paper);
+		//获取大题
 		List<PaperDetail> paperDetails = paperDetailRepo.findByPaperOrderByNumber(paper);
+
+		//抽取大题号对应的小题
+		Map<String,List<PaperDetailUnit>> pduMap = allPaperDetailUnits.stream()
+				.collect(Collectors.groupingBy(PaperDetailUnit::getDetailId));
+		//最终保存的所有小题
+		List<PaperDetailUnit> savePaperDetailUnits = new ArrayList<>();
+		//保存试卷信息
 		paper.setId(null);
 		paper.setPaperType(paperType);
-		Paper newPaper = paperRepo.save(paper);//重新保存成新的paper
+		Paper newPaper = paperRepo.insert(paper);
+
 		for(int i = 0;i<paperDetails.size();i++){
 			PaperDetail paperDetail = paperDetails.get(i);
+
+			List<PaperDetailUnit> paperDetailUnits = pduMap.get(paperDetail.getId());
+			if(paperDetailUnits == null || paperDetailUnits.size() == 0){
+				continue;
+			}
+			Collections.sort(paperDetailUnits);
+
 			//将大题中最小的number取出
-			PaperDetailUnit topDetailUnit = paperDetailUnitService.findTopOrderByNumber(paperDetail,"ASC");
+			PaperDetailUnit topDetailUnit = paperDetailUnits.get(0);
 			int minNumber = topDetailUnit.getNumber();
-			List<PaperDetailUnit> paperDetailUnits = paperDetailUnitService.getUnitsByPaperDetail(paperDetail);
-			
-			paperDetail.setPaper(newPaper);//关联新Paper
-			paperDetail.setId(null);
-			PaperDetail newPaperDetail = paperDetailRepo.save(paperDetail);//保存新的paperDetail
+
 			//小题乱序
 			if(paperDetailUnits!=null&&paperDetailUnits.size()>0){
 				if((topDetailUnit.getQuestionType()==QuesStructType.SINGLE_ANSWER_QUESTION
@@ -284,17 +342,33 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 					Collections.shuffle(paperDetailUnits);//打乱小题List
 				}
 			}
-			
+			//设置大题信息
+			paperDetail.setId(null);
+			paperDetail.setPaper(newPaper);
+
 			for(int j = 0;j<paperDetailUnits.size();j++){
 				//重新设置保存PaperDetailUnit
 				PaperDetailUnit paperDetailUnit = paperDetailUnits.get(j);
-				paperDetailUnit.setPaperType(newPaper.getPaperType());
-				paperDetailUnit.setPaper(newPaper);				//关联新Paper
-				paperDetailUnit.setPaperDetail(newPaperDetail); //关联新paperDetail
+				paperDetailUnit.setPaperType(paperType);
+				paperDetailUnit.setPaper(newPaper);
+				paperDetailUnit.setPaperDetail(paperDetail);
 				paperDetailUnit.setNumber(minNumber+j);			//重新设置序号
 				reSavePaperDetailUtilAndQuestion(paperDetailUnit,upSetOptionOrder);
+				savePaperDetailUnits.add(paperDetailUnit);
 			}
+
 		}
+		//保存大题信息
+		paperDetailRepo.insert(paperDetails);
+		//保存小题信息
+		paperDetailUnitRepo.insert(savePaperDetailUnits);
+
+
+		//清空所有list
+		allPaperDetailUnits.clear();
+		savePaperDetailUnits.clear();
+		paperDetails.clear();
+
 		return newPaper;
 	}
 	
@@ -408,7 +482,6 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 			}
 		}
 		paperDetailUnit.setId(null);
-		paperDetailUnitRepo.save(paperDetailUnit);//保存新的paperDetailUnit
 	}
 
 	@Override
@@ -437,18 +510,28 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 	 * @return
 	 */
 	private PaperDto getPaperDtoByPaper(Paper paper){
-		PaperDto paperDto = BeanCopierUtil.copyProperties(paper, PaperDto.class);
-        // 获取大题
-        List<PaperDetail> paperDetails = paperDetailRepo.findByPaperOrderByNumber(paper);
-        List<PaperDetailDto> paperDetailDtos = BeanCopierUtil.copyPropertiesOfList(paperDetails, PaperDetailDto.class);
+		PaperDto paperDto = paperDtoAssembler.toDto(paper);
+
+		//将小题全部取出来,只取一次
+		List<PaperDetailUnit> allPaperDetailUnits = paperDetailUnitRepo.findByPaperOrderByNumber(paper);
+		//获取大题
+		List<PaperDetail> paperDetails = paperDetailRepo.findByPaperOrderByNumber(paper);
+		//抽取大题Id对应的小题
+		Map<String,List<PaperDetailUnit>> pduMap = allPaperDetailUnits.stream()
+				.collect(Collectors.groupingBy(PaperDetailUnit::getDetailId));
+        // 获取大题Dto
+        List<PaperDetailDto> paperDetailDtos = paperDetailDtoAssembler.toDtoList(paperDetails);
         paperDto.setPaperDetails(paperDetailDtos);
+
         // 封装小题
         for (int i = 0; i < paperDetailDtos.size(); i++) {
         	//根据大题查出大题下面的小题
-            List<PaperDetailUnit> paperDetailUnits = paperDetailUnitRepo.findByPaperDetailOrderByNumber(paperDetails.get(i));
+			PaperDetail paperDetail = paperDetails.get(i);
+
+            List<PaperDetailUnit> paperDetailUnits = pduMap.get(paperDetail.getId());
 			//设置答案
             setSelectQuestoionAnswer(paperDetailUnits);
-            List<PaperDetailUnitDto> paperDetailUnitDtos = BeanCopierUtil.copyPropertiesOfList(paperDetailUnits,PaperDetailUnitDto.class);
+            List<PaperDetailUnitDto> paperDetailUnitDtos = paperDetailUnitDtoAssembler.toDtoList(paperDetailUnits);
             for (int j = 0; j < paperDetailUnitDtos.size(); j++) {
             	PaperDetailUnit paperDetailUnit = paperDetailUnits.get(j);
             	if(paperDetailUnit==null||paperDetailUnit.getQuestion()==null){
@@ -467,9 +550,9 @@ public class ExtractConfigServiceImpl implements ExtractConfigService {
 				}
                 if (unitDto.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {// 假如是套题
                     List<Question> subQuesList = paperDetailUnit.getQuestion().getSubQuestions();
-                    List<SubQuestionDto> subQuesDtos = BeanCopierUtil.copyPropertiesOfList(subQuesList,SubQuestionDto.class);
+                    List<SubQuestionDto> subQuesDtos = subQuestionDtoAssembler.toDtoList(subQuesList);
                     for (int m = 0; m < subQuesList.size(); m++) {
-                        List<QuesOptionDto> quesOptionDtos = BeanCopierUtil.copyPropertiesOfList(subQuesList.get(m).getQuesOptions(), QuesOptionDto.class);
+                        List<QuesOptionDto> quesOptionDtos = subQuestionDtoAssembler.toOptionDtoList(subQuesList.get(m).getQuesOptions());
                         subQuesDtos.get(m).setQuesOptions(quesOptionDtos);
 						if(StringUtils.isNotEmpty(subQuesList.get(m).getQuesAnswer())){
 							subQuesDtos.get(m).setQuesAnswer(subQuesList.get(m).getQuesAnswer());

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

@@ -822,7 +822,7 @@ public class PaperServiceImpl implements PaperService{
             	pdu.setScore(ques.getScore());
             }else {
             	pdu.setNumber(paperDetailUnit.getNumber());//设置为大题中最大的number
-                pdu.setScore(paperDetailUnit.getScore());
+            	pdu.setScore(paperDetailUnit.getScore());
 			}
             //处理套题
             if(pdu.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION){

+ 5 - 5
cqb-starter/src/main/resources/application-dev.properties

@@ -1,11 +1,11 @@
 #spring.data.mongodb.uri=mongodb://root:Qmth87863577@119.23.127.95:3717/?authSource=admin&authMechanism=SCRAM-SHA-1
-spring.data.mongodb.uri=mongodb://192.168.1.99:27017/comm-ques-bank
+spring.data.mongodb.uri=mongodb://192.168.10.30:27017/comm-ques-bank
 spring.data.mongodb.grid-fs-database=comm-ques-bank
 spring.data.mongodb.database=comm-ques-bank
-eureka.client.serviceUrl.defaultZone=http://192.168.1.99:1111/eureka/
+eureka.client.serviceUrl.defaultZone=http://192.168.10.30:1111/eureka/
 spring.application.name=ExamCloud-service-question
 
-spring.redis.host=192.168.1.99
+spring.redis.host=192.168.10.30
 spring.redis.port=6379
 
 upyun.bucketName=exam-cloud-test
@@ -20,7 +20,7 @@ upyun.zipDirectory=paperZipDirectory
 upyun.radioType=mp3,wma
 
 
-spring.datasource.url=jdbc:mysql://192.168.1.99:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
+spring.datasource.url=jdbc:mysql://192.168.10.30:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
 spring.datasource.username=root
 spring.datasource.password=root
 spring.datasource.validation-query=SELECT 1 FROM DUAL
@@ -30,7 +30,7 @@ spring.jpa.show-sql=false
 spring.jpa.hibernate.ddl-auto=update
 
 
-spring.rabbitmq.host=192.168.1.99
+spring.rabbitmq.host=192.168.10.30
 spring.rabbitmq.port=5672
 spring.rabbitmq.username=examcloud
 spring.rabbitmq.password=examcloud

+ 3 - 3
cqb-starter/src/main/resources/application-test.properties

@@ -1,4 +1,4 @@
-spring.data.mongodb.uri=mongodb://192.168.1.99:27017/comm-ques-bank
+spring.data.mongodb.uri=mongodb://localhost:27017/comm-ques-bank
 spring.data.mongodb.grid-fs-database=comm-ques-bank
 spring.data.mongodb.database=comm-ques-bank
 eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
@@ -19,7 +19,7 @@ upyun.zipDirectory=paperZipDirectory
 upyun.radioType=mp3
 
 
-spring.datasource.url=jdbc:mysql://192.168.1.99:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
+spring.datasource.url=jdbc:mysql://localhost:3306/exam_cloud_test?useUnicode=true&characterEncoding=UTF-8
 spring.datasource.username=root
 spring.datasource.password=root
 spring.datasource.validation-query=SELECT 1 FROM DUAL
@@ -29,7 +29,7 @@ spring.jpa.show-sql=false
 spring.jpa.hibernate.ddl-auto=update
 
 
-spring.rabbitmq.host=192.168.1.99
+spring.rabbitmq.host=localhost
 spring.rabbitmq.port=5672
 spring.rabbitmq.username=examcloud
 spring.rabbitmq.password=examcloud

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

@@ -1,28 +1,46 @@
 package com.qmth.cqb;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang3.StringUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Example;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import cn.com.qmth.examcloud.common.dto.question.QuestionDto;
 
+import com.qmth.cqb.paper.dao.ExportServiceManageRepo;
 import com.qmth.cqb.paper.dao.PaperRepo;
 import com.qmth.cqb.paper.model.ExamFile;
 import com.qmth.cqb.paper.model.ExamPaper;
+import com.qmth.cqb.paper.model.ExportServiceManage;
 import com.qmth.cqb.paper.model.Paper;
 import com.qmth.cqb.paper.service.ExamFileService;
 import com.qmth.cqb.paper.service.ExtractConfigService;
+import com.qmth.cqb.paper.service.PaperService;
+import com.qmth.cqb.paper.service.export.ExportPaperAbstractService;
+import com.qmth.cqb.paper.service.export.SddxExportPaperService;
 import com.qmth.cqb.paper.service.export.SxsfExportPaperService;
+import com.qmth.cqb.utils.SpringContextUtils;
 import com.qmth.cqb.utils.enums.ExamFileType;
+import com.qmth.cqb.utils.enums.PaperType;
 
 /**
  * @author  	chenken
@@ -43,10 +61,75 @@ public class ExtractConfigServiceTest {
 	
 	@Autowired
 	private ExamFileService examFileService;
+	@Autowired
+	private ExportServiceManageRepo exportServiceManageRepo;
+	@Autowired
+	private SddxExportPaperService sddxExportPaperService;
+	@Autowired
+    private MongoTemplate mongoTemplate;
 	
 	private MockHttpServletRequest request;  
     private MockHttpServletResponse response; 
     
+    @Test
+    public void downloadPaper() throws Exception{
+    	Query query = new Query();
+    	query.addCriteria(Criteria.where("orgId").is(135+""));
+    	query.addCriteria(Criteria.where("paperType").is(PaperType.GENERATE.name()));
+    	List<Paper> paperList = this.mongoTemplate.find(query, Paper.class);
+    	for(Paper paper:paperList){
+    		try {
+    			StringBuffer sb = new StringBuffer();
+    			List<String> paperIds = readFromFile();
+    			for(String paperId:paperIds){
+    				sb.append(paperId);
+    	        	sb.append("\r\n");
+    			}
+    			if(!paperIds.contains(paper.getId())){
+    				System.out.println("当前正在导出ID:"+paper.getId());
+    				sddxExportPaperService.downloadPaper(paper.getId(), "shandong");
+    				writeToFile(sb.toString()+"\r\n"+paper.getId());
+    			}
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+    	}
+    }
+    
+    /** 
+     * DOC 从文件里读内容. 
+     *  
+     * @throws IOException 
+     */  
+    private static List<String> readFromFile() throws IOException {  
+    	BufferedReader bReader = new BufferedReader(new FileReader("E:\\paperIds.txt"));
+    	List<String> paperIds = new ArrayList<String>();
+    	String temp = "";
+        while((temp=bReader.readLine())!=null) {
+        	if(StringUtils.isNotBlank(temp)){
+        		paperIds.add(temp);
+        	}
+        }
+        bReader.close();
+        return paperIds;
+    }
+    
+    /** 
+     * DOC 往文件里写入数据. 
+     *  
+     * @throws IOException 
+     */  
+    private static void writeToFile(String writerContent) throws IOException {  
+        File file = new File("E:\\paperIds.txt");// 要写入的文本文件  
+        if (!file.exists()) {// 如果文件不存在,则创建该文件  
+            file.createNewFile();  
+        }  
+        FileWriter writer = new FileWriter(file);// 获取该文件的输出流  
+        writer.write(writerContent);// 写内容  
+        writer.flush();// 清空缓冲区,立即将输出流里的内容写到文件里  
+        writer.close();// 关闭输出流,施放资源  
+    }
+    
     @Test
 	public void test1() throws Exception{
     	ExamFile examFile = new ExamFile();