Jelajahi Sumber

给阅卷提供的作答代码重写

lideyin 5 tahun lalu
induk
melakukan
e43e85bfa6

+ 209 - 77
src/main/java/cn/com/qmth/examcloud/bridge/modules/cloudmarking/controller/CloudMarkingClientController.java

@@ -1,5 +1,8 @@
 package cn.com.qmth.examcloud.bridge.modules.cloudmarking.controller;
 
+import cn.com.qmth.examcloud.bridge.modules.cloudmarking.bean.Block;
+import cn.com.qmth.examcloud.bridge.modules.cloudmarking.bean.Section;
+import cn.com.qmth.examcloud.bridge.modules.cloudmarking.bean.Sections;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.util.HttpClientUtil;
 import cn.com.qmth.examcloud.commons.util.IOUtil;
@@ -11,6 +14,7 @@ import cn.com.qmth.examcloud.core.oe.admin.api.OeExamStudentCloudService;
 import cn.com.qmth.examcloud.core.oe.admin.api.bean.ToBeMarkExamRecordBean;
 import cn.com.qmth.examcloud.core.oe.admin.api.bean.ToBeMarkExamStudentBean;
 import cn.com.qmth.examcloud.core.oe.admin.api.bean.ToBeMarkSubjectiveAnswerBean;
+import cn.com.qmth.examcloud.core.oe.admin.api.request.GetToBeMarkExamRecordReq;
 import cn.com.qmth.examcloud.core.oe.admin.api.request.GetToBeMarkExamStudentReq;
 import cn.com.qmth.examcloud.core.oe.admin.api.response.GetToBeMarkExamRecordResp;
 import cn.com.qmth.examcloud.core.oe.admin.api.response.GetToBeMarkExamStudentResp;
@@ -33,10 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -82,38 +83,24 @@ public class CloudMarkingClientController {
             throw new StatusException("101002", "该考试批次下无待阅考生数据");
         }
 
+        if (logger.isDebugEnabled()) {
+//            logger.debug("[BATCH_GET_ANSWER-" + examId + "],获取考试批次下所有考生:" + JsonUtil.toJson(examStudentList));
+            logger.debug("[001.BATCH_GET_ANSWER-" + examId + "],获取考试批次下所有考生数量:" + examStudentList.size());
+        }
+
         for (ToBeMarkExamStudentBean stu : examStudentList) {
-            String hostUrl = "http://localhost:8020/cmc/getSubjectiveAnswer/" + stu.getExamStudentId();
-            HttpGet httpGet = HttpClientUtil.buildHttpGet(hostUrl);
-            CloseableHttpClient httpClient = HttpClientUtil.getHttpClient();
-            CloseableHttpResponse response = null;
-
-            try {
-                response = httpClient.execute(httpGet);
-                int statusCode = response.getStatusLine().getStatusCode();
-                String strEntity = EntityUtils.toString(response.getEntity(), "UTF-8");
-                if (HttpStatus.SC_OK != statusCode) {
-                    logger.error("[HTTP-FAIL]. statusCode=" + statusCode + "; responseEntity="
-                            + strEntity + "; uri=" + httpGet.getURI());
-
-                    continue;
-                }
-                saveDataToLocal(strEntity, examId);
+            GetToBeMarkExamRecordReq getExamRecordReq = new GetToBeMarkExamRecordReq();
+            getExamRecordReq.setExamStudentIdList(Arrays.asList(stu.getExamStudentId()));
 
-            } catch (IOException e) {
-                throw new StatusException("IO操作异常", e.getMessage());
-            } finally {
-                if (null != response) {
-                    HttpClientUtil.close(response);
-                }
-            }
+            GetToBeMarkExamRecordResp getExamRecordResp = examRecordCloudService.getToBeMarkExamRecord(getExamRecordReq);
+
+            saveDataToLocal(getExamRecordResp,examId);
         }
 
         return ResponseEntity.ok().body("数据生成完毕.");
     }
 
-    private void saveDataToLocal(String strEntity, Long examId) {
-        GetToBeMarkExamRecordResp resp = JsonUtil.fromJson(strEntity, GetToBeMarkExamRecordResp.class);
+    private void saveDataToLocal(GetToBeMarkExamRecordResp resp, Long examId) {
 
         if (!resp.getToBeMarkExamRecordBeanList().isEmpty()) {
 
@@ -134,64 +121,42 @@ public class CloudMarkingClientController {
                 final String tempAnswerDir =
                         systemConfig.getTempDataDir() + "/exam-" + rb.getExamId() + "/" + rb.getCourseCode() + "-" + rb.getPaperType();
 
-                List<Map<String, Object>> answerMapList = new ArrayList<>();
+                if (logger.isDebugEnabled()) {
+                    logger.debug("[BATCH_GET_ANSWER-" + examId + "],临时文件目录:" + JsonUtil.toJson(tempAnswerDir));
+                }
+
+                List<Map<String, Object>> resultMapList = new ArrayList<>();
 
                 //循环主观题答案
                 for (ToBeMarkSubjectiveAnswerBean sab : rb.getSubjectiveAnswerList()) {
-                    Map<String, Object> answerMap = Maps.newHashMap();
-                    answerMap.put("mainNumber", sab.getMainNumber());
-                    answerMap.put("subNumber", sab.getOrder());
-
-                    Map<String, Object> bodyMap = Maps.newHashMap();
-
-                    List<Map<String, Object>> sectionMapList = new ArrayList<>();
-                    Map<String, Object> sectionMap = Maps.newHashMap();
-                    List<Map<String, Object>> blockMapList = new ArrayList<>();
-
-                    //校验答案格式,校验成功才追加至集合,否则不追加
-                    if (validateAnswer(sab.getRealAnswerType(), sab.getStudentAnswer())) {
-                        //图片文件特殊处理
-                        if (!StringUtils.isNullOrEmpty(sab.getStudentAnswer()) &&
-                                "image".equals(sab.getRealAnswerType())) {
-                            if (sab.getStudentAnswer().indexOf("|") > -1) {
-                                String[] imgAnswers = sab.getStudentAnswer().split("\\|");
-                                for (int i = 0; i < imgAnswers.length; i++) {
-                                    Map<String, Object> blockMap = Maps.newHashMap();
-                                    blockMap.put("type", sab.getRealAnswerType());
-                                    blockMap.put("value", transformedAnswer(sab.getRealAnswerType(), imgAnswers[i]));
-
-                                    //又拍云图片的宽*高
-                                    String imgWH = RegExpUtil.find(imgAnswers[i], "(\\d+)x(\\d+)");
-                                    if (!StringUtils.isNullOrEmpty(imgWH)) {
-                                        Map<String, Object> paramMap = new HashMap<>();
-                                        paramMap.put("width", Integer.valueOf(imgWH.split("x")[0]));
-                                        paramMap.put("height", Integer.valueOf(imgWH.split("x")[1]));
-                                        blockMap.put("param", paramMap);
-                                    }
-
-                                    blockMapList.add(blockMap);
-                                }
-                            }
-                        } else {
-                            Map<String, Object> blockMap = Maps.newHashMap();
-                            blockMap.put("type", sab.getRealAnswerType());
-                            blockMap.put("value", transformedAnswer(sab.getRealAnswerType(), sab.getStudentAnswer()));
-                            blockMapList.add(blockMap);
-                        }
-                    }
+                    Map<String, Object> resultMap = Maps.newHashMap();
+                    //构建基本信息
+                    resultMap.put("mainNumber", sab.getMainNumber());//大题号
+                    resultMap.put("subNumber", sab.getOrder());//小题号
+
+                    //构建题干
+                    resultMap.put("body",getBodyOrAnswer(sab.getBody()));
 
-                    sectionMap.put("blocks", blockMapList);
-                    sectionMapList.add(sectionMap);
+                    //构建标准答案
+                    resultMap.put("answer",getBodyOrAnswer(sab.getAnswer()));
 
-                    bodyMap.put("sections", sectionMapList);
-                    answerMap.put("body", bodyMap);
+                    //构建学生作答
+                    resultMap.put("studentAnswer", buildStudentAnswerMap(sab));
 
-                    answerMapList.add(answerMap);
+                    resultMapList.add(resultMap);
                 }
 
                 //将考生结果保存至临时文件
-                String answerJson = JsonUtil.toJson(answerMapList);
+                String answerJson = JsonUtil.toJson(resultMapList);
                 String jsonFilePath = tempAnswerDir + "/" + rb.getExamRecordDataId() + ".json";
+
+                if (logger.isDebugEnabled()) {
+                    logger.debug("[BATCH_GET_ANSWER-" + examId + "],最终作答结果路径:jsonFilePath=" + jsonFilePath);
+                }
+                if (logger.isDebugEnabled()) {
+                    logger.debug("[BATCH_GET_ANSWER-" + examId + "],最终作答结果:answerJson=" + answerJson);
+                }
+
                 IOUtil.toFile(answerJson.getBytes(Charset.forName("UTF-8")), jsonFilePath);
             }
 
@@ -201,9 +166,59 @@ public class CloudMarkingClientController {
                 IOUtil.toFile(sb.toString().getBytes(Charset.forName("UTF-8")), txtFilePath);
             }
 
+        } else {
+            if (logger.isDebugEnabled()) {
+                logger.debug("[006.BATCH_GET_ANSWER-" + examId + "],enter saveDataToLocal-----GetToBeMarkExamRecordResp 空数据");
+            }
         }
     }
 
+    private Map<String, Object> buildStudentAnswerMap(ToBeMarkSubjectiveAnswerBean sab) {
+        Map<String, Object> studentAnswerMap = Maps.newHashMap();
+
+        List<Map<String, Object>> sectionMapList = new ArrayList<>();
+        Map<String, Object> sectionMap = Maps.newHashMap();
+        List<Map<String, Object>> blockMapList = new ArrayList<>();
+
+        //校验答案格式,校验成功才追加至集合,否则不追加
+        if (validateAnswer(sab.getRealAnswerType(), sab.getStudentAnswer())) {
+            //图片文件特殊处理
+            if (!StringUtils.isNullOrEmpty(sab.getStudentAnswer()) &&
+                    "image".equals(sab.getRealAnswerType())) {
+                if (sab.getStudentAnswer().indexOf("|") > -1) {
+                    String[] imgAnswers = sab.getStudentAnswer().split("\\|");
+                    for (int i = 0; i < imgAnswers.length; i++) {
+                        Map<String, Object> blockMap = Maps.newHashMap();
+                        blockMap.put("type", sab.getRealAnswerType());
+                        blockMap.put("value", transformedAnswer(sab.getRealAnswerType(), imgAnswers[i]));
+
+                        //又拍云图片的宽*高
+                        String imgWH = RegExpUtil.find(imgAnswers[i], "(\\d+)x(\\d+)");
+                        if (!StringUtils.isNullOrEmpty(imgWH)) {
+                            Map<String, Object> paramMap = new HashMap<>();
+                            paramMap.put("width", Integer.valueOf(imgWH.split("x")[0]));
+                            paramMap.put("height", Integer.valueOf(imgWH.split("x")[1]));
+                            blockMap.put("param", paramMap);
+                        }
+
+                        blockMapList.add(blockMap);
+                    }
+                }
+            } else {
+                Map<String, Object> blockMap = Maps.newHashMap();
+                blockMap.put("type", sab.getRealAnswerType());
+                blockMap.put("value", transformedAnswer(sab.getRealAnswerType(), sab.getStudentAnswer()));
+                blockMapList.add(blockMap);
+            }
+        }
+
+        sectionMap.put("blocks", blockMapList);
+        sectionMapList.add(sectionMap);
+
+        studentAnswerMap.put("sections", sectionMapList);
+        return studentAnswerMap;
+    }
+
     private String transformedAnswer(String answerType, String studentAnswer) {
         if ("image".equals(answerType)) {
             String regExp = "(ftp|https?)\\:\\/\\/([\\w\\_\\-]+)\\.([\\w\\-]+[\\.]?)*[\\w]+\\.[a-zA-Z]{2,10}(.*)\\.(png|jpg|gif|jpeg)";
@@ -239,6 +254,123 @@ public class CloudMarkingClientController {
         return true;
     }
 
+    /**
+     * 获取格式化后后的题干或标准答案
+     * @param str
+     * @return
+     */
+    private Sections getBodyOrAnswer(String str) {
+        Sections body = new Sections();
+        List<Section> sections = new ArrayList<>();
+        // 得到小题题干或者答案行数
+        if (org.apache.commons.lang3.StringUtils.isBlank(str)) {
+            return body;
+        }
+        String[] questionRowStrings = str.split("</p>");
+        for (int i = 0; i < questionRowStrings.length; i++) {
+            List<Block> blocks = disposeQuestionBodyOrOption(questionRowStrings[i]);
+            if (blocks != null && blocks.size() > 0) {
+                Section section = new Section();
+                // 将小题题干拆分为Block集合
+                section.setBlocks(blocks);
+                sections.add(section);
+            }
+        }
+        body.setSections(sections);
+        return body;
+    }
+
+    private List<Block> disposeQuestionBodyOrOption(String questionRow) {
+        List<Block> blocks = new ArrayList<>();
+        // 去掉每行里面的<p>,<span>,</span>标签
+        questionRow = questionRow.replaceAll("<p>", "").replaceAll("</p>", "").replaceAll("<span>", "")
+                .replaceAll("</span>", "").replaceAll("</a>", "");
+        String[] questionRowStrings = questionRow.split("<|/>|>");
+        for (int i = 0; i < questionRowStrings.length; i++) {
+            Block block = new Block();
+            String rowStr = questionRowStrings[i];
+            // 判断是否有图片
+            if (rowStr.startsWith("img")) {
+                rowStr = "<" + rowStr + ">";
+                Map<String, Object> param = new HashMap<>();
+                // 需要继续做截取,取到Parma
+                block.setType("image");
+                // 获取图片的路径
+                List<String> strSrcList = getImg(rowStr, "src");
+                if (strSrcList.size() > 0) {
+                    String strSrc = strSrcList.get(0).replaceAll("src=\"", "").replaceAll("\"", "");
+                    block.setValue(strSrc);
+                }
+                // 获取图片的高度
+                List<String> strHeightList = getImg(rowStr, "height");
+                if (strHeightList.size() > 0) {
+                    String strHeight = strHeightList.get(0).replaceAll("height=\"", "").replaceAll("\"", "");
+                    param.put("height", strHeight);
+                }
+                // 获取图片的宽度
+                List<String> strWidthList = getImg(rowStr, "width");
+                if (strHeightList.size() > 0) {
+                    String strWidth = strWidthList.get(0).replaceAll("width=\"", "").replaceAll("\"", "");
+                    param.put("width", strWidth);
+                }
+                block.setParam(param);
+                blocks.add(block);
+            } else if (rowStr.startsWith("a") && rowStr.contains("id") && rowStr.contains("name")) { // 处理音频
+                rowStr = "<" + rowStr + ">";
+                block.setPlayTime(1);
+                block.setType("audio");
+                block.setValue(this.getAttrValue(rowStr, "id"));
+                blocks.add(block);
+            } else {
+                block.setType("text");
+                rowStr = rowStr.replace("&nbsp;", "");// 消除空格
+                rowStr = rowStr.replace("&quot;", "\"");// 将&quot;转换成\"
+                rowStr = rowStr.replace("&lt;", "<");// 将&lt;转换成<
+                rowStr = rowStr.replace("&gt;", ">");// 将&gt;转换成>
+                rowStr = rowStr.replace("&amp;", "&");// 将&amp;转换成&
+                if (org.apache.commons.lang3.StringUtils.isNotBlank(rowStr)) {
+                    block.setValue(rowStr);
+                    blocks.add(block);
+                }
+            }
+        }
+
+        return blocks;
+    }
+
+    /**
+     * 获取图片里面的路径,长度,宽度
+     */
+    private List<String> getImg(String s, String str) {
+        String regex;
+        List<String> list = new ArrayList<>();
+        regex = str + "=\"(.*?)\"";
+        Pattern pa = Pattern.compile(regex, Pattern.DOTALL);
+        Matcher ma = pa.matcher(s);
+        while (ma.find()) {
+            list.add(ma.group());
+        }
+        return list;
+    }
+
+    private String getAttrValue(String questionStr, String attrName) {
+        Pattern aPattern = Pattern.compile("a.*");
+        Matcher aMatcher = aPattern.matcher(questionStr);
+
+        if (aMatcher.find()) {
+            String idRegex = attrName + "=\".*?\"";
+            Pattern idPattern = Pattern.compile(idRegex);
+            Matcher idMatcher = idPattern.matcher(aMatcher.group());
+            if (idMatcher.find()) {
+                return idMatcher.group()
+                        .replaceAll(attrName + "=\"", "")
+                        .replaceAll("\"", "");
+            }
+        }
+
+        return "";
+    }
+
     /**
      * 校验字符串和正则表达式是否匹配
      *