|
@@ -0,0 +1,435 @@
|
|
|
+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.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 MyConsumer3 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<QuestionVo3> vos) {
|
|
|
+ List<KdQuestion> ret = new ArrayList<>();
|
|
|
+ for (QuestionVo3 vo : vos) {
|
|
|
+ try {
|
|
|
+ KdQuestion q = of(vo);
|
|
|
+ ret.add(q);
|
|
|
+ } catch (StatusException e) {
|
|
|
+ GkExportPaperByCourseCode.addValid();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private KdQuestion of(QuestionVo3 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);
|
|
|
+ return q;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<QuestionVo3> getQuestion(Connection connect, String courseCode) throws SQLException, IOException {
|
|
|
+ List<QuestionVo3> qs = new ArrayList<>();
|
|
|
+ PreparedStatement preState = null;
|
|
|
+ ResultSet resultSet = null;
|
|
|
+ try {
|
|
|
+ String sql = " select q.* 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()) {
|
|
|
+ QuestionVo3 q = new QuestionVo3();
|
|
|
+ q.setQid(resultSet.getLong("id"));
|
|
|
+ q.setPid(resultSet.getLong("parent"));
|
|
|
+ q.setCategory(resultSet.getLong("category"));
|
|
|
+ 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<QuestionVo3> vos = getQuestion(connect, dto.getCourseCode());
|
|
|
+ if (CollectionUtils.isEmpty(vos)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<KdQuestion> qs = of(vos);
|
|
|
+ fillAnswer(connect, qs, dto.getCourseCode());
|
|
|
+
|
|
|
+ Map<QuesStructType, List<KdQuestion>> qmap = new HashMap<>();
|
|
|
+ for (KdQuestion q : qs) {
|
|
|
+ if(q.isValid()) {
|
|
|
+ List<KdQuestion> list = qmap.get(q.getQuesStructType());
|
|
|
+ if (list == null) {
|
|
|
+ list = new ArrayList<>();
|
|
|
+ qmap.put(q.getQuesStructType(), list);
|
|
|
+ }
|
|
|
+ list.add(q);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (QuesStructType 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, QuesStructType 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, QuesStructType 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.getName();
|
|
|
+ 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.getId() + "/");
|
|
|
+ paperdir.mkdirs();
|
|
|
+ try {
|
|
|
+ FileUtil.writeFile(paperdir.getAbsolutePath(), "/paper_" + indx + ".json", JSONObject.toJSONString(paper));
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void initResult() {
|
|
|
+
|
|
|
+ }
|
|
|
+}
|