|
@@ -13,7 +13,10 @@ import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetPaperStructReq;
|
|
import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetQuestionAnswerReq;
|
|
import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetQuestionAnswerReq;
|
|
import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetSubjectivePaperStructReq;
|
|
import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetSubjectivePaperStructReq;
|
|
import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetSubjectiveQuestionReq;
|
|
import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetSubjectiveQuestionReq;
|
|
-import cn.com.qmth.examcloud.exchange.outer.api.response.*;
|
|
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.response.OuterGetPaperStructResp;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.response.OuterGetQuestionAnswerResp;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.response.OuterGetSubjectivePaperStructResp;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.response.OuterGetSubjectiveQuestionResp;
|
|
import cn.com.qmth.examcloud.exchange.outer.service.OutletPaperStructService;
|
|
import cn.com.qmth.examcloud.exchange.outer.service.OutletPaperStructService;
|
|
import cn.com.qmth.examcloud.exchange.outer.service.bean.OuterCourseBean;
|
|
import cn.com.qmth.examcloud.exchange.outer.service.bean.OuterCourseBean;
|
|
import cn.com.qmth.examcloud.exchange.outer.service.bean.OuterQuestionBean;
|
|
import cn.com.qmth.examcloud.exchange.outer.service.bean.OuterQuestionBean;
|
|
@@ -24,8 +27,14 @@ import cn.com.qmth.examcloud.question.commons.core.paper.DefaultQuestionUnitWrap
|
|
import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
|
|
import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
|
|
import cn.com.qmth.examcloud.question.commons.core.question.QuestionType;
|
|
import cn.com.qmth.examcloud.question.commons.core.question.QuestionType;
|
|
import cn.com.qmth.examcloud.support.cache.CacheHelper;
|
|
import cn.com.qmth.examcloud.support.cache.CacheHelper;
|
|
|
|
+import cn.com.qmth.examcloud.support.cache.bean.CourseCacheBean;
|
|
import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigPaperCacheBean;
|
|
import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigPaperCacheBean;
|
|
import cn.com.qmth.examcloud.support.cache.bean.QuestionAnswerCacheBean;
|
|
import cn.com.qmth.examcloud.support.cache.bean.QuestionAnswerCacheBean;
|
|
|
|
+import cn.com.qmth.examcloud.support.enums.BlockType;
|
|
|
|
+import cn.com.qmth.examcloud.support.handler.richText.RichTextHandler;
|
|
|
|
+import cn.com.qmth.examcloud.support.handler.richText.RichTextHandlerFactory;
|
|
|
|
+import cn.com.qmth.examcloud.support.handler.richText.bean.SectionBean;
|
|
|
|
+import cn.com.qmth.examcloud.support.handler.richText.bean.SectionCollectionBean;
|
|
import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
|
|
import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
|
|
import cn.com.qmth.examcloud.web.support.ControllerSupport;
|
|
import cn.com.qmth.examcloud.web.support.ControllerSupport;
|
|
import cn.com.qmth.examcloud.web.support.StatusResponse;
|
|
import cn.com.qmth.examcloud.web.support.StatusResponse;
|
|
@@ -35,11 +44,6 @@ import io.swagger.annotations.ApiOperation;
|
|
import io.swagger.annotations.ApiResponse;
|
|
import io.swagger.annotations.ApiResponse;
|
|
import io.swagger.annotations.ApiResponses;
|
|
import io.swagger.annotations.ApiResponses;
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
import org.apache.commons.collections.CollectionUtils;
|
|
-import org.jsoup.Jsoup;
|
|
|
|
-import org.jsoup.nodes.Document;
|
|
|
|
-import org.jsoup.nodes.Element;
|
|
|
|
-import org.jsoup.safety.Whitelist;
|
|
|
|
-import org.jsoup.select.Elements;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.PostMapping;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
@@ -47,11 +51,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
-import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
-import java.util.Map;
|
|
|
|
-import java.util.regex.Matcher;
|
|
|
|
-import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* @Description 考试作答服务
|
|
* @Description 考试作答服务
|
|
@@ -72,6 +72,7 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
@Autowired
|
|
@Autowired
|
|
private OutletPaperStructService outletPaperStructService;
|
|
private OutletPaperStructService outletPaperStructService;
|
|
|
|
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
@ApiOperation(value = "获取主观题试卷结构", httpMethod = "POST")
|
|
@ApiOperation(value = "获取主观题试卷结构", httpMethod = "POST")
|
|
@ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetSubjectivePaperStructResp.class),
|
|
@ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetSubjectivePaperStructResp.class),
|
|
@@ -130,6 +131,8 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
@PostMapping("/getSubjectiveQuestion")
|
|
@PostMapping("/getSubjectiveQuestion")
|
|
@Override
|
|
@Override
|
|
public OuterGetSubjectiveQuestionResp getSubjectiveQuestion(@RequestBody OuterGetSubjectiveQuestionReq req) {
|
|
public OuterGetSubjectiveQuestionResp getSubjectiveQuestion(@RequestBody OuterGetSubjectiveQuestionReq req) {
|
|
|
|
+ Long st = System.currentTimeMillis();
|
|
|
|
+
|
|
Long examId = req.getExamId();
|
|
Long examId = req.getExamId();
|
|
if (null == examId) {
|
|
if (null == examId) {
|
|
throw new StatusException("101001", "考试id不允许为空");
|
|
throw new StatusException("101001", "考试id不允许为空");
|
|
@@ -154,6 +157,11 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
throw new StatusException("101005", "数据量最大不得超过500");
|
|
throw new StatusException("101005", "数据量最大不得超过500");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
|
+ log.debug("0 [GET_SUBJECTIVE_QUESTION-" + examId + "-" + subjectCode + "-" + startId + "] start...");
|
|
|
|
+ }
|
|
|
|
+
|
|
GetPagedToBeMarkExamRecordReq pagedReq = new GetPagedToBeMarkExamRecordReq();
|
|
GetPagedToBeMarkExamRecordReq pagedReq = new GetPagedToBeMarkExamRecordReq();
|
|
pagedReq.setExamId(examId);
|
|
pagedReq.setExamId(examId);
|
|
pagedReq.setSubjectCode(subjectCode);
|
|
pagedReq.setSubjectCode(subjectCode);
|
|
@@ -161,10 +169,27 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
pagedReq.setSize(size);
|
|
pagedReq.setSize(size);
|
|
GetPagedToBeMarkExamRecordResp pagedResp = examRecordCloudService.getPagedToBeMarkExamRecord(pagedReq);
|
|
GetPagedToBeMarkExamRecordResp pagedResp = examRecordCloudService.getPagedToBeMarkExamRecord(pagedReq);
|
|
|
|
|
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
|
+ log.debug("1.[GET_SUBJECTIVE_QUESTION-" + examId + "-" + subjectCode + "-" + startId + "]" +
|
|
|
|
+ "通过rpc获取待阅卷列表耗时:" + (System.currentTimeMillis() - startTime) + " ms");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ startTime = System.currentTimeMillis();
|
|
|
|
+
|
|
OuterGetSubjectiveQuestionResp resp = new OuterGetSubjectiveQuestionResp();
|
|
OuterGetSubjectiveQuestionResp resp = new OuterGetSubjectiveQuestionResp();
|
|
resp.setNextId(pagedResp.getNextId());
|
|
resp.setNextId(pagedResp.getNextId());
|
|
resp.setDataList(getOuterExamRecordBean(pagedResp.getToBeMarkExamRecordBeanList()));
|
|
resp.setDataList(getOuterExamRecordBean(pagedResp.getToBeMarkExamRecordBeanList()));
|
|
|
|
|
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
|
+ log.debug("2.[GET_SUBJECTIVE_QUESTION-" + examId + "-" + subjectCode + "-" + startId + "]" +
|
|
|
|
+ "构造满足条件的考试记录集合耗时:" + (System.currentTimeMillis() - startTime) + " ms");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
|
+ log.debug("999.[GET_SUBJECTIVE_QUESTION-" + examId + "-" + subjectCode + "-" + startId + "] end..." +
|
|
|
|
+ "合计耗时:" + (System.currentTimeMillis() - st) + " ms");
|
|
|
|
+ }
|
|
|
|
+
|
|
return resp;
|
|
return resp;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -175,7 +200,7 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
@Override
|
|
@Override
|
|
public OuterGetQuestionAnswerResp getQuestionAnswer(@RequestBody OuterGetQuestionAnswerReq req) {
|
|
public OuterGetQuestionAnswerResp getQuestionAnswer(@RequestBody OuterGetQuestionAnswerReq req) {
|
|
if (StringUtils.isNullOrEmpty(req.getQuestionId())) {
|
|
if (StringUtils.isNullOrEmpty(req.getQuestionId())) {
|
|
- throw new StatusException("102001","题目id不允许为空");
|
|
|
|
|
|
+ throw new StatusException("102001", "题目id不允许为空");
|
|
}
|
|
}
|
|
|
|
|
|
QuestionAnswerCacheBean questionAnswer = CacheHelper.getQuestionAnswer(req.getQuestionId());
|
|
QuestionAnswerCacheBean questionAnswer = CacheHelper.getQuestionAnswer(req.getQuestionId());
|
|
@@ -285,7 +310,7 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
for (PagedToBeMarkExamRecordBean pb : toBeMarkExamRecordBeanList) {
|
|
for (PagedToBeMarkExamRecordBean pb : toBeMarkExamRecordBeanList) {
|
|
OuterExamRecordBean resultBean = new OuterExamRecordBean();
|
|
OuterExamRecordBean resultBean = new OuterExamRecordBean();
|
|
resultBean.setExamId(pb.getExamId());
|
|
resultBean.setExamId(pb.getExamId());
|
|
- resultBean.setStudentCode(pb.getStudentCode());
|
|
|
|
|
|
+ resultBean.setStudentCode(pb.getIdentityNumber());//因为外部接口定义的名字虽然叫studentCode,实际是身份证号
|
|
resultBean.setName(pb.getStudentName());
|
|
resultBean.setName(pb.getStudentName());
|
|
resultBean.setCollege(pb.getGrade());
|
|
resultBean.setCollege(pb.getGrade());
|
|
resultBean.setClassName(null);
|
|
resultBean.setClassName(null);
|
|
@@ -311,6 +336,7 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
private List<OuterSubjectiveQuestionRecordBean> getSubjectives(Long examId,
|
|
private List<OuterSubjectiveQuestionRecordBean> getSubjectives(Long examId,
|
|
List<PagedToBeMarkSubjectiveAnswerBean> subjectiveAnswerList) {
|
|
List<PagedToBeMarkSubjectiveAnswerBean> subjectiveAnswerList) {
|
|
List<OuterSubjectiveQuestionRecordBean> resultList = new ArrayList<>();
|
|
List<OuterSubjectiveQuestionRecordBean> resultList = new ArrayList<>();
|
|
|
|
+ RichTextHandler complexRichTextHandler = RichTextHandlerFactory.getHandler("complex");
|
|
|
|
|
|
for (PagedToBeMarkSubjectiveAnswerBean pb : subjectiveAnswerList) {
|
|
for (PagedToBeMarkSubjectiveAnswerBean pb : subjectiveAnswerList) {
|
|
OuterSubjectiveQuestionRecordBean resultBean = new OuterSubjectiveQuestionRecordBean();
|
|
OuterSubjectiveQuestionRecordBean resultBean = new OuterSubjectiveQuestionRecordBean();
|
|
@@ -318,132 +344,110 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
resultBean.setSubNumber(pb.getOrder());
|
|
resultBean.setSubNumber(pb.getOrder());
|
|
resultBean.setQuestionId(pb.getQuestionId());
|
|
resultBean.setQuestionId(pb.getQuestionId());
|
|
|
|
|
|
- resultBean.setAnswer(getFormattedAnswer(pb.getAnswer()));
|
|
|
|
- resultBean.setStudentAnswer(
|
|
|
|
- getFormattedStudentAnswer(pb.getStudentAnswer(), pb.getAnswerType(), pb.getQuestionType(), examId));
|
|
|
|
- resultBean.setBody(getFormattedBody(pb.getBody()));
|
|
|
|
- resultBean.setParentBody(getFormattedParentBody(pb.getParentBody()));
|
|
|
|
|
|
+ resultBean.setAnswer(transferFrom(complexRichTextHandler.handle(pb.getAnswer())));
|
|
|
|
|
|
- resultList.add(resultBean);
|
|
|
|
- }
|
|
|
|
|
|
+ //格式化学生答案
|
|
|
|
+ String transformedAnswerType = getTransformedAnswerType(pb.getAnswerType(), pb.getQuestionType(), examId);
|
|
|
|
|
|
- return resultList;
|
|
|
|
- }
|
|
|
|
|
|
+ RichTextHandler richTextHandler = null;
|
|
|
|
+ String stuAnswer = pb.getStudentAnswer();
|
|
|
|
+ SectionCollectionBean formattedStudentAnswer = new SectionCollectionBean();
|
|
|
|
|
|
- /**
|
|
|
|
- * 格式化父题干
|
|
|
|
- *
|
|
|
|
- * @param parentBody
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private OuterSectionCollectionBean getFormattedParentBody(String parentBody) {
|
|
|
|
- if (StringUtils.isNullOrEmpty(parentBody)) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return getBodyOrAnswer(parentBody);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 格式化小题题干
|
|
|
|
- *
|
|
|
|
- * @param body
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private OuterSectionCollectionBean getFormattedBody(String body) {
|
|
|
|
- if (StringUtils.isNullOrEmpty(body)) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return getBodyOrAnswer(body);
|
|
|
|
- }
|
|
|
|
|
|
+ //图片作答特殊处理:将图片作答中的文字部分和图片部分拆开
|
|
|
|
+ if (BlockType.image.name().equals(transformedAnswerType)) {
|
|
|
|
+ if (!StringUtils.isNullOrEmpty(stuAnswer)) {
|
|
|
|
+ //图片作答的标识
|
|
|
|
+ String firstMatch = RegExpUtil.find(stuAnswer, "<div \\S*photo-answers-block\\S*>");
|
|
|
|
|
|
- /**
|
|
|
|
- * 格式化学生答案
|
|
|
|
- *
|
|
|
|
- * @param studentAnswer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private OuterSectionCollectionBean getFormattedStudentAnswer(String studentAnswer,
|
|
|
|
- AnswerType answerType,
|
|
|
|
- QuestionType questionType, Long examId) {
|
|
|
|
- String transformedAnswerType = getTransformedAnswerType(answerType, questionType, examId);
|
|
|
|
-
|
|
|
|
- List<OuterSectionBean> sectionBeanList = new ArrayList<>();
|
|
|
|
- List<OuterBlockBean> blockBeanList = new ArrayList<>();
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //图片文件特殊处理
|
|
|
|
- if ("image".equals(transformedAnswerType)) {
|
|
|
|
- //图片文本部分
|
|
|
|
- String txtStr = getImgTxt(studentAnswer);
|
|
|
|
- if (!StringUtils.isNullOrEmpty(txtStr)) {
|
|
|
|
- OuterBlockBean blockBean = new OuterBlockBean();
|
|
|
|
- blockBean.setType("text");
|
|
|
|
- blockBean.setValue(txtStr);
|
|
|
|
- blockBeanList.add(blockBean);
|
|
|
|
- }
|
|
|
|
|
|
+ int index;
|
|
|
|
+ if (StringUtils.isNullOrEmpty(firstMatch)) {
|
|
|
|
+ index = -1;
|
|
|
|
+ } else {
|
|
|
|
+ index = stuAnswer.indexOf(firstMatch);
|
|
|
|
+ }
|
|
|
|
|
|
- //图片部分
|
|
|
|
- if (validateImgAnswer(studentAnswer)) {
|
|
|
|
- String imgSrc = getImgSrc(studentAnswer);
|
|
|
|
- if (imgSrc.indexOf("|") > -1) {
|
|
|
|
- String[] imgAnswers = imgSrc.split("\\|");
|
|
|
|
-
|
|
|
|
- for (int i = 0; i < imgAnswers.length; i++) {
|
|
|
|
- OuterBlockBean blockBean = new OuterBlockBean();
|
|
|
|
- blockBean.setType(transformedAnswerType);
|
|
|
|
- blockBean.setValue(getSimpleTransformedAnswer(transformedAnswerType, 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]));
|
|
|
|
- blockBean.setParam(paramMap);
|
|
|
|
|
|
+ //只有文字作答,处理文字
|
|
|
|
+ if (index == -1) {
|
|
|
|
+ richTextHandler = RichTextHandlerFactory.getHandler(BlockType.text.name());
|
|
|
|
+ formattedStudentAnswer = richTextHandler.handle(stuAnswer);
|
|
|
|
+ } else {
|
|
|
|
+ //只有图片作答,处理图片
|
|
|
|
+ if (index == 0) {
|
|
|
|
+ richTextHandler = RichTextHandlerFactory.getHandler(BlockType.image.name());
|
|
|
|
+ formattedStudentAnswer = richTextHandler.handle(stuAnswer);
|
|
|
|
+ }
|
|
|
|
+ //既有图片又有文字
|
|
|
|
+ else {
|
|
|
|
+ //文字部分
|
|
|
|
+ String stuAnswer_text = stuAnswer.substring(0, index);
|
|
|
|
+ SectionCollectionBean formattedStudentAnswer_text =
|
|
|
|
+ RichTextHandlerFactory.getHandler(BlockType.text.name()).handle(stuAnswer_text);
|
|
|
|
+
|
|
|
|
+ //图片部分
|
|
|
|
+ String stuAnswer_image = stuAnswer.substring(index);
|
|
|
|
+ SectionCollectionBean formattedStudentAnswer_image =
|
|
|
|
+ RichTextHandlerFactory.getHandler(BlockType.image.name()).handle(stuAnswer_image);
|
|
|
|
+
|
|
|
|
+ formattedStudentAnswer = new SectionCollectionBean();
|
|
|
|
+ List<SectionBean> sections = new ArrayList<>();
|
|
|
|
+ sections.addAll(formattedStudentAnswer_text.getSections());
|
|
|
|
+ sections.addAll(formattedStudentAnswer_image.getSections());
|
|
|
|
+ formattedStudentAnswer.setSections(sections);
|
|
}
|
|
}
|
|
-
|
|
|
|
- blockBeanList.add(blockBean);
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } else if ("audio".equals(transformedAnswerType)) {
|
|
|
|
- if (validateAudioAnswer(studentAnswer)) {
|
|
|
|
- OuterBlockBean blockBean = new OuterBlockBean();
|
|
|
|
- blockBean.setType(transformedAnswerType);
|
|
|
|
- blockBean.setValue(getSimpleTransformedAnswer(transformedAnswerType, studentAnswer));
|
|
|
|
- blockBeanList.add(blockBean);
|
|
|
|
|
|
+ //非图片作答,则直接根据作答类型进行处理
|
|
|
|
+ else {
|
|
|
|
+ richTextHandler = RichTextHandlerFactory.getHandler(transformedAnswerType);
|
|
|
|
+ formattedStudentAnswer = richTextHandler.handle(stuAnswer);
|
|
}
|
|
}
|
|
|
|
|
|
- } else {
|
|
|
|
- OuterBlockBean blockBean = new OuterBlockBean();
|
|
|
|
- blockBean.setType(transformedAnswerType);
|
|
|
|
- blockBean.setValue(getSimpleTransformedAnswer(transformedAnswerType, studentAnswer));
|
|
|
|
- blockBeanList.add(blockBean);
|
|
|
|
- }
|
|
|
|
|
|
+ OuterSectionCollectionBean stuAnswerResult = transferFrom(formattedStudentAnswer);
|
|
|
|
|
|
- OuterSectionBean sectionBean = new OuterSectionBean();
|
|
|
|
- sectionBean.setBlocks(blockBeanList);
|
|
|
|
- sectionBeanList.add(sectionBean);
|
|
|
|
|
|
+ resultBean.setStudentAnswer(stuAnswerResult);
|
|
|
|
|
|
- OuterSectionCollectionBean resultBean = new OuterSectionCollectionBean();
|
|
|
|
- resultBean.setSections(sectionBeanList);
|
|
|
|
- return resultBean;
|
|
|
|
|
|
+ resultBean.setBody(transferFrom(complexRichTextHandler.handle(pb.getBody())));
|
|
|
|
+ resultBean.setParentBody(transferFrom(complexRichTextHandler.handle(pb.getParentBody())));
|
|
|
|
+
|
|
|
|
+ resultList.add(resultBean);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return resultList;
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * 格式化标准答案
|
|
|
|
- *
|
|
|
|
- * @param answer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private OuterSectionCollectionBean getFormattedAnswer(String answer) {
|
|
|
|
- if (StringUtils.isNullOrEmpty(answer)) {
|
|
|
|
- return null;
|
|
|
|
|
|
+ private static OuterSectionCollectionBean transferFrom(SectionCollectionBean sectionCollection) {
|
|
|
|
+ List<SectionBean> sections = sectionCollection.getSections();
|
|
|
|
+ if (null == sections || sections.isEmpty()) {
|
|
|
|
+ return new OuterSectionCollectionBean();
|
|
}
|
|
}
|
|
|
|
|
|
- return getBodyOrAnswer(answer);
|
|
|
|
|
|
+ OuterSectionCollectionBean result = new OuterSectionCollectionBean();
|
|
|
|
+
|
|
|
|
+ List<OuterSectionBean> outerSections = new ArrayList<>();
|
|
|
|
+ sections.stream().forEach(sec -> {
|
|
|
|
+ OuterSectionBean outerSection = new OuterSectionBean();
|
|
|
|
+ List<OuterBlockBean> outerBlocks = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ if (null != sec.getBlocks() && !sec.getBlocks().isEmpty()) {
|
|
|
|
+ sec.getBlocks().stream().forEach(bl -> {
|
|
|
|
+ OuterBlockBean outerBlock = new OuterBlockBean();
|
|
|
|
+ outerBlock.setType(bl.getType());
|
|
|
|
+ outerBlock.setValue(bl.getValue());
|
|
|
|
+ outerBlock.setParam(bl.getParam());
|
|
|
|
+ outerBlock.setPlayTime(bl.getPlayTime());
|
|
|
|
+
|
|
|
|
+ outerBlocks.add(outerBlock);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ outerSection.setBlocks(outerBlocks);
|
|
|
|
+ outerSections.add(outerSection);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ result.setSections(outerSections);
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -469,212 +473,4 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
|
|
|
return "text";
|
|
return "text";
|
|
}
|
|
}
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 获取图片作答的文本部分
|
|
|
|
- *
|
|
|
|
- * @param studentAnswer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private String getImgTxt(String studentAnswer) {
|
|
|
|
- if (!StringUtils.isNullOrEmpty(studentAnswer)) {
|
|
|
|
- return Jsoup.clean(studentAnswer, Whitelist.none());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 获取图片作答图片路径
|
|
|
|
- *
|
|
|
|
- * @param studentAnswer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private String getImgSrc(String studentAnswer) {
|
|
|
|
- if (StringUtils.isNullOrEmpty(studentAnswer)) {
|
|
|
|
- return studentAnswer;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //图片题特殊处理(因为图片作答题中有html标签,只需要取url即可)
|
|
|
|
- Document doc = Jsoup.parse(studentAnswer);
|
|
|
|
- Elements imgElements = doc.select("img[src]");
|
|
|
|
-
|
|
|
|
- String imgSrc = "";
|
|
|
|
-
|
|
|
|
- for (Element el : imgElements) {
|
|
|
|
- String src = el.attr("src");
|
|
|
|
- if (!StringUtils.isNullOrEmpty(src)) {
|
|
|
|
- imgSrc += src + "|";
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (!StringUtils.isNullOrEmpty(imgSrc)) {
|
|
|
|
- return imgSrc.substring(0, imgSrc.length() - 1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return imgSrc;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 单个答案再次格式化,去除地址中的多余后缀
|
|
|
|
- *
|
|
|
|
- * @param answerType
|
|
|
|
- * @param studentAnswer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private String getSimpleTransformedAnswer(String answerType, String studentAnswer) {
|
|
|
|
- if ("image".equals(answerType)) {
|
|
|
|
- String regExp = "(ftp|https?)\\:\\/\\/([\\w\\_\\-]+)\\.([\\w\\-]+[\\.]?)*[\\w]+\\.[a-zA-Z]{2,10}(.*)\\.(png|jpg|gif|jpeg)";
|
|
|
|
- return RegExpUtil.find(studentAnswer, regExp);
|
|
|
|
- }
|
|
|
|
- return studentAnswer;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 获取格式化后后的题干或标准答案
|
|
|
|
- *
|
|
|
|
- * @param str
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private OuterSectionCollectionBean getBodyOrAnswer(String str) {
|
|
|
|
- OuterSectionCollectionBean body = new OuterSectionCollectionBean();
|
|
|
|
- List<OuterSectionBean> 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<OuterBlockBean> blocks = disposeQuestionBodyOrOption(questionRowStrings[i]);
|
|
|
|
- if (blocks != null && blocks.size() > 0) {
|
|
|
|
- OuterSectionBean section = new OuterSectionBean();
|
|
|
|
- // 将小题题干拆分为Block集合
|
|
|
|
- section.setBlocks(blocks);
|
|
|
|
- sections.add(section);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- body.setSections(sections);
|
|
|
|
- return body;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private List<OuterBlockBean> disposeQuestionBodyOrOption(String questionRow) {
|
|
|
|
- List<OuterBlockBean> 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++) {
|
|
|
|
- OuterBlockBean block = new OuterBlockBean();
|
|
|
|
- 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, "url"));
|
|
|
|
- blocks.add(block);
|
|
|
|
- } else {
|
|
|
|
- block.setType("text");
|
|
|
|
- rowStr = rowStr.replace(" ", "");// 消除空格
|
|
|
|
- rowStr = rowStr.replace(""", "\"");// 将"转换成\"
|
|
|
|
- rowStr = rowStr.replace("<", "<");// 将<转换成<
|
|
|
|
- rowStr = rowStr.replace(">", ">");// 将>转换成>
|
|
|
|
- rowStr = rowStr.replace("&", "&");// 将&转换成&
|
|
|
|
- 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 "";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 校验图片答案格式是否正确
|
|
|
|
- *
|
|
|
|
- * @param studentAnswer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private boolean validateImgAnswer(String studentAnswer) {
|
|
|
|
- if (StringUtils.isNullOrEmpty(studentAnswer)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- String regExp = "[\\s\\S]*(ftp|https?)\\:\\/\\/([\\w\\_\\-]+)\\.([\\w\\-]+[\\.]?)*[\\w]+\\.[a-zA-Z]{2,10}(.*)\\.(png|jpg|gif|jpeg).*[\\s\\S]*";
|
|
|
|
- return studentAnswer.matches(regExp);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 校验音频答案格式是否正确
|
|
|
|
- *
|
|
|
|
- * @param studentAnswer
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
- private boolean validateAudioAnswer(String studentAnswer) {
|
|
|
|
- if (StringUtils.isNullOrEmpty(studentAnswer)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- String regExp = "^(ftp|https?)\\:\\/\\/([\\w\\_\\-]+)\\.([\\w\\-]+[\\.]?)*[\\w]+\\.[a-zA-Z]{2,10}(.*)\\.(mp3)";
|
|
|
|
- return studentAnswer.matches(regExp);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
}
|
|
}
|