|
@@ -23,475 +23,478 @@ import com.alibaba.fastjson.JSONException;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
|
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 static String paperDir = "d:/guangkai/paper/";
|
|
|
- private static String imgDir = "d:/guangkai";
|
|
|
-
|
|
|
- private 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<QuestionVo> vos, List<QuestionVo> subvosList) {
|
|
|
- List<KdQuestion> ret = new ArrayList<>();
|
|
|
- Map<String, List<QuestionVo>> submap = new HashMap<>();
|
|
|
- if (CollectionUtils.isNotEmpty(subvosList)) {
|
|
|
- for (QuestionVo vo : subvosList) {
|
|
|
- List<QuestionVo> tem = submap.get(vo.getPid());
|
|
|
- if (tem == null) {
|
|
|
- tem = new ArrayList<>();
|
|
|
- submap.put(vo.getPid(), tem);
|
|
|
- }
|
|
|
- tem.add(vo);
|
|
|
- }
|
|
|
- }
|
|
|
- for (QuestionVo vo : vos) {
|
|
|
- try {
|
|
|
- KdQuestion q = of(vo);
|
|
|
- if (QuesStructType.NESTED_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- List<QuestionVo> subvos = submap.get(q.getId());
|
|
|
- q.setScore((double) subvos.size());
|
|
|
- List<Double> subScores = new ArrayList<>();
|
|
|
- List<KdQuestion> subQues = new ArrayList<>();
|
|
|
- q.setSubScores(subScores);
|
|
|
- q.setSubQuestions(subQues);
|
|
|
- int num = 0;
|
|
|
- for (QuestionVo subvo : subvos) {
|
|
|
- num++;
|
|
|
- subScores.add(1.0);
|
|
|
- KdQuestion subq = of(subvo);
|
|
|
- subq.setId(null);
|
|
|
- if (CusQuesStructType.cloze.equals(q.getCusType()) && StringUtils.isBlank(subq.getBody())) {
|
|
|
- subq.setBody("___" + num + "___");
|
|
|
- }
|
|
|
- subQues.add(subq);
|
|
|
- }
|
|
|
- }
|
|
|
- ret.add(q);
|
|
|
- } catch (StatusException e) {
|
|
|
- GkExportPaperByCourseCode.addValid();
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- private String changeBlank(String text, int answerCount,String qid) {
|
|
|
- StringBuffer buffer = new StringBuffer();
|
|
|
- String regex = "<fillblank/>";
|
|
|
-
|
|
|
- Pattern pattern = Pattern.compile(regex);
|
|
|
- Matcher matcher = pattern.matcher(text);
|
|
|
- // 使用find()方法查找匹配项
|
|
|
- int num = 0;
|
|
|
- while (matcher.find()) {
|
|
|
- num++;
|
|
|
- matcher.appendReplacement(buffer, "###");
|
|
|
- }
|
|
|
- matcher.appendTail(buffer);
|
|
|
- if (answerCount != num) {
|
|
|
- throw new StatusException("答案数不匹配:"+qid);
|
|
|
- }
|
|
|
- return buffer.toString();
|
|
|
- }
|
|
|
-
|
|
|
- private String changeCloze(String text) {
|
|
|
- StringBuffer buffer = new StringBuffer();
|
|
|
- String regex = "<fillblank/>";
|
|
|
-
|
|
|
- Pattern pattern = Pattern.compile(regex);
|
|
|
- Matcher matcher = pattern.matcher(text);
|
|
|
- // 使用find()方法查找匹配项
|
|
|
- int num = 0;
|
|
|
- while (matcher.find()) {
|
|
|
- num++;
|
|
|
- matcher.appendReplacement(buffer, "___" + num + "___");
|
|
|
- }
|
|
|
- matcher.appendTail(buffer);
|
|
|
- return buffer.toString();
|
|
|
- }
|
|
|
-
|
|
|
- private KdQuestion of(QuestionVo vo) {
|
|
|
- KdQuestion q = new KdQuestion();
|
|
|
- q.setCusType(vo.getqType());
|
|
|
- q.setQuesStructType(QuesStructType.getQuesStructTypeById(vo.getqType().getTypeId()));
|
|
|
- q.setTypeId(vo.getTypeId());
|
|
|
- q.setDetailName(vo.getTypeName());
|
|
|
- q.setBody(vo.getBody());
|
|
|
- q.setDifficultyDegree(0.5);
|
|
|
- q.setHaveAudio(false);
|
|
|
- q.setId(vo.getQid());
|
|
|
- q.setScore(1.0);
|
|
|
- if (QuesStructType.SINGLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- List<KdQuesOption> options = new ArrayList<>();
|
|
|
- q.setOptions(options);
|
|
|
- int num = 0;
|
|
|
- int answerCount = 0;
|
|
|
- for (String a : vo.getAnswer().getSubArea()) {
|
|
|
- num++;
|
|
|
- KdQuesOption o = new KdQuesOption();
|
|
|
- options.add(o);
|
|
|
- o.setNumber(num);
|
|
|
- o.setBody(a);
|
|
|
- o.setSelect(vo.getAnswer().getAnswer().contains("" + (num - 1)));
|
|
|
- if (o.getSelect()) {
|
|
|
- answerCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- if (answerCount == 0) {
|
|
|
- throw new StatusException("没有答案:"+q.getId());
|
|
|
- }
|
|
|
- if (answerCount > 1) {
|
|
|
- throw new StatusException("答案过多");
|
|
|
- }
|
|
|
- } else if (QuesStructType.MULTIPLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- List<KdQuesOption> options = new ArrayList<>();
|
|
|
- q.setOptions(options);
|
|
|
- int num = 0;
|
|
|
- int answerCount = 0;
|
|
|
- for (String a : vo.getAnswer().getSubArea()) {
|
|
|
- num++;
|
|
|
- KdQuesOption o = new KdQuesOption();
|
|
|
- options.add(o);
|
|
|
- o.setNumber(num);
|
|
|
- o.setBody(a);
|
|
|
- o.setSelect(vo.getAnswer().getAnswer().contains("" + (num - 1)));
|
|
|
- if (o.getSelect()) {
|
|
|
- answerCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- if (answerCount == 0) {
|
|
|
- throw new StatusException("没有答案");
|
|
|
- }
|
|
|
- if (answerCount > 10) {
|
|
|
- throw new StatusException("答案超过10个:" + vo.getQid());
|
|
|
- }
|
|
|
- } else if (QuesStructType.BOOL_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- if (vo.getAnswer().getAnswer().contains("0")) {
|
|
|
- q.setAnswer("正确");
|
|
|
- } else if (vo.getAnswer().getAnswer().contains("1")) {
|
|
|
- q.setAnswer("错误");
|
|
|
- } else {
|
|
|
- throw new StatusException("答案有误");
|
|
|
- }
|
|
|
- } else if (QuesStructType.FILL_BLANK_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- int aCount = 0;
|
|
|
- List<String> tem = new ArrayList<>();
|
|
|
- for (List<String> ss : vo.getfAnswer().getAnswer()) {
|
|
|
- for (String s : ss) {
|
|
|
- aCount++;
|
|
|
- tem.add(s);
|
|
|
- }
|
|
|
- }
|
|
|
- q.setAnswer(StringUtils.join(tem, "##"));
|
|
|
- q.setBody(changeBlank(q.getBody(), aCount,q.getId()));
|
|
|
- } else if (QuesStructType.TEXT_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- q.setAnswer(StringUtils.join(vo.getAnswer().getAnswer(), ""));
|
|
|
- } else if (QuesStructType.NESTED_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
- if (CusQuesStructType.cloze.equals(q.getCusType())) {
|
|
|
- q.setBody(changeCloze(q.getBody()));
|
|
|
- }
|
|
|
- } else {
|
|
|
- throw new StatusException("题型有误");
|
|
|
- }
|
|
|
- disposeQuestionImg(q);
|
|
|
- return q;
|
|
|
- }
|
|
|
-
|
|
|
- private List<QuestionVo> getQuestion(Connection connect, String courseCode) throws SQLException, IOException {
|
|
|
- List<QuestionVo> qs = new ArrayList<>();
|
|
|
- PreparedStatement preState = null;
|
|
|
- ResultSet resultSet = null;
|
|
|
- try {
|
|
|
- String sql = " select q.TYPE_ID typeId,f.name typeName,f.ANSWER_TYPE qType "
|
|
|
- + " ,q.ID qid,q.TITLE body,q.FATHER_ID pid " + " ,q.answer,q.SHOW_ORDER seq "
|
|
|
- + " from pe_question_bank t " + " INNER JOIN pe_questions q on t.id=q.BANK_ID "
|
|
|
- + " INNER JOIN pe_question_type f on f.id=q.TYPE_ID " + " where t.course_id='" + courseCode + "'";
|
|
|
-
|
|
|
- preState = connect.prepareStatement(sql);
|
|
|
-
|
|
|
- resultSet = preState.executeQuery();
|
|
|
-
|
|
|
- while (resultSet.next()) {
|
|
|
- QuestionVo q = new QuestionVo();
|
|
|
- q.setQid(resultSet.getString("qid"));
|
|
|
- q.setTypeId(resultSet.getString("typeId"));
|
|
|
- q.setTypeName(resultSet.getString("typeName"));
|
|
|
- q.setPid(resultSet.getString("pid"));
|
|
|
- q.setqType(CusQuesStructType.valueOf(resultSet.getString("qType")));
|
|
|
- q.setBody(resultSet.getString("body"));
|
|
|
- q.setSeq(resultSet.getInt("seq"));
|
|
|
- String an=resultSet.getString("answer");
|
|
|
- try {
|
|
|
- if (CusQuesStructType.fillblank.equals(q.getqType())) {
|
|
|
- q.setfAnswer(JSONObject.parseObject(an, FillBlankAnswerVo.class));
|
|
|
- } else {
|
|
|
- q.setAnswer(JSONObject.parseObject(an, AnswerVo.class));
|
|
|
- }
|
|
|
- } catch (JSONException e) {
|
|
|
- try {
|
|
|
- System.out.println("old#############qid:" + q.getQid()+" "+an);
|
|
|
- an=fomat(an);
|
|
|
- System.out.println("new#############qid:" + q.getQid()+" "+an);
|
|
|
- if (CusQuesStructType.fillblank.equals(q.getqType())) {
|
|
|
- q.setfAnswer(JSONObject.parseObject(an, FillBlankAnswerVo.class));
|
|
|
- } else {
|
|
|
- q.setAnswer(JSONObject.parseObject(an, AnswerVo.class));
|
|
|
- }
|
|
|
-
|
|
|
- GkExportPaperByCourseCode.addRectify();
|
|
|
- } catch (Exception e1) {
|
|
|
- GkExportPaperByCourseCode.addValid();
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
- qs.add(q);
|
|
|
- }
|
|
|
- return qs;
|
|
|
- } finally {
|
|
|
- if (resultSet != null) {
|
|
|
- resultSet.close();
|
|
|
- }
|
|
|
- if (preState != null) {
|
|
|
- preState.close();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private String fomat(String text) {
|
|
|
- StringBuffer buffer = new StringBuffer();
|
|
|
- Matcher matcher = xieGangPat.matcher(text);
|
|
|
- // 使用find()方法查找匹配项
|
|
|
- while (matcher.find()) {
|
|
|
- String tem=matcher.group(1);
|
|
|
- matcher.appendReplacement(buffer, "\\\\\\\\"+tem);
|
|
|
- }
|
|
|
- matcher.appendTail(buffer);
|
|
|
- return buffer.toString();
|
|
|
- }
|
|
|
-
|
|
|
-// public static void main(String[] args) {
|
|
|
-// String s="a\"\\\",b\\h";
|
|
|
-// System.out.println(s);
|
|
|
-// System.out.println(fomat(s));
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
- private List<QuestionVo> getSubQuestion(Connection connect, String courseCode, List<String> pids)
|
|
|
- throws SQLException, IOException {
|
|
|
- List<QuestionVo> qs = new ArrayList<>();
|
|
|
- if(CollectionUtils.isEmpty(pids)) {
|
|
|
- return qs;
|
|
|
- }
|
|
|
- PreparedStatement preState = null;
|
|
|
- ResultSet resultSet = null;
|
|
|
- try {
|
|
|
- String sql = " select f.name typeName,f.ANSWER_TYPE qType " + " ,q.ID qid,q.TITLE body,q.FATHER_ID pid "
|
|
|
- + " ,q.answer,q.SHOW_ORDER seq " + " from pe_questions q "
|
|
|
- + " INNER JOIN pe_question_type f on f.id=q.TYPE_ID " + " where q.FATHER_ID in ('"
|
|
|
- + StringUtils.join(pids, "','") + "') order by q.SHOW_ORDER";
|
|
|
-
|
|
|
- preState = connect.prepareStatement(sql);
|
|
|
-
|
|
|
- resultSet = preState.executeQuery();
|
|
|
-
|
|
|
- while (resultSet.next()) {
|
|
|
- QuestionVo q = new QuestionVo();
|
|
|
- q.setQid(resultSet.getString("qid"));
|
|
|
- q.setTypeName(resultSet.getString("typeName"));
|
|
|
- q.setPid(resultSet.getString("pid"));
|
|
|
- q.setqType(CusQuesStructType.valueOf(resultSet.getString("qType")));
|
|
|
- q.setBody(resultSet.getString("body"));
|
|
|
- q.setAnswer(JSONObject.parseObject(resultSet.getString("answer"), AnswerVo.class));
|
|
|
- q.setSeq(resultSet.getInt("seq"));
|
|
|
- qs.add(q);
|
|
|
- }
|
|
|
- return qs;
|
|
|
- } finally {
|
|
|
- if (resultSet != null) {
|
|
|
- resultSet.close();
|
|
|
- }
|
|
|
- if (preState != null) {
|
|
|
- preState.close();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void disposeQuestionImg(KdQuestion q) {
|
|
|
- q.setBody(disposeImg(q.getBody(), q.getId()));
|
|
|
- if (CollectionUtils.isNotEmpty(q.getOptions())) {
|
|
|
- for (KdQuesOption o : q.getOptions()) {
|
|
|
- o.setBody(disposeImg(o.getBody(), q.getId()));
|
|
|
- }
|
|
|
- }
|
|
|
- q.setAnswer(disposeImg(q.getAnswer(), q.getId()));
|
|
|
- }
|
|
|
-
|
|
|
- private String disposeImg(String str, String qid) {
|
|
|
- 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("/resourcefile/bdeditor")) {
|
|
|
- if (srcMap.get(imgSrc) == null) {
|
|
|
- File img = new File(imgDir + imgSrc);
|
|
|
- if (!img.exists()) {
|
|
|
- throw new StatusException("图片有误:" + qid);
|
|
|
- }
|
|
|
- String base64 = FileUtil.fileToBase64Src(img);
|
|
|
- srcMap.put(imgSrc, base64);
|
|
|
- }
|
|
|
- } else if (imgSrc.toLowerCase().trim().startsWith("http")) {
|
|
|
- if (srcMap.get(imgSrc) == null) {
|
|
|
- File img = new File(imgDir + "/" + UUID.randomUUID() + ".png");
|
|
|
- FileUtil.saveUrlAs(imgSrc, img.getAbsolutePath());
|
|
|
- String base64 = FileUtil.fileToBase64Src(img);
|
|
|
- img.delete();
|
|
|
- srcMap.put(imgSrc, base64);
|
|
|
- }
|
|
|
- } else if (imgSrc.toLowerCase().trim().startsWith("/formula")) {
|
|
|
- if (srcMap.get(imgSrc) == null) {
|
|
|
- File img = new File(imgDir + "/" + UUID.randomUUID() + ".png");
|
|
|
- FileUtil.saveUrlAs("https://ougd-exam.webtrn.cn" + imgSrc, img.getAbsolutePath());
|
|
|
- String base64 = FileUtil.fileToBase64Src(img);
|
|
|
- img.delete();
|
|
|
- srcMap.put(imgSrc, base64);
|
|
|
- }
|
|
|
- } else {
|
|
|
- throw new StatusException("图片有误:" + qid);
|
|
|
- }
|
|
|
- }
|
|
|
- for (String imgSrc : srcMap.keySet()) {
|
|
|
- str = str.replaceAll(imgSrc, srcMap.get(imgSrc));
|
|
|
- }
|
|
|
- return str;
|
|
|
- }
|
|
|
-
|
|
|
- private void exportPaper(Connection connect, PaperExportDto dto) throws Exception {
|
|
|
- List<QuestionVo> vos = getQuestion(connect, dto.getCourseCode());
|
|
|
- if (CollectionUtils.isEmpty(vos)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- List<String> pids = vos.stream().filter(e -> e.getqType().getTypeId() == 6).map(QuestionVo::getQid)
|
|
|
- .collect(Collectors.toList());
|
|
|
- List<QuestionVo> subvos = getSubQuestion(connect, dto.getCourseCode(), pids);
|
|
|
- List<KdQuestion> qs = of(vos, subvos);
|
|
|
-// fillProp(connect, qs);
|
|
|
-// fillAnswer(connect, qs, dto.getCourseCode());
|
|
|
-
|
|
|
- Map<DetailDto, List<KdQuestion>> qmap = new HashMap<>();
|
|
|
- for (KdQuestion q : qs) {
|
|
|
- DetailDto tem = new DetailDto(q.getTypeId(), q.getDetailName());
|
|
|
- List<KdQuestion> list = qmap.get(tem);
|
|
|
- if (list == null) {
|
|
|
- list = new ArrayList<>();
|
|
|
- qmap.put(tem, list);
|
|
|
- }
|
|
|
- list.add(q);
|
|
|
- }
|
|
|
- for (DetailDto qt : qmap.keySet()) {
|
|
|
- createPapers(qmap.get(qt), qt, dto);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void createPapers(List<KdQuestion> qs, DetailDto 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, DetailDto 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() {
|
|
|
-
|
|
|
- }
|
|
|
+
|
|
|
+ // private static String[] sucStr = new String[] { "对", "正确", "√", "是",
|
|
|
+ // "True" };
|
|
|
+ // private static String[] errStr = new String[] { "错", "错误", "×", "不正确",
|
|
|
+ // "否", "False" };
|
|
|
+ // private static String paperSuff = "(231205)";
|
|
|
+ private int maxqc = 200;
|
|
|
+
|
|
|
+ private static String paperDir = Param.dataDir + "paper/";
|
|
|
+
|
|
|
+ private static String imgDir = Param.dataDir;
|
|
|
+
|
|
|
+ private 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/" + Param.dbName + "?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<QuestionVo> vos, List<QuestionVo> subvosList) {
|
|
|
+ List<KdQuestion> ret = new ArrayList<>();
|
|
|
+ Map<String, List<QuestionVo>> submap = new HashMap<>();
|
|
|
+ if (CollectionUtils.isNotEmpty(subvosList)) {
|
|
|
+ for (QuestionVo vo : subvosList) {
|
|
|
+ List<QuestionVo> tem = submap.get(vo.getPid());
|
|
|
+ if (tem == null) {
|
|
|
+ tem = new ArrayList<>();
|
|
|
+ submap.put(vo.getPid(), tem);
|
|
|
+ }
|
|
|
+ tem.add(vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (QuestionVo vo : vos) {
|
|
|
+ try {
|
|
|
+ KdQuestion q = of(vo);
|
|
|
+ if (QuesStructType.NESTED_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ List<QuestionVo> subvos = submap.get(q.getId());
|
|
|
+ q.setScore((double) subvos.size());
|
|
|
+ List<Double> subScores = new ArrayList<>();
|
|
|
+ List<KdQuestion> subQues = new ArrayList<>();
|
|
|
+ q.setSubScores(subScores);
|
|
|
+ q.setSubQuestions(subQues);
|
|
|
+ int num = 0;
|
|
|
+ for (QuestionVo subvo : subvos) {
|
|
|
+ num++;
|
|
|
+ subScores.add(1.0);
|
|
|
+ KdQuestion subq = of(subvo);
|
|
|
+ subq.setId(null);
|
|
|
+ if (CusQuesStructType.cloze.equals(q.getCusType()) && StringUtils.isBlank(subq.getBody())) {
|
|
|
+ subq.setBody("___" + num + "___");
|
|
|
+ }
|
|
|
+ subQues.add(subq);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ret.add(q);
|
|
|
+ } catch (StatusException e) {
|
|
|
+ GkExportPaperByCourseCode.addValid();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String changeBlank(String text, int answerCount, String qid) {
|
|
|
+ StringBuffer buffer = new StringBuffer();
|
|
|
+ String regex = "<fillblank/>";
|
|
|
+
|
|
|
+ Pattern pattern = Pattern.compile(regex);
|
|
|
+ Matcher matcher = pattern.matcher(text);
|
|
|
+ // 使用find()方法查找匹配项
|
|
|
+ int num = 0;
|
|
|
+ while (matcher.find()) {
|
|
|
+ num++;
|
|
|
+ matcher.appendReplacement(buffer, "###");
|
|
|
+ }
|
|
|
+ matcher.appendTail(buffer);
|
|
|
+ if (answerCount != num) {
|
|
|
+ throw new StatusException("答案数不匹配:" + qid);
|
|
|
+ }
|
|
|
+ return buffer.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String changeCloze(String text) {
|
|
|
+ StringBuffer buffer = new StringBuffer();
|
|
|
+ String regex = "<fillblank/>";
|
|
|
+
|
|
|
+ Pattern pattern = Pattern.compile(regex);
|
|
|
+ Matcher matcher = pattern.matcher(text);
|
|
|
+ // 使用find()方法查找匹配项
|
|
|
+ int num = 0;
|
|
|
+ while (matcher.find()) {
|
|
|
+ num++;
|
|
|
+ matcher.appendReplacement(buffer, "___" + num + "___");
|
|
|
+ }
|
|
|
+ matcher.appendTail(buffer);
|
|
|
+ return buffer.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private KdQuestion of(QuestionVo vo) {
|
|
|
+ KdQuestion q = new KdQuestion();
|
|
|
+ q.setCusType(vo.getqType());
|
|
|
+ q.setQuesStructType(QuesStructType.getQuesStructTypeById(vo.getqType().getTypeId()));
|
|
|
+ q.setTypeId(vo.getTypeId());
|
|
|
+ q.setDetailName(vo.getTypeName());
|
|
|
+ q.setBody(vo.getBody());
|
|
|
+ q.setDifficultyDegree(0.5);
|
|
|
+ q.setHaveAudio(false);
|
|
|
+ q.setId(vo.getQid());
|
|
|
+ q.setScore(1.0);
|
|
|
+ if (QuesStructType.SINGLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ List<KdQuesOption> options = new ArrayList<>();
|
|
|
+ q.setOptions(options);
|
|
|
+ int num = 0;
|
|
|
+ int answerCount = 0;
|
|
|
+ for (String a : vo.getAnswer().getSubArea()) {
|
|
|
+ num++;
|
|
|
+ KdQuesOption o = new KdQuesOption();
|
|
|
+ options.add(o);
|
|
|
+ o.setNumber(num);
|
|
|
+ o.setBody(a);
|
|
|
+ o.setSelect(vo.getAnswer().getAnswer().contains("" + (num - 1)));
|
|
|
+ if (o.getSelect()) {
|
|
|
+ answerCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (answerCount == 0) {
|
|
|
+ throw new StatusException("没有答案:" + q.getId());
|
|
|
+ }
|
|
|
+ if (answerCount > 1) {
|
|
|
+ throw new StatusException("答案过多");
|
|
|
+ }
|
|
|
+ } else if (QuesStructType.MULTIPLE_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ List<KdQuesOption> options = new ArrayList<>();
|
|
|
+ q.setOptions(options);
|
|
|
+ int num = 0;
|
|
|
+ int answerCount = 0;
|
|
|
+ for (String a : vo.getAnswer().getSubArea()) {
|
|
|
+ num++;
|
|
|
+ KdQuesOption o = new KdQuesOption();
|
|
|
+ options.add(o);
|
|
|
+ o.setNumber(num);
|
|
|
+ o.setBody(a);
|
|
|
+ o.setSelect(vo.getAnswer().getAnswer().contains("" + (num - 1)));
|
|
|
+ if (o.getSelect()) {
|
|
|
+ answerCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (answerCount == 0) {
|
|
|
+ throw new StatusException("没有答案");
|
|
|
+ }
|
|
|
+ if (answerCount > 10) {
|
|
|
+ throw new StatusException("答案超过10个:" + vo.getQid());
|
|
|
+ }
|
|
|
+ } else if (QuesStructType.BOOL_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ if (vo.getAnswer().getAnswer().contains("0")) {
|
|
|
+ q.setAnswer("正确");
|
|
|
+ } else if (vo.getAnswer().getAnswer().contains("1")) {
|
|
|
+ q.setAnswer("错误");
|
|
|
+ } else {
|
|
|
+ throw new StatusException("答案有误");
|
|
|
+ }
|
|
|
+ } else if (QuesStructType.FILL_BLANK_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ int aCount = 0;
|
|
|
+ List<String> tem = new ArrayList<>();
|
|
|
+ for (List<String> ss : vo.getfAnswer().getAnswer()) {
|
|
|
+ for (String s : ss) {
|
|
|
+ aCount++;
|
|
|
+ tem.add(s);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ q.setAnswer(StringUtils.join(tem, "##"));
|
|
|
+ q.setBody(changeBlank(q.getBody(), aCount, q.getId()));
|
|
|
+ } else if (QuesStructType.TEXT_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ q.setAnswer(StringUtils.join(vo.getAnswer().getAnswer(), ""));
|
|
|
+ } else if (QuesStructType.NESTED_ANSWER_QUESTION.equals(q.getQuesStructType())) {
|
|
|
+ if (CusQuesStructType.cloze.equals(q.getCusType())) {
|
|
|
+ q.setBody(changeCloze(q.getBody()));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new StatusException("题型有误");
|
|
|
+ }
|
|
|
+ disposeQuestionImg(q);
|
|
|
+ return q;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<QuestionVo> getQuestion(Connection connect, String courseCode) throws SQLException, IOException {
|
|
|
+ List<QuestionVo> qs = new ArrayList<>();
|
|
|
+ PreparedStatement preState = null;
|
|
|
+ ResultSet resultSet = null;
|
|
|
+ try {
|
|
|
+ String sql = " select q.TYPE_ID typeId,f.name typeName,f.ANSWER_TYPE qType "
|
|
|
+ + " ,q.ID qid,q.TITLE body,q.FATHER_ID pid " + " ,q.answer,q.SHOW_ORDER seq "
|
|
|
+ + " from pe_question_bank t " + " INNER JOIN pe_questions q on t.id=q.BANK_ID "
|
|
|
+ + " INNER JOIN pe_question_type f on f.id=q.TYPE_ID " + " where t.course_id='" + courseCode + "'";
|
|
|
+
|
|
|
+ preState = connect.prepareStatement(sql);
|
|
|
+
|
|
|
+ resultSet = preState.executeQuery();
|
|
|
+
|
|
|
+ while (resultSet.next()) {
|
|
|
+ QuestionVo q = new QuestionVo();
|
|
|
+ q.setQid(resultSet.getString("qid"));
|
|
|
+ q.setTypeId(resultSet.getString("typeId"));
|
|
|
+ q.setTypeName(resultSet.getString("typeName"));
|
|
|
+ q.setPid(resultSet.getString("pid"));
|
|
|
+ q.setqType(CusQuesStructType.valueOf(resultSet.getString("qType")));
|
|
|
+ q.setBody(resultSet.getString("body"));
|
|
|
+ q.setSeq(resultSet.getInt("seq"));
|
|
|
+ String an = resultSet.getString("answer");
|
|
|
+ try {
|
|
|
+ if (CusQuesStructType.fillblank.equals(q.getqType())) {
|
|
|
+ q.setfAnswer(JSONObject.parseObject(an, FillBlankAnswerVo.class));
|
|
|
+ } else {
|
|
|
+ q.setAnswer(JSONObject.parseObject(an, AnswerVo.class));
|
|
|
+ }
|
|
|
+ } catch (JSONException e) {
|
|
|
+ try {
|
|
|
+ System.out.println("old#############qid:" + q.getQid() + " " + an);
|
|
|
+ an = fomat(an);
|
|
|
+ System.out.println("new#############qid:" + q.getQid() + " " + an);
|
|
|
+ if (CusQuesStructType.fillblank.equals(q.getqType())) {
|
|
|
+ q.setfAnswer(JSONObject.parseObject(an, FillBlankAnswerVo.class));
|
|
|
+ } else {
|
|
|
+ q.setAnswer(JSONObject.parseObject(an, AnswerVo.class));
|
|
|
+ }
|
|
|
+
|
|
|
+ GkExportPaperByCourseCode.addRectify();
|
|
|
+ } catch (Exception e1) {
|
|
|
+ GkExportPaperByCourseCode.addValid();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ qs.add(q);
|
|
|
+ }
|
|
|
+ return qs;
|
|
|
+ } finally {
|
|
|
+ if (resultSet != null) {
|
|
|
+ resultSet.close();
|
|
|
+ }
|
|
|
+ if (preState != null) {
|
|
|
+ preState.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String fomat(String text) {
|
|
|
+ StringBuffer buffer = new StringBuffer();
|
|
|
+ Matcher matcher = xieGangPat.matcher(text);
|
|
|
+ // 使用find()方法查找匹配项
|
|
|
+ while (matcher.find()) {
|
|
|
+ String tem = matcher.group(1);
|
|
|
+ matcher.appendReplacement(buffer, "\\\\\\\\" + tem);
|
|
|
+ }
|
|
|
+ matcher.appendTail(buffer);
|
|
|
+ return buffer.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ // public static void main(String[] args) {
|
|
|
+ // String s="a\"\\\",b\\h";
|
|
|
+ // System.out.println(s);
|
|
|
+ // System.out.println(fomat(s));
|
|
|
+ // }
|
|
|
+
|
|
|
+ private List<QuestionVo> getSubQuestion(Connection connect, String courseCode, List<String> pids)
|
|
|
+ throws SQLException, IOException {
|
|
|
+ List<QuestionVo> qs = new ArrayList<>();
|
|
|
+ if (CollectionUtils.isEmpty(pids)) {
|
|
|
+ return qs;
|
|
|
+ }
|
|
|
+ PreparedStatement preState = null;
|
|
|
+ ResultSet resultSet = null;
|
|
|
+ try {
|
|
|
+ String sql = " select f.name typeName,f.ANSWER_TYPE qType " + " ,q.ID qid,q.TITLE body,q.FATHER_ID pid "
|
|
|
+ + " ,q.answer,q.SHOW_ORDER seq " + " from pe_questions q "
|
|
|
+ + " INNER JOIN pe_question_type f on f.id=q.TYPE_ID " + " where q.FATHER_ID in ('"
|
|
|
+ + StringUtils.join(pids, "','") + "') order by q.SHOW_ORDER";
|
|
|
+
|
|
|
+ preState = connect.prepareStatement(sql);
|
|
|
+
|
|
|
+ resultSet = preState.executeQuery();
|
|
|
+
|
|
|
+ while (resultSet.next()) {
|
|
|
+ QuestionVo q = new QuestionVo();
|
|
|
+ q.setQid(resultSet.getString("qid"));
|
|
|
+ q.setTypeName(resultSet.getString("typeName"));
|
|
|
+ q.setPid(resultSet.getString("pid"));
|
|
|
+ q.setqType(CusQuesStructType.valueOf(resultSet.getString("qType")));
|
|
|
+ q.setBody(resultSet.getString("body"));
|
|
|
+ q.setAnswer(JSONObject.parseObject(resultSet.getString("answer"), AnswerVo.class));
|
|
|
+ q.setSeq(resultSet.getInt("seq"));
|
|
|
+ qs.add(q);
|
|
|
+ }
|
|
|
+ return qs;
|
|
|
+ } finally {
|
|
|
+ if (resultSet != null) {
|
|
|
+ resultSet.close();
|
|
|
+ }
|
|
|
+ if (preState != null) {
|
|
|
+ preState.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void disposeQuestionImg(KdQuestion q) {
|
|
|
+ q.setBody(disposeImg(q.getBody(), q.getId()));
|
|
|
+ if (CollectionUtils.isNotEmpty(q.getOptions())) {
|
|
|
+ for (KdQuesOption o : q.getOptions()) {
|
|
|
+ o.setBody(disposeImg(o.getBody(), q.getId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ q.setAnswer(disposeImg(q.getAnswer(), q.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private String disposeImg(String str, String qid) {
|
|
|
+ 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("/resourcefile/bdeditor")) {
|
|
|
+ if (srcMap.get(imgSrc) == null) {
|
|
|
+ File img = new File(imgDir + imgSrc);
|
|
|
+ if (!img.exists()) {
|
|
|
+ throw new StatusException("图片有误:" + qid);
|
|
|
+ }
|
|
|
+ String base64 = FileUtil.fileToBase64Src(img);
|
|
|
+ srcMap.put(imgSrc, base64);
|
|
|
+ }
|
|
|
+ } else if (imgSrc.toLowerCase().trim().startsWith("http")) {
|
|
|
+ if (srcMap.get(imgSrc) == null) {
|
|
|
+ File img = new File(imgDir + "/" + UUID.randomUUID() + ".png");
|
|
|
+ FileUtil.saveUrlAs(imgSrc, img.getAbsolutePath());
|
|
|
+ String base64 = FileUtil.fileToBase64Src(img);
|
|
|
+ img.delete();
|
|
|
+ srcMap.put(imgSrc, base64);
|
|
|
+ }
|
|
|
+ } else if (imgSrc.toLowerCase().trim().startsWith("/formula")) {
|
|
|
+ if (srcMap.get(imgSrc) == null) {
|
|
|
+ File img = new File(imgDir + "/" + UUID.randomUUID() + ".png");
|
|
|
+ FileUtil.saveUrlAs("https://ougd-exam.webtrn.cn" + imgSrc, img.getAbsolutePath());
|
|
|
+ String base64 = FileUtil.fileToBase64Src(img);
|
|
|
+ img.delete();
|
|
|
+ srcMap.put(imgSrc, base64);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new StatusException("图片有误:" + qid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (String imgSrc : srcMap.keySet()) {
|
|
|
+ str = str.replaceAll(imgSrc, srcMap.get(imgSrc));
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void exportPaper(Connection connect, PaperExportDto dto) throws Exception {
|
|
|
+ List<QuestionVo> vos = getQuestion(connect, dto.getCourseCode());
|
|
|
+ if (CollectionUtils.isEmpty(vos)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> pids = vos.stream().filter(e -> e.getqType().getTypeId() == 6).map(QuestionVo::getQid)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ List<QuestionVo> subvos = getSubQuestion(connect, dto.getCourseCode(), pids);
|
|
|
+ List<KdQuestion> qs = of(vos, subvos);
|
|
|
+ // fillProp(connect, qs);
|
|
|
+ // fillAnswer(connect, qs, dto.getCourseCode());
|
|
|
+
|
|
|
+ Map<DetailDto, List<KdQuestion>> qmap = new HashMap<>();
|
|
|
+ for (KdQuestion q : qs) {
|
|
|
+ DetailDto tem = new DetailDto(q.getTypeId(), q.getDetailName());
|
|
|
+ List<KdQuestion> list = qmap.get(tem);
|
|
|
+ if (list == null) {
|
|
|
+ list = new ArrayList<>();
|
|
|
+ qmap.put(tem, list);
|
|
|
+ }
|
|
|
+ list.add(q);
|
|
|
+ }
|
|
|
+ for (DetailDto qt : qmap.keySet()) {
|
|
|
+ createPapers(qmap.get(qt), qt, dto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void createPapers(List<KdQuestion> qs, DetailDto 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, DetailDto 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(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(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() {
|
|
|
+
|
|
|
+ }
|
|
|
}
|