Browse Source

merge from release_v3.0

deason 5 năm trước cách đây
mục cha
commit
7926eb8384
27 tập tin đã thay đổi với 1076 bổ sung818 xóa
  1. 1 1
      examcloud-core-questions-api-provider/pom.xml
  2. 8 8
      examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ExportPaperController.java
  3. 47 1
      examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ExportTemplateController.java
  4. 23 30
      examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ExtractConfigController.java
  5. 36 22
      examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ImportPaperController.java
  6. 4 4
      examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/PaperController.java
  7. 1 1
      examcloud-core-questions-base/pom.xml
  8. 1 1
      examcloud-core-questions-base/src/main/java/cn/com/qmth/examcloud/core/questions/base/FileDisposeUtil.java
  9. 23 5
      examcloud-core-questions-base/src/main/java/cn/com/qmth/examcloud/core/questions/base/word/DocxProcessUtil.java
  10. 2 0
      examcloud-core-questions-base/src/main/resources/export_template/origin_paper/doc_section.ftl
  11. 2 0
      examcloud-core-questions-base/src/main/resources/export_template/origin_paper/exam_reamark_document.ftl
  12. 2 0
      examcloud-core-questions-base/src/main/resources/export_template/origin_paper/question_options.ftl
  13. 2 0
      examcloud-core-questions-base/src/main/resources/export_template/origin_paper/question_section.ftl
  14. 1 1
      examcloud-core-questions-dao/pom.xml
  15. 1 1
      examcloud-core-questions-dao/src/main/java/cn/com/qmth/examcloud/core/questions/dao/ExportServiceManageRepo.java
  16. 3 0
      examcloud-core-questions-dao/src/main/java/cn/com/qmth/examcloud/core/questions/dao/entity/QuestionPkgPath.java
  17. 1 1
      examcloud-core-questions-service/pom.xml
  18. 17 19
      examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/ImportDdCollegePaperService.java
  19. 9 9
      examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/impl/ExtractConfigFileServiceImpl.java
  20. 741 652
      examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/temp/CqdxService.java
  21. 142 53
      examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/util/ExportPaperUtil.java
  22. 1 1
      examcloud-core-questions-starter/pom.xml
  23. 3 2
      examcloud-core-questions-starter/shell/start.sh
  24. 2 2
      examcloud-core-questions-starter/shell/stop.sh
  25. 0 1
      examcloud-core-questions-starter/shell/version
  26. 1 1
      examcloud-core-questions-starter/src/main/resources/security.properties
  27. 2 2
      pom.xml

+ 1 - 1
examcloud-core-questions-api-provider/pom.xml

@@ -8,7 +8,7 @@
     <parent>
         <artifactId>examcloud-core-questions</artifactId>
         <groupId>cn.com.qmth.examcloud.core.questions</groupId>
-        <version>2019-SNAPSHOT</version>
+        <version>v3.0-RELEASE</version>
     </parent>
 
     <dependencies>

+ 8 - 8
examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ExportPaperController.java

@@ -50,16 +50,16 @@ public class ExportPaperController extends ControllerSupport {
      * @return
      */
     @ApiOperation(value = "导出试卷", notes = "导出试卷")
-    @GetMapping(value = "/paper/export/{id}/{exportContentList}/{orgName}/{loginName}/{examType}")
+    @GetMapping(value = "/paper/export/{id}/{exportContentList}/{orgId}/{loginName}/{examType}")
     public void getPaperById(HttpServletRequest request, HttpServletResponse response, @PathVariable String id,
-            @PathVariable String orgName, @PathVariable String exportContentList, @PathVariable String loginName,
+            @PathVariable String orgId, @PathVariable String exportContentList, @PathVariable String loginName,
             @PathVariable String examType) {
         log.info("导出开始");
         String psw = request.getParameter("psw");
-        ExportServiceManage esm = exportServiceManageRepo.findByOrgName(orgName);
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(orgId);
 
         if (esm == null) {
-            throw new StatusException("500", String.format("学校【%s】尚未配置导出模板!", orgName));
+            throw new StatusException("500", "尚未配置导出功能!");
         }
         User user = getAccessUser();
         exportPaperService.exportPaperFile(id, esm.getExportServiceName(), exportContentList, response, loginName,
@@ -78,16 +78,16 @@ public class ExportPaperController extends ControllerSupport {
      * @param loginName
      */
     @ApiOperation(value = "批量导出试卷", notes = "批量导出")
-    @GetMapping(value = "/paper/batch_export/{paperIds}/{exportContentList}/{orgName}/{loginName}/{examType}")
+    @GetMapping(value = "/paper/batch_export/{paperIds}/{exportContentList}/{orgId}/{loginName}/{examType}")
     public void getPaperByIds(HttpServletRequest request, HttpServletResponse response, @PathVariable String paperIds,
-            @PathVariable String orgName, @PathVariable String exportContentList, @PathVariable String loginName,
+            @PathVariable String orgId, @PathVariable String exportContentList, @PathVariable String loginName,
             @PathVariable String examType) {
         log.info("批量导出");
         List<String> paperList = Stream.of(paperIds.split(",")).collect(Collectors.toList());
-        ExportServiceManage esm = exportServiceManageRepo.findByOrgName(orgName);
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(orgId);
 
         if (esm == null) {
-            throw new StatusException("500", String.format("学校【%s】尚未配置导出模板!", orgName));
+            throw new StatusException("500", "尚未配置导出功能!");
         }
 
         try {

+ 47 - 1
examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ExportTemplateController.java

@@ -2,6 +2,7 @@ package cn.com.qmth.examcloud.core.questions.api.controller;
 
 import javax.validation.constraints.NotNull;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.web.bind.annotation.DeleteMapping;
@@ -17,7 +18,10 @@ import org.springframework.web.multipart.MultipartFile;
 
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.questions.base.bean.ExportServiceManageBean;
 import cn.com.qmth.examcloud.core.questions.base.dto.ExportTemplateDto;
+import cn.com.qmth.examcloud.core.questions.dao.ExportServiceManageRepo;
+import cn.com.qmth.examcloud.core.questions.dao.entity.ExportServiceManage;
 import cn.com.qmth.examcloud.core.questions.service.ExportTemplateService;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import io.swagger.annotations.Api;
@@ -27,7 +31,8 @@ import io.swagger.annotations.ApiOperation;
 @RestController
 @RequestMapping("${api_cqb}/exportTemplate")
 public class ExportTemplateController extends ControllerSupport {
-
+    @Autowired
+    ExportServiceManageRepo exportServiceManageRepo;
     @Autowired
     private ExportTemplateService exportTemplateService;
 
@@ -94,4 +99,45 @@ public class ExportTemplateController extends ControllerSupport {
         }
         exportTemplateService.disenable(rootOrgId, id);
     }
+    
+    @ApiOperation(value = "查询配置")
+    @GetMapping("/config/{rootOrgId}")
+    public ExportServiceManageBean getConfig(@PathVariable Long rootOrgId) {
+        User accessUser = getAccessUser();
+        if (!isSuperAdmin()) {
+            if (!rootOrgId.equals(accessUser.getRootOrgId())) {
+                throw new StatusException("100005", "无效的请求");
+            }
+        }
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(String.valueOf(rootOrgId));
+        ExportServiceManageBean bean=new ExportServiceManageBean();
+        if(esm!=null) {
+            bean.setOrgId(esm.getOrgId());
+            bean.setId(esm.getId());
+            bean.setExportServiceName(esm.getExportServiceName());
+        }
+        return bean;
+    }
+
+    @ApiOperation(value = "新增/修改配置")
+    @PutMapping("/config/{rootOrgId}")
+    public void modifyConfig(@RequestParam @NotNull(message = "配置名称不能为空!") String serviceName,
+            @PathVariable Long rootOrgId) {
+        User accessUser = getAccessUser();
+        if (!isSuperAdmin()) {
+            if (!rootOrgId.equals(accessUser.getRootOrgId())) {
+                throw new StatusException("100006", "无效的请求");
+            }
+        }
+        if(StringUtils.isBlank(serviceName)) {
+            throw new StatusException("100007", "配置名称不能为空!");
+        }
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(String.valueOf(rootOrgId));
+        if(esm==null) {
+            esm=new ExportServiceManage();
+            esm.setOrgId(String.valueOf(rootOrgId));
+        }
+        esm.setExportServiceName(serviceName.trim());
+        exportServiceManageRepo.save(esm);
+    }
 }

+ 23 - 30
examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ExtractConfigController.java

@@ -1,28 +1,6 @@
 package cn.com.qmth.examcloud.core.questions.api.controller;
 
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.core.questions.base.enums.ExportWay;
@@ -37,6 +15,21 @@ import cn.com.qmth.examcloud.core.questions.service.cache.ExtractConfigCache;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import cn.com.qmth.examcloud.web.support.Naked;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -50,7 +43,7 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping("${api_cqb}/")
 public class ExtractConfigController extends ControllerSupport {
     private static final Logger logger = LoggerFactory.getLogger(ExtractConfigController.class);
-    
+
     @Autowired
     private ExtractConfigService extractConfigService;
 
@@ -87,7 +80,7 @@ public class ExtractConfigController extends ControllerSupport {
 
             //清除缓存
             extractConfigCache.remove(extractConfig.getExamId(), extractConfig.getCourseCode());
-            
+
             return new ResponseEntity<>(HttpStatus.OK);
         } catch (Exception e) {
             logger.error(e.getMessage(), e);
@@ -183,10 +176,10 @@ public class ExtractConfigController extends ControllerSupport {
 
     @Naked
     @ApiOperation(value = "导出单张考试试卷、答案、试卷结构", notes = "导出单张考试试卷、答案、试卷结构")
-    @GetMapping(value = "/exportSingleExamPaperInfo/{orgName}/{exportWay}/{examId}/{courseId}/{exportContentList}/{loginName}")
+    @GetMapping(value = "/exportSingleExamPaperInfo/{orgId}/{exportWay}/{examId}/{courseId}/{exportContentList}/{loginName}")
     public void exportSingleExamPaperInfo(HttpServletResponse response,
                                           @PathVariable String exportWay,
-                                          @PathVariable String orgName,
+                                          @PathVariable String orgId,
                                           @PathVariable String examId,
                                           @PathVariable String courseId,
                                           @PathVariable String exportContentList,
@@ -203,7 +196,7 @@ public class ExtractConfigController extends ControllerSupport {
         }
         exportModel.setExportContentList(list);
         try {
-            extractConfigFileService.exportExamPaperInfo(exportModel, response, loginName, orgName, psw);
+            extractConfigFileService.exportExamPaperInfo(exportModel, response, loginName, orgId, psw);
         } catch (Exception e) {
             log.error(e.getMessage(), e);
         }
@@ -228,10 +221,10 @@ public class ExtractConfigController extends ControllerSupport {
 
     @Naked
     @ApiOperation(value = "导出整个考试下所有 课程的试卷、答案、试卷结构", notes = "导出整个考试下所有 课程的试卷、答案、试卷结构")
-    @GetMapping(value = "/exportBatchExamPaperInfo/{orgName}/{exportWay}/{examId}/{exportContentList}/{loginName}")
+    @GetMapping(value = "/exportBatchExamPaperInfo/{orgId}/{exportWay}/{examId}/{exportContentList}/{loginName}")
     public void exportBatchExamPaperInfo(HttpServletResponse response,
                                          @PathVariable String exportWay,
-                                         @PathVariable String orgName,
+                                         @PathVariable String orgId,
                                          @PathVariable String examId,
                                          @PathVariable String exportContentList,
                                          @PathVariable String loginName) {
@@ -245,7 +238,7 @@ public class ExtractConfigController extends ControllerSupport {
         }
         exportModel.setExportContentList(list);
         try {
-            extractConfigFileService.exportExamPaperInfo(exportModel, response, loginName, orgName, null);
+            extractConfigFileService.exportExamPaperInfo(exportModel, response, loginName, orgId, null);
         } catch (Exception e) {
             log.error(e.getMessage(), e);
         }

+ 36 - 22
examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/ImportPaperController.java

@@ -1,30 +1,36 @@
 package cn.com.qmth.examcloud.core.questions.api.controller;
 
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.validation.constraints.NotNull;
+
+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.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.core.questions.base.exception.PaperException;
-import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
 import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
 import cn.com.qmth.examcloud.core.questions.service.ClonePaperService;
 import cn.com.qmth.examcloud.core.questions.service.ImportDdCollegePaperService;
 import cn.com.qmth.examcloud.core.questions.service.ImportPaperService;
-import cn.com.qmth.examcloud.core.questions.service.PaperService;
+import cn.com.qmth.examcloud.core.questions.service.temp.CqdxService;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import io.swagger.annotations.ApiOperation;
-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.*;
-import org.springframework.web.multipart.MultipartFile;
-import org.springframework.web.multipart.commons.CommonsMultipartFile;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.validation.constraints.NotNull;
 
 /**
  * @author weiwenhai
@@ -40,13 +46,11 @@ public class ImportPaperController extends ControllerSupport {
 	@Autowired
 	private ClonePaperService clonePaperService;
 	@Autowired
-	ImportPaperService importPaperService;
+	private ImportPaperService importPaperService;
 	@Autowired
 	private ImportDdCollegePaperService importDdCollegePaperService;
 	@Autowired
-	PaperRepo paperRepo;
-	@Autowired
-	PaperService paperService;
+	private CqdxService cqdxService;
 
 	/**
 	 * 导入试卷
@@ -116,9 +120,19 @@ public class ImportPaperController extends ControllerSupport {
 	@ApiOperation(value = "导入地大试卷", notes = "导入地大试卷")
 	@PostMapping(value = "/importDdCollegePaper")
 	public ResponseEntity<Object> importDdCollegePaper(
-			@RequestPart @NotNull(message = "上传文件不能为空!") MultipartFile dataFile,@RequestParam Long rootOrgId) {
+			@RequestPart @NotNull(message = "上传文件不能为空!") MultipartFile dataFile, @RequestParam Long rootOrgId,@RequestParam String courseCode,@RequestParam(required = false) String suff) {
+		User user = getAccessUser();
+		importDdCollegePaperService.importDdCollegePaper(dataFile, user, rootOrgId,courseCode,suff);
+		return new ResponseEntity<>(HttpStatus.OK);
+	}
+
+	@ApiOperation(value = "导入重庆试卷", notes = "导入重庆试卷")
+	@PostMapping(value = "/importCqCollegePaper")
+	public ResponseEntity<Object> importCqCollegePaper(
+			@RequestPart @NotNull(message = "上传文件不能为空!") MultipartFile dataFile, @RequestParam Long rootOrgId,
+			@RequestParam String paperNameSuffix, @RequestParam String impType) {
 		User user = getAccessUser();
-		importDdCollegePaperService.importDdCollegePaper(dataFile,user, rootOrgId);
+		cqdxService.bulidPaper(dataFile, user, rootOrgId, paperNameSuffix,impType);
 		return new ResponseEntity<>(HttpStatus.OK);
 	}
 

+ 4 - 4
examcloud-core-questions-api-provider/src/main/java/cn/com/qmth/examcloud/core/questions/api/controller/PaperController.java

@@ -104,7 +104,7 @@ public class PaperController extends ControllerSupport {
         if ("success".equals(msgMap.get("msg"))) {
             return new ResponseEntity<>(msgMap, HttpStatus.OK);
         } else {
-            return new ResponseEntity<>(msgMap, HttpStatus.INTERNAL_SERVER_ERROR);
+            throw new StatusException("1000",msgMap.get("msg").toString());
         }
     }
 
@@ -210,7 +210,7 @@ public class PaperController extends ControllerSupport {
         if (msgMap.get("msg").equals("success")) {
             return new ResponseEntity<>(msgMap, HttpStatus.OK);
         } else {
-            return new ResponseEntity<>(msgMap, HttpStatus.INTERNAL_SERVER_ERROR);
+            throw new StatusException("1001","试卷["+msgMap.get("paperName")+"]中有试题被组卷使用,不能删除!");
         }
 
     }
@@ -553,13 +553,13 @@ public class PaperController extends ControllerSupport {
                 Paper oldpaper = cn.com.qmth.examcloud.core.questions.base.Model.of(paperRepo.findById(paperIdArray[i]));
                 boolean result = paperService.checkPaperName(oldpaper.getName(), PaperType.GENERATE, user.getRootOrgId() + "");
                 if (!result) {
-                    throw new StatusException("Q-160565", "考试试卷:" + oldpaper.getName() + "已经存在");
+                    throw new StatusException("160565", "考试试卷:" + oldpaper.getName() + "已经存在");
                 }
             }
             paperService.useBasePaper(paperIds, user.getDisplayName());
             return new ResponseEntity<>(HttpStatus.OK);
         } catch (Exception e) {
-            throw new StatusException("Q-160537", e.getMessage());
+            throw new StatusException("160537", e.getMessage());
         }
     }
 

+ 1 - 1
examcloud-core-questions-base/pom.xml

@@ -6,7 +6,7 @@
 	<parent>
 		<artifactId>examcloud-core-questions</artifactId>
 		<groupId>cn.com.qmth.examcloud.core.questions</groupId>
-		<version>2019-SNAPSHOT</version>
+		<version>v3.0-RELEASE</version>
 	</parent>
 	<artifactId>examcloud-core-questions-base</artifactId>
 	<packaging>jar</packaging>

+ 1 - 1
examcloud-core-questions-base/src/main/java/cn/com/qmth/examcloud/core/questions/base/FileDisposeUtil.java

@@ -52,7 +52,7 @@ public class FileDisposeUtil {
         try {
             url = new URL(fileUrl);
         } catch (MalformedURLException e) {
-            logger.error(e.getMessage(), e);
+            logger.error("fileUrl:"+fileUrl, e);
             return false;
         }
 

+ 23 - 5
examcloud-core-questions-base/src/main/java/cn/com/qmth/examcloud/core/questions/base/word/DocxProcessUtil.java

@@ -131,10 +131,14 @@ public final class DocxProcessUtil {
      */
     public static String getPText(P p) {
         String returnText = "";
-        List<Object> tList = getAllElementFromObject(p, Text.class);
+        List<Object> tList = getAllElementWithBrFromObject(p, Text.class);
         for (Object obj : tList) {
-            Text text = (Text) obj;
-            returnText += text.getValue().trim();
+        	if (obj.getClass().equals(Text.class)) {
+	            Text text = (Text) obj;
+	            returnText += text.getValue().trim();
+        	}else if(obj.getClass().equals(Br.class)){
+        		returnText += "<br/>";
+        	}
         }
         return returnText.trim();
     }
@@ -374,7 +378,22 @@ public final class DocxProcessUtil {
         }
         return result;
     }
+    public static List<Object> getAllElementWithBrFromObject(Object obj, Class<?> toSearch) {
 
+        List<Object> result = new ArrayList<>();
+        if (obj instanceof JAXBElement) {
+            obj = ((JAXBElement<?>) obj).getValue();
+        }
+        if (obj.getClass().equals(toSearch)||obj.getClass().equals(Br.class)) {
+            result.add(obj);
+        }else if (obj instanceof ContentAccessor) {
+            List<?> children = ((ContentAccessor) obj).getContent();
+            for (Object child : children) {
+                result.addAll(getAllElementWithBrFromObject(child, toSearch));
+            }
+        }
+        return result;
+    }
     /**
      * omml转换成mml
      *
@@ -926,8 +945,7 @@ public final class DocxProcessUtil {
             // ""                 会报错
             // "abc"              会报错
             // "<xxx>abc<xxx>"    不报错
-            logger.warn(e.getMessage());
-            throw new IllegalArgumentException("内容需要定义在HTML标签中");
+            throw new IllegalArgumentException("内容需要定义在HTML标签中:"+e.getCause().getMessage());
         }
 
         //转换完后就初始化image

+ 2 - 0
examcloud-core-questions-base/src/main/resources/export_template/origin_paper/doc_section.ftl

@@ -53,6 +53,8 @@
 			</wp:inline>
 		</w:drawing>
 	</w:r>
+	<#elseif element.type=="doctag">
+	${element.value}
 	<#else>
 	<w:r w:rsidRPr="003A4B1C">
 		<w:rPr>

+ 2 - 0
examcloud-core-questions-base/src/main/resources/export_template/origin_paper/exam_reamark_document.ftl

@@ -89,6 +89,8 @@
 			</wp:inline>
 		</w:drawing>
 	</w:r>
+	<#elseif element.type=="doctag">
+	${element.value}
 	<#else>
 	<w:r w:rsidRPr="003A4B1C">
 		<w:rPr>

+ 2 - 0
examcloud-core-questions-base/src/main/resources/export_template/origin_paper/question_options.ftl

@@ -78,6 +78,8 @@
 			</wp:inline>
 		</w:drawing>
 	</w:r>
+	<#elseif element.type=="doctag">
+	${element.value}
 	<#else>
 	<#if element.param?exists&&element.param.tab>
 	<w:r>

+ 2 - 0
examcloud-core-questions-base/src/main/resources/export_template/origin_paper/question_section.ftl

@@ -62,6 +62,8 @@
 			</wp:inline>
 		</w:drawing>
 	</w:r>
+	<#elseif element.type=="doctag">
+	${element.value}
 	<#else>
 	<w:r w:rsidRPr="003A4B1C">
 		<w:rPr>

+ 1 - 1
examcloud-core-questions-dao/pom.xml

@@ -4,7 +4,7 @@
 	<parent>
 		<artifactId>examcloud-core-questions</artifactId>
 		<groupId>cn.com.qmth.examcloud.core.questions</groupId>
-		<version>2019-SNAPSHOT</version>
+		<version>v3.0-RELEASE</version>
 	</parent>
 	<artifactId>examcloud-core-questions-dao</artifactId>
 	<packaging>jar</packaging>

+ 1 - 1
examcloud-core-questions-dao/src/main/java/cn/com/qmth/examcloud/core/questions/dao/ExportServiceManageRepo.java

@@ -5,7 +5,7 @@ import org.springframework.data.mongodb.repository.MongoRepository;
 import org.springframework.data.repository.query.QueryByExampleExecutor;
 
 public interface ExportServiceManageRepo extends MongoRepository<ExportServiceManage, Long>, QueryByExampleExecutor<ExportServiceManage> {
-    ExportServiceManage findByOrgName(String orgName);
+//    ExportServiceManage findByOrgName(String orgName);
 
     ExportServiceManage findByOrgId(String orgId);
 }

+ 3 - 0
examcloud-core-questions-dao/src/main/java/cn/com/qmth/examcloud/core/questions/dao/entity/QuestionPkgPath.java

@@ -4,7 +4,10 @@ import cn.com.qmth.examcloud.core.questions.dao.entity.base.IdBase;
 
 /**
  * Created by songyue on 17/11/19.
+ * 
  */
+//新方案导出不存word字节信息
+@Deprecated
 public class QuestionPkgPath extends IdBase {
 
     private byte[] quesPkg;

+ 1 - 1
examcloud-core-questions-service/pom.xml

@@ -4,7 +4,7 @@
 	<parent>
 		<artifactId>examcloud-core-questions</artifactId>
 		<groupId>cn.com.qmth.examcloud.core.questions</groupId>
-		<version>2019-SNAPSHOT</version>
+		<version>v3.0-RELEASE</version>
 	</parent>
 	<artifactId>examcloud-core-questions-service</artifactId>
 	<packaging>jar</packaging>

+ 17 - 19
examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/ImportDdCollegePaperService.java

@@ -5,8 +5,8 @@ import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -46,7 +46,6 @@ import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetail;
 import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
 import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
 import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
-import cn.com.qmth.examcloud.core.questions.dao.entity.QuestionPkgPath;
 import cn.com.qmth.examcloud.core.questions.service.impl.CourseService;
 import cn.com.qmth.examcloud.core.questions.service.temp.ImgDataUtils;
 import cn.com.qmth.examcloud.core.questions.service.temp.vo.TestFillAnswer;
@@ -87,7 +86,7 @@ public class ImportDdCollegePaperService {
     @Autowired
     private SystemProperties systemProperties;
 
-    public void importDdCollegePaper(MultipartFile dataFile, User user, Long rootOrgId) {
+    public void importDdCollegePaper(MultipartFile dataFile, User user, Long rootOrgId,String courseCode,String suff) {
         String tempDir = systemProperties.getTempDataDir();
         String dir = tempDir + File.separator + UUID.randomUUID() + File.separator;
         try {
@@ -97,7 +96,8 @@ public class ImportDdCollegePaperService {
             zfile.createNewFile();
             dataFile.transferTo(zfile);
             FileUtil.unZip(dfile, zfile);
-            resolvingImportFile(dataFile.getOriginalFilename().split("\\.")[0], dir, user, rootOrgId);
+            String excelFileName=dataFile.getOriginalFilename().substring(0, dataFile.getOriginalFilename().lastIndexOf("."))+".xlsx";
+            resolvingImportFile(dir, excelFileName, user, rootOrgId,courseCode,suff);
         } catch (StatusException e) {
             throw e;
         } catch (Exception e) {
@@ -107,10 +107,10 @@ public class ImportDdCollegePaperService {
         }
     }
 
-    private void resolvingImportFile(String courseCode, String dir, User user, Long rootOrgId) throws IOException {
+    private void resolvingImportFile(String dir,String excelFileName, User user, Long rootOrgId,String courseCode,String suff) throws IOException {
         XSSFWorkbook wb = null;
         try {
-            wb = new XSSFWorkbook(dir + courseCode + ".xlsx");
+            wb = new XSSFWorkbook(dir + excelFileName);
             XSSFSheet sheet0 = wb.getSheetAt(0);
             Course course = courseService.getCourse(rootOrgId, courseCode);
             if (course == null) {
@@ -121,7 +121,7 @@ public class ImportDdCollegePaperService {
                 XSSFRow row = sheet0.getRow(i);
                 TestPaper tp = new TestPaper();
                 tp.setId(row.getCell(0).getStringCellValue());
-                tp.setName(row.getCell(1).getStringCellValue());
+                tp.setName(row.getCell(1).getStringCellValue()+(suff==null?"":suff));
                 tp.setTestPaperContentId(row.getCell(2).getStringCellValue());
                 tp.setScore(getDoubleByString(row.getCell(3).getStringCellValue()));
                 papers.add(tp);
@@ -144,7 +144,7 @@ public class ImportDdCollegePaperService {
                 // 定义小题集合
                 List<PaperDetailUnit> paperDetailUnits = new ArrayList<>();
                 // 试题---资源 对应关系
-                Map<Question, QuestionPkgPath> map2 = new HashMap<>();
+                Set<Question> set = new LinkedHashSet<Question>();
                 // 定义试卷难度
                 double difficulty = 0;
                 int error = 1;
@@ -159,7 +159,7 @@ public class ImportDdCollegePaperService {
                             // 初始化试题对象
                             Question question = null;
                             try {
-                                question = initQuestion(testQuestionInfo, testQuestion, course, map2, difficulty, dir,
+                                question = initQuestion(testQuestionInfo, testQuestion, course, set, difficulty, dir,
                                         quesheet);
                             } catch (Exception e) {
                                 throw new StatusException("600001",
@@ -207,7 +207,7 @@ public class ImportDdCollegePaperService {
                         number++;
                     }
                 }
-                quesRepo.saveAll(map2.keySet());
+                quesRepo.saveAll(set);
                 paperRepo.save(paper);
                 paperDetailRepo.saveAll(paperDetails);
                 paperDetailUnitRepo.saveAll(paperDetailUnits);
@@ -268,7 +268,7 @@ public class ImportDdCollegePaperService {
 
     // 将大题和小题分类
     private Map<Integer, List<TestQuestion>> sortPaperDetail(List<TestQuestion> questions) {
-        Map<Integer, List<TestQuestion>> map = new HashMap<>();
+        Map<Integer, List<TestQuestion>> map = new LinkedHashMap<>();
         List<TestQuestion> sortQuestions = null;
         for (TestQuestion testQuestion : questions) {
             if (map.get(testQuestion.getdNumber()) == null) {
@@ -330,7 +330,7 @@ public class ImportDdCollegePaperService {
 
     // 初始化试题对象
     private Question initQuestion(TestQuestionInfo testQuestionInfo, TestQuestion testQuestion, Course course,
-            Map<Question, QuestionPkgPath> map, double difficulty, String dir, XSSFSheet sheet) throws Exception {
+    		Set<Question> set, double difficulty, String dir, XSSFSheet sheet) throws Exception {
         Question question = new Question();
         question.setCreateTime(CommonUtils.getCurDateTime());
         question.setScore(testQuestion.getScore());
@@ -341,14 +341,14 @@ public class ImportDdCollegePaperService {
         question.setDifficultyDegree(0.5);
         question.setPublicity(true);
         // 按试题分类初始化题干,答案,选项
-        initQuestionInfo(question, testQuestionInfo, map, testQuestion, dir, sheet);
+        initQuestionInfo(question, testQuestionInfo, set, testQuestion, dir, sheet);
         difficulty = question.getScore() * 0.5 + difficulty;
         return question;
     }
 
     // 初始化题干,答案,选项,资源
     private void initQuestionInfo(Question question, TestQuestionInfo testQuestionInfo,
-            Map<Question, QuestionPkgPath> map, TestQuestion testQuestion, String dir, XSSFSheet sheet)
+    		Set<Question> set, TestQuestion testQuestion, String dir, XSSFSheet sheet)
             throws Exception {
         WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
         // 选词填空
@@ -403,7 +403,7 @@ public class ImportDdCollegePaperService {
                     subQuestion.setPublicity(true);
                     subQuestion.setScore(testQuestion2.getScore());
                     // 按试题分类初始化题干,答案,选项
-                    initQuestionInfo(subQuestion, testQuestionInfo2, map, testQuestion2, dir, sheet);
+                    initQuestionInfo(subQuestion, testQuestionInfo2, set, testQuestion2, dir, sheet);
                     subQues.add(subQuestion);
                 }
                 question.setSubQuestions(subQues);
@@ -443,7 +443,7 @@ public class ImportDdCollegePaperService {
             question.setSubQuestions(subQuestions);
         }
         // 问答题 、 名词解释
-        if (testQuestionInfo.getQuestionType() == 60 || testQuestionInfo.getQuestionType() == 69) {
+        if (testQuestionInfo.getQuestionType() == 60 || testQuestionInfo.getQuestionType() == 69 ||testQuestionInfo.getQuestionType() == 61) {
             String quesBody = testQuestionInfo.getQuestionHTML();
             // 去掉<span>标签中的lang
             quesBody = replaceLang(quesBody);
@@ -621,9 +621,7 @@ public class ImportDdCollegePaperService {
             question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage,
                     CommonUtils.formatHtml("<p>" + question.getQuesAnswer() + "</p>")));
         }
-        byte[] pkgByte = DocxProcessUtil.getPkgByte(wordMLPackage);
-        QuestionPkgPath quesPkgPath = new QuestionPkgPath(pkgByte);
-        map.put(question, quesPkgPath);
+        set.add(question);
     }
 
     // 去除<span> 标签中lang = EN - US

+ 9 - 9
examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/impl/ExtractConfigFileServiceImpl.java

@@ -165,9 +165,9 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
      * @throws Exception
      */
     private void uploadPaperFile(ExtractConfig extractConfig, String paperId, ExportStructure exportStructure, User user, ExamPaper examPaper) throws Exception {
-        ExportServiceManage esm = exportServiceManageRepo.findByOrgName(user.getRootOrgName());
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(String.valueOf(user.getRootOrgId()));
         if (esm == null) {
-            esm = exportServiceManageRepo.findByOrgName("天津大学");
+            throw new StatusException("500", "尚未配置导出功能!");
         }
         ExportPaperAbstractService exportPaperAbstractService = (ExportPaperAbstractService) SpringContextUtils.getBeanById(esm.getExportServiceName());
         exportPaperAbstractService.uploadFile(extractConfig, paperId, exportStructure, user, examPaper);
@@ -188,7 +188,7 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
     }
 
     @Override
-    public void exportExamPaperInfo(ExportPaperInfoModel exportModel, HttpServletResponse response, String loginName, String orgName, String psw) throws Exception {
+    public void exportExamPaperInfo(ExportPaperInfoModel exportModel, HttpServletResponse response, String loginName, String orgId, String psw) throws Exception {
         String tempDir = loginName + System.currentTimeMillis();
         String downloadDir = sysProperty.getDownloadDirectory() + "/" + tempDir;
         String downZipDir = sysProperty.getZipDirectory() + "/" + tempDir;
@@ -252,7 +252,7 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
                             String groupCode = examPaper.getGroupCode();
                             String paperId = examPaper.getPaper().getId();
                             if (groupCode.equals(examFile.getGroupCode())) {
-                                downloadAudio(paperId, examFile, downloadDir, orgName);
+                                downloadAudio(paperId, examFile, downloadDir, orgId);
                             }
 
                         }
@@ -287,11 +287,11 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
      *
      * @throws Exception
      */
-    private void downloadAudio(String paperId, ExamFile examFile, String downloadDir, String orgName) throws Exception {
+    private void downloadAudio(String paperId, ExamFile examFile, String downloadDir, String orgId) throws Exception {
         //Paper paper = paperRepo.findOne(paperId);
-        ExportServiceManage esm = exportServiceManageRepo.findByOrgName(orgName);
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(orgId);
         if (esm == null) {
-            esm = exportServiceManageRepo.findByOrgName("陕西师范大学");
+            throw new StatusException("500", "尚未配置导出功能!");
         }
         ExportPaperAbstractService exportPaperAbstractService = (ExportPaperAbstractService) SpringContextUtils.getBeanById(esm.getExportServiceName());
         PaperExp paperExp = exportPaperAbstractService.initPaperExp(paperId);
@@ -504,9 +504,9 @@ public class ExtractConfigFileServiceImpl implements ExtractConfigFileService {
         //主观题集合
         List<SubjectiveQuestionStructure> subjectiveQuestionStructureList = new ArrayList<>();
 
-        ExportServiceManage esm = exportServiceManageRepo.findByOrgName(exportStructure.getOrgName());
+        ExportServiceManage esm = exportServiceManageRepo.findByOrgId(exportStructure.getOrgId());
         if (esm == null) {
-            esm = exportServiceManageRepo.findByOrgName("陕西师范大学");
+            throw new StatusException("500", "尚未配置导出功能!");
         }
         ExportPaperAbstractService exportPaperAbstractService = (ExportPaperAbstractService) SpringContextUtils.getBeanById(esm.getExportServiceName());
         Set<Entry<String, String>> entrySet = paperIds.entrySet();

+ 741 - 652
examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/temp/CqdxService.java

@@ -2,9 +2,11 @@ package cn.com.qmth.examcloud.core.questions.service.temp;
 
 import java.io.File;
 import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -15,672 +17,759 @@ import org.apache.commons.collections4.map.HashedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
 import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.questions.base.CommonUtils;
+import cn.com.qmth.examcloud.core.questions.base.IdUtils;
+import cn.com.qmth.examcloud.core.questions.base.converter.utils.FileUtil;
+import cn.com.qmth.examcloud.core.questions.base.enums.PaperStatus;
+import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
 import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
+import cn.com.qmth.examcloud.core.questions.dao.PaperDetailRepo;
+import cn.com.qmth.examcloud.core.questions.dao.PaperDetailUnitRepo;
+import cn.com.qmth.examcloud.core.questions.dao.PaperRepo;
+import cn.com.qmth.examcloud.core.questions.dao.QuesRepo;
+import cn.com.qmth.examcloud.core.questions.dao.entity.Course;
+import cn.com.qmth.examcloud.core.questions.dao.entity.Paper;
+import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetail;
+import cn.com.qmth.examcloud.core.questions.dao.entity.PaperDetailUnit;
+import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
+import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
+import cn.com.qmth.examcloud.core.questions.service.QuesTypeNameService;
+import cn.com.qmth.examcloud.core.questions.service.impl.CourseService;
+import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
 
 @Component
 public class CqdxService {
-    private static final Logger log = LoggerFactory.getLogger(CqdxService.class);
-    final Long rootOrgId = 1407L;
-    final String rootDir = "D:/paper/cqu/temps";
-//    @Autowired
-//    private CourseService courseService;
-//    @Autowired
-//    private QuesRepo quesRepo;
-//    @Autowired
-//    private PaperRepo paperRepo;
-//    @Autowired
-//    private PaperDetailRepo paperDetailRepo;
-//    @Autowired
-//    private PaperDetailUnitRepo paperDetailUnitRepo;
-//    @Autowired
-//    private QuesPkgPathRepo quesPkgPathRepo;
-
-//    public void bulidPaper() throws Exception {
-//        // 获取所有xml的路径
-//        List<String> files = this.loadFiles();
-//
-//        //试卷名称(后缀)
-//        final String paperNameSuffix = "192";
-//
-//        int i = 0;
-//        log.debug("XML的文件数:" + files.size());
-//        for (String filePath : files) {
-//            log.debug("第" + (++i) + "个xml文件开始处理,文件名为:" + filePath);
-//
-////            if (i < 30) {
-////                continue;
-////            }
-//
-//            Map<Object, Object> paperInfoMap = this.readXml(filePath, paperNameSuffix);
-//            // 查询课程
-//            Course course = courseService.getCourse(rootOrgId, paperInfoMap.get("courseCode").toString());
-//            // 初始化试卷
-//            Paper paper = initPaper(paperInfoMap, course);
-//            // 大题集合
-//            List<PaperDetail> paperDetails = initPaperDetails(paperInfoMap, paper);
-//            // 试题---资源 对应关系
-//            Map<Question, QuestionPkgPath> questionMaps = new HashMap<>();
-//
-//            // 定义小题集合
-//            List<PaperDetailUnit> paperDetailUnits;
-//            try {
-//                paperDetailUnits = initpaperDetailUnits(paper, paperDetails, questionMaps, paperInfoMap, course);
-//                if (paperDetailUnits == null) {
-//                    log.debug("-->有错误的XML:" + filePath);
-//                    break;
-//                }
-//            } catch (Exception e) {
-//                log.debug("==>有错误的XML:" + filePath + " Error:" + e.getMessage());
-//                break;
-//            }
-//
-//            // 保存试题资源
-//            /*quesPkgPathRepo.saveAll(questionMaps.values());
-//            for (Map.Entry<Question, QuestionPkgPath> entry : questionMaps.entrySet()) {
-//                entry.getKey().setQuesPkgPathId(entry.getValue().getId());
+	private static final Logger log = LoggerFactory.getLogger(CqdxService.class);
+//	final Long rootOrgId = 1407L;
+//	final String rootDir = "D:/paper/cqu/temps";
+	@Autowired
+	private CourseService courseService;
+	@Autowired
+	private QuesRepo quesRepo;
+	@Autowired
+	private PaperRepo paperRepo;
+	@Autowired
+	private PaperDetailRepo paperDetailRepo;
+	@Autowired
+	private PaperDetailUnitRepo paperDetailUnitRepo;
+//	@Autowired
+//	private QuesPkgPathRepo quesPkgPathRepo;
+	@Autowired
+	private QuesTypeNameService quesTypeNameService;
+
+	public void bulidPaper(MultipartFile dataFile, User user, Long rootOrgId, String paperNameSuffix, String impType) {
+		String tempDir = PropertyHolder.getString("examcloud.web.sys.tempDataDir");
+		String dir = tempDir + File.separator + UUID.randomUUID() + File.separator;
+		try {
+			File dfile = new File(dir);
+			dfile.mkdirs();
+			File zfile = new File(dir + dataFile.getOriginalFilename());
+			zfile.createNewFile();
+			dataFile.transferTo(zfile);
+			Map<Object, Object> paperInfoMap = this.readXml(zfile.getAbsolutePath(), paperNameSuffix, impType);
+			// 查询课程
+			Course course = courseService.getCourse(rootOrgId, paperInfoMap.get("courseCode").toString());
+			// 初始化试卷
+			Paper paper = initPaper(paperInfoMap, course, user);
+			// 大题集合
+			List<PaperDetail> paperDetails = initPaperDetails(paperInfoMap, paper, user);
+			// 试题---资源 对应关系
+			List<Question> questionLists = new ArrayList<>();
+
+			// 定义小题集合
+			List<PaperDetailUnit> paperDetailUnits;
+			paperDetailUnits = initpaperDetailUnits(paper, paperDetails, questionLists, paperInfoMap, course, user);
+			if (paperDetailUnits == null) {
+				throw new StatusException("100001", "有错误的XML");
+			}
+
+			// 保存试题资源
+//			quesPkgPathRepo.saveAll(questionMaps.values());
+//			for (Map.Entry<Question, QuestionPkgPath> entry : questionMaps.entrySet()) {
+//				entry.getKey().setQuesPkgPathId(entry.getValue().getId());
+//			}
+			quesRepo.saveAll(questionLists);
+			paperRepo.save(paper);
+			paperDetailRepo.saveAll(paperDetails);
+			paperDetailUnitRepo.saveAll(paperDetailUnits);
+			if (paperDetailUnits.size() > 0) {
+				quesTypeNameService.saveQuesTypeName(paperDetailUnits);
+			}
+		} catch (StatusException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new StatusException("100002", "导入试卷失败:" + e.getMessage(), e);
+		} finally {
+			FileUtil.deleteFolder(dir);
+		}
+	}
+
+	public void bulidPaper() throws Exception {
+		// 获取所有xml的路径
+//		List<String> files = this.loadFiles();
+
+		// 试卷名称(后缀)
+//		final String paperNameSuffix = "192";
+
+//		int i = 0;
+//		log.debug("XML的文件数:" + files.size());
+//		for (String filePath : files) {
+//			log.debug("第" + (++i) + "个xml文件开始处理,文件名为:" + filePath);
+
+//            if (i < 30) {
+//                continue;
 //            }
-//            quesRepo.saveAll(questionMaps.keySet());
-//            paperRepo.save(paper);
-//            paperDetailRepo.saveAll(paperDetails);
-//            paperDetailUnitRepo.saveAll(paperDetailUnits);*/
-//
-//            // 将正常文件移动到新目录
-//            /*File okFile = new File(rootDir + "/" + filePath);
-//            String newFilePath = rootDir + "/ok/" + okFile.getName();
-//            File newFile = new File(newFilePath);
-//            okFile.renameTo(newFile);*/
-//
-//            log.debug("第" + i + "个xml文件已经处理完,文件名为:" + filePath);
-//        }
-//        log.debug("处理完成...");
-//    }
-
-    // 初始化试卷
-//    private Paper initPaper(Map<Object, Object> paperInfoMap, Course course) {
-//        Paper paper = new Paper();
-//        paper.setName((String) paperInfoMap.get("name"));
-//        paper.setTitle((String) paperInfoMap.get("name"));
-//        paper.setPaperType(PaperType.IMPORT);
-//        paper.setPaperStatus(PaperStatus.DRAFT);
-//        paper.setOrgId(course.getOrgId());
-//        paper.setCreator("feng");
-//        paper.setTotalScore(Double.valueOf((String) paperInfoMap
-//                .get("totalScore")));
-//        paper.setCourse(course);
-//        paper.setCourseName(course.getName());
-//        paper.setCourseNo(course.getCode());
-//        paper.setCreateTime(CommonUtils.getCurDateTime());
-//        paper.setPaperDetailCount(Integer.valueOf((String) paperInfoMap
-//                .get("detailCount")));
-//        paper.setUnitCount(Integer.valueOf((String) paperInfoMap
-//                .get("unitCount")));
-//        paper.setDifficultyDegree(0.5);
-//        return paper;
-//    }
-//
-//    // 初始化大题集合
-//    private List<PaperDetail> initPaperDetails(
-//            Map<Object, Object> paperInfoMap, Paper paper) {
-//        // 定义大题集合
-//        List<PaperDetail> paperDetails = new ArrayList<PaperDetail>();
-//        int length = paperInfoMap.size() - 5;
-//        for (int i = 0; i < length; i++) {
-//            QuestionsTemp detailInfo = (QuestionsTemp) paperInfoMap.get(String
-//                    .valueOf(i + 1));
-//            PaperDetail paperDetail = new PaperDetail();
-//            paperDetail.setPaper(paper);
-//            paperDetail.setNumber(Integer.valueOf(detailInfo.getNumber()));
-//            paperDetail.setName(detailInfo.getName());
-//            paperDetail.setScore(Double.valueOf(detailInfo.getTotalScore()));
-//            paperDetail.setUnitCount(Integer.valueOf(detailInfo.getCount()));
-//            paperDetail.setCreator("feng");
-//            paperDetail.setCreateTime(CommonUtils.getCurDateTime());
-//            paperDetails.add(paperDetail);
-//        }
-//        return paperDetails;
-//    }
-
-    public Map<Object, Object> readXml(String xmlPath, String paperNameSuffix) throws Exception {
-        Map<Object, Object> paperInfoMap = new HashedMap<>();
-        DocumentBuilderFactory a = DocumentBuilderFactory.newInstance();
-        DocumentBuilder b = a.newDocumentBuilder();
-
-        // “file:///”表示是本地计算机,否则报错“unknown protocol”
-        Document document = b.parse("file:///" + xmlPath);
-        NodeList exerciseDocuments = document
-                .getElementsByTagName("ExerciseDocument");
-        // 遍历exerciseDocument节点
-        for (int i = 0; i < exerciseDocuments.getLength(); i++) {
-            // 获取第一个exerciseDocument
-            Node node = exerciseDocuments.item(i);
-            // 获取exerciseDocument节点下的所有属性
-            NamedNodeMap namedNodeMap = node.getAttributes();
-            // 课程代码
-            paperInfoMap.put("courseCode", namedNodeMap.getNamedItem("CourseId").getTextContent());
-            // 试卷名称(后缀)
-            paperInfoMap.put("name", namedNodeMap.getNamedItem("CourseName").getTextContent() + namedNodeMap.getNamedItem("ProblemDocumentName").getTextContent() + "(" + paperNameSuffix + ")");
-            // 试卷总分
-            paperInfoMap.put("totalScore", namedNodeMap.getNamedItem("Score").getTextContent());
-            // 大题数量
-            paperInfoMap.put("detailCount", namedNodeMap.getNamedItem("ProblemCollectionCount").getTextContent());
-            // 小题数量
-            paperInfoMap.put("unitCount", namedNodeMap.getNamedItem("ProblemCount").getTextContent());
-            // 获取ProblemCollection所有节点
-            NodeList problemList = node.getChildNodes();
-            for (int j = 0; j < problemList.getLength(); j++) {
-                // 大题节点
-                Node detailNode = problemList.item(j);
-                if (detailNode.getNodeName().equals("ProblemCollection")) {
-                    Map<Object, Object> detailInfoMap = new HashedMap<Object, Object>();
-                    QuestionsTemp detailInfo = new QuestionsTemp();
-                    // 大题序号
-                    detailInfo.setNumber(detailNode.getAttributes().getNamedItem("Index").getTextContent());
-                    // 大题名称
-                    detailInfo.setName(detailNode.getAttributes().getNamedItem("ProblemTypeName").getTextContent());
-                    // 大题总分
-                    detailInfo.setTotalScore(detailNode.getAttributes().getNamedItem("Score").getTextContent());
-                    // 大题总数
-                    detailInfo.setCount(detailNode.getAttributes().getNamedItem("ProblemCount").getTextContent());
-                    // 获取所有Problem节点
-                    NodeList unitList = detailNode.getChildNodes();
-                    for (int k = 0; k < unitList.getLength(); k++) {
-                        Node unitNode = unitList.item(k);
-                        if (unitNode.getNodeName().equals("Problem")) {
-                            QuestionsTemp unitInfo = new QuestionsTemp();
-                            // 小题分数
-                            unitInfo.setScore(unitNode.getAttributes().getNamedItem("Score").getTextContent());
-                            // 小题序号
-                            unitInfo.setNumber(unitNode.getAttributes().getNamedItem("Index").getTextContent());
-                            // 小题题型
-                            String type = unitNode.getAttributes().getNamedItem("ProblemClassType").getTextContent();
-                            // 获取题目文本节点
-                            NodeList unitInfoList = unitNode.getChildNodes();
-                            for (int z = 0; z < unitInfoList.getLength(); z++) {
-                                Node unitInfoNode = unitInfoList.item(z);
-                                if (unitInfoNode.getNodeName().equals("Content")) {
-                                    // 小题题干
-                                    unitInfo.setBody(unitInfoNode.getTextContent());
-                                }
-                                // 选择题
-                                if (unitInfoNode.getNodeName().equals("ChoiceItem")) {
-                                    NodeList optionsInfoList = unitInfoNode.getChildNodes();
-                                    String answer = "";
-                                    if (type.equals("MonomialChoice")) {
-                                        unitInfo.setType(QuesStructType.SINGLE_ANSWER_QUESTION);
-                                    }
-                                    if (type.equals("MultipleChoice")) {
-                                        unitInfo.setType(QuesStructType.MULTIPLE_ANSWER_QUESTION);
-                                    }
-                                    Map<Object, Object> options = new HashedMap<Object, Object>();
-                                    for (int u = 0; u < optionsInfoList.getLength(); u++) {
-                                        Node optionsInfoNode = optionsInfoList.item(u);
-                                        if (optionsInfoNode.getNodeName().equals("Options")) {
-                                            // 所有选项节点
-                                            NodeList optionInfoList = optionsInfoNode.getChildNodes();
-                                            for (int r = 0; r < optionInfoList.getLength(); r++) {
-                                                Node optionInfoNode = optionInfoList.item(r);
-                                                if (optionInfoNode.getNodeName().equals("Option")) {
-                                                    // 选项序号,内容
-                                                    options.put(optionInfoNode.getAttributes().getNamedItem("Index").getTextContent(), optionInfoNode.getTextContent());
-                                                    if (optionInfoNode.getAttributes().getNamedItem("Selected").getTextContent().equals("True")) {
-                                                        if (StringUtils.isBlank(answer)) {
-                                                            answer = optionInfoNode.getAttributes().getNamedItem("Index").getTextContent();
-                                                        } else {
-                                                            answer = answer + "," + optionInfoNode.getAttributes().getNamedItem("Index").getTextContent();
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                            // 小题选项
-                                            unitInfo.setOptions(options);
-                                            unitInfo.setAnswer(answer);
-                                        }
-                                    }
-                                }
-                                // 完形填空,单选类的阅读理解
-                                if (unitInfoNode.getNodeName().equals("ChoiceItems")) {
-                                    unitInfo.setType(QuesStructType.NESTED_ANSWER_QUESTION);
-                                    Map<Object, Object> subQues = new HashedMap<Object, Object>();
-                                    Map<Object, Object> subOptions = new HashedMap<Object, Object>();
-                                    NodeList choiceItemsList = unitInfoNode.getChildNodes();
-                                    int number = 1;
-                                    for (int h = 0; h < choiceItemsList.getLength(); h++) {
-                                        Node subUnitInfoNode = choiceItemsList.item(h);
-                                        String answer = "";
-                                        if (subUnitInfoNode.getNodeName().equals("ChoiceItem")) {
-                                            // 每一个子题选项
-                                            QuestionsTemp subUnit = new QuestionsTemp();
-                                            NodeList subOptionsInfoList = subUnitInfoNode.getChildNodes();
-                                            for (int hu = 0; hu < subOptionsInfoList.getLength(); hu++) {
-                                                Node subOptionsInfoNode = subOptionsInfoList.item(hu);
-                                                if (subOptionsInfoNode.getNodeName().equals("Options")) {
-                                                    // 所有选项节点
-                                                    NodeList subOptionInfoList = subOptionsInfoNode.getChildNodes();
-                                                    for (int hr = 0; hr < subOptionInfoList.getLength(); hr++) {
-                                                        Node subOptionInfoNode = subOptionInfoList.item(hr);
-                                                        if (subOptionInfoNode.getNodeName().equals("Option")) {
-                                                            // 子题选项序号,内容
-                                                            subOptions.put(subOptionInfoNode.getAttributes().getNamedItem("Index").getTextContent(), subOptionInfoNode.getTextContent());
-                                                            if (subOptionInfoNode.getAttributes().getNamedItem("Selected").getTextContent().equals("True")) {
-                                                                if (StringUtils.isBlank(answer)) {
-                                                                    answer = subOptionInfoNode.getAttributes().getNamedItem("Index").getTextContent();
-                                                                } else {
-                                                                    answer = answer + "," + subOptionInfoNode.getAttributes().getNamedItem("Index").getTextContent();
-                                                                }
-                                                            }
-                                                        }
-                                                    }
-                                                    // 子题选项
-                                                    subUnit.setOptions(subOptions);
-                                                    // 子题答案
-                                                    subUnit.setAnswer(answer);
-                                                    if (answer.contains(",")) {
-                                                        subUnit.setType(QuesStructType.MULTIPLE_ANSWER_QUESTION);
-                                                    } else {
-                                                        subUnit.setType(QuesStructType.SINGLE_ANSWER_QUESTION);
-                                                    }
-                                                }
-                                                if (subOptionsInfoNode.getNodeName().equals("Content")) {
-                                                    subUnit.setBody(subOptionsInfoNode.getTextContent());
-                                                }
-                                                if (subOptionsInfoNode.getNodeName().equals("Answer")) {
-                                                    subUnit.setType(QuesStructType.TEXT_ANSWER_QUESTION);
-                                                    subUnit.setAnswer(subOptionsInfoNode.getTextContent());
-                                                }
-                                            }
-                                            if (StringUtils.isBlank(subUnit.getBody())) {
-                                                subUnit.setBody("__________");
-                                            }
-                                            subUnit.setNumber(String.valueOf(number));
-                                            subQues.put(subUnit.getNumber(), subUnit);
-                                            number++;
-                                        }
-                                    }
-                                    unitInfo.setSubQues(subQues);
-                                }
-                                // 普通答案
-                                if (unitInfoNode.getNodeName().equals("Answer")) {
-                                    // 判断题
-                                    if (type.equals("TrueOrFalse")) {
-                                        unitInfo.setType(QuesStructType.BOOL_ANSWER_QUESTION);
-                                        String answerString = unitInfoNode.getTextContent();
-                                        if (answerString.contains("False")) {
-                                            unitInfo.setAnswer("错误");
-                                        } else {
-                                            unitInfo.setAnswer("正确");
-                                        }
-                                    }
-                                    // 主观题
-                                    if (type.equals("EssayQuestion")) {
-                                        unitInfo.setType(QuesStructType.TEXT_ANSWER_QUESTION);
-                                        unitInfo.setAnswer(unitInfoNode.getTextContent());
-                                    }
-                                }
-                            }
-                            // 添加小题到大题
-                            detailInfoMap.put(unitInfo.getNumber(), unitInfo);
-                        }
-                    }
-                    detailInfo.setQues(detailInfoMap);
-                    // 添加大题到试卷
-                    paperInfoMap.put(detailInfo.getNumber(), detailInfo);
-                }
-            }
-        }
-        return paperInfoMap;
-    }
-
-    // 初始化小题集合
-//    private List<PaperDetailUnit> initpaperDetailUnits(Paper paper, List<PaperDetail> paperDetails, Map<Question, QuestionPkgPath> map,
-//                                                       Map<Object, Object> paperInfoMap, Course course) throws Exception {
-//        List<PaperDetailUnit> paperDetailUnits = new ArrayList<PaperDetailUnit>();
-//        int detailCount = paperDetails.size();
-//        int nm = 0;
-//        for (int i = 0; i < detailCount; i++) {
-//            PaperDetail detail = paperDetails.get(i);
-//            QuestionsTemp detailTemp = (QuestionsTemp) paperInfoMap.get(String
-//                    .valueOf(i + 1));
-//            Map<Object, Object> detailInfoMap = detailTemp.getQues();
-//            int quesCount = detailInfoMap.size();
-//            for (int j = 0; j < quesCount; j++) {
-//                WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage
-//                        .createPackage();
-//                QuestionsTemp quesTemp = (QuestionsTemp) detailInfoMap
-//                        .get(String.valueOf(j + 1));
-//                Question question = new Question();
-//                question.setCreateTime(CommonUtils.getCurDateTime());
-//                question.setScore(Double.valueOf(quesTemp.getScore()));
-//                question.setCourse(course);
-//                question.setOrgId(course.getOrgId());
-//                question.setHasAudio(false);
-//                question.setDifficulty("中");
-//                question.setDifficultyDegree(0.5);
-//                question.setPublicity(true);
-//                question.setQuestionType(quesTemp.getType());
-//
-//                String body = imgList(quesTemp.getBody());
-//                question.setQuesBody(replaceBlank(body));
-//                try {
-//                    question.setQuesBodyWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(question.getQuesBody())));
-//                } catch (Exception e) {
-//                    log.debug("错误题干信息:" + question.getQuesBody());
-//                    throw new IllegalArgumentException("题干信息错误!");
-//                }
-//                if (question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION) {
-//                    question.setQuesAnswer(quesTemp.getAnswer());
-//                    question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml("<p>" + question.getQuesAnswer() + "</p>")));
-//                } else {
-//                    question.setQuesAnswer(imgList(quesTemp.getAnswer()));
-//                    try {
-//                        question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(question.getQuesAnswer())));
-//                    } catch (Exception e) {
-//                        log.debug("错误答案信息:" + question.getQuesAnswer());
-//                        throw new IllegalArgumentException("答案信息错误!");
-//                    }
-//                }
-//                // 存在选项
-//                if (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
-//                        || question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
-//                    List<QuesOption> quesOptions = new ArrayList<QuesOption>();
-//                    Map<Object, Object> optionMap = quesTemp.getOptions();
-//                    int optionCount = optionMap.size();
-//                    for (int k = 0; k < optionCount; k++) {
-//                        QuesOption quesOption = new QuesOption();
-//                        quesOption.setNumber(String.valueOf(k + 1));
-//
-//                        String optionBody = imgList((String) optionMap.get(String.valueOf(k + 1)));
-//                        if (optionBody.startsWith("<p><p") || optionBody.startsWith("<P><P")) {
-//                            quesOption.setOptionBody(replaceFirstP(optionBody));
-//                        } else {
-//                            quesOption.setOptionBody(optionBody);
-//                        }
-//
-//                        try {
-//                            quesOption.setOptionBodyWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(quesOption.getOptionBody())));
-//                        } catch (Exception e) {
-//                            log.debug("错误的选项:" + quesOption.getOptionBody());
-//                            throw new IllegalArgumentException("选项信息错误!");
-//                        }
-//                        if (question.getQuesAnswer().contains(String.valueOf(k + 1))) {
-//                            quesOption.setIsCorrect((short) 1);
-//                        } else {
-//                            quesOption.setIsCorrect((short) 0);
-//                        }
-//                        quesOptions.add(quesOption);
-//                    }
-//                    question.setQuesOptions(quesOptions);
-//                    String[] answers = question.getQuesAnswer()
-//                            .replaceAll("<p>", "").replaceAll("</p>", "")
-//                            .replaceAll("<P>", "").replaceAll("</P>", "")
-//                            .split(",");
-//                    String answer = "";
-//                    for (int a = 0; a < answers.length; a++) {
-//                        char c1 = (char) (Integer.valueOf(answers[a]) + 64);
-//                        if (a == 0) {
-//                            answer = String.valueOf(c1);
-//                        } else {
-//                            answer = answer + "," + c1;
-//                        }
-//                    }
-//                    question.setQuesAnswer("<p>" + answer + "</p>");
-//                    question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(question.getQuesAnswer())));
-//                }
-//                // 存在子题
-//                if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
-//                    List<Question> subQuestions = new ArrayList<>();
-//                    int subQuesCount = quesTemp.getSubQues().size();
-//                    BigDecimal totalScore = BigDecimal.valueOf(question.getScore());
-//                    BigDecimal sum = BigDecimal.valueOf(subQuesCount);
-//                    double score = totalScore.divide(sum).doubleValue();
-//                    for (int s = 0; s < subQuesCount; s++) {
-//                        QuestionsTemp subQuesTmp = (QuestionsTemp) quesTemp.getSubQues().get(String.valueOf(s + 1));
-//                        Question subQuestion = new Question();
-//                        subQuestion.setId(IdUtils.uuid());
-//                        subQuestion.setQuestionType(subQuesTmp.getType());
-//                        subQuestion.setDifficulty("中");
-//                        subQuestion.setDifficultyDegree(0.5);
-//                        subQuestion.setPublicity(true);
-//                        subQuestion.setScore(score);
+
+//			Map<Object, Object> paperInfoMap = this.readXml(filePath, paperNameSuffix);
+//			// 查询课程
+//			Course course = courseService.getCourse(rootOrgId, paperInfoMap.get("courseCode").toString());
+//			// 初始化试卷
+//			Paper paper = initPaper(paperInfoMap, course);
+//			// 大题集合
+//			List<PaperDetail> paperDetails = initPaperDetails(paperInfoMap, paper);
+//			// 试题---资源 对应关系
+//			Map<Question, QuestionPkgPath> questionMaps = new HashMap<>();
 //
-//                        String subBody = imgList(subQuesTmp.getBody());
-//                        question.setQuesBody(replaceBlank(body));
-//                        subQuestion.setQuesBody(subBody);
+//			// 定义小题集合
+//			List<PaperDetailUnit> paperDetailUnits;
+//			try {
+//				paperDetailUnits = initpaperDetailUnits(paper, paperDetails, questionMaps, paperInfoMap, course);
+//				if (paperDetailUnits == null) {
+//					log.debug("-->有错误的XML:" + filePath);
+//					break;
+//				}
+//			} catch (Exception e) {
+//				log.debug("==>有错误的XML:" + filePath + " Error:" + e.getMessage());
+//				break;
+//			}
 //
-//                        subQuestion.setQuesBodyWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(subQuestion.getQuesBody())));
-//                        subQuestion.setQuesAnswer(imgList(subQuesTmp.getAnswer()));
-//                        subQuestion.setQuesBodyWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(subQuestion.getQuesAnswer())));
-//                        // 存在选项
-//                        if (subQuestion.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
-//                                || subQuestion.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
-//                            List<QuesOption> subQuesOptions = new ArrayList<QuesOption>();
-//                            Map<Object, Object> subOptionMap = subQuesTmp.getOptions();
-//                            int subOptionCount = subOptionMap.size();
-//                            for (int k = 0; k < subOptionCount; k++) {
-//                                QuesOption subQuesOption = new QuesOption();
-//                                subQuesOption.setNumber(String.valueOf(k));
+//			// 保存试题资源
+//			quesPkgPathRepo.saveAll(questionMaps.values());
+//			for (Map.Entry<Question, QuestionPkgPath> entry : questionMaps.entrySet()) {
+//				entry.getKey().setQuesPkgPathId(entry.getValue().getId());
+//			}
+//			quesRepo.saveAll(questionMaps.keySet());
+//			paperRepo.save(paper);
+//			paperDetailRepo.saveAll(paperDetails);
+//			paperDetailUnitRepo.saveAll(paperDetailUnits);
 //
-//                                String optionBody = imgList((String) subOptionMap.get(String.valueOf(k + 1)));
-//                                if (optionBody.startsWith("<p><p") || optionBody.startsWith("<P><P")) {
-//                                    subQuesOption.setOptionBody(replaceFirstP(optionBody));
-//                                } else {
-//                                    subQuesOption.setOptionBody(optionBody);
-//                                }
+//			// 将正常文件移动到新目录
+//			File okFile = new File(rootDir + "/" + filePath);
+//			String newFilePath = rootDir + "/ok/" + okFile.getName();
+//			File newFile = new File(newFilePath);
+//			okFile.renameTo(newFile);
 //
-//                                subQuesOption.setOptionBodyWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(subQuesOption.getOptionBody())));
-//                                if (subQuestion.getQuesAnswer().contains(String.valueOf(k + 1))) {
-//                                    subQuesOption.setIsCorrect((short) 1);
-//                                } else {
-//                                    subQuesOption.setIsCorrect((short) 0);
-//                                }
-//                                subQuesOptions.add(subQuesOption);
-//                            }
-//                            subQuestion.setQuesOptions(subQuesOptions);
-//                            String[] answers = subQuestion.getQuesAnswer()
-//                                    .replaceAll("<p>", "").replaceAll("</p>", "")
-//                                    .replaceAll("<P>", "").replaceAll("</P>", "")
-//                                    .split(",");
-//                            String answer = "";
-//                            for (int a = 0; a < answers.length; a++) {
-//                                char c1 = (char) (Integer.valueOf(answers[a]) + 64);
-//                                if (a == 0) {
-//                                    answer = String.valueOf(c1);
-//                                } else {
-//                                    answer = answer + "," + c1;
-//                                }
-//                            }
-//                            subQuestion.setQuesAnswer(answer);
-//                            subQuestion.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml("<p>" + subQuestion.getQuesAnswer() + "</p>")));
-//                        }
-//                        subQuestions.add(subQuestion);
-//                    }
-//                    question.setSubQuestions(subQuestions);
-//                }
-//                byte[] pkgByte = DocxProcessUtil.getPkgByte(wordMLPackage);
-//                QuestionPkgPath quesPkgPath = new QuestionPkgPath(pkgByte);
-//                map.put(question, quesPkgPath);
-//                // 包装小题
-//                PaperDetailUnit paperDetailUnit = new PaperDetailUnit();
-//                paperDetailUnit.setPaper(paper);
-//                paperDetailUnit.setNumber(nm + 1);
-//                paperDetailUnit.setScore(question.getScore());
-//                paperDetailUnit.setPaperDetail(detail);
-//                paperDetailUnit.setQuestionType(question.getQuestionType());
-//                paperDetailUnit.setCreator("feng");
-//                paperDetailUnit.setCreateTime(CommonUtils.getCurDateTime());
-//                paperDetailUnit.setQuestion(question);
-//                paperDetailUnits.add(paperDetailUnit);
-//                nm++;
-//            }
-//        }
-//        return paperDetailUnits;
-//    }
-
-    public String imgList(String str) throws Exception {
-        if (StringUtils.isBlank(str)) {
-            str = "<p></p>";
-        }
-        str = str.trim().replace("<br>", "").replace("</br>", "");
-        if (!str.contains("<p>") && !str.contains("</P>")) {
-            str = "<p>" + str + "</p>";
-        }
-        //先处理span标签
-        List<String> spans = parseSpans(str);
-        if (spans != null && spans.size() > 0) {
-            for (String span : spans) {
-                str = str.replace(span, "").replace("</span>", "").replace("</SPAN>", "");
-            }
-        }
-        str = str.replace("<o:p>", "").replace("</o:p>", "").replace("border=0", "").replace("class=MsoNormal", "").replace("&phiv;", "").replace("</SPAN>", "");
-        // 获取img标签
-        List<String> srcList = ImgDataUtils.parseImages(str);
-        if (srcList != null && srcList.size() > 0) {
-            for (String img : srcList) {
-                // 获取height,width值
-                List<String> height = getTagAHei(img);
-                List<String> width = getTagAWid(img);
-                List<String> parseImageSrc = ImgDataUtils.parseImageSrc(img);
-                if (parseImageSrc != null && parseImageSrc.size() > 0) {
-                    String src = parseImageSrc.get(0).replace("{ResourcePath}", "http://file.5any.com/UniversityV4.0");
-                    String url = regexCH(src);
-                    log.info("img url:" + url);
-                    url = url.replaceAll("\\\\", "/");
-
-                    String base64 = ImgDataUtils.loadImageToBase64(url);
-                    if (base64 == null) {
-                        throw new Exception("图片下载失败!" + url);
-                    } else {
-                        if (src.contains("jpg")) {
-                            str = str.replace(parseImageSrc.get(0),
-                                    "data:image/jpg;base64," + base64);
-                        } else {
-                            str = str.replace(parseImageSrc.get(0),
-                                    "data:image/png;base64," + base64);
-                        }
-                        if (height != null && height.size() > 0) {
-                            str = str.replace("height=" + height.get(0),
-                                    "height=\"" + height.get(0) + "\"");
-                        }
-                        if (width != null && width.size() > 0) {
-                            str = str.replace("width=" + width.get(0),
-                                    "width=\"" + width.get(0) + "\"");
-                        }
-                    }
-                }
-            }
-        }
-        return str.replace("<IMG", "<img");
-    }
-
-    // 將url路徑中的中文转码
-    public String regexCH(String str) throws UnsupportedEncodingException {
-        StringBuffer s = new StringBuffer();
-        Pattern pat = Pattern.compile("[\u4E00-\u9FA5]");
-        Matcher mat = pat.matcher(str);
-        while (mat.find()) {
-            s.append(mat.group());
-        }
-        String url = java.net.URLEncoder.encode(s.toString(), "utf-8");
-        return str.replace(s.toString(), url);
-    }
-
-    public List<String> loadFiles() {
-        // 获取某文件夹下所有XML文件的路径
-        List<String> paths = new ArrayList<>();
-        File dir = new File(rootDir);
-        this.loadMoreFiles(dir, paths);
-        return paths;
-    }
-
-    private void loadMoreFiles(File file, List<String> paths) {
-        if (file.isDirectory()) {
-            File[] subFiles = file.listFiles();
-            for (File subFile : subFiles) {
-                this.loadMoreFiles(subFile, paths);
-            }
-        } else {
-            String path = file.getPath()
-                    .replaceAll("\\\\", "/");
-
-            if (file.getName().endsWith(".xml")) {
-                paths.add(path);
-            } else {
-                log.debug("无效文件:" + path);
-            }
-        }
-    }
-
-    public static List<String> parseSpans(String content) {
-        if (content == null) {
-            return new ArrayList<>();
-        }
-        List<String> spans = new ArrayList<>();
-        String reg = "<(span|SPAN)(.*?)(/>|>)";
-        Pattern pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
-        Matcher matcher = pattern.matcher(content);
-        while (matcher.find()) {
-            String span = matcher.group();
-            spans.add(span);
-        }
-        return spans;
-    }
-
-    public List<String> getTagAHei(String htmlString) {
-        List<String> list = new ArrayList<String>();
-        Pattern p = Pattern
-                .compile("<IMG[^<>]*\\s+height=([0-9A-Za-z-_.]+)\\s*");
-        Matcher m = p.matcher(htmlString);
-        while (m.find()) {
-            String str = m.group(1);
-            list.add(str);
-        }
-        return list;
-    }
-
-    public List<String> getTagAWid(String htmlString) {
-        List<String> list = new ArrayList<String>();
-        Pattern p = Pattern
-                .compile("<IMG[^<>]*\\s+width=([0-9A-Za-z-_.]+)\\s*");
-        Matcher m = p.matcher(htmlString);
-        while (m.find()) {
-            String str = m.group(1);
-            list.add(str);
-        }
-        return list;
-    }
-
-    /**
-     * 将[BLANK] 替换为 ###
-     */
-    public static String replaceBlank(String str) {
-        if (str == null) {
-            return null;
-        }
-        return str.replace("[BLANK]", "###");
-    }
-
-    /**
-     * 替换首个P标签
-     */
-    public static String replaceFirstP(String str) {
-        if (str == null) {
-            return null;
-        }
-        if (str.startsWith("<p>") && str.endsWith("</p>")) {
-            //去掉头<p >
-            str = str.replaceFirst("<p>", "");
-            //去掉尾</p>
-            int index = str.lastIndexOf("</p>");
-            if (index > 0) {
-                str = str.substring(0, index);
-            }
-        }
-        return str;
-    }
+//			log.debug("第" + i + "个xml文件已经处理完,文件名为:" + filePath);
+//		}
+//		log.debug("处理完成...");
+	}
+
+	// 初始化试卷
+	private Paper initPaper(Map<Object, Object> paperInfoMap, Course course, User user) {
+		Paper paper = new Paper();
+		paper.setName((String) paperInfoMap.get("name"));
+		paper.setTitle((String) paperInfoMap.get("name"));
+		paper.setPaperType(PaperType.IMPORT);
+		paper.setPaperStatus(PaperStatus.DRAFT);
+		paper.setOrgId(course.getOrgId());
+		paper.setCreator(user.getDisplayName());
+		paper.setTotalScore(Double.valueOf((String) paperInfoMap.get("totalScore")));
+		paper.setCourse(course);
+		paper.setCourseName(course.getName());
+		paper.setCourseNo(course.getCode());
+		paper.setCreateTime(CommonUtils.getCurDateTime());
+		paper.setPaperDetailCount(Integer.valueOf((String) paperInfoMap.get("detailCount")));
+		paper.setUnitCount(Integer.valueOf((String) paperInfoMap.get("unitCount")));
+		paper.setDifficultyDegree(0.5);
+		return paper;
+	}
+
+	// 初始化大题集合
+	private List<PaperDetail> initPaperDetails(Map<Object, Object> paperInfoMap, Paper paper, User user) {
+		// 定义大题集合
+		List<PaperDetail> paperDetails = new ArrayList<PaperDetail>();
+		int length = paperInfoMap.size() - 5;
+		for (int i = 0; i < length; i++) {
+			QuestionsTemp detailInfo = (QuestionsTemp) paperInfoMap.get(String.valueOf(i + 1));
+			PaperDetail paperDetail = new PaperDetail();
+			paperDetail.setPaper(paper);
+			paperDetail.setNumber(Integer.valueOf(detailInfo.getNumber()));
+			paperDetail.setName(detailInfo.getName());
+			paperDetail.setScore(Double.valueOf(detailInfo.getTotalScore()));
+			paperDetail.setUnitCount(Integer.valueOf(detailInfo.getCount()));
+			paperDetail.setCreator(user.getDisplayName());
+			paperDetail.setCreateTime(CommonUtils.getCurDateTime());
+			paperDetails.add(paperDetail);
+		}
+		return paperDetails;
+	}
+
+	private String transProblemDocumentName(String problemDocumentName, String impType) {
+		if ("old".equals(impType)) {
+			String s1 = problemDocumentName.substring(0, 1);
+			String s2 = problemDocumentName.substring(1);
+			if ("A".equals(s1)) {
+				return "G"+s2;
+			}
+			if ("B".equals(s1)) {
+				return "H"+s2;
+			}
+			if ("C".equals(s1)) {
+				return "I"+s2;
+			}
+		}
+		return problemDocumentName;
+	}
+
+	public Map<Object, Object> readXml(String xmlPath, String paperNameSuffix, String impType) throws Exception {
+		Map<Object, Object> paperInfoMap = new HashedMap<>();
+		DocumentBuilderFactory a = DocumentBuilderFactory.newInstance();
+		DocumentBuilder b = a.newDocumentBuilder();
+
+		// “file:///”表示是本地计算机,否则报错“unknown protocol”
+		Document document = b.parse("file:///" + xmlPath);
+		NodeList exerciseDocuments = document.getElementsByTagName("ExerciseDocument");
+		// 遍历exerciseDocument节点
+		for (int i = 0; i < exerciseDocuments.getLength(); i++) {
+			// 获取第一个exerciseDocument
+			Node node = exerciseDocuments.item(i);
+			// 获取exerciseDocument节点下的所有属性
+			NamedNodeMap namedNodeMap = node.getAttributes();
+			// 课程代码
+			paperInfoMap.put("courseCode", namedNodeMap.getNamedItem("CourseId").getTextContent());
+			// 试卷名称(后缀)
+			paperInfoMap.put("name", namedNodeMap.getNamedItem("CourseName").getTextContent() + "(" + paperNameSuffix
+					+ ")" + transProblemDocumentName(namedNodeMap.getNamedItem("ProblemDocumentName").getTextContent(),impType));
+			// 试卷总分
+			paperInfoMap.put("totalScore", namedNodeMap.getNamedItem("Score").getTextContent());
+			// 大题数量
+			paperInfoMap.put("detailCount", namedNodeMap.getNamedItem("ProblemCollectionCount").getTextContent());
+			// 小题数量
+			paperInfoMap.put("unitCount", namedNodeMap.getNamedItem("ProblemCount").getTextContent());
+			// 获取ProblemCollection所有节点
+			NodeList problemList = node.getChildNodes();
+			for (int j = 0; j < problemList.getLength(); j++) {
+				// 大题节点
+				Node detailNode = problemList.item(j);
+				if (detailNode.getNodeName().equals("ProblemCollection")) {
+					Map<Object, Object> detailInfoMap = new HashedMap<Object, Object>();
+					QuestionsTemp detailInfo = new QuestionsTemp();
+					// 大题序号
+					detailInfo.setNumber(detailNode.getAttributes().getNamedItem("Index").getTextContent());
+					// 大题名称
+					detailInfo.setName(detailNode.getAttributes().getNamedItem("ProblemTypeName").getTextContent());
+					// 大题总分
+					detailInfo.setTotalScore(detailNode.getAttributes().getNamedItem("Score").getTextContent());
+					// 大题总数
+					detailInfo.setCount(detailNode.getAttributes().getNamedItem("ProblemCount").getTextContent());
+					// 获取所有Problem节点
+					NodeList unitList = detailNode.getChildNodes();
+					for (int k = 0; k < unitList.getLength(); k++) {
+						Node unitNode = unitList.item(k);
+						if (unitNode.getNodeName().equals("Problem")) {
+							QuestionsTemp unitInfo = new QuestionsTemp();
+							// 小题分数
+							unitInfo.setScore(unitNode.getAttributes().getNamedItem("Score").getTextContent());
+							// 小题序号
+							unitInfo.setNumber(unitNode.getAttributes().getNamedItem("Index").getTextContent());
+							// 小题题型
+							String type = unitNode.getAttributes().getNamedItem("ProblemClassType").getTextContent();
+							// 获取题目文本节点
+							NodeList unitInfoList = unitNode.getChildNodes();
+							for (int z = 0; z < unitInfoList.getLength(); z++) {
+								Node unitInfoNode = unitInfoList.item(z);
+								if (unitInfoNode.getNodeName().equals("Content")) {
+									// 小题题干
+									unitInfo.setBody(unitInfoNode.getTextContent());
+								}
+								// 选择题
+								if (unitInfoNode.getNodeName().equals("ChoiceItem")) {
+									NodeList optionsInfoList = unitInfoNode.getChildNodes();
+									String answer = "";
+									if (type.equals("MonomialChoice")) {
+										unitInfo.setType(QuesStructType.SINGLE_ANSWER_QUESTION);
+									}
+									if (type.equals("MultipleChoice")) {
+										unitInfo.setType(QuesStructType.MULTIPLE_ANSWER_QUESTION);
+									}
+									Map<Object, Object> options = new HashedMap<Object, Object>();
+									for (int u = 0; u < optionsInfoList.getLength(); u++) {
+										Node optionsInfoNode = optionsInfoList.item(u);
+										if (optionsInfoNode.getNodeName().equals("Options")) {
+											// 所有选项节点
+											NodeList optionInfoList = optionsInfoNode.getChildNodes();
+											for (int r = 0; r < optionInfoList.getLength(); r++) {
+												Node optionInfoNode = optionInfoList.item(r);
+												if (optionInfoNode.getNodeName().equals("Option")) {
+													// 选项序号,内容
+													options.put(optionInfoNode.getAttributes().getNamedItem("Index")
+															.getTextContent(), optionInfoNode.getTextContent());
+													if (optionInfoNode.getAttributes().getNamedItem("Selected")
+															.getTextContent().equals("True")) {
+														if (StringUtils.isBlank(answer)) {
+															answer = optionInfoNode.getAttributes()
+																	.getNamedItem("Index").getTextContent();
+														} else {
+															answer = answer + "," + optionInfoNode.getAttributes()
+																	.getNamedItem("Index").getTextContent();
+														}
+													}
+												}
+											}
+											// 小题选项
+											unitInfo.setOptions(options);
+											unitInfo.setAnswer(answer);
+										}
+									}
+								}
+								// 完形填空,单选类的阅读理解
+								if (unitInfoNode.getNodeName().equals("ChoiceItems")) {
+									unitInfo.setType(QuesStructType.NESTED_ANSWER_QUESTION);
+									Map<Object, Object> subQues = new HashedMap<Object, Object>();
+									Map<Object, Object> subOptions = new HashedMap<Object, Object>();
+									NodeList choiceItemsList = unitInfoNode.getChildNodes();
+									int number = 1;
+									for (int h = 0; h < choiceItemsList.getLength(); h++) {
+										Node subUnitInfoNode = choiceItemsList.item(h);
+										String answer = "";
+										if (subUnitInfoNode.getNodeName().equals("ChoiceItem")) {
+											// 每一个子题选项
+											QuestionsTemp subUnit = new QuestionsTemp();
+											NodeList subOptionsInfoList = subUnitInfoNode.getChildNodes();
+											for (int hu = 0; hu < subOptionsInfoList.getLength(); hu++) {
+												Node subOptionsInfoNode = subOptionsInfoList.item(hu);
+												if (subOptionsInfoNode.getNodeName().equals("Options")) {
+													// 所有选项节点
+													NodeList subOptionInfoList = subOptionsInfoNode.getChildNodes();
+													for (int hr = 0; hr < subOptionInfoList.getLength(); hr++) {
+														Node subOptionInfoNode = subOptionInfoList.item(hr);
+														if (subOptionInfoNode.getNodeName().equals("Option")) {
+															// 子题选项序号,内容
+															subOptions.put(
+																	subOptionInfoNode.getAttributes()
+																			.getNamedItem("Index").getTextContent(),
+																	subOptionInfoNode.getTextContent());
+															if (subOptionInfoNode.getAttributes()
+																	.getNamedItem("Selected").getTextContent()
+																	.equals("True")) {
+																if (StringUtils.isBlank(answer)) {
+																	answer = subOptionInfoNode.getAttributes()
+																			.getNamedItem("Index").getTextContent();
+																} else {
+																	answer = answer + ","
+																			+ subOptionInfoNode.getAttributes()
+																					.getNamedItem("Index")
+																					.getTextContent();
+																}
+															}
+														}
+													}
+													// 子题选项
+													subUnit.setOptions(subOptions);
+													// 子题答案
+													subUnit.setAnswer(answer);
+													if (answer.contains(",")) {
+														subUnit.setType(QuesStructType.MULTIPLE_ANSWER_QUESTION);
+													} else {
+														subUnit.setType(QuesStructType.SINGLE_ANSWER_QUESTION);
+													}
+												}
+												if (subOptionsInfoNode.getNodeName().equals("Content")) {
+													subUnit.setBody(subOptionsInfoNode.getTextContent());
+												}
+												if (subOptionsInfoNode.getNodeName().equals("Answer")) {
+													subUnit.setType(QuesStructType.TEXT_ANSWER_QUESTION);
+													subUnit.setAnswer(subOptionsInfoNode.getTextContent());
+												}
+											}
+											if (StringUtils.isBlank(subUnit.getBody())) {
+												subUnit.setBody("__________");
+											}
+											subUnit.setNumber(String.valueOf(number));
+											subQues.put(subUnit.getNumber(), subUnit);
+											number++;
+										}
+									}
+									unitInfo.setSubQues(subQues);
+								}
+								// 普通答案
+								if (unitInfoNode.getNodeName().equals("Answer")) {
+									// 判断题
+									if (type.equals("TrueOrFalse")) {
+										unitInfo.setType(QuesStructType.BOOL_ANSWER_QUESTION);
+										String answerString = unitInfoNode.getTextContent();
+										if (answerString.contains("False")) {
+											unitInfo.setAnswer("错误");
+										} else {
+											unitInfo.setAnswer("正确");
+										}
+									}
+									// 主观题
+									if (type.equals("EssayQuestion")) {
+										unitInfo.setType(QuesStructType.TEXT_ANSWER_QUESTION);
+										unitInfo.setAnswer(unitInfoNode.getTextContent());
+									}
+								}
+							}
+							// 添加小题到大题
+							detailInfoMap.put(unitInfo.getNumber(), unitInfo);
+						}
+					}
+					detailInfo.setQues(detailInfoMap);
+					// 添加大题到试卷
+					paperInfoMap.put(detailInfo.getNumber(), detailInfo);
+				}
+			}
+		}
+		return paperInfoMap;
+	}
+
+	// 初始化小题集合
+	private List<PaperDetailUnit> initpaperDetailUnits(Paper paper, List<PaperDetail> paperDetails,
+			List<Question> questionLists, Map<Object, Object> paperInfoMap, Course course, User user)
+			throws Exception {
+		List<PaperDetailUnit> paperDetailUnits = new ArrayList<PaperDetailUnit>();
+		int detailCount = paperDetails.size();
+		int nm = 0;
+		for (int i = 0; i < detailCount; i++) {
+			PaperDetail detail = paperDetails.get(i);
+			QuestionsTemp detailTemp = (QuestionsTemp) paperInfoMap.get(String.valueOf(i + 1));
+			Map<Object, Object> detailInfoMap = detailTemp.getQues();
+			int quesCount = detailInfoMap.size();
+			for (int j = 0; j < quesCount; j++) {
+//				WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
+				QuestionsTemp quesTemp = (QuestionsTemp) detailInfoMap.get(String.valueOf(j + 1));
+				Question question = new Question();
+				question.setCreateTime(CommonUtils.getCurDateTime());
+				question.setScore(Double.valueOf(quesTemp.getScore()));
+				question.setCourse(course);
+				question.setOrgId(course.getOrgId());
+				question.setHasAudio(false);
+				question.setDifficulty("中");
+				question.setDifficultyDegree(0.5);
+				question.setPublicity(true);
+				question.setQuestionType(quesTemp.getType());
+
+				String body = imgList(quesTemp.getBody());
+				question.setQuesBody(replaceBlank(body));
+				try {
+//					question.setQuesBodyWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(question.getQuesBody())));
+				} catch (Exception e) {
+					log.error("错误题干信息:" + question.getQuesBody());
+					throw new IllegalArgumentException("题干信息错误!"+e.getMessage());
+				}
+				if (question.getQuestionType() == QuesStructType.BOOL_ANSWER_QUESTION) {
+					question.setQuesAnswer(quesTemp.getAnswer());
+//					question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml("<p>" + question.getQuesAnswer() + "</p>")));
+				} else {
+					question.setQuesAnswer(imgList(quesTemp.getAnswer()));
+					try {
+//						question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml(question.getQuesAnswer())));
+					} catch (Exception e) {
+						log.error("错误答案信息:" + question.getQuesAnswer());
+						throw new IllegalArgumentException("答案信息错误!"+e.getMessage());
+					}
+				}
+				// 存在选项
+				if (question.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
+						|| question.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
+					List<QuesOption> quesOptions = new ArrayList<QuesOption>();
+					Map<Object, Object> optionMap = quesTemp.getOptions();
+					int optionCount = optionMap.size();
+					for (int k = 0; k < optionCount; k++) {
+						QuesOption quesOption = new QuesOption();
+						quesOption.setNumber(String.valueOf(k + 1));
+
+						String optionBody = imgList((String) optionMap.get(String.valueOf(k + 1)));
+						if (optionBody.startsWith("<p><p") || optionBody.startsWith("<P><P")) {
+							quesOption.setOptionBody(replaceFirstP(optionBody));
+						} else {
+							quesOption.setOptionBody(optionBody);
+						}
+
+						try {
+//							quesOption.setOptionBodyWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml(quesOption.getOptionBody())));
+						} catch (Exception e) {
+							log.error("错误的选项:" + quesOption.getOptionBody());
+							throw new IllegalArgumentException("选项信息错误!"+e.getMessage());
+						}
+						if (question.getQuesAnswer().contains(String.valueOf(k + 1))) {
+							quesOption.setIsCorrect((short) 1);
+						} else {
+							quesOption.setIsCorrect((short) 0);
+						}
+						quesOptions.add(quesOption);
+					}
+					question.setQuesOptions(quesOptions);
+					String[] answers = question.getQuesAnswer().replaceAll("<p>", "").replaceAll("</p>", "")
+							.replaceAll("<P>", "").replaceAll("</P>", "").split(",");
+					String answer = "";
+					for (int a = 0; a < answers.length; a++) {
+						char c1 = (char) (Integer.valueOf(answers[a]) + 64);
+						if (a == 0) {
+							answer = String.valueOf(c1);
+						} else {
+							answer = answer + "," + c1;
+						}
+					}
+					question.setQuesAnswer("<p>" + answer + "</p>");
+//					question.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage, CommonUtils.formatHtml(question.getQuesAnswer())));
+				}
+				// 存在子题
+				if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
+					List<Question> subQuestions = new ArrayList<>();
+					int subQuesCount = quesTemp.getSubQues().size();
+					BigDecimal totalScore = BigDecimal.valueOf(question.getScore());
+					BigDecimal sum = BigDecimal.valueOf(subQuesCount);
+					double score = totalScore.divide(sum).doubleValue();
+					for (int s = 0; s < subQuesCount; s++) {
+						QuestionsTemp subQuesTmp = (QuestionsTemp) quesTemp.getSubQues().get(String.valueOf(s + 1));
+						Question subQuestion = new Question();
+						subQuestion.setId(IdUtils.uuid());
+						subQuestion.setQuestionType(subQuesTmp.getType());
+						subQuestion.setDifficulty("中");
+						subQuestion.setDifficultyDegree(0.5);
+						subQuestion.setPublicity(true);
+						subQuestion.setScore(score);
+
+						String subBody = imgList(subQuesTmp.getBody());
+						question.setQuesBody(replaceBlank(body));
+						subQuestion.setQuesBody(subBody);
+
+//						subQuestion.setQuesBodyWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml(subQuestion.getQuesBody())));
+						subQuestion.setQuesAnswer(imgList(subQuesTmp.getAnswer()));
+//						subQuestion.setQuesBodyWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml(subQuestion.getQuesAnswer())));
+						// 存在选项
+						if (subQuestion.getQuestionType() == QuesStructType.SINGLE_ANSWER_QUESTION
+								|| subQuestion.getQuestionType() == QuesStructType.MULTIPLE_ANSWER_QUESTION) {
+							List<QuesOption> subQuesOptions = new ArrayList<QuesOption>();
+							Map<Object, Object> subOptionMap = subQuesTmp.getOptions();
+							int subOptionCount = subOptionMap.size();
+							for (int k = 0; k < subOptionCount; k++) {
+								QuesOption subQuesOption = new QuesOption();
+								subQuesOption.setNumber(String.valueOf(k));
+
+								String optionBody = imgList((String) subOptionMap.get(String.valueOf(k + 1)));
+								if (optionBody.startsWith("<p><p") || optionBody.startsWith("<P><P")) {
+									subQuesOption.setOptionBody(replaceFirstP(optionBody));
+								} else {
+									subQuesOption.setOptionBody(optionBody);
+								}
+
+//								subQuesOption.setOptionBodyWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml(subQuesOption.getOptionBody())));
+								if (subQuestion.getQuesAnswer().contains(String.valueOf(k + 1))) {
+									subQuesOption.setIsCorrect((short) 1);
+								} else {
+									subQuesOption.setIsCorrect((short) 0);
+								}
+								subQuesOptions.add(subQuesOption);
+							}
+							subQuestion.setQuesOptions(subQuesOptions);
+							String[] answers = subQuestion.getQuesAnswer().replaceAll("<p>", "").replaceAll("</p>", "")
+									.replaceAll("<P>", "").replaceAll("</P>", "").split(",");
+							String answer = "";
+							for (int a = 0; a < answers.length; a++) {
+								char c1 = (char) (Integer.valueOf(answers[a]) + 64);
+								if (a == 0) {
+									answer = String.valueOf(c1);
+								} else {
+									answer = answer + "," + c1;
+								}
+							}
+							subQuestion.setQuesAnswer(answer);
+//							subQuestion.setQuesAnswerWord(DocxProcessUtil.html2Docx(wordMLPackage,CommonUtils.formatHtml("<p>" + subQuestion.getQuesAnswer() + "</p>")));
+						}
+						subQuestions.add(subQuestion);
+					}
+					question.setSubQuestions(subQuestions);
+				}
+//				byte[] pkgByte = DocxProcessUtil.getPkgByte(wordMLPackage);
+//				QuestionPkgPath quesPkgPath = new QuestionPkgPath(pkgByte);
+				questionLists.add(question);
+				// 包装小题
+				PaperDetailUnit paperDetailUnit = new PaperDetailUnit();
+				paperDetailUnit.setPaper(paper);
+				paperDetailUnit.setNumber(nm + 1);
+				paperDetailUnit.setScore(question.getScore());
+				paperDetailUnit.setPaperDetail(detail);
+				paperDetailUnit.setQuestionType(question.getQuestionType());
+				paperDetailUnit.setCreator(user.getDisplayName());
+				paperDetailUnit.setCreateTime(CommonUtils.getCurDateTime());
+				paperDetailUnit.setQuestion(question);
+				paperDetailUnits.add(paperDetailUnit);
+				paperDetailUnit.setPaperType(PaperType.IMPORT);
+				nm++;
+			}
+		}
+		return paperDetailUnits;
+	}
+
+	public String imgList(String str) throws Exception {
+		if (StringUtils.isBlank(str)) {
+			str = "<p></p>";
+		}
+		str = str.trim().replace("<br>", "").replace("</br>", "");
+		if (!str.contains("<p>") && !str.contains("</P>")) {
+			str = "<p>" + str + "</p>";
+		}
+		// 先处理span标签
+		List<String> spans = parseSpans(str);
+		if (spans != null && spans.size() > 0) {
+			for (String span : spans) {
+				str = str.replace(span, "").replace("</span>", "").replace("</SPAN>", "");
+			}
+		}
+		str = str.replace("<o:p>", "").replace("</o:p>", "").replace("border=0", "").replace("class=MsoNormal", "")
+				.replace("&phiv;", "").replace("</SPAN>", "");
+		// 获取img标签
+		List<String> srcList = ImgDataUtils.parseImages(str);
+		if (srcList != null && srcList.size() > 0) {
+			for (String img : srcList) {
+				// 获取height,width值
+				List<String> height = getTagAHei(img);
+				List<String> width = getTagAWid(img);
+				List<String> parseImageSrc = ImgDataUtils.parseImageSrc(img);
+				if (parseImageSrc != null && parseImageSrc.size() > 0) {
+					String src = parseImageSrc.get(0).replace("{ResourcePath}", "http://file.5any.com/UniversityV4.0");
+					String url = regexCH(src);
+					log.info("img url:" + url);
+					url = url.replaceAll("\\\\", "/");
+
+					String base64 = ImgDataUtils.loadImageToBase64(url);
+					if (base64 == null) {
+						throw new Exception("图片下载失败!" + url);
+					} else {
+						if (src.contains("jpg")) {
+							str = str.replace(parseImageSrc.get(0), "data:image/jpg;base64," + base64);
+						} else {
+							str = str.replace(parseImageSrc.get(0), "data:image/png;base64," + base64);
+						}
+						if (height != null && height.size() > 0) {
+							str = str.replace("height=" + height.get(0), "height=\"" + height.get(0) + "\"");
+						}
+						if (width != null && width.size() > 0) {
+							str = str.replace("width=" + width.get(0), "width=\"" + width.get(0) + "\"");
+						}
+					}
+				}
+			}
+		}
+		return str.replace("<IMG", "<img");
+	}
+
+	// 將url路徑中的中文转码
+	public String regexCH(String str) throws UnsupportedEncodingException {
+		StringBuffer s = new StringBuffer();
+		Pattern pat = Pattern.compile("[\u4E00-\u9FA5]");
+		Matcher mat = pat.matcher(str);
+		while (mat.find()) {
+			s.append(mat.group());
+		}
+		String url = java.net.URLEncoder.encode(s.toString(), "utf-8");
+		return str.replace(s.toString(), url);
+	}
+
+//	public List<String> loadFiles() {
+	// 获取某文件夹下所有XML文件的路径
+//		List<String> paths = new ArrayList<>();
+//		File dir = new File(rootDir);
+//		this.loadMoreFiles(dir, paths);
+//		return paths;
+//	}
+
+	private void loadMoreFiles(File file, List<String> paths) {
+		if (file.isDirectory()) {
+			File[] subFiles = file.listFiles();
+			for (File subFile : subFiles) {
+				this.loadMoreFiles(subFile, paths);
+			}
+		} else {
+			String path = file.getPath().replaceAll("\\\\", "/");
+
+			if (file.getName().endsWith(".xml")) {
+				paths.add(path);
+			} else {
+				log.error("无效文件:" + path);
+			}
+		}
+	}
+
+	public static List<String> parseSpans(String content) {
+		if (content == null) {
+			return new ArrayList<>();
+		}
+		List<String> spans = new ArrayList<>();
+		String reg = "<(span|SPAN)(.*?)(/>|>)";
+		Pattern pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
+		Matcher matcher = pattern.matcher(content);
+		while (matcher.find()) {
+			String span = matcher.group();
+			spans.add(span);
+		}
+		return spans;
+	}
+
+	public List<String> getTagAHei(String htmlString) {
+		List<String> list = new ArrayList<String>();
+		Pattern p = Pattern.compile("<IMG[^<>]*\\s+height=([0-9A-Za-z-_.]+)\\s*");
+		Matcher m = p.matcher(htmlString);
+		while (m.find()) {
+			String str = m.group(1);
+			list.add(str);
+		}
+		return list;
+	}
+
+	public List<String> getTagAWid(String htmlString) {
+		List<String> list = new ArrayList<String>();
+		Pattern p = Pattern.compile("<IMG[^<>]*\\s+width=([0-9A-Za-z-_.]+)\\s*");
+		Matcher m = p.matcher(htmlString);
+		while (m.find()) {
+			String str = m.group(1);
+			list.add(str);
+		}
+		return list;
+	}
+
+	/**
+	 * 将[BLANK] 替换为 ###
+	 */
+	public static String replaceBlank(String str) {
+		if (str == null) {
+			return null;
+		}
+		str=str.replaceAll("<div>", "<p>");
+		str=str.replaceAll("</div>", "</p>");
+		return str.replaceAll("[BLANK]", "###");
+	}
+
+	/**
+	 * 替换首个P标签
+	 */
+	public static String replaceFirstP(String str) {
+		if (str == null) {
+			return null;
+		}
+		if (str.startsWith("<p>") && str.endsWith("</p>")) {
+			// 去掉头<p >
+			str = str.replaceFirst("<p>", "");
+			// 去掉尾</p>
+			int index = str.lastIndexOf("</p>");
+			if (index > 0) {
+				str = str.substring(0, index);
+			}
+		}
+		return str;
+	}
 
 }

+ 142 - 53
examcloud-core-questions-service/src/main/java/cn/com/qmth/examcloud/core/questions/service/util/ExportPaperUtil.java

@@ -1,7 +1,10 @@
 package cn.com.qmth.examcloud.core.questions.service.util;
 
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -10,6 +13,8 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.imageio.ImageIO;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -31,7 +36,6 @@ import cn.com.qmth.examcloud.core.questions.base.json.JOptionDto;
 import cn.com.qmth.examcloud.core.questions.base.json.JSection;
 import cn.com.qmth.examcloud.core.questions.base.json.JsonImportUtil;
 import cn.com.qmth.examcloud.core.questions.base.json.SectionElement;
-import cn.com.qmth.examcloud.core.questions.base.json.SectionElementParams;
 import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
 import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
 import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailExp;
@@ -60,6 +64,8 @@ public class ExportPaperUtil {
     public static final String ELEMENT_TYPE_TEXT = "text";
 
     public static final String ELEMENT_TYPE_IMG = "image";
+    
+    public static final String ELEMENT_TYPE_DOCTAG = "doctag";
 
     private static final String ENCODING = "UTF-8";
 
@@ -362,9 +368,10 @@ public class ExportPaperUtil {
                 if ("img".equals(ce.nodeName())) {
                     se.setType(ELEMENT_TYPE_IMG);
                     se.setValue(ce.attr("src"));
-                    SectionElementParams sep = se.getParam();
-                    sep.setHeight(getHeight(ce));
-                    sep.setWidth(getWidth(ce));
+                    setImageSize(se, ce);
+                } else if ("br".equals(ce.nodeName())) {
+                    se.setType(ELEMENT_TYPE_DOCTAG);
+                    se.setValue("<w:r w:rsidRPr=\"003A4B1C\"><w:br/></w:r>");
                 } else {
                     Element el = (Element) ce;
                     se.setType(ELEMENT_TYPE_TEXT);
@@ -376,46 +383,69 @@ public class ExportPaperUtil {
     }
 
     private static int getWidth(Node ce) {
-        int n = 50;
+        int n = 0;
         String str = ce.attr("width");
-        if (StringUtils.isNoneBlank(str)) {
-            return getWordImgSize(str);
+        if (StringUtils.isNotBlank(str)) {
+        	String sizeStr = str.replace("px", "");
+        	if (StringUtils.isNotBlank(sizeStr)) {
+        		try {
+	        		return Integer.valueOf(sizeStr.trim()) * docImageSzie;
+	        	} catch (NumberFormatException e) {
+					log.warn("image width value is invalid");
+					return 0;
+				}
+        	}
         }
         String style = ce.attr("style");
-        if (StringUtils.isNoneBlank(style)) {
+        if (StringUtils.isNotBlank(style)) {
             Matcher m = widthRex.matcher(style);
             if (m.find()) {
-                return Integer.valueOf(m.group(1)) * docImageSzie;
+            	String size=m.group(1).trim();
+            	if(StringUtils.isNotBlank(size)) {
+            		try {
+	            		return Integer.valueOf(size) * docImageSzie;
+	            	} catch (NumberFormatException e) {
+						log.warn("image style width value is invalid");
+						return 0;
+					}
+            	}
             }
         }
         return n;
     }
 
     private static int getHeight(Node ce) {
-        int n = 50;
+        int n = 0;
         String str = ce.attr("height");
-        if (StringUtils.isNoneBlank(str)) {
-            return getWordImgSize(str);
+        if (StringUtils.isNotBlank(str)) {
+        	String sizeStr = str.replace("px", "");
+        	if (StringUtils.isNotBlank(sizeStr)) {
+        		try {
+					return Integer.valueOf(sizeStr.trim()) * docImageSzie;
+				} catch (NumberFormatException e) {
+					log.error("image height value is invalid");
+					return 0;
+				}
+        	}
         }
         String style = ce.attr("style");
-        if (StringUtils.isNoneBlank(style)) {
+        if (StringUtils.isNotBlank(style)) {
             Matcher m = heightRex.matcher(style);
             if (m.find()) {
-                return Integer.valueOf(m.group(1)) * docImageSzie;
+            	String size=m.group(1).trim();
+            	if(StringUtils.isNotBlank(size)) {
+            		try {
+	            		return Integer.valueOf(size) * docImageSzie;
+	            	} catch (NumberFormatException e) {
+						log.error("image style height value is invalid");
+						return 0;
+					}
+            	}
             }
         }
         return n;
     }
 
-    private static Integer getWordImgSize(String px) {
-        if (StringUtils.isBlank(px)) {
-            return null;
-        }
-        String sizeStr = px.replace("px", "");
-        Integer size = Integer.valueOf(sizeStr) * docImageSzie;
-        return size;
-    }
-
     private static void dispose(File docxTargetDir, PaperExp paperExp) throws IOException {
         ExportTempDataDto dto = new ExportTempDataDto();
         if (paperExp.getPaperDetails() != null && paperExp.getPaperDetails().size() > 0) {
@@ -496,20 +526,27 @@ public class ExportPaperUtil {
 
     private static void disposeQuestion(Question qes, ExportTempDataDto dto) {
         if (qes != null) {
+            //处理题干
             List<JSection> slist1 = getSections(qes.getQuesBody(),false);
-            if (slist1 != null && slist1.size() > 0) {
-                if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题题干不加题号
-                    dto.setSubNum(dto.getSubNum() + 1);
-                    SectionElement se = new SectionElement();
-                    se.setType(ELEMENT_TYPE_TEXT);
-                    se.setValue(dto.getSubNum() + ".");
-                    slist1.get(0).getElements().add(0, se);
-                }
-
-                htmlToDoc(slist1, dto);
-                qes.setQuesBodyWord(getQuestionDoc(slist1));
+            if (slist1 == null||slist1.size()==0) {
+                slist1=new ArrayList<JSection>();
+                JSection sec=new JSection();
+                List<SectionElement> ses=new ArrayList<SectionElement>();
+                sec.setElements(ses);
+                slist1.add(sec);
             }
+            if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题题干不加题号
+                dto.setSubNum(dto.getSubNum() + 1);
+                SectionElement se = new SectionElement();
+                se.setType(ELEMENT_TYPE_TEXT);
+                se.setValue(dto.getSubNum() + ".");
+                slist1.get(0).getElements().add(0, se);
+            }
+
+            htmlToDoc(slist1, dto);
+            qes.setQuesBodyWord(getQuestionDoc(slist1));
 
+            //处理选项
             if (qes.getQuesOptions() != null && qes.getQuesOptions().size() > 0) {
                 int index = 0;
                 for (QuesOption qo : qes.getQuesOptions()) {
@@ -526,13 +563,15 @@ public class ExportPaperUtil {
 
                 }
             }
+            
+            //处理答案
             List<JSection> slist3 = getSections(qes.getQuesAnswer());
             if (slist3 == null||slist3.size()==0) {
-            	slist3=new ArrayList<JSection>();
-            	JSection sec=new JSection();
-            	List<SectionElement> ses=new ArrayList<SectionElement>();
-            	sec.setElements(ses);
-            	slist3.add(sec);
+                slist3=new ArrayList<JSection>();
+                JSection sec=new JSection();
+                List<SectionElement> ses=new ArrayList<SectionElement>();
+                sec.setElements(ses);
+                slist3.add(sec);
             }
             SectionElement se = new SectionElement();
             se.setType(ELEMENT_TYPE_TEXT);
@@ -568,19 +607,26 @@ public class ExportPaperUtil {
             if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题题干不加题号
                 dto.setSubNum(dto.getSubNum() + 1);
             }
+            //处理题干
             List<JSection> slist1 = getSections(qes.getQuesBody(),true);
-            if (slist1 != null && slist1.size() > 0) {
-                if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题题干不加题号
-                    SectionElement se = new SectionElement();
-                    se.setType(ELEMENT_TYPE_TEXT);
-                    se.setValue(dto.getSubNum() + ".");
-                    slist1.get(0).getElements().add(0, se);
-                }
-
-                htmlToDoc(slist1, dto);
-                qes.setQuesBodyWord(getQuestionDoc(slist1));
+            if (slist1 == null||slist1.size()==0) {
+                slist1=new ArrayList<JSection>();
+                JSection sec=new JSection();
+                List<SectionElement> ses=new ArrayList<SectionElement>();
+                sec.setElements(ses);
+                slist1.add(sec);
+            }
+            if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题题干不加题号
+                SectionElement se = new SectionElement();
+                se.setType(ELEMENT_TYPE_TEXT);
+                se.setValue(dto.getSubNum() + ".");
+                slist1.get(0).getElements().add(0, se);
             }
 
+            htmlToDoc(slist1, dto);
+            qes.setQuesBodyWord(getQuestionDoc(slist1));
+
+            //处理选项
             if (qes.getQuesOptions() != null && qes.getQuesOptions().size() > 0) {
                 int index = 0;
                 JOptionDto joDto = new JOptionDto();
@@ -603,11 +649,18 @@ public class ExportPaperUtil {
                 disposeQuesOptions(joDto);// 处理选项列数
                 qes.setQuesOptionsWord(getPaperQuestionDoc(joDto.getOptions()));
             }
-            if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题不加答案序号
+            
+            //处理答案
+            if (qes.getSubQuestions() == null || qes.getSubQuestions().size() == 0) {// 套题不加答案及序号
                 dto.setAnswerNum(dto.getAnswerNum() + 1);
-            }
-            List<JSection> slist3 = getSections(qes.getQuesAnswer());
-            if (slist3 != null && slist3.size() > 0) {
+                List<JSection> slist3 = getSections(qes.getQuesAnswer());
+                if (slist3 == null||slist3.size()==0) {
+                    slist3=new ArrayList<JSection>();
+                    JSection sec=new JSection();
+                    List<SectionElement> ses=new ArrayList<SectionElement>();
+                    sec.setElements(ses);
+                    slist3.add(sec);
+                }
                 SectionElement se = new SectionElement();
                 se.setType(ELEMENT_TYPE_TEXT);
                 se.setValue(dto.getAnswerNum() + ".");
@@ -616,6 +669,7 @@ public class ExportPaperUtil {
                 htmlToDoc(slist3, dto);
                 qes.setQuesAnswerWord(getQuestionDoc(slist3));
             }
+            
 
             if (qes.getSubQuestions() != null && qes.getSubQuestions().size() > 0) {
                 dto.setSubNum(0);
@@ -741,5 +795,40 @@ public class ExportPaperUtil {
             throw new ExamCloudRuntimeException(e);
         }
     }
+    
+    
+    private static void setImageSize(SectionElement imageEle,Node ce) {
+    	int width=getWidth(ce);
+    	int height=getHeight(ce);
+    	if(width<100||height<100) {
+    		String base64=imageEle.getValue();
+    		if (base64.contains("data:image")) {
+                base64 = base64.substring(base64.indexOf(",") + 1);
+            }
+            BASE64Decoder decoder = new BASE64Decoder();
+    		
+    		InputStream is = null;
+            try {
+            	byte[] bytes = decoder.decodeBuffer(base64);
+                is = new ByteArrayInputStream(bytes);
+                BufferedImage image = ImageIO.read(is);
+                width=image.getWidth()* docImageSzie;
+                height=image.getHeight()* docImageSzie;
+            }catch (IOException e) {
+            	log.error(e.getMessage(), e);
+            } finally {
+                if (is != null) {
+                    try {
+						is.close();
+					} catch (IOException e) {
+						log.error(e.getMessage(), e);
+					}
+                }
+            }
+    	}
+    	imageEle.getParam().setHeight(height);
+    	imageEle.getParam().setWidth(width);
+		
+	}
 
 }

+ 1 - 1
examcloud-core-questions-starter/pom.xml

@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>cn.com.qmth.examcloud.core.questions</groupId>
 		<artifactId>examcloud-core-questions</artifactId>
-		<version>2019-SNAPSHOT</version>
+		<version>v3.0-RELEASE</version>
 	</parent>
 	<artifactId>examcloud-core-questions-starter</artifactId>
 	<packaging>jar</packaging>

+ 3 - 2
examcloud-core-questions-starter/shell/start.sh

@@ -1,8 +1,9 @@
 #!/bin/bash
 
 FILE_PATH=$(cd `dirname $0`; pwd)
-APP_VERSION=`cat $FILE_PATH/version`
-APP_MAIN_JAR="examcloud-core-questions-starter-"$APP_VERSION"-SNAPSHOT.jar"
+
+APP_MAIN_JAR="examcloud-core-questions-starter-v3.0-RELEASE.jar"
+
 JAVA_OPTS=`cat $FILE_PATH/start.vmoptions`
 APP_ARGS=`cat $FILE_PATH/start.args`
 

+ 2 - 2
examcloud-core-questions-starter/shell/stop.sh

@@ -1,8 +1,8 @@
 #!/bin/bash
 
 FILE_PATH=$(cd `dirname $0`; pwd)
-APP_VERSION=`cat $FILE_PATH/version`
-APP_MAIN_JAR="examcloud-core-questions-starter-"$APP_VERSION"-SNAPSHOT.jar"
+
+APP_MAIN_JAR="examcloud-core-questions-starter-v3.0-RELEASE.jar"
 
 PID_LIST=`ps -ef|grep $APP_MAIN_JAR|grep java|awk '{print $2}'`
 

+ 0 - 1
examcloud-core-questions-starter/shell/version

@@ -1 +0,0 @@
-2019

+ 1 - 1
examcloud-core-questions-starter/src/main/resources/security.properties

@@ -1,2 +1,2 @@
-[s][${api_cqb}/][/paper/export/{id}/{exportContentList}/{orgName}/{loginName}/{examType}][GET]=true
+[s][${api_cqb}/][/paper/export/{id}/{exportContentList}/{orgId}/{loginName}/{examType}][GET]=true
 [s][${api_cqb}/default_question][/question][POST]=true

+ 2 - 2
pom.xml

@@ -4,11 +4,11 @@
 	<parent>
 		<groupId>cn.com.qmth.examcloud</groupId>
 		<artifactId>examcloud-parent</artifactId>
-		<version>2019</version>
+		<version>v3.0-RELEASE</version>
 	</parent>
 	<groupId>cn.com.qmth.examcloud.core.questions</groupId>
 	<artifactId>examcloud-core-questions</artifactId>
-	<version>2019-SNAPSHOT</version>
+	<version>v3.0-RELEASE</version>
 	<packaging>pom</packaging>
 
 	<modules>