xiatian 6 ماه پیش
والد
کامیت
c516d17e27

+ 11 - 5
file/流程.txt

@@ -1,5 +1,5 @@
 #必要步骤
-
+(修改本地化:dbName和账号、试卷前缀)
 1、将云开数据库 导入 本地
 
 2、建要处理的科目临时表
@@ -35,24 +35,30 @@ and (q.topic like '%$$%' or q.answer like '%$$%' or an.answer_text like '%$$%');
 
     查询 存在公式关键字的字段,并将结果集导出至Excel,使用公式处理工具“formula-analysis 1.0.1.exe”
     将Excel的内容执行处理后,复制至临时表“temp_gs”,然后执行update语句。
+    查询
     select id,topic from wq_question where topic like '%$$%';
+    修改
     update wq_question INNER JOIN temp_gs on wq_question.id=temp_gs.id
     set wq_question.topic= CONCAT_WS('',temp_gs.content1,temp_gs.content2,temp_gs.content3,temp_gs.content4);
     执行完update后,清空“temp_gs”。
 
     同上
+    查询
     select id,answer from wq_question where answer like '%$$%';
+    修改
     update wq_question INNER JOIN temp_gs on wq_question.id=temp_gs.id
     set wq_question.answer= CONCAT_WS('',temp_gs.content1,temp_gs.content2,temp_gs.content3,temp_gs.content4);
 
     同上
+    查询
     select id,answer_text from wq_question_answer_item where answer_text like '%$$%';
+     修改
     update wq_question_answer_item INNER JOIN temp_gs on wq_question_answer_item.id=temp_gs.id
     set wq_question_answer_item.answer_text= CONCAT_WS('',temp_gs.content1,temp_gs.content2,temp_gs.content3,temp_gs.content4);
 }
 
 4、云开数据库中 本地化的表“wq_knowledge_system”需要新加的字段root_id,
-再在yunkai-export代码“SetRootId.java”中更新属性树(修改本地化:dbName和账号)
+再在yunkai-export代码“FillRootId.java”中更新属性树
 
 
 5、检查是否存在 非标准格式的 套题,若存在,直接当作 单独的题 处理,执行以下分析脚本。
@@ -62,14 +68,14 @@ from wq_question t left join wq_question_question_bank f on t.question_id=f.ques
 where t.question_id!=-1 and t.rent_id=811 
 and f.question_bank_id is not null;
 
-6、执行yunkai-export代码“ExportProperty.java”(修改本地化:dbName和账号、学校存放的文件目录)
+6、执行yunkai-export代码“ExportProperty.java”
 学校存放的文件目录 提前置入 相关Excel文件 ,然后才可执行!!!
 
 
-7、执行yunkai-export代码“ExportPaperByCourseCode.java”(修改本地化:dbName和账号、试卷前缀)
+7、执行yunkai-export代码“ExportPaperByCourseCode.java”
 MyConsumer.java内的paperDir需要修改正确 ,然后才可执行!!!
 
-8、执行yunkai-import代码“ExportPaperByCourseCode.java”(修改本地化:dbName和账号、试卷前缀)
+8、执行yunkai-import代码“ExportPaperByCourseCode.java”
 {
 a、云平台管理端导入课程
 b、导入课程属性,执行ImportPropByCourse(修改sourceDir、host、rootOrgId、key、token)

+ 5 - 0
pom.xml

@@ -12,6 +12,11 @@
         <maven.compiler.target>1.8</maven.compiler.target>
 	</properties>
 	<dependencies>
+		<dependency>
+			<groupId>org.scilab.forge</groupId>
+			<artifactId>jlatexmath</artifactId>
+			<version>1.0.7</version>
+		</dependency>
 		<dependency>
 			<groupId>net.coobird</groupId>
 			<artifactId>thumbnailator</artifactId>

+ 33 - 21
src/main/java/cn/com/qmth/ex/ExportPaperByCourseCode.java

@@ -1,8 +1,10 @@
 package cn.com.qmth.ex;
 
 import java.util.Date;
+import java.util.Vector;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
 
@@ -10,25 +12,35 @@ import cn.com.qmth.ex.bean.MyConsumer;
 import cn.com.qmth.ex.bean.MyProducer;
 
 public class ExportPaperByCourseCode {
-	private static Logger logger = LogManager.getLogger(ExportPaperByCourseCode.class);
-	private static AtomicInteger count=new AtomicInteger(0);
-	
-	public static void main(String[] args) {
-		logger.debug("导出开始");
-		Date start=new Date();
-		try {
-			MyProducer pro=new MyProducer();
-			pro.startDispose(MyConsumer.class, 8, null);
-		} catch (Exception e) {
-			logger.error(e.getCause(), e);
-		}
-		Date end=new Date();
-		logger.debug("导出结束,耗时:"+((end.getTime()-start.getTime())/1000));
-	}
-
-
-	public static void  addDisposeCount() {
-		count.addAndGet(1);
-		logger.debug("处理了"+count);
-	}
+
+    private static Logger logger = LogManager.getLogger(ExportPaperByCourseCode.class);
+
+    private static AtomicInteger count = new AtomicInteger(0);
+
+    private static Vector<String> noQuestion = new Vector<>();
+
+    public static void main(String[] args) {
+        logger.debug("导出开始");
+        Date start = new Date();
+        try {
+            MyProducer pro = new MyProducer();
+            pro.startDispose(MyConsumer.class, 8, null);
+        } catch (Exception e) {
+            logger.error(e.getCause(), e);
+        }
+        Date end = new Date();
+        if (noQuestion.size() > 0) {
+            logger.debug("无试题:" + StringUtils.join(noQuestion, ","));
+        }
+        logger.debug("导出结束,耗时:" + ((end.getTime() - start.getTime()) / 1000));
+    }
+
+    public static void addDisposeCount() {
+        count.addAndGet(1);
+        logger.debug("处理了" + count);
+    }
+
+    public static void addNoQues(String code) {
+        noQuestion.add(code);
+    }
 }

+ 204 - 180
src/main/java/cn/com/qmth/ex/bean/FileUtil.java

@@ -1,5 +1,7 @@
 package cn.com.qmth.ex.bean;
 
+import java.awt.Color;
+import java.awt.image.BufferedImage;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
@@ -31,91 +33,115 @@ import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
+import javax.imageio.ImageIO;
+
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
+import org.scilab.forge.jlatexmath.TeXConstants;
+import org.scilab.forge.jlatexmath.TeXFormula;
 
 import sun.misc.BASE64Decoder;
 
-/**
- * @author chenken
- * @date 2017年7月17日 上午9:36:32
- * @company QMTH
- */
 public class FileUtil {
-	public static void clearDirectory(String path) {
-		if (!path.endsWith(File.separator)) {
-			path = path + File.separator;
-		}
-		File dirFile = new File(path);
-		if (!dirFile.exists() || !dirFile.isDirectory()) {
-			return;
-		}
-		File[] files = dirFile.listFiles();
-		if (files != null) {
-			for (int i = 0; i < files.length; i++) {
-				if (files[i].isFile()) {
-					deleteFile(files[i].getAbsolutePath());
-				} else {
-					deleteDirectory(files[i].getAbsolutePath());
-				}
-			}
-		}
-	}
-	
-	public static void writeFile(String dir,String name,String content) throws IOException {
-		BufferedWriter out=null;
-		try {
-			File writename = new File(dir+name);
-			writename.createNewFile();
-			out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(writename), "UTF-8"));  
-			out.write(content);
-			out.flush();
-		} finally {
-			if(out!=null) {
-				out.close();
-			}
-		}
-	}
-	
-	public static void base64ToFile(File file,String base64Str){
-		if (base64Str.contains("data:image")) {//base64图片
-			base64Str = base64Str.substring(base64Str.indexOf(",") + 1);
+
+    protected String latexFormatToBase64(String latexFormat) {
+        String result;
+        String filePath = "temp/" + UUID.randomUUID() + ".png";
+        File file = new File(filePath);
+        try {
+            FileUtil.makeDirs(file.getParent());
+            file.createNewFile();
+
+            int style = TeXConstants.STYLE_DISPLAY; // 样式 符号以最大的尺寸呈现
+            float size = 24; // 生成公式图片的字体大小
+            Color fg = Color.BLACK; // 字体颜色,黑色
+            Color bg = null; // 图片背景色,默认为透明北京
+            BufferedImage image = (BufferedImage) TeXFormula.createBufferedImage(latexFormat, style, size, fg, bg);
+            ImageIO.write(image, "png", file);
+            result = FileUtil.fileToBase64(file);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            FileUtil.deleteFile(file.getAbsolutePath());
+        }
+        return result;
+    }
+
+    public static void clearDirectory(String path) {
+        if (!path.endsWith(File.separator)) {
+            path = path + File.separator;
+        }
+        File dirFile = new File(path);
+        if (!dirFile.exists() || !dirFile.isDirectory()) {
+            return;
+        }
+        File[] files = dirFile.listFiles();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isFile()) {
+                    deleteFile(files[i].getAbsolutePath());
+                } else {
+                    deleteDirectory(files[i].getAbsolutePath());
+                }
+            }
+        }
+    }
+
+    public static void writeFile(String dir, String name, String content) throws IOException {
+        BufferedWriter out = null;
+        try {
+            File writename = new File(dir + name);
+            writename.createNewFile();
+            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(writename), "UTF-8"));
+            out.write(content);
+            out.flush();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    public static void base64ToFile(File file, String base64Str) {
+        if (base64Str.contains("data:image")) {// base64图片
+            base64Str = base64Str.substring(base64Str.indexOf(",") + 1);
             BASE64Decoder decoder = new BASE64Decoder();
-			try {
-	            byte[] bytes = decoder.decodeBuffer(base64Str);
-				FileUtils.writeByteArrayToFile(file, bytes);
-			} catch (IOException e) {
-				throw new RuntimeException(e);
-			}
-        }else {
-        	throw new RuntimeException("not base64 string");
-        }
-	}
-	
-	public static String fileToBase64Src(File imgFile){
-		String fn=imgFile.getName();
-		String suff=fn.substring(fn.lastIndexOf(".")+1).toLowerCase();
-		return "data:image/"+suff+";base64,"+fileToBase64(imgFile);
-	}
-    public static String fileToBase64(File imgFile){
+            try {
+                byte[] bytes = decoder.decodeBuffer(base64Str);
+                FileUtils.writeByteArrayToFile(file, bytes);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            throw new RuntimeException("not base64 string");
+        }
+    }
+
+    public static String fileToBase64Src(File imgFile) {
+        String fn = imgFile.getName();
+        String suff = fn.substring(fn.lastIndexOf(".") + 1).toLowerCase();
+        return "data:image/" + suff + ";base64," + fileToBase64(imgFile);
+    }
+
+    public static String fileToBase64(File imgFile) {
         InputStream is = null;
         byte[] base64Byte;
         try {
-			base64Byte = new byte[0];
-			byte[] imgByte;
-			is = new FileInputStream(imgFile);
-			imgByte = IOUtils.toByteArray(is);
-			base64Byte = Base64.encodeBase64(imgByte);
-		}  catch (IOException e) {
-			throw new RuntimeException(e);
-		} finally {
-			if(is!=null)
-				try {
-					is.close();
-				} catch (IOException e) {
-				}
-		}
+            base64Byte = new byte[0];
+            byte[] imgByte;
+            is = new FileInputStream(imgFile);
+            imgByte = IOUtils.toByteArray(is);
+            base64Byte = Base64.encodeBase64(imgByte);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (is != null)
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+        }
         return new String(base64Byte);
     }
 
@@ -133,14 +159,14 @@ public class FileUtil {
         try {
             url = new URL(fileUrl);
         } catch (MalformedURLException e) {
-        	throw new RuntimeException("文件链接错误:"+fileUrl,e);
+            throw new RuntimeException("文件链接错误:" + fileUrl, e);
         }
 
         HttpURLConnection connection;
         try {
             connection = (HttpURLConnection) url.openConnection();
         } catch (IOException e) {
-        	throw new RuntimeException("下载出错:"+e.getMessage(),e);
+            throw new RuntimeException("下载出错:" + e.getMessage(), e);
         }
 
         try (DataInputStream dataInputStream = new DataInputStream(connection.getInputStream());
@@ -156,7 +182,7 @@ public class FileUtil {
             dataOutputStream.flush();
             return true;
         } catch (Exception e) {
-        	throw new RuntimeException("下载出错:"+fileUrl,e);
+            throw new RuntimeException("下载出错:" + fileUrl, e);
         } finally {
             if (connection != null) {
                 connection.disconnect();
@@ -164,7 +190,6 @@ public class FileUtil {
         }
     }
 
-
     /**
      * 获得文件MIME类型
      *
@@ -177,7 +202,7 @@ public class FileUtil {
         try {
             type = Files.probeContentType(path);
         } catch (IOException e) {
-        	throw new RuntimeException("出错:"+e.getMessage(),e);
+            throw new RuntimeException("出错:" + e.getMessage(), e);
         }
         return type;
     }
@@ -197,17 +222,17 @@ public class FileUtil {
 
         File sourceFile = new File(sourceFilePath);
         if (!sourceFile.exists()) {
-        	throw new RuntimeException("待压缩的文件目录:" + sourceFilePath + "不存在.");
+            throw new RuntimeException("待压缩的文件目录:" + sourceFilePath + "不存在.");
         }
 
         File zipFile = new File(zipFilePath + File.separator + fileName + ".zip");
         if (zipFile.exists()) {
-        	throw new RuntimeException(zipFilePath + "目录下存在名字为:" + fileName + ".zip" + "打包文件.");
+            throw new RuntimeException(zipFilePath + "目录下存在名字为:" + fileName + ".zip" + "打包文件.");
         }
 
         File[] sourceFiles = sourceFile.listFiles();
         if (null == sourceFiles || sourceFiles.length < 1) {
-        	throw new RuntimeException("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
+            throw new RuntimeException("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
         }
 
         try (FileOutputStream fos = new FileOutputStream(zipFile);
@@ -238,11 +263,11 @@ public class FileUtil {
 
                     zos.flush();
                 } catch (Exception e) {
-                	throw new RuntimeException("出错:"+e.getMessage(),e);
+                    throw new RuntimeException("出错:" + e.getMessage(), e);
                 }
             }
         } catch (Exception e) {
-        	throw new RuntimeException("出错:"+e.getMessage(),e);
+            throw new RuntimeException("出错:" + e.getMessage(), e);
         }
     }
 
@@ -331,36 +356,37 @@ public class FileUtil {
             }
         }
     }
+
     /**
      * 文件压缩
      *
-     * @param target  目录或文件
-     * @param zipFile 压缩后的ZIP文件
+     * @param target
+     *            目录或文件
+     * @param zipFile
+     *            压缩后的ZIP文件
      */
     public static boolean doZip(File target, File zipFile) {
         if (target == null || !target.exists()) {
-        	throw new RuntimeException("目录或文件不能为空!");
+            throw new RuntimeException("目录或文件不能为空!");
         }
 
         if (zipFile == null) {
-        	throw new RuntimeException("待压缩的文件不能为空!");
+            throw new RuntimeException("待压缩的文件不能为空!");
         }
 
-        try (
-                OutputStream outStream = new FileOutputStream(zipFile);
-                ZipOutputStream zipOutStream = new ZipOutputStream(outStream, Charset.forName("UTF-8"));
-        ) {
+        try (OutputStream outStream = new FileOutputStream(zipFile);
+                ZipOutputStream zipOutStream = new ZipOutputStream(outStream, Charset.forName("UTF-8"));) {
             if (!zipFile.exists()) {
                 boolean ok = zipFile.createNewFile();
                 if (!ok) {
-                	throw new RuntimeException("压缩的文件创建失败!");
+                    throw new RuntimeException("压缩的文件创建失败!");
                 }
             }
 
             if (target.isDirectory()) {
                 File[] files = target.listFiles();
                 if (files.length == 0) {
-                	throw new RuntimeException("文件夹内未找到任何文件!");
+                    throw new RuntimeException("文件夹内未找到任何文件!");
                 }
 
                 for (File file : files) {
@@ -370,14 +396,14 @@ public class FileUtil {
                 doZip(zipOutStream, target, null);
             }
         } catch (IOException e) {
-        	throw new RuntimeException(e);
+            throw new RuntimeException(e);
         }
 
         return true;
     }
 
     private static void doZip(ZipOutputStream zipOutStream, File target, String parentDir) throws IOException {
-        //log.info("Zip:" + parentDir);
+        // log.info("Zip:" + parentDir);
         if (parentDir == null) {
             parentDir = "";
         }
@@ -405,34 +431,36 @@ public class FileUtil {
                     zipOutStream.write(bytes, 0, len);
                 }
             } catch (IOException e) {
-            	throw new RuntimeException(e);
+                throw new RuntimeException(e);
             }
             zipOutStream.closeEntry();
         }
     }
-    
+
     /**
      * 解压文件
      *
-     * @param targetDir 解压目录
-     * @param zipFile   待解压的ZIP文件
+     * @param targetDir
+     *            解压目录
+     * @param zipFile
+     *            待解压的ZIP文件
      */
     public static List<File> unZip(File targetDir, File zipFile) {
         if (targetDir == null) {
-        	throw new RuntimeException("解压目录不能为空!");
+            throw new RuntimeException("解压目录不能为空!");
         }
 
         if (zipFile == null) {
-        	throw new RuntimeException("待解压的文件不能为空!");
+            throw new RuntimeException("待解压的文件不能为空!");
         }
 
         if (!zipFile.exists()) {
-        	throw new RuntimeException("待解压的文件不存在!" + zipFile.getAbsolutePath());
+            throw new RuntimeException("待解压的文件不存在!" + zipFile.getAbsolutePath());
         }
 
         String zipName = zipFile.getName().toLowerCase();
         if (zipFile.isDirectory() || zipName.indexOf(".zip") < 0) {
-        	throw new RuntimeException("待解压的文件格式错误!");
+            throw new RuntimeException("待解压的文件格式错误!");
         }
 
         if (!targetDir.exists()) {
@@ -444,11 +472,11 @@ public class FileUtil {
         try (ZipFile zip = new ZipFile(zipFile, Charset.forName("UTF-8"));) {
 
             @SuppressWarnings("rawtypes")
-			Enumeration entries = zip.entries();
+            Enumeration entries = zip.entries();
             while (entries.hasMoreElements()) {
                 ZipEntry entry = (ZipEntry) entries.nextElement();
 
-                //Linux中需要替换掉路径的反斜杠
+                // Linux中需要替换掉路径的反斜杠
                 String entryName = (File.separator + entry.getName()).replaceAll("\\\\", "/");
 
                 String filePath = targetDir.getAbsolutePath() + entryName;
@@ -461,19 +489,18 @@ public class FileUtil {
                         dir.mkdirs();
                     }
 
-                    try (OutputStream os = new FileOutputStream(target);
-                         InputStream is = zip.getInputStream(entry);) {
+                    try (OutputStream os = new FileOutputStream(target); InputStream is = zip.getInputStream(entry);) {
                         IOUtils.copy(is, os);
                         os.flush();
                     } catch (IOException e) {
-                    	throw new RuntimeException(e);
+                        throw new RuntimeException(e);
                     }
                     result.add(target);
                 }
             }
 
         } catch (IOException e) {
-        	throw new RuntimeException(e);
+            throw new RuntimeException(e);
         }
 
         return result;
@@ -541,61 +568,60 @@ public class FileUtil {
         String path = FileUtil.class.getResource("/").getPath() + "templates/docx";
         return path;
     }
-    
+
     public static void deleteFolder(String path) {
 
-		File file = new File(path);
-		if (file.exists()) {
-			if (file.isFile()) {
-				deleteFile(path);
-			} else {
-				deleteDirectory(path);
-			}
-		}
-	}
-
-	public static void deleteFile(String path) {
-		File file = new File(path);
-		if (file.isFile() && file.exists()) {
-			file.delete();
-		}
-	}
-
-	public static void deleteDirectory(String path) {
-		if (!path.endsWith(File.separator)) {
-			path = path + File.separator;
-		}
-		File dirFile = new File(path);
-		if (!dirFile.exists() || !dirFile.isDirectory()) {
-			return;
-		}
-		File[] files = dirFile.listFiles();
-		if (files != null) {
-			for (int i = 0; i < files.length; i++) {
-				if (files[i].isFile()) {
-					deleteFile(files[i].getAbsolutePath());
-				} else {
-					deleteDirectory(files[i].getAbsolutePath());
-				}
-			}
-		}
-
-		dirFile.delete();
-	}
-	public static File cutFile(String sourcePath, String targetPath, int n) {
+        File file = new File(path);
+        if (file.exists()) {
+            if (file.isFile()) {
+                deleteFile(path);
+            } else {
+                deleteDirectory(path);
+            }
+        }
+    }
+
+    public static void deleteFile(String path) {
+        File file = new File(path);
+        if (file.isFile() && file.exists()) {
+            file.delete();
+        }
+    }
+
+    public static void deleteDirectory(String path) {
+        if (!path.endsWith(File.separator)) {
+            path = path + File.separator;
+        }
+        File dirFile = new File(path);
+        if (!dirFile.exists() || !dirFile.isDirectory()) {
+            return;
+        }
+        File[] files = dirFile.listFiles();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isFile()) {
+                    deleteFile(files[i].getAbsolutePath());
+                } else {
+                    deleteDirectory(files[i].getAbsolutePath());
+                }
+            }
+        }
+
+        dirFile.delete();
+    }
+
+    public static File cutFile(String sourcePath, String targetPath, int n) {
         File file = new File(sourcePath);
         File newFile = new File(targetPath);
 
-        try (
-                FileInputStream fis = new FileInputStream(file);
+        try (FileInputStream fis = new FileInputStream(file);
                 InputStream is = new BufferedInputStream(fis);
-                OutputStream os = new FileOutputStream(newFile);
-        ) {
+                OutputStream os = new FileOutputStream(newFile);) {
 
-            //从n个字节开始读,注意中文是两个字节
+            // 从n个字节开始读,注意中文是两个字节
             fis.skip(n);
 
-            //指定文件位置读取的文件流,存入新文件
+            // 指定文件位置读取的文件流,存入新文件
             byte buffer[] = new byte[4 * 1024];
             int len;
             while ((len = is.read(buffer)) != -1) {
@@ -605,16 +631,19 @@ public class FileUtil {
             os.flush();
             return newFile;
         } catch (IOException e) {
-        	throw new RuntimeException(e);
+            throw new RuntimeException(e);
         }
     }
 
     /**
      * 读取文件前面部分N个字节
      *
-     * @param path       文件路径
-     * @param headerSize 头信息字节数(必须2的倍数)
-     * @param signSize   签名信息字节数
+     * @param path
+     *            文件路径
+     * @param headerSize
+     *            头信息字节数(必须2的倍数)
+     * @param signSize
+     *            签名信息字节数
      * @return
      */
     public static String[] readFileHeader(String path, int headerSize, int signSize) {
@@ -622,11 +651,8 @@ public class FileUtil {
         String[] codes = new String[n + 1];
 
         File file = new File(path);
-        try (
-                FileInputStream fis = new FileInputStream(file);
-                DataInputStream ois = new DataInputStream(fis);
-        ) {
-            //分n次读取文件(n * 2)个字节
+        try (FileInputStream fis = new FileInputStream(file); DataInputStream ois = new DataInputStream(fis);) {
+            // 分n次读取文件(n * 2)个字节
             for (int i = 0; i < n; i++) {
                 codes[i] = String.valueOf(ois.readShort());
             }
@@ -639,7 +665,7 @@ public class FileUtil {
                 codes[2] = ss.toString();
             }
         } catch (IOException e) {
-        	throw new RuntimeException(e);
+            throw new RuntimeException(e);
         }
 
         return codes;
@@ -651,7 +677,7 @@ public class FileUtil {
      * @param file
      * @return
      */
-	public static String readFileContent(File file) {
+    public static String readFileContent(File file) {
         StringBuilder content = new StringBuilder();
         InputStreamReader streamReader = null;
         BufferedReader bufferedReader = null;
@@ -666,7 +692,7 @@ public class FileUtil {
                 }
             }
         } catch (Exception e) {
-        	throw new RuntimeException(e);
+            throw new RuntimeException(e);
         } finally {
             IOUtils.closeQuietly(streamReader);
             IOUtils.closeQuietly(bufferedReader);
@@ -674,7 +700,6 @@ public class FileUtil {
         return content.toString();
     }
 
-
     /**
      * 生成日期目录路径
      */
@@ -707,7 +732,8 @@ public class FileUtil {
     /**
      * 获取无后缀的文件名
      *
-     * @param fileName 示例:../xxx/abc.xx
+     * @param fileName
+     *            示例:../xxx/abc.xx
      * @return 示例:../xxx/abc
      */
     public static String getFilePathName(String fileName) {
@@ -754,26 +780,24 @@ public class FileUtil {
         if (!file.exists()) {
             if (makeDirs(file.getParent())) {
                 boolean ok;
-				try {
-					ok = file.createNewFile();
-				} catch (IOException e) {
-					throw new RuntimeException("文件创建失败!");
-				}
+                try {
+                    ok = file.createNewFile();
+                } catch (IOException e) {
+                    throw new RuntimeException("文件创建失败!");
+                }
                 if (!ok) {
                     throw new RuntimeException("文件创建失败!");
                 }
             }
         }
 
-        try (
-                FileOutputStream fos = new FileOutputStream(file);
+        try (FileOutputStream fos = new FileOutputStream(file);
                 OutputStreamWriter write = new OutputStreamWriter(fos, encoding);
-                BufferedWriter bw = new BufferedWriter(write);
-        ) {
+                BufferedWriter bw = new BufferedWriter(write);) {
             bw.write(content);
             bw.flush();
         } catch (IOException e) {
-        	throw new RuntimeException("文件创建失败!",e);
+            throw new RuntimeException("文件创建失败!", e);
         }
     }
 

+ 429 - 425
src/main/java/cn/com/qmth/ex/bean/MyConsumer.java

@@ -26,429 +26,433 @@ import cn.com.qmth.ex.config.Param;
 import cn.com.qmth.ex.multithread.Consumer;
 
 public class MyConsumer extends Consumer<PaperExportDto> {
-	private static String[] sucStr = new String[] { "对", "正确", "√", "是", "True" };
-	private static String[] errStr = new String[] { "错", "错误", "×", "不正确", "否", "False" };
-//	private static String paperSuff = "(231205)";
-	private int maxqc = 200;
-
-	private Pattern imgPat = Pattern.compile("<img[^<]+src=\"([^<\"]+)\"[^<]*>");
-
-	@Override
-	public void consume(PaperExportDto dto) {
-		Connection connect = null;
-		File sub = new File(Param.dataDir+"/paper/" + dto.getCourseCode() + "/");
-		sub.mkdir();
-		try {
-			Class.forName("com.mysql.cj.jdbc.Driver");
-
-			String url = "jdbc:mysql://localhost:3306/" + Param.dbName + "?serverTimezone=GMT%2B8";
-
-			String user = Param.dbUser;
-
-			String password = Param.dbPass;
-			connect = DriverManager.getConnection(url, user, password);
-			exportPaper(connect, dto);
-			ExportPaperByCourseCode.addDisposeCount();
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		} finally {
-			if (connect != null) {
-				try {
-					connect.close();
-				} catch (SQLException e) {
-				}
-			}
-		}
-	}
-
-	private List<KdQuestion> getQuestion(Connection connect, String courseCode) throws SQLException, IOException {
-		List<KdQuestion> qs = new ArrayList<>();
-		PreparedStatement preState = null;
-		ResultSet resultSet = null;
-		try {
-			String sql = " select q.id,q.question_type,q.topic,q.difficulty,q.answer "
-					+ " from wq_question_bank_subject t " + " left join wq_subject sub on t.subject_id=sub.id"
-					+ " left join wq_question_bank b on t.question_bank_id=b.id "
-					+ " left join wq_question_question_bank f on t.question_bank_id=f.question_bank_id "
-					+ " left join wq_question q on f.question_id=q.id " + " where sub.subject_code='" + courseCode
-					+ "' and b.rent_id=811 and b.is_deleted=0 " + " and q.is_deleted=0 and q.rent_id=811 ";
-
-			preState = connect.prepareStatement(sql);
-
-			resultSet = preState.executeQuery();
-
-			while (resultSet.next()) {
-				KdQuestion q = new KdQuestion();
-				q.setScore(1.0);
-				q.setHaveAudio(false);
-				q.setId(resultSet.getLong("id"));
-				q.setBody(disposeImg(resultSet.getString("topic"), courseCode));
-				q.setQst(YunkaiQuesStructType.getByYunKaiType(resultSet.getInt("question_type")));
-				q.setQuesStructType(QuesStructType.getQuesStructTypeById(q.getQst().getType()));
-				YunkaiDifficulty yd = YunkaiDifficulty.getByYunKaiType(resultSet.getInt("difficulty"));
-				q.setDifficultyDegree(yd == null ? 0.5 : yd.getType());
-//				if (!q.getQst().isObjective()) {
-//					continue;
-//				}
-//				q.setDifficulty(YunkaiDifficulty.ZHONGDENG);
-				q.setAnswer(disposeImg(resultSet.getString("answer"), courseCode));
-				q.setObjective(q.getQst().isObjective());
-				qs.add(q);
-			}
-			return qs;
-		} finally {
-			if (resultSet != null) {
-				resultSet.close();
-			}
-			if (preState != null) {
-				preState.close();
-			}
-		}
-	}
-
-	private String disposeImg(String str, String courseCode) {
-		if (StringUtils.isBlank(str)) {
-			return str;
-		}
-		Matcher matcher = imgPat.matcher(str);
-		Map<String, String> srcMap = new HashMap<>();
-		while (matcher.find()) {
-			String imgSrc = matcher.group(1).trim();
-			if (imgSrc.toLowerCase().trim().startsWith("http")) {
-				if (srcMap.get(imgSrc) == null) {
-					String suff = imgSrc.substring(imgSrc.lastIndexOf(".") + 1).toLowerCase();
-					File img = new File(Param.dataDir+"/paper/" + courseCode + "/" + UUID.randomUUID() + "." + suff);
-					FileUtil.saveUrlAs(imgSrc, img.getAbsolutePath());
-					String base64 = FileUtil.fileToBase64Src(img);
-					img.delete();
-					srcMap.put(imgSrc, base64);
-				}
-			}
-		}
-		for (String imgSrc : srcMap.keySet()) {
-			str = str.replaceAll(imgSrc, srcMap.get(imgSrc));
-		}
-		return str;
-	}
-
-	private List<QuestionProp> getQuestionProp(Connection connect, List<KdQuestion> qs) {
-		List<QuestionProp> as = new ArrayList<>();
-		List<Long> ids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
-		String idsstr = StringUtils.join(ids, ",");
-		PreparedStatement preState = null;
-		ResultSet resultSet = null;
-		try {
-			String sql = " select t.knowledge_system_id,t.question_id " + " from wq_question_knowledge_system t "
-					+ " where t.question_id in (" + idsstr + ") ";
-			preState = connect.prepareStatement(sql);
-
-			resultSet = preState.executeQuery();
-
-			while (resultSet.next()) {
-				QuestionProp a = new QuestionProp();
-				a.setKnowledgeId(resultSet.getLong("knowledge_system_id"));
-				a.setQuestionId(resultSet.getLong("question_id"));
-				as.add(a);
-			}
-			return as;
-		} catch (Exception e1) {
-			throw new RuntimeException(e1);
-		} finally {
-			if (resultSet != null) {
-				try {
-					resultSet.close();
-				} catch (SQLException e1) {
-				}
-			}
-			if (preState != null) {
-				try {
-					preState.close();
-				} catch (SQLException e1) {
-				}
-			}
-		}
-	}
-
-	private void fillProp(Connection connect, List<KdQuestion> qs) {
-		List<QuestionProp> qps = new BatchGetDataUtil<QuestionProp, KdQuestion>() {
-
-			@Override
-			protected List<QuestionProp> getData(List<KdQuestion> paramList) {
-				return getQuestionProp(connect, paramList);
-			}
-		}.getDataForBatch(qs, 200);
-		if (CollectionUtils.isEmpty(qps)) {
-			return;
-		}
-		Map<Long, KdQuestion> map = new HashMap<>();
-		for (KdQuestion q : qs) {
-			map.put(q.getId(), q);
-		}
-		for (QuestionProp qp : qps) {
-			KdQuestion q = map.get(qp.getQuestionId());
-			List<Long> qpids = q.getPropIds();
-			if (qpids == null) {
-				qpids = new ArrayList<>();
-				q.setPropIds(qpids);
-			}
-			qpids.add(qp.getKnowledgeId());
-		}
-	}
-
-	private void fillAnswer(Connection connect, List<KdQuestion> qs, String courseCode) {
-		List<Answer> qps = new BatchGetDataUtil<Answer, KdQuestion>() {
-
-			@Override
-			protected List<Answer> getData(List<KdQuestion> paramList) {
-				return getAnswerBatch(connect, paramList, courseCode);
-			}
-		}.getDataForBatch(qs, 200);
-		if (CollectionUtils.isEmpty(qps)) {
-			return;
-		}
-
-		Map<Long, List<Answer>> map = new HashMap<>();
-		for (Answer qp : qps) {
-			List<Answer> list = map.get(qp.getQuestionId());
-			if (list == null) {
-				list = new ArrayList<>();
-				map.put(qp.getQuestionId(), list);
-			}
-			list.add(qp);
-		}
-
-		for (KdQuestion q : qs) {
-			q.setQuesStructType(QuesStructType.getQuesStructTypeById(q.getQst().getType()));
-			if (YunkaiQuesStructType.DANXUAN.equals(q.getQst())) {
-				List<KdQuesOption> ops = new ArrayList<>();
-				q.setOptions(ops);
-				int num = 0;
-				for (Answer a : map.get(q.getId())) {
-					num++;
-					KdQuesOption op = new KdQuesOption();
-					ops.add(op);
-					op.setNumber(num);
-					op.setBody(a.getBody());
-					op.setSelect(a.getRight() == 1);
-					if (op.getSelect()) {
-						q.setAnswer(getOptionNum(num));
-					}
-				}
-			} else if (YunkaiQuesStructType.DUOXUAN.equals(q.getQst())
-					|| YunkaiQuesStructType.BUDINGXIANG.equals(q.getQst())) {
-				List<String> as = new ArrayList<>();
-				List<KdQuesOption> ops = new ArrayList<>();
-				q.setOptions(ops);
-				int num = 0;
-				for (Answer a : map.get(q.getId())) {
-					num++;
-					KdQuesOption op = new KdQuesOption();
-					ops.add(op);
-					op.setNumber(num);
-					op.setBody(a.getBody());
-					op.setSelect(a.getRight() == 1);
-					if (op.getSelect()) {
-						as.add(getOptionNum(num));
-					}
-				}
-				q.setAnswer(StringUtils.join(as, ","));
-			} else if (YunkaiQuesStructType.PANDUAN.equals(q.getQst())) {
-				for (Answer a : map.get(q.getId())) {
-					if (a.getRight() == 1) {
-						q.setAnswer(getBool(a.getBody()));
-					}
-				}
-
-			} else if (YunkaiQuesStructType.TIANKONGTI.equals(q.getQst())) {
-				q.setBody(relaceQuestionIdx(q.getBody()));
-				if (map.get(q.getId()) != null) {
-					List<String> as = new ArrayList<>();
-					try {
-						for (Answer a : map.get(q.getId())) {
-							if (a.getRight() == 1) {
-								as.add(a.getBody());
-							}
-						}
-					} catch (Exception e) {
-						throw e;
-					}
-					q.setAnswer(StringUtils.join(as, "##"));
-				}
-			} else {
-				// nothing
-			}
-		}
-	}
-
-	private String relaceQuestionIdx(String str) {
-		StringBuffer sb = new StringBuffer("");
-		Pattern pattern = Pattern.compile("__(\\d+)__");
-
-		Matcher matcher = pattern.matcher(str);
-
-		while (matcher.find()) {
-			matcher.appendReplacement(sb, "###");
-		}
-
-		if (StringUtils.isEmpty(sb.toString())) {
-			return str;
-		} else {
-			matcher.appendTail(sb);
-			return sb.toString();
-		}
-	}
-
-	/**
-	 * 将数字1,2,3,4转化成A,B,C,D
-	 *
-	 * @param number
-	 * @return
-	 */
-	private  String getOptionNum(int number) {
-		char optionNum = (char) (64 + number);
-		return String.valueOf(optionNum);
-	}
-
-	private String getBool(String val) {
-		String valid = "错答案:正确";
-		if (val.contains(valid)) {
-			return "正确";
-		}
-		for (String suc : sucStr) {
-			if (val.contains(suc)) {
-				return "正确";
-			}
-		}
-		for (String err : errStr) {
-			if (val.contains(err)) {
-				return "错误";
-			}
-		}
-		return "正确";
-	}
-
-	private List<Answer> getAnswerBatch(Connection connect, List<KdQuestion> qs, String courseCode) {
-		List<Answer> as = new ArrayList<>();
-		List<Long> ids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
-		String idsstr = StringUtils.join(ids, ",");
-		PreparedStatement preState = null;
-		ResultSet resultSet = null;
-		try {
-			String sql = " select t.question_id,t.answer_text,t.is_right " + " from wq_question_answer_item t "
-					+ " where t.question_id in (" + idsstr + ")  " + " order by t.question_id,t.sequence ";
-			preState = connect.prepareStatement(sql);
-
-			resultSet = preState.executeQuery();
-
-			while (resultSet.next()) {
-				Answer a = new Answer();
-				a.setBody(disposeImg(resultSet.getString("answer_text"), courseCode));
-				a.setRight(resultSet.getInt("is_right"));
-				a.setQuestionId(resultSet.getLong("question_id"));
-				as.add(a);
-			}
-			return as;
-		} catch (Exception e1) {
-			throw new RuntimeException(e1);
-		} finally {
-			if (resultSet != null) {
-				try {
-					resultSet.close();
-				} catch (SQLException e1) {
-				}
-			}
-			if (preState != null) {
-				try {
-					preState.close();
-				} catch (SQLException e1) {
-				}
-			}
-		}
-	}
-
-	private void exportPaper(Connection connect, PaperExportDto dto) throws Exception {
-		List<KdQuestion> qs = getQuestion(connect, dto.getCourseCode());
-		if (qs.size() == 0) {
-			return;
-		}
-		fillProp(connect, qs);
-		fillAnswer(connect, qs, dto.getCourseCode());
-
-		Map<YunkaiQuesStructType, List<KdQuestion>> qmap = new HashMap<>();
-		for (KdQuestion q : qs) {
-			if (QuesStructType.SINGLE_ANSWER_QUESTION.equals(q.getQuesStructType())
-					|| QuesStructType.MULTIPLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
-				if(CollectionUtils.isEmpty(q.getOptions())) {
-					continue;
-				}
-				if(q.getOptions().size()==1) {
-					continue;
-				}
-			}
-			List<KdQuestion> list = qmap.get(q.getQst());
-			if (list == null) {
-				list = new ArrayList<>();
-				qmap.put(q.getQst(), list);
-			}
-			list.add(q);
-		}
-		for (YunkaiQuesStructType qt : qmap.keySet()) {
-			createPapers(qmap.get(qt), qt, dto);
-		}
-	}
-
-	private void createPapers(List<KdQuestion> qs, YunkaiQuesStructType qt, PaperExportDto dto) {
-		if (qs == null || qs.size() == 0) {
-			return;
-		}
-		if (qs.size() <= maxqc) {
-			createPaper(qs, qt, dto, 1);
-		} else {
-			int size = qs.size();
-			int len = maxqc;
-			int count = (size + len - 1) / len;
-
-			for (int i = 0; i < count; i++) {
-				List<KdQuestion> subList = qs.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
-				createPaper(subList, qt, dto, i + 1);
-			}
-		}
-
-	}
-
-	private void createPaper(List<KdQuestion> qs, YunkaiQuesStructType qt, PaperExportDto dto, int indx) {
-		if (qs.size() == 0) {
-			return;
-		}
-		String detailName = qt.getYunKaiDesc();
-		KdPaper paper = new KdPaper();
-		paper.setDetailCount(1);
-		paper.setUnitCount(qs.size());
-		paper.setTotalScore((double) qs.size());
-		paper.setName(Param.paperPrefix + detailName + "_" + indx);
-		paper.setCourseCode(dto.getCourseCode());
-		List<KdDetail> des = new ArrayList<>();
-		KdDetail d = new KdDetail();
-		d.setName(detailName);
-		d.setNumber(1);
-		d.setQuestionCount(qs.size());
-		d.setTotalScore((double) qs.size());
-		d.setQuestions(qs);
-		des.add(d);
-		paper.setDetails(des);
-		paper.setDetailCount(1);
-		paper.setUnitCount(qs.size());
-		File paperdir = new File(Param.dataDir+"/paper/" + dto.getCourseCode() + "/" + qt.getYunKaiType() + "/");
-		paperdir.mkdirs();
-		try {
-			FileUtil.writeFile(paperdir.getAbsolutePath(), "/paper_" + indx + ".json", JSONObject.toJSONString(paper));
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	@Override
-	public void initResult() {
-
-	}
+
+    private static String[] sucStr = new String[] { "对", "正确", "√", "是", "True" };
+
+    private static String[] errStr = new String[] { "错", "错误", "×", "不正确", "否", "False" };
+
+    // private static String paperSuff = "(231205)";
+    private int maxqc = 200;
+
+    private Pattern imgPat = Pattern.compile("<img[^<]+src=\"([^<\"]+)\"[^<]*>");
+
+    @Override
+    public void consume(PaperExportDto dto) {
+        Connection connect = null;
+        File sub = new File(Param.dataDir + "/paper/" + dto.getCourseCode() + "/");
+        sub.mkdir();
+        try {
+            Class.forName("com.mysql.cj.jdbc.Driver");
+
+            String url = "jdbc:mysql://localhost:3306/" + Param.dbName + "?serverTimezone=GMT%2B8";
+
+            String user = Param.dbUser;
+
+            String password = Param.dbPass;
+            connect = DriverManager.getConnection(url, user, password);
+            exportPaper(connect, dto);
+            ExportPaperByCourseCode.addDisposeCount();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (connect != null) {
+                try {
+                    connect.close();
+                } catch (SQLException e) {
+                }
+            }
+        }
+    }
+
+    private List<KdQuestion> getQuestion(Connection connect, String courseCode) throws SQLException, IOException {
+        List<KdQuestion> qs = new ArrayList<>();
+        PreparedStatement preState = null;
+        ResultSet resultSet = null;
+        try {
+            String sql = " select q.id,q.question_type,q.topic,q.difficulty,q.answer "
+                    + " from wq_question_bank_subject t " + " left join wq_subject sub on t.subject_id=sub.id"
+                    + " left join wq_question_bank b on t.question_bank_id=b.id "
+                    + " left join wq_question_question_bank f on t.question_bank_id=f.question_bank_id "
+                    + " left join wq_question q on f.question_id=q.id " + " where sub.subject_code='" + courseCode
+                    + "' and b.rent_id=811 and b.is_deleted=0 " + " and q.is_deleted=0 and q.rent_id=811 ";
+
+            preState = connect.prepareStatement(sql);
+
+            resultSet = preState.executeQuery();
+
+            while (resultSet.next()) {
+                KdQuestion q = new KdQuestion();
+                q.setScore(1.0);
+                q.setHaveAudio(false);
+                q.setId(resultSet.getLong("id"));
+                q.setBody(disposeImg(resultSet.getString("topic"), courseCode));
+                q.setQst(YunkaiQuesStructType.getByYunKaiType(resultSet.getInt("question_type")));
+                q.setQuesStructType(QuesStructType.getQuesStructTypeById(q.getQst().getType()));
+                YunkaiDifficulty yd = YunkaiDifficulty.getByYunKaiType(resultSet.getInt("difficulty"));
+                q.setDifficultyDegree(yd == null ? 0.5 : yd.getType());
+                // if (!q.getQst().isObjective()) {
+                // continue;
+                // }
+                // q.setDifficulty(YunkaiDifficulty.ZHONGDENG);
+                q.setAnswer(disposeImg(resultSet.getString("answer"), courseCode));
+                q.setObjective(q.getQst().isObjective());
+                qs.add(q);
+            }
+            return qs;
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (preState != null) {
+                preState.close();
+            }
+        }
+    }
+
+    private String disposeImg(String str, String courseCode) {
+        if (StringUtils.isBlank(str)) {
+            return str;
+        }
+        Matcher matcher = imgPat.matcher(str);
+        Map<String, String> srcMap = new HashMap<>();
+        while (matcher.find()) {
+            String imgSrc = matcher.group(1).trim();
+            if (imgSrc.toLowerCase().trim().startsWith("http")) {
+                if (srcMap.get(imgSrc) == null) {
+                    String suff = imgSrc.substring(imgSrc.lastIndexOf(".") + 1).toLowerCase();
+                    File img = new File(Param.dataDir + "/paper/" + courseCode + "/" + UUID.randomUUID() + "." + suff);
+                    FileUtil.saveUrlAs(imgSrc, img.getAbsolutePath());
+                    String base64 = FileUtil.fileToBase64Src(img);
+                    img.delete();
+                    srcMap.put(imgSrc, base64);
+                }
+            }
+        }
+        for (String imgSrc : srcMap.keySet()) {
+            str = str.replaceAll(imgSrc, srcMap.get(imgSrc));
+        }
+        return str;
+    }
+
+    private List<QuestionProp> getQuestionProp(Connection connect, List<KdQuestion> qs) {
+        List<QuestionProp> as = new ArrayList<>();
+        List<Long> ids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
+        String idsstr = StringUtils.join(ids, ",");
+        PreparedStatement preState = null;
+        ResultSet resultSet = null;
+        try {
+            String sql = " select t.knowledge_system_id,t.question_id " + " from wq_question_knowledge_system t "
+                    + " where t.question_id in (" + idsstr + ") ";
+            preState = connect.prepareStatement(sql);
+
+            resultSet = preState.executeQuery();
+
+            while (resultSet.next()) {
+                QuestionProp a = new QuestionProp();
+                a.setKnowledgeId(resultSet.getLong("knowledge_system_id"));
+                a.setQuestionId(resultSet.getLong("question_id"));
+                as.add(a);
+            }
+            return as;
+        } catch (Exception e1) {
+            throw new RuntimeException(e1);
+        } finally {
+            if (resultSet != null) {
+                try {
+                    resultSet.close();
+                } catch (SQLException e1) {
+                }
+            }
+            if (preState != null) {
+                try {
+                    preState.close();
+                } catch (SQLException e1) {
+                }
+            }
+        }
+    }
+
+    private void fillProp(Connection connect, List<KdQuestion> qs) {
+        List<QuestionProp> qps = new BatchGetDataUtil<QuestionProp, KdQuestion>() {
+
+            @Override
+            protected List<QuestionProp> getData(List<KdQuestion> paramList) {
+                return getQuestionProp(connect, paramList);
+            }
+        }.getDataForBatch(qs, 200);
+        if (CollectionUtils.isEmpty(qps)) {
+            return;
+        }
+        Map<Long, KdQuestion> map = new HashMap<>();
+        for (KdQuestion q : qs) {
+            map.put(q.getId(), q);
+        }
+        for (QuestionProp qp : qps) {
+            KdQuestion q = map.get(qp.getQuestionId());
+            List<Long> qpids = q.getPropIds();
+            if (qpids == null) {
+                qpids = new ArrayList<>();
+                q.setPropIds(qpids);
+            }
+            qpids.add(qp.getKnowledgeId());
+        }
+    }
+
+    private void fillAnswer(Connection connect, List<KdQuestion> qs, String courseCode) {
+        List<Answer> qps = new BatchGetDataUtil<Answer, KdQuestion>() {
+
+            @Override
+            protected List<Answer> getData(List<KdQuestion> paramList) {
+                return getAnswerBatch(connect, paramList, courseCode);
+            }
+        }.getDataForBatch(qs, 200);
+        if (CollectionUtils.isEmpty(qps)) {
+            return;
+        }
+
+        Map<Long, List<Answer>> map = new HashMap<>();
+        for (Answer qp : qps) {
+            List<Answer> list = map.get(qp.getQuestionId());
+            if (list == null) {
+                list = new ArrayList<>();
+                map.put(qp.getQuestionId(), list);
+            }
+            list.add(qp);
+        }
+
+        for (KdQuestion q : qs) {
+            q.setQuesStructType(QuesStructType.getQuesStructTypeById(q.getQst().getType()));
+            if (YunkaiQuesStructType.DANXUAN.equals(q.getQst())) {
+                List<KdQuesOption> ops = new ArrayList<>();
+                q.setOptions(ops);
+                int num = 0;
+                for (Answer a : map.get(q.getId())) {
+                    num++;
+                    KdQuesOption op = new KdQuesOption();
+                    ops.add(op);
+                    op.setNumber(num);
+                    op.setBody(a.getBody());
+                    op.setSelect(a.getRight() == 1);
+                    if (op.getSelect()) {
+                        q.setAnswer(getOptionNum(num));
+                    }
+                }
+            } else if (YunkaiQuesStructType.DUOXUAN.equals(q.getQst())
+                    || YunkaiQuesStructType.BUDINGXIANG.equals(q.getQst())) {
+                List<String> as = new ArrayList<>();
+                List<KdQuesOption> ops = new ArrayList<>();
+                q.setOptions(ops);
+                int num = 0;
+                for (Answer a : map.get(q.getId())) {
+                    num++;
+                    KdQuesOption op = new KdQuesOption();
+                    ops.add(op);
+                    op.setNumber(num);
+                    op.setBody(a.getBody());
+                    op.setSelect(a.getRight() == 1);
+                    if (op.getSelect()) {
+                        as.add(getOptionNum(num));
+                    }
+                }
+                q.setAnswer(StringUtils.join(as, ","));
+            } else if (YunkaiQuesStructType.PANDUAN.equals(q.getQst())) {
+                for (Answer a : map.get(q.getId())) {
+                    if (a.getRight() == 1) {
+                        q.setAnswer(getBool(a.getBody()));
+                    }
+                }
+
+            } else if (YunkaiQuesStructType.TIANKONGTI.equals(q.getQst())) {
+                q.setBody(relaceQuestionIdx(q.getBody()));
+                if (map.get(q.getId()) != null) {
+                    List<String> as = new ArrayList<>();
+                    try {
+                        for (Answer a : map.get(q.getId())) {
+                            if (a.getRight() == 1) {
+                                as.add(a.getBody());
+                            }
+                        }
+                    } catch (Exception e) {
+                        throw e;
+                    }
+                    q.setAnswer(StringUtils.join(as, "##"));
+                }
+            } else {
+                // nothing
+            }
+        }
+    }
+
+    private String relaceQuestionIdx(String str) {
+        StringBuffer sb = new StringBuffer("");
+        Pattern pattern = Pattern.compile("__(\\d+)__");
+
+        Matcher matcher = pattern.matcher(str);
+
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, "###");
+        }
+
+        if (StringUtils.isEmpty(sb.toString())) {
+            return str;
+        } else {
+            matcher.appendTail(sb);
+            return sb.toString();
+        }
+    }
+
+    /**
+     * 将数字1,2,3,4转化成A,B,C,D
+     *
+     * @param number
+     * @return
+     */
+    private String getOptionNum(int number) {
+        char optionNum = (char) (64 + number);
+        return String.valueOf(optionNum);
+    }
+
+    private String getBool(String val) {
+        String valid = "错答案:正确";
+        if (val.contains(valid)) {
+            return "正确";
+        }
+        for (String suc : sucStr) {
+            if (val.contains(suc)) {
+                return "正确";
+            }
+        }
+        for (String err : errStr) {
+            if (val.contains(err)) {
+                return "错误";
+            }
+        }
+        return "正确";
+    }
+
+    private List<Answer> getAnswerBatch(Connection connect, List<KdQuestion> qs, String courseCode) {
+        List<Answer> as = new ArrayList<>();
+        List<Long> ids = qs.stream().map(e -> e.getId()).collect(Collectors.toList());
+        String idsstr = StringUtils.join(ids, ",");
+        PreparedStatement preState = null;
+        ResultSet resultSet = null;
+        try {
+            String sql = " select t.question_id,t.answer_text,t.is_right " + " from wq_question_answer_item t "
+                    + " where t.question_id in (" + idsstr + ")  " + " order by t.question_id,t.sequence ";
+            preState = connect.prepareStatement(sql);
+
+            resultSet = preState.executeQuery();
+
+            while (resultSet.next()) {
+                Answer a = new Answer();
+                a.setBody(disposeImg(resultSet.getString("answer_text"), courseCode));
+                a.setRight(resultSet.getInt("is_right"));
+                a.setQuestionId(resultSet.getLong("question_id"));
+                as.add(a);
+            }
+            return as;
+        } catch (Exception e1) {
+            throw new RuntimeException(e1);
+        } finally {
+            if (resultSet != null) {
+                try {
+                    resultSet.close();
+                } catch (SQLException e1) {
+                }
+            }
+            if (preState != null) {
+                try {
+                    preState.close();
+                } catch (SQLException e1) {
+                }
+            }
+        }
+    }
+
+    private void exportPaper(Connection connect, PaperExportDto dto) throws Exception {
+        List<KdQuestion> qs = getQuestion(connect, dto.getCourseCode());
+        if (qs.size() == 0) {
+            ExportPaperByCourseCode.addNoQues(dto.getCourseCode());
+            return;
+        }
+        fillProp(connect, qs);
+        fillAnswer(connect, qs, dto.getCourseCode());
+
+        Map<YunkaiQuesStructType, List<KdQuestion>> qmap = new HashMap<>();
+        for (KdQuestion q : qs) {
+            if (QuesStructType.SINGLE_ANSWER_QUESTION.equals(q.getQuesStructType())
+                    || QuesStructType.MULTIPLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
+                if (CollectionUtils.isEmpty(q.getOptions())) {
+                    continue;
+                }
+                if (q.getOptions().size() == 1) {
+                    continue;
+                }
+            }
+            List<KdQuestion> list = qmap.get(q.getQst());
+            if (list == null) {
+                list = new ArrayList<>();
+                qmap.put(q.getQst(), list);
+            }
+            list.add(q);
+        }
+        for (YunkaiQuesStructType qt : qmap.keySet()) {
+            createPapers(qmap.get(qt), qt, dto);
+        }
+    }
+
+    private void createPapers(List<KdQuestion> qs, YunkaiQuesStructType qt, PaperExportDto dto) {
+        if (qs == null || qs.size() == 0) {
+            return;
+        }
+        if (qs.size() <= maxqc) {
+            createPaper(qs, qt, dto, 1);
+        } else {
+            int size = qs.size();
+            int len = maxqc;
+            int count = (size + len - 1) / len;
+
+            for (int i = 0; i < count; i++) {
+                List<KdQuestion> subList = qs.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
+                createPaper(subList, qt, dto, i + 1);
+            }
+        }
+
+    }
+
+    private void createPaper(List<KdQuestion> qs, YunkaiQuesStructType qt, PaperExportDto dto, int indx) {
+        if (qs.size() == 0) {
+            return;
+        }
+        String detailName = qt.getYunKaiDesc();
+        KdPaper paper = new KdPaper();
+        paper.setDetailCount(1);
+        paper.setUnitCount(qs.size());
+        paper.setTotalScore((double) qs.size());
+        paper.setName(Param.paperPrefix + detailName + "_" + indx);
+        paper.setCourseCode(dto.getCourseCode());
+        List<KdDetail> des = new ArrayList<>();
+        KdDetail d = new KdDetail();
+        d.setName(detailName);
+        d.setNumber(1);
+        d.setQuestionCount(qs.size());
+        d.setTotalScore((double) qs.size());
+        d.setQuestions(qs);
+        des.add(d);
+        paper.setDetails(des);
+        paper.setDetailCount(1);
+        paper.setUnitCount(qs.size());
+        File paperdir = new File(Param.dataDir + "/paper/" + dto.getCourseCode() + "/" + qt.getYunKaiType() + "/");
+        paperdir.mkdirs();
+        try {
+            FileUtil.writeFile(paperdir.getAbsolutePath(), "/paper_" + indx + ".json", JSONObject.toJSONString(paper));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void initResult() {
+
+    }
 }

+ 3 - 3
src/main/java/cn/com/qmth/ex/config/Param.java

@@ -6,9 +6,9 @@ public class Param {
 
     public static String dbPass = "123456";
 
-    public static String dbName = "yunkai_240913";
+    public static String dbName = "yunkai_241204";
 
-    public static String dataDir = "d:/yunkai";
+    public static String dataDir = "e:/files/yunkai/241204";
 
-    public static String paperPrefix = "(240913)";
+    public static String paperPrefix = "(241204)";
 }