xiatian 1 ano atrás
pai
commit
81ce30e681

+ 49 - 0
src/main/java/cn/com/qmth/export/DetailDto3.java

@@ -0,0 +1,49 @@
+package cn.com.qmth.export;
+
+public class DetailDto3 {
+	private String typeId;
+	private String typeName;
+	
+	
+	public DetailDto3(String typeId, String typeName) {
+		super();
+		this.typeId = typeId;
+		this.typeName = typeName;
+	}
+	public String getTypeId() {
+		return typeId;
+	}
+	public void setTypeId(String typeId) {
+		this.typeId = typeId;
+	}
+	public String getTypeName() {
+		return typeName;
+	}
+	public void setTypeName(String typeName) {
+		this.typeName = typeName;
+	}
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((typeName == null) ? 0 : typeName.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		DetailDto3 other = (DetailDto3) obj;
+		if (typeName == null) {
+			if (other.typeName != null)
+				return false;
+		} else if (!typeName.equals(other.typeName))
+			return false;
+		return true;
+	}
+	
+}

+ 64 - 0
src/main/java/cn/com/qmth/export/GkExportPaperByCourseCode4.java

@@ -0,0 +1,64 @@
+package cn.com.qmth.export;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+/**moodle按属性分试卷
+ * @author Administrator
+ *
+ */
+public class GkExportPaperByCourseCode4 {
+	private static Logger logger = LogManager.getLogger(GkExportPaperByCourseCode4.class);
+	//试卷后缀
+	private static String paperSuff = "(240524)";
+	//数据库名
+	private static String dbName="guangkai_mdl";
+	private static AtomicInteger count=new AtomicInteger(0);
+	
+	private static AtomicInteger valid=new AtomicInteger(0);
+	
+	private static AtomicInteger imgValid=new AtomicInteger(0);
+	
+	private static AtomicInteger rectify=new AtomicInteger(0);
+	
+	public static void main(String[] args) {
+		logger.debug("导出开始");
+		Date start=new Date();
+		try {
+			MyProducer4 pro=new MyProducer4();
+			Map<String, Object> param=new HashMap<>();
+			param.put("paperSuff", paperSuff);
+			param.put("dbName", dbName);
+			pro.startDispose(MyConsumer4.class, 8, param);
+		} catch (Exception e) {
+			logger.error(e.getCause(), e);
+		}
+		logger.debug("导出结束,纠正:"+rectify);
+		logger.debug("导出结束,舍弃:"+valid);
+		logger.debug("导出结束,(图片)舍弃:"+imgValid);
+		Date end=new Date();
+		logger.debug("导出结束,耗时:"+((end.getTime()-start.getTime())/1000));
+	}
+
+
+	public static void  addDisposeCount() {
+		count.addAndGet(1);
+		logger.debug("处理了"+count);
+	}
+	
+	public static void  addRectify() {
+		rectify.addAndGet(1);
+	}
+	public static void  addValid() {
+		valid.addAndGet(1);
+	}
+	
+	public static void  addImgValid() {
+		imgValid.addAndGet(1);
+	}
+}

+ 440 - 0
src/main/java/cn/com/qmth/export/MyConsumer4.java

@@ -0,0 +1,440 @@
+package cn.com.qmth.export;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.alibaba.fastjson.JSONObject;
+
+public class MyConsumer4 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 = 200000;
+
+	private static String paperDir = "d:/guangkai/paper/";
+	private static String imgDir = "d:/guangkai/files/";
+
+	private static Pattern imgPat = Pattern.compile("<img[^<]+src=['\"]([^<\"]+)['\"][^<]*>");
+	
+//	private Pattern xieGangPat = Pattern.compile("\\\\([^\"]|(\",))");
+
+	@Override
+	public void consume(PaperExportDto dto) {
+		Connection connect = null;
+		File sub = new File(paperDir + dto.getCourseCode() + "/");
+		sub.mkdir();
+		try {
+			Class.forName("com.mysql.cj.jdbc.Driver");
+
+			String url = "jdbc:mysql://localhost:3306/" + dto.getDbName() + "?serverTimezone=GMT%2B8";
+
+			String user = "root";
+
+			String password = "123456";
+			connect = DriverManager.getConnection(url, user, password);
+			exportPaper(connect, dto);
+			GkExportPaperByCourseCode.addDisposeCount();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		} finally {
+			if (connect != null) {
+				try {
+					connect.close();
+				} catch (SQLException e) {
+				}
+			}
+		}
+	}
+
+	private List<KdQuestion> of(List<QuestionVo4> vos) {
+		List<KdQuestion> ret = new ArrayList<>();
+		for (QuestionVo4 vo : vos) {
+			try {
+				KdQuestion q = of(vo);
+				ret.add(q);
+			} catch (StatusException e) {
+				GkExportPaperByCourseCode.addValid();
+				continue;
+			}
+		}
+		return ret;
+	}
+
+
+
+	private KdQuestion of(QuestionVo4 vo) {
+		KdQuestion q = new KdQuestion();
+		q.setPropIds(new ArrayList<>());
+		q.getPropIds().add(vo.getCategory());
+		q.setQuesStructType(QuesStructType.getQuesStructTypeById(vo.getqType().getTypeId()));
+		q.setBody(vo.getBody());
+		q.setDifficultyDegree(0.5);
+		q.setHaveAudio(false);
+		q.setId(vo.getQid().toString());
+		q.setScore(1.0);
+		q.setDetailName(vo.getCategoryName());
+		return q;
+	}
+
+	private List<QuestionVo4> getQuestion(Connection connect, String courseCode) throws SQLException, IOException {
+		List<QuestionVo4> qs = new ArrayList<>();
+		PreparedStatement preState = null;
+		ResultSet resultSet = null;
+		try {
+			String sql = " select q.*,qc.name categoryName from mdl_course c "
+					+" inner join mdl_context ct on ct.instanceid=c.id "
+					+" inner join mdl_question_categories qc on qc.contextid=ct.id "
+					+" inner join mdl_question q on q.category=qc.id "
+					+" where c.idnumber='"+courseCode+"' and q.qtype in('multichoice','multichoiceset','truefalse') "
+					+" and q.parent=0 ";
+
+			preState = connect.prepareStatement(sql);
+
+			resultSet = preState.executeQuery();
+
+			while (resultSet.next()) {
+				QuestionVo4 q = new QuestionVo4();
+				q.setQid(resultSet.getLong("id"));
+				q.setPid(resultSet.getLong("parent"));
+				q.setCategory(resultSet.getLong("category"));
+				q.setCategoryName(resultSet.getString("categoryName"));
+				q.setqType(CusQuesStructType3.valueOf(resultSet.getString("qType")));
+				q.setBody(resultSet.getString("questiontext"));
+				qs.add(q);
+			}
+			return qs;
+		} finally {
+			if (resultSet != null) {
+				resultSet.close();
+			}
+			if (preState != null) {
+				preState.close();
+			}
+		}
+	}
+	
+	
+//	public static void main(String[] args) {
+//		String s="a\"\\\",b\\h";
+//		System.out.println(s);
+//		System.out.println(fomat(s));
+//	}
+	
+	
+
+	private void disposeQuestionImg(Connection connect,String courseCode,KdQuestion q) throws NumberFormatException, SQLException {
+		q.setBody(disposeImg(connect, courseCode, "questiontext", q.getBody(), Long.valueOf(q.getId())));
+		if (CollectionUtils.isNotEmpty(q.getOptions())) {
+			for (KdQuesOption o : q.getOptions()) {
+				o.setBody(disposeImg(connect, courseCode, "answer", o.getBody(), Long.valueOf(o.getId())));
+			}
+		}
+	}
+
+	private String disposeImg(Connection connect,String courseCode,String filearea,String str, Long itemId) throws SQLException {
+		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.startsWith("data:image/")) {
+
+			} else if (imgSrc.startsWith("@@PLUGINFILE@@")) {
+				if (srcMap.get(imgSrc) == null) {
+					File img = getImage(connect, imgSrc, courseCode, itemId, filearea);
+					String base64 = FileUtil.fileToBase64Src(img);
+					srcMap.put(imgSrc, base64);
+				}
+			}else {
+				throw new StatusException("图片有误:" + itemId);
+			}
+		}
+		for (String imgSrc : srcMap.keySet()) {
+			str = str.replaceAll(imgSrc.replaceAll("\\?", "\\\\?"), srcMap.get(imgSrc));
+		}
+		return str;
+	}
+	
+	
+	
+	private File getImage(Connection connect,String imgSrc,String courseCode,Long itemId,String filearea) throws SQLException {
+		String fileName=getFileName(imgSrc);
+		PreparedStatement preState = null;
+		ResultSet resultSet = null;
+		try {
+			String hash = null;
+			int count=0;
+			String sql = " select * from mdl_files where itemid = " + itemId + " and source='" + fileName
+					+ "' and component = 'question' and filearea = '"+filearea+"' ";
+			preState = connect.prepareStatement(sql);
+
+			resultSet = preState.executeQuery();
+
+			while (resultSet.next()) {
+				count++;
+				hash = resultSet.getString("contenthash");
+			}
+			if(count!=1) {
+				throw new StatusException("图片有误:" + itemId+filearea);
+			}
+			String suff = fileName.substring(fileName.lastIndexOf("."));
+			File file = new File(imgDir + courseCode + "/" + hash + suff);
+			if (!file.exists()) {
+				throw new StatusException("图片有误:" + itemId+filearea);
+			}
+			return file;
+		} finally {
+			if (resultSet != null) {
+				resultSet.close();
+			}
+			if (preState != null) {
+				preState.close();
+			}
+		}
+	}
+	private String getFileName(String s) {
+		int end = s.length();
+		int f = s.indexOf("?");
+		if (f != -1) {
+			end = f;
+		}
+		try {
+			return URLDecoder.decode(s.substring(s.lastIndexOf("/") + 1, end), "utf-8");
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	private void exportPaper(Connection connect, PaperExportDto dto) throws Exception {
+		List<QuestionVo4> vos = getQuestion(connect, dto.getCourseCode());
+		if (CollectionUtils.isEmpty(vos)) {
+			return;
+		}
+		List<KdQuestion> qs = of(vos);
+		fillAnswer(connect, qs, dto.getCourseCode());
+
+		Map<DetailDto3, List<KdQuestion>> qmap = new HashMap<>();
+		for (KdQuestion q : qs) {
+			if(q.isValid()) {
+				DetailDto3 tem=new DetailDto3(null, q.getDetailName());
+				List<KdQuestion> list = qmap.get(tem);
+				if (list == null) {
+					tem.setTypeId(UUID.randomUUID().toString());
+					list = new ArrayList<>();
+					qmap.put(tem, list);
+				}
+				list.add(q);
+			}
+		}
+		for (DetailDto3 qt : qmap.keySet()) {
+			createPapers(qmap.get(qt), qt, dto);
+		}
+	}
+
+	private void fillAnswer(Connection connect, List<KdQuestion> qs, String courseCode) throws NumberFormatException, SQLException {
+		List<Answer> qps = new BatchGetDataUtil<Answer, KdQuestion>() {
+
+			@Override
+			protected List<Answer> getData(List<KdQuestion> paramList) {
+				return getAnswerBatch(connect, paramList);
+			}
+		}.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) {
+			try {
+				List<Answer> as=map.get(Long.valueOf(q.getId()));
+				if (CollectionUtils.isEmpty(as)) {
+					throw new StatusException("没有答案:"+q.getId());
+				}
+				if (QuesStructType.SINGLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
+					List<KdQuesOption> options = new ArrayList<>();
+					q.setOptions(options);
+					int num = 0;
+					int answerCount = 0;
+					for (Answer a : as) {
+						num++;
+						KdQuesOption o = new KdQuesOption();
+						options.add(o);
+						o.setId(a.getaId());
+						o.setNumber(num);
+						o.setBody(a.getBody());
+						o.setSelect(a.getFraction()>0);
+						if (o.getSelect()) {
+							answerCount++;
+						}
+					}
+					if (answerCount == 0) {
+						throw new StatusException("没有答案:"+q.getId());
+					}
+					if (answerCount > 1) {
+						q.setQuesStructType(QuesStructType.MULTIPLE_ANSWER_QUESTION);
+					}
+				} else if (QuesStructType.BOOL_ANSWER_QUESTION.equals(q.getQuesStructType())) {
+					for (Answer a : as) {
+						if (a.getFraction() > 0) {
+							q.setAnswer("对".equals(a.getBody().trim()) ? "正确" : "错误");
+							break;
+						}
+					}
+					if(StringUtils.isBlank(q.getAnswer())) {
+						throw new StatusException("答案有误:"+q.getId());
+					}
+				} else {
+					throw new StatusException("题型有误:"+q.getId());
+				}
+			}catch (StatusException e) {
+				GkExportPaperByCourseCode3.addValid();
+				q.setValid(false);
+				continue;
+			}
+			try {
+				disposeQuestionImg(connect, courseCode, q);
+			} catch (StatusException e) {
+				GkExportPaperByCourseCode3.addImgValid();
+				q.setValid(false);
+				continue;
+			}
+		}
+		
+	}
+
+
+
+
+	private List<Answer> getAnswerBatch(Connection connect, List<KdQuestion> qs) {
+		List<Answer> as = new ArrayList<>();
+		List<Long> ids = qs.stream().map(e -> Long.valueOf(e.getId())).collect(Collectors.toList());
+		String idsstr = StringUtils.join(ids, ",");
+		PreparedStatement preState = null;
+		ResultSet resultSet = null;
+		try {
+			String sql = " select t.id,t.question,t.answer,t.fraction  from mdl_question_answers t "
+					+ " where t.question in (" + idsstr + ")  ";
+			preState = connect.prepareStatement(sql);
+
+			resultSet = preState.executeQuery();
+
+			while (resultSet.next()) {
+				Answer a = new Answer();
+				a.setBody(resultSet.getString("answer"));
+				a.setFraction(resultSet.getDouble("fraction"));
+				a.setQuestionId(resultSet.getLong("question"));
+				a.setaId(resultSet.getLong("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 createPapers(List<KdQuestion> qs, DetailDto3 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, DetailDto3 qt, PaperExportDto dto, int indx) {
+		if (qs.size() == 0) {
+			return;
+		}
+		double score = 0.0;
+		int unit = 0;
+		for (KdQuestion q : qs) {
+			if (CollectionUtils.isNotEmpty(q.getSubQuestions())) {
+				unit = unit + q.getSubQuestions().size();
+			} else {
+				unit++;
+			}
+			score = Calculator.add(score, q.getScore(), 1);
+		}
+		String detailName = qt.getTypeName();
+		KdPaper paper = new KdPaper();
+		paper.setDetailCount(1);
+		paper.setUnitCount(unit);
+		paper.setTotalScore(score);
+		paper.setName(dto.getPaperSuff() + detailName + "_" + indx);
+		paper.setCourseCode(dto.getCourseCode());
+		List<KdDetail> des = new ArrayList<>();
+		KdDetail d = new KdDetail();
+		d.setName(detailName);
+		d.setNumber(1);
+		d.setQuestionCount(unit);
+		d.setTotalScore(score);
+		d.setQuestions(qs);
+		des.add(d);
+		paper.setDetails(des);
+		paper.setDetailCount(1);
+		paper.setUnitCount(qs.size());
+		File paperdir = new File(paperDir + dto.getCourseCode() + "/" + qt.getTypeId() + "/");
+		paperdir.mkdirs();
+		try {
+			FileUtil.writeFile(paperdir.getAbsolutePath(), "/paper_" + indx + ".json", JSONObject.toJSONString(paper));
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public void initResult() {
+
+	}
+}

+ 75 - 0
src/main/java/cn/com/qmth/export/MyProducer4.java

@@ -0,0 +1,75 @@
+package cn.com.qmth.export;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.Map;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+
+public class MyProducer4 extends Producer {
+	private static Logger logger = LogManager.getLogger(MyProducer4.class);
+	private static String dir = "d:/guangkai/";
+	private static String paperDir = "d:/guangkai/paper/";
+
+	@Override
+	protected void produce(Map<String, Object> param) throws Exception {
+		logger.info("***************************任务生产开始");
+		String paperSuff = (String)param.get("paperSuff");
+		String dbName = (String)param.get("dbName");
+		File excelFolder = new File(paperDir);
+		if (excelFolder.exists()) {
+			FileUtil.clearDirectory(paperDir);
+		} else {
+			excelFolder.mkdirs();
+		}
+		LinkedHashSet<String> cs = readSubject();
+		if (CollectionUtils.isEmpty(cs)) {
+			logger.debug("无数据导出");
+			return;
+		} else {
+			logger.debug(cs.size() + "个课程");
+		}
+		for (String c : cs) {
+			offer(new PaperExportDto(c, paperSuff,dbName));
+		}
+		logger.info("***************************任务生产结束");
+	}
+	
+	
+	private static LinkedHashSet<String> readSubject() {
+		LinkedHashSet<String> list = new LinkedHashSet<>();
+		XSSFWorkbook wb = null;
+		try {
+			wb = new XSSFWorkbook(dir + "subject_info.xlsx");
+			XSSFSheet sheet = wb.getSheetAt(0);
+			int rows = sheet.getLastRowNum();
+			for (int i = 1; i <= rows; i++) {
+				XSSFRow row = sheet.getRow(i);
+				String yunkaiCode;
+				try {
+					yunkaiCode = row.getCell(1).getStringCellValue().trim();
+				} catch (Exception e) {
+					yunkaiCode = (row.getCell(1).getNumericCellValue()+"").trim();
+				}
+				list.add(yunkaiCode);
+			}
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		} finally {
+			if (wb != null) {
+				try {
+					wb.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+		return list;
+	}
+}

+ 48 - 0
src/main/java/cn/com/qmth/export/QuestionVo4.java

@@ -0,0 +1,48 @@
+package cn.com.qmth.export;
+
+public class QuestionVo4 {
+	private Long qid;
+	private Long pid;
+	private CusQuesStructType3 qType;
+	private String body;
+	private Long category;
+	private String categoryName;
+	public Long getQid() {
+		return qid;
+	}
+	public void setQid(Long qid) {
+		this.qid = qid;
+	}
+	public Long getPid() {
+		return pid;
+	}
+	public void setPid(Long pid) {
+		this.pid = pid;
+	}
+	public CusQuesStructType3 getqType() {
+		return qType;
+	}
+	public void setqType(CusQuesStructType3 qType) {
+		this.qType = qType;
+	}
+	public String getBody() {
+		return body;
+	}
+	public void setBody(String body) {
+		this.body = body;
+	}
+	public Long getCategory() {
+		return category;
+	}
+	public void setCategory(Long category) {
+		this.category = category;
+	}
+	public String getCategoryName() {
+		return categoryName;
+	}
+	public void setCategoryName(String categoryName) {
+		this.categoryName = categoryName;
+	}
+
+
+}