xiatian 1 年之前
父節點
當前提交
c98ec7be77

+ 160 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/DebugService.java

@@ -0,0 +1,160 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.bson.types.ObjectId;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import cn.com.qmth.dp.examcloud.oe.entity.question.PaperDetailUnit;
+import cn.com.qmth.dp.examcloud.oe.entity.question.QuesOption;
+import cn.com.qmth.dp.examcloud.oe.entity.question.Question;
+
+@Service
+public class DebugService {
+    
+
+
+    public static final String QUESOPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    public static final String ELEMENT_TYPE_RID = "imageId";
+
+    public static final String ELEMENT_TYPE_TEXT = "text";
+
+    public static final String ELEMENT_TYPE_IMG = "image";
+    
+    public static final String ELEMENT_TYPE_DOCTAG = "doctag";
+
+
+	@Autowired
+	MongoTemplate mongoTemplate;
+
+	public void start() {
+		Query query = new Query();
+		query.addCriteria(Criteria.where("paper.$id").is(new ObjectId("64ddd05a391d2033f36b0a20")));
+		List<PaperDetailUnit> ps = mongoTemplate.find(query, PaperDetailUnit.class, "paperDetailUnit");
+		ExportPaperUtil.disposePaperDoc(ps);
+//		for(PaperDetailUnit p:ps) {
+//			disposeQuestion(p.getQuestion());
+//		}
+	}
+	
+	private static void disposeQuestion(Question qes) {
+        if (qes != null) {
+
+            //处理选项
+            if (qes.getQuesOptions() != null && qes.getQuesOptions().size() > 0) {
+                int index = 0;
+                for (QuesOption qo : qes.getQuesOptions()) {
+                    List<JSection> slist2 = getSections(qo.getOptionBody());
+                    if (slist2 != null && slist2.size() > 0) {
+                        SectionElement se = new SectionElement();
+                        se.setType(ELEMENT_TYPE_TEXT);
+                        se.setValue(QUESOPS.charAt(index) + ".");
+                        index++;
+                        slist2.get(0).getElements().add(0, se);
+//                        qo.setOptionBodyWord(getQuestionDoc(slist2));
+                    }else {
+                    	System.out.println("******");
+                    }
+
+                }
+            }
+            
+            if (qes.getSubQuestions() != null && qes.getSubQuestions().size() > 0) {
+                for (Question sunqes : qes.getSubQuestions()) {
+                    disposeQuestion(sunqes);// 递归处理套题
+                }
+            }
+        }
+    }
+	private static List<JSection> getSections(String html) {
+        return getSections(html, false);
+    }
+
+    private static List<JSection> getSections(String html, boolean diposeFillBlank) {
+        if (StringUtils.isBlank(html)) {
+            return getEmptySections();
+        }
+        html = html.trim();
+        if (!html.startsWith("<p>")) {
+            html = "<p>" + html + "</p>";
+        }
+        List<JSection> ss = new ArrayList<JSection>();
+        Document doc = Jsoup.parse(html);
+        Element b = doc.body();
+        for (Node e : b.childNodes()) {
+            if ("p".equals(e.nodeName()) && e.childNodeSize() > 0) {
+                JSection s = new JSection();
+                List<SectionElement> ses = new ArrayList<SectionElement>();
+                s.setElements(ses);
+                for (Node ce : e.childNodes()) {
+                    getSectionElement(ce, ses, diposeFillBlank);
+                }
+                ss.add(s);
+            }
+        }
+        return ss;
+
+    }
+    
+    private static List<JSection> getEmptySections(){
+    	List<JSection> ss = new ArrayList<JSection>();
+    	JSection s = new JSection();
+        List<SectionElement> ses = new ArrayList<SectionElement>();
+        s.setElements(ses);
+        SectionElement se=new SectionElement();
+        se.setType(ELEMENT_TYPE_TEXT);
+        se.setValue("");
+        ses.add(se);
+        ss.add(s);
+        return ss;
+    }
+
+    private static void getSectionElement(Node ce, List<SectionElement> ses, boolean diposeFillBlank) {
+        if ("span".equals(ce.nodeName()) && ce.childNodeSize() > 0) {
+            for (Node e : ce.childNodes()) {
+                getSectionElement(e, ses, diposeFillBlank);
+            }
+        } else {
+            if (ce instanceof TextNode) {
+            	SectionElement se = new SectionElement();
+                TextNode tn = (TextNode) ce;
+                se.setType(ELEMENT_TYPE_TEXT);
+                String text = tn.text();
+                if (diposeFillBlank) {
+                    text = text.replaceAll("###", "______").replaceAll("##", "______");
+                }
+                text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\u0000", " ");
+                se.setValue(text);
+                ses.add(se);
+            } else if (ce instanceof Element) {
+            	SectionElement se = new SectionElement();
+                if ("img".equals(ce.nodeName())) {
+                    se.setType(ELEMENT_TYPE_IMG);
+                    se.setValue(ce.attr("src"));
+//                    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);
+                    se.setValue(el.text());
+                }
+                ses.add(se);
+            }
+        }
+    }
+
+}

+ 343 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/ExportPaperUtil.java

@@ -0,0 +1,343 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.imageio.ImageIO;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.nodes.TextNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.dp.examcloud.oe.entity.question.PaperDetailUnit;
+import cn.com.qmth.dp.examcloud.oe.entity.question.QuesOption;
+import cn.com.qmth.dp.examcloud.oe.entity.question.Question;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import sun.misc.BASE64Decoder;
+
+public class ExportPaperUtil {
+	private static final Logger log = LoggerFactory.getLogger(ExportPaperUtil.class);
+	private static final int docImageSzie = 12700;
+
+	private static final String DOCX_SUFFIX = ".docx";
+
+	private static final String ZIP_SUFFIX = ".zip";
+
+	public static final String QUESOPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+	public static final String ELEMENT_TYPE_RID = "imageId";
+
+	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";
+
+	private static Pattern heightRex = Pattern.compile("height:([\\s\\S]*?)px");
+
+	private static Pattern widthRex = Pattern.compile("width:([\\s\\S]*?)px");
+
+	public static void disposePaperDoc(List<PaperDetailUnit> ps){
+		ExportTempDataDto dto = new ExportTempDataDto();
+		for (PaperDetailUnit pdue : ps) {
+			Question qes = pdue.getQuestion();
+			disposePaperQuestion(qes, dto);
+		}
+
+	}
+
+	private static void disposePaperQuestion(Question qes, ExportTempDataDto dto) {
+		if (qes != null) {
+			// 处理题干
+			List<JSection> slist1 = getSections(qes.getQuesBody(), true);
+			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(qes.getQuestionSeq() + ".");
+				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();
+				List<JOption> ops = new ArrayList<JOption>();
+				joDto.setOptions(ops);
+				for (QuesOption qo : qes.getQuesOptions()) {
+					List<JSection> slist2 = getSections(qo.getOptionBody());
+					if (slist2 != null && slist2.size() > 0) {
+						SectionElement se = new SectionElement();
+						se.setType(ELEMENT_TYPE_TEXT);
+						se.setValue(QUESOPS.charAt(index) + ".");
+						index++;
+						slist2.get(0).getElements().add(0, se);
+						htmlToDoc(slist2, dto);
+						JOption jo = new JOption();
+						jo.setJsections(slist2);
+						ops.add(jo);
+					}
+				}
+//                disposeQuesOptions(joDto);// 处理选项列数
+//                qes.setQuesOptionsWord(getPaperQuestionDoc(joDto.getOptions()));
+			}
+
+			// 处理答案
+			if (qes.getSubQuestions() == null || qes.getSubQuestions().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(qes.getQuestionSeq() + ".");
+				slist3.get(0).getElements().add(0, se);
+
+				htmlToDoc(slist3, dto);
+//                qes.setQuesAnswerWord(getQuestionDoc(slist3));
+			}
+
+			if (qes.getSubQuestions() != null && qes.getSubQuestions().size() > 0) {
+				for (Question sunqes : qes.getSubQuestions()) {
+					disposePaperQuestion(sunqes, dto);// 递归处理套题
+				}
+			}
+		}
+	}
+
+	private static void htmlToDoc(List<JSection> slist, ExportTempDataDto dto) {
+		for (JSection js : slist) {
+			for (SectionElement se : js.getElements()) {
+				if (ELEMENT_TYPE_IMG.equals(se.getType())) {
+					dto.setIndex(dto.getIndex() + 1);
+					se.getParam().setIndex(dto.getIndex());
+					se.getParam().setRid(ELEMENT_TYPE_RID + dto.getIndex());
+					se.getParam().setType(getImageType(se.getValue()));
+					dto.getTypes().add(se.getParam().getType());
+					dto.getImages().add(se);
+				}
+			}
+		}
+	}
+
+	private static String getImageType(String src) {
+		if (src.contains("data:image")) {
+			return src.substring(11, src.indexOf(";"));
+		} else {
+			try {
+				URL url = new URL(src);
+				return url.getPath().substring(url.getPath().lastIndexOf(".") + 1);
+			} catch (MalformedURLException e) {
+				throw new StatusException("1000", "图片链接格式错误:" + src);
+			}
+		}
+	}
+
+	private static List<JSection> getSections(String html) {
+		return getSections(html, false);
+	}
+
+	private static List<JSection> getSections(String html, boolean diposeFillBlank) {
+		if (StringUtils.isBlank(html)) {
+			return getEmptySections();
+		}
+		html = html.trim();
+		if (!html.startsWith("<p>")) {
+			html = "<p>" + html + "</p>";
+		}
+		List<JSection> ss = new ArrayList<JSection>();
+		Document doc = Jsoup.parse(html);
+		Element b = doc.body();
+		for (Node e : b.childNodes()) {
+			if ("p".equals(e.nodeName()) && e.childNodeSize() > 0) {
+				JSection s = new JSection();
+				List<SectionElement> ses = new ArrayList<SectionElement>();
+				s.setElements(ses);
+				for (Node ce : e.childNodes()) {
+					getSectionElement(ce, ses, diposeFillBlank);
+				}
+				ss.add(s);
+			}
+		}
+		return ss;
+
+	}
+
+	private static List<JSection> getEmptySections() {
+		List<JSection> ss = new ArrayList<JSection>();
+		JSection s = new JSection();
+		List<SectionElement> ses = new ArrayList<SectionElement>();
+		s.setElements(ses);
+		SectionElement se = new SectionElement();
+		se.setType(ELEMENT_TYPE_TEXT);
+		se.setValue("");
+		ses.add(se);
+		ss.add(s);
+		return ss;
+	}
+
+	private static void getSectionElement(Node ce, List<SectionElement> ses, boolean diposeFillBlank) {
+		if ("span".equals(ce.nodeName()) && ce.childNodeSize() > 0) {
+			for (Node e : ce.childNodes()) {
+				getSectionElement(e, ses, diposeFillBlank);
+			}
+		} else {
+			if (ce instanceof TextNode) {
+				SectionElement se = new SectionElement();
+				TextNode tn = (TextNode) ce;
+				se.setType(ELEMENT_TYPE_TEXT);
+				String text = tn.text();
+				if (diposeFillBlank) {
+					text = text.replaceAll("###", "______").replaceAll("##", "______");
+				}
+				text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;")
+						.replaceAll("\u0000", " ");
+				se.setValue(text);
+				ses.add(se);
+			} else if (ce instanceof Element) {
+				SectionElement se = new SectionElement();
+				if ("img".equals(ce.nodeName())) {
+					se.setType(ELEMENT_TYPE_IMG);
+					se.setValue(ce.attr("src"));
+					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);
+					se.setValue(el.text());
+				}
+				ses.add(se);
+			}
+		}
+	}
+
+	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);
+
+	}
+
+	private static int getWidth(Node ce) {
+		int n = 0;
+		String str = ce.attr("width");
+		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.isNotBlank(style)) {
+			Matcher m = widthRex.matcher(style);
+			if (m.find()) {
+				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 = 0;
+		String str = ce.attr("height");
+		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.isNotBlank(style)) {
+			Matcher m = heightRex.matcher(style);
+			if (m.find()) {
+				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;
+	}
+
+}

+ 50 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/ExportTempDataDto.java

@@ -0,0 +1,50 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ExportTempDataDto {
+
+    private int mainNum = 0;
+
+    private int index = 0;
+
+    private Set<String> types = new HashSet<String>();
+
+    private List<SectionElement> images = new ArrayList<SectionElement>();
+
+    public int getIndex() {
+        return index;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+    public Set<String> getTypes() {
+        return types;
+    }
+
+    public void setTypes(Set<String> types) {
+        this.types = types;
+    }
+
+    public List<SectionElement> getImages() {
+        return images;
+    }
+
+    public void setImages(List<SectionElement> images) {
+        this.images = images;
+    }
+
+    public int getMainNum() {
+        return mainNum;
+    }
+
+    public void setMainNum(int mainNum) {
+        this.mainNum = mainNum;
+    }
+
+}

+ 27 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/JOption.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+import java.util.List;
+
+public class JOption {
+
+    private int cols = 1;
+
+    private List<JSection> jsections;
+
+    public List<JSection> getJsections() {
+        return jsections;
+    }
+
+    public void setJsections(List<JSection> jsections) {
+        this.jsections = jsections;
+    }
+
+    public int getCols() {
+        return cols;
+    }
+
+    public void setCols(int cols) {
+        this.cols = cols;
+    }
+
+}

+ 20 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/JOptionDto.java

@@ -0,0 +1,20 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+import java.util.List;
+
+public class JOptionDto {
+    List<JOption> options;
+
+    
+    public List<JOption> getOptions() {
+        return options;
+    }
+
+    
+    public void setOptions(List<JOption> options) {
+        this.options = options;
+    }
+
+    
+    
+}

+ 17 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/JSection.java

@@ -0,0 +1,17 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+import java.util.List;
+
+public class JSection {
+
+    List<SectionElement> elements;
+
+    public List<SectionElement> getElements() {
+        return elements;
+    }
+
+    public void setElements(List<SectionElement> elements) {
+        this.elements = elements;
+    }
+
+}

+ 38 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/SectionElement.java

@@ -0,0 +1,38 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+public class SectionElement {
+
+    private String type;
+
+    private String value;
+
+    private SectionElementParams param=new SectionElementParams();
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    
+    public SectionElementParams getParam() {
+        return param;
+    }
+
+    
+    public void setParam(SectionElementParams param) {
+        this.param = param;
+    }
+
+
+}

+ 65 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/debug/SectionElementParams.java

@@ -0,0 +1,65 @@
+package cn.com.qmth.dp.examcloud.oe.modules.debug;
+
+public class SectionElementParams {
+
+    private Integer width;
+
+    private Integer height;
+
+    private String rid;
+
+    private Integer index;
+
+    private String type;
+
+    private boolean tab = false;
+
+    public Integer getWidth() {
+        return width;
+    }
+
+    public void setWidth(Integer width) {
+        this.width = width;
+    }
+
+    public Integer getHeight() {
+        return height;
+    }
+
+    public void setHeight(Integer height) {
+        this.height = height;
+    }
+
+    public String getRid() {
+        return rid;
+    }
+
+    public void setRid(String rid) {
+        this.rid = rid;
+    }
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(Integer index) {
+        this.index = index;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public boolean isTab() {
+        return tab;
+    }
+
+    public void setTab(boolean tab) {
+        this.tab = tab;
+    }
+
+}

二進制
src/main/resources/subject_codes.xlsx