|
@@ -0,0 +1,481 @@
|
|
|
|
+package cn.com.qmth.examcloud.exchange.outer.api.provider;
|
|
|
|
+
|
|
|
|
+import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
|
+import cn.com.qmth.examcloud.commons.util.RegExpUtil;
|
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordCloudService;
|
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.PagedToBeMarkExamRecordBean;
|
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.PagedToBeMarkSubjectiveAnswerBean;
|
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.request.GetPagedToBeMarkExamRecordReq;
|
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.response.GetPagedToBeMarkExamRecordResp;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.ExamQuestionOuterService;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.bean.*;
|
|
|
|
+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.OuterGetSubjectivePaperStructReq;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.request.OuterGetSubjectiveQuestionReq;
|
|
|
|
+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.bean.OuterCourseBean;
|
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.service.bean.OuterQuestionBean;
|
|
|
|
+import cn.com.qmth.examcloud.question.commons.core.paper.DefaultPaper;
|
|
|
|
+import cn.com.qmth.examcloud.question.commons.core.paper.DefaultQuestionGroup;
|
|
|
|
+import cn.com.qmth.examcloud.question.commons.core.paper.DefaultQuestionStructureWrapper;
|
|
|
|
+import cn.com.qmth.examcloud.question.commons.core.paper.DefaultQuestionUnitWrapper;
|
|
|
|
+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.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.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.web.support.ControllerSupport;
|
|
|
|
+import cn.com.qmth.examcloud.web.support.StatusResponse;
|
|
|
|
+import com.mysql.cj.util.StringUtils;
|
|
|
|
+import io.swagger.annotations.Api;
|
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
|
+import io.swagger.annotations.ApiResponse;
|
|
|
|
+import io.swagger.annotations.ApiResponses;
|
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.web.bind.annotation.PostMapping;
|
|
|
|
+import org.springframework.web.bind.annotation.RequestBody;
|
|
|
|
+import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @Description 考试作答服务
|
|
|
|
+ * @Author lideyin
|
|
|
|
+ * @Date 2020/3/30 14:48
|
|
|
|
+ * @Version 1.0
|
|
|
|
+ */
|
|
|
|
+@Api("考试作答服务")
|
|
|
|
+@RestController
|
|
|
|
+@RequestMapping("${$rmp.cloud.exchange.outer}/question")
|
|
|
|
+public class ExamQuestionOuterServiceProvider extends ControllerSupport implements ExamQuestionOuterService {
|
|
|
|
+
|
|
|
|
+ private static final long serialVersionUID = 7607495598308348018L;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private ExamRecordCloudService examRecordCloudService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private OutletPaperStructService outletPaperStructService;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ @ApiOperation(value = "获取主观题试卷结构", httpMethod = "POST")
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetSubjectivePaperStructResp.class),
|
|
|
|
+ @ApiResponse(code = 500, message = "系统异常(异常信息见响应体)", response = StatusResponse.class)})
|
|
|
|
+ @PostMapping("/getSubjectivePaperStruct")
|
|
|
|
+ public OuterGetSubjectivePaperStructResp getSubjectivePaperStruct(@RequestBody OuterGetSubjectivePaperStructReq req) {
|
|
|
|
+ if (req.getExamId() == null) {
|
|
|
|
+ throw new StatusException("101201", "考试ID不能为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取考试相关联的课程列表
|
|
|
|
+ List<OuterCourseBean> courses = outletPaperStructService.getExamCourses(req.getExamId());
|
|
|
|
+ if (CollectionUtils.isEmpty(courses)) {
|
|
|
|
+ log.warn(String.format("getExamCourses is empty, examId = %s", req.getExamId()));
|
|
|
|
+ throw new StatusException("101202", "考试相关的课程列表为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<OuterSubjectivePaperStructBean> paperStructList = new ArrayList<>();
|
|
|
|
+ for (OuterCourseBean course : courses) {
|
|
|
|
+ OuterSubjectivePaperStructBean paperStruct = new OuterSubjectivePaperStructBean();
|
|
|
|
+ paperStruct.setExamId(req.getExamId());
|
|
|
|
+ paperStruct.setSubjectCode(course.getCode());
|
|
|
|
+ paperStruct.setSubjectName(course.getName());
|
|
|
|
+ paperStructList.add(paperStruct);
|
|
|
|
+
|
|
|
|
+ // 根据考试和课程获取调卷规则下试卷的试题列表
|
|
|
|
+ List<OuterQuestionBean> questions = outletPaperStructService.getPaperStructQuestions(req.getExamId(), course.getCode());
|
|
|
|
+ if (CollectionUtils.isEmpty(questions)) {
|
|
|
|
+ // 当前考试和课程对应的调卷规则不存在时,则获取不到试卷试题
|
|
|
|
+ log.warn(String.format("getPaperStructQuestions is empty, examId = %s, courseCode = %s", req.getExamId(), course.getCode()));
|
|
|
|
+ paperStruct.setQuestions(new ArrayList<>());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<OuterSubjectiveQuestionBean> newQuestions = new ArrayList<>();
|
|
|
|
+ for (OuterQuestionBean question : questions) {
|
|
|
|
+ OuterSubjectiveQuestionBean newQuestion = new OuterSubjectiveQuestionBean();
|
|
|
|
+ newQuestion.setMainNumber(question.getMainNumber());
|
|
|
|
+ newQuestion.setMainTitle(question.getMainTitle());
|
|
|
|
+ newQuestion.setSubNumber(question.getSubNumber());
|
|
|
|
+ newQuestion.setTotalScore(question.getTotalScore());
|
|
|
|
+ newQuestions.add(newQuestion);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ paperStruct.setQuestions(newQuestions);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ OuterGetSubjectivePaperStructResp resp = new OuterGetSubjectivePaperStructResp();
|
|
|
|
+ resp.setPaperStructList(paperStructList);
|
|
|
|
+ return resp;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @ApiOperation(value = "获取主观题作答结果", httpMethod = "POST")
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetSubjectiveQuestionResp.class),
|
|
|
|
+ @ApiResponse(code = 500, message = "系统异常(异常信息见响应体)", response = StatusResponse.class)})
|
|
|
|
+ @PostMapping("/getSubjectiveQuestion")
|
|
|
|
+ @Override
|
|
|
|
+ public OuterGetSubjectiveQuestionResp getSubjectiveQuestion(@RequestBody OuterGetSubjectiveQuestionReq req) {
|
|
|
|
+ Long st = System.currentTimeMillis();
|
|
|
|
+
|
|
|
|
+ Long examId = req.getExamId();
|
|
|
|
+ if (null == examId) {
|
|
|
|
+ throw new StatusException("101001", "考试id不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String subjectCode = req.getSubjectCode();
|
|
|
|
+ if (StringUtils.isNullOrEmpty(subjectCode)) {
|
|
|
|
+ throw new StatusException("101002", "科目代码不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Long startId = req.getStartId();
|
|
|
|
+ if (null == startId) {
|
|
|
|
+ throw new StatusException("101003", "考生id不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Integer size = req.getSize();
|
|
|
|
+ if (null == size) {
|
|
|
|
+ throw new StatusException("101004", "数据量大小不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (size.intValue() > 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();
|
|
|
|
+ pagedReq.setExamId(examId);
|
|
|
|
+ pagedReq.setSubjectCode(subjectCode);
|
|
|
|
+ pagedReq.setStartId(startId);
|
|
|
|
+ pagedReq.setSize(size);
|
|
|
|
+ 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();
|
|
|
|
+ resp.setNextId(pagedResp.getNextId());
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @ApiOperation(value = "获取题目答案", httpMethod = "POST")
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetQuestionAnswerResp.class),
|
|
|
|
+ @ApiResponse(code = 500, message = "系统异常(异常信息见响应体)", response = StatusResponse.class)})
|
|
|
|
+ @PostMapping("/getQuestionAnswer")
|
|
|
|
+ @Override
|
|
|
|
+ public OuterGetQuestionAnswerResp getQuestionAnswer(@RequestBody OuterGetQuestionAnswerReq req) {
|
|
|
|
+ if (StringUtils.isNullOrEmpty(req.getQuestionId())) {
|
|
|
|
+ throw new StatusException("102001", "题目id不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ QuestionAnswerCacheBean questionAnswer = CacheHelper.getQuestionAnswer(req.getQuestionId());
|
|
|
|
+
|
|
|
|
+ OuterGetQuestionAnswerResp resp = new OuterGetQuestionAnswerResp();
|
|
|
|
+ resp.setAnswerList(questionAnswer.getRightAnswers());
|
|
|
|
+
|
|
|
|
+ return resp;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @ApiOperation(value = "获取试卷结构(题库中的原始试卷结构)", httpMethod = "POST")
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetQuestionAnswerResp.class),
|
|
|
|
+ @ApiResponse(code = 500, message = "系统异常(异常信息见响应体)", response = StatusResponse.class)})
|
|
|
|
+ @PostMapping("/getPaperStruct")
|
|
|
|
+ @Override
|
|
|
|
+ public OuterGetPaperStructResp getPaperStruct(@RequestBody OuterGetPaperStructReq req) {
|
|
|
|
+ if (null == req.getExamId()) {
|
|
|
|
+ throw new StatusException("103001", "考试记录id不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (null == req.getCourseId()) {
|
|
|
|
+ throw new StatusException("103002", "课程id不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (StringUtils.isNullOrEmpty(req.getPaperType())) {
|
|
|
|
+ throw new StatusException("103003", "试卷类型不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (StringUtils.isNullOrEmpty(req.getBasePaperId())) {
|
|
|
|
+ throw new StatusException("103004", "原始试卷id不允许为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CourseCacheBean course = CacheHelper.getCourse(req.getCourseId());
|
|
|
|
+ if (null == course) {
|
|
|
|
+ throw new StatusException("103005", "课程id不正确");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ExtractConfigPaperCacheBean extractConfigPaper = CacheHelper.getExtractConfigPaper(req.getExamId(),
|
|
|
|
+ course.getCode(), req.getPaperType(), req.getBasePaperId());
|
|
|
|
+
|
|
|
|
+ OuterGetPaperStructResp resp = new OuterGetPaperStructResp();
|
|
|
|
+ if (null != extractConfigPaper.getDefaultPaper()) {
|
|
|
|
+ resp.setDefaultPaper(transferPaperFrom(extractConfigPaper.getDefaultPaper()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return resp;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private DefaultPaperBean transferPaperFrom(DefaultPaper defaultPaper) {
|
|
|
|
+ DefaultPaperBean defaultPaperBean = new DefaultPaperBean();
|
|
|
|
+ defaultPaperBean.setFullyObjective(defaultPaper.getFullyObjective());
|
|
|
|
+ defaultPaperBean.setName(defaultPaper.getName());
|
|
|
|
+
|
|
|
|
+ List<DefaultQuestionGroup> qgList = defaultPaper.getQuestionGroupList();
|
|
|
|
+ List<DefaultQuestionGroupBean> qgBeanList = new ArrayList<>();
|
|
|
|
+ for (DefaultQuestionGroup dqg : qgList) {
|
|
|
|
+ DefaultQuestionGroupBean dqgBean = new DefaultQuestionGroupBean();
|
|
|
|
+ dqgBean.setGroupName(dqg.getGroupName());
|
|
|
|
+ dqgBean.setGroupScore(dqg.getGroupScore());
|
|
|
|
+
|
|
|
|
+ List<DefaultQuestionStructureWrapper> qwList = dqg.getQuestionWrapperList();
|
|
|
|
+ List<DefaultQuestionStructureWrapperBean> qwBeanList = new ArrayList<>();
|
|
|
|
+ for (DefaultQuestionStructureWrapper qw : qwList) {
|
|
|
|
+ DefaultQuestionStructureWrapperBean qwBean = new DefaultQuestionStructureWrapperBean();
|
|
|
|
+ qwBean.setQuestionId(qw.getQuestionId());
|
|
|
|
+ qwBean.setVersion(qw.getVersion());
|
|
|
|
+ qwBean.setQuestionScore(qw.getQuestionScore());
|
|
|
|
+ qwBean.setLimitedPlayTimes(qw.getLimitedPlayTimes());
|
|
|
|
+ qwBean.setPlayedTimes(qw.getPlayedTimes());
|
|
|
|
+ qwBean.setTimeLimit(qw.getTimeLimit());
|
|
|
|
+
|
|
|
|
+ List<DefaultQuestionUnitWrapper> quwList = qw.getQuestionUnitWrapperList();
|
|
|
|
+ List<DefaultQuestionUnitWrapperBean> quwBeanList = new ArrayList<>();
|
|
|
|
+ for (DefaultQuestionUnitWrapper quw : quwList) {
|
|
|
|
+ DefaultQuestionUnitWrapperBean quwBean = new DefaultQuestionUnitWrapperBean();
|
|
|
|
+ quwBean.setOptionPermutation(quw.getOptionPermutation());
|
|
|
|
+ quwBean.setQuestionScore(quw.getQuestionScore());
|
|
|
|
+ quwBean.setQuestionType(quw.getQuestionType() == null ? null : quw.getQuestionType().name());
|
|
|
|
+ quwBean.setAnswerType(quw.getAnswerType() == null ? null : quw.getAnswerType().name());
|
|
|
|
+
|
|
|
|
+ quwBeanList.add(quwBean);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ qwBean.setQuestionUnitWrapperList(quwBeanList);
|
|
|
|
+
|
|
|
|
+ qwBeanList.add(qwBean);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dqgBean.setQuestionWrapperList(qwBeanList);
|
|
|
|
+
|
|
|
|
+ qgBeanList.add(dqgBean);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ defaultPaperBean.setQuestionGroupList(qgBeanList);
|
|
|
|
+
|
|
|
|
+ return defaultPaperBean;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构造满足条件的考试记录集合
|
|
|
|
+ *
|
|
|
|
+ * @param toBeMarkExamRecordBeanList
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private List<OuterExamRecordBean> getOuterExamRecordBean(List<PagedToBeMarkExamRecordBean> toBeMarkExamRecordBeanList) {
|
|
|
|
+ if (null == toBeMarkExamRecordBeanList || toBeMarkExamRecordBeanList.isEmpty()) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<OuterExamRecordBean> resultList = new ArrayList<>();
|
|
|
|
+ for (PagedToBeMarkExamRecordBean pb : toBeMarkExamRecordBeanList) {
|
|
|
|
+ OuterExamRecordBean resultBean = new OuterExamRecordBean();
|
|
|
|
+ resultBean.setExamId(pb.getExamId());
|
|
|
|
+ resultBean.setStudentCode(pb.getIdentityNumber());//因为外部接口定义的名字虽然叫studentCode,实际是身份证号
|
|
|
|
+ resultBean.setName(pb.getStudentName());
|
|
|
|
+ resultBean.setCollege(pb.getGrade());
|
|
|
|
+ resultBean.setClassName(null);
|
|
|
|
+ resultBean.setTeacher(null);
|
|
|
|
+ resultBean.setSubjectCode(pb.getCourseCode());
|
|
|
|
+ resultBean.setSubjectName(pb.getCourseName());
|
|
|
|
+ resultBean.setExamNumber(String.valueOf(pb.getExamRecordDataId()));
|
|
|
|
+
|
|
|
|
+ resultBean.setSubjectives(getSubjectives(pb.getExamId(), pb.getSubjectiveAnswerList()));
|
|
|
|
+
|
|
|
|
+ resultList.add(resultBean);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return resultList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 构造满足条件的主观题集合
|
|
|
|
+ *
|
|
|
|
+ * @param subjectiveAnswerList
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private List<OuterSubjectiveQuestionRecordBean> getSubjectives(Long examId,
|
|
|
|
+ List<PagedToBeMarkSubjectiveAnswerBean> subjectiveAnswerList) {
|
|
|
|
+ List<OuterSubjectiveQuestionRecordBean> resultList = new ArrayList<>();
|
|
|
|
+ RichTextHandler complexRichTextHandler = RichTextHandlerFactory.getHandler("complex");
|
|
|
|
+
|
|
|
|
+ for (PagedToBeMarkSubjectiveAnswerBean pb : subjectiveAnswerList) {
|
|
|
|
+ OuterSubjectiveQuestionRecordBean resultBean = new OuterSubjectiveQuestionRecordBean();
|
|
|
|
+ resultBean.setMainNumber(pb.getMainNumber());
|
|
|
|
+ resultBean.setSubNumber(pb.getOrder());
|
|
|
|
+ resultBean.setQuestionId(pb.getQuestionId());
|
|
|
|
+
|
|
|
|
+ resultBean.setAnswer(transferFrom(complexRichTextHandler.handle(pb.getAnswer())));
|
|
|
|
+
|
|
|
|
+ //格式化学生答案
|
|
|
|
+ String transformedAnswerType = getTransformedAnswerType(pb.getAnswerType(), pb.getQuestionType(), examId);
|
|
|
|
+
|
|
|
|
+ RichTextHandler richTextHandler = null;
|
|
|
|
+ String stuAnswer = pb.getStudentAnswer();
|
|
|
|
+ SectionCollectionBean formattedStudentAnswer = new SectionCollectionBean();
|
|
|
|
+
|
|
|
|
+ //图片作答特殊处理:将图片作答中的文字部分和图片部分拆开
|
|
|
|
+ if (BlockType.image.name().equals(transformedAnswerType)) {
|
|
|
|
+ if (!StringUtils.isNullOrEmpty(stuAnswer)) {
|
|
|
|
+ //图片作答的标识
|
|
|
|
+ String firstMatch = RegExpUtil.find(stuAnswer, "<div \\S*photo-answers-block\\S*>");
|
|
|
|
+
|
|
|
|
+ int index;
|
|
|
|
+ if (StringUtils.isNullOrEmpty(firstMatch)) {
|
|
|
|
+ index = -1;
|
|
|
|
+ } else {
|
|
|
|
+ index = stuAnswer.indexOf(firstMatch);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //只有文字作答,处理文字
|
|
|
|
+ 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);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //非图片作答,则直接根据作答类型进行处理
|
|
|
|
+ else {
|
|
|
|
+ richTextHandler = RichTextHandlerFactory.getHandler(transformedAnswerType);
|
|
|
|
+ formattedStudentAnswer = richTextHandler.handle(stuAnswer);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ OuterSectionCollectionBean stuAnswerResult = transferFrom(formattedStudentAnswer);
|
|
|
|
+
|
|
|
|
+ resultBean.setStudentAnswer(stuAnswerResult);
|
|
|
|
+
|
|
|
|
+ resultBean.setBody(transferFrom(complexRichTextHandler.handle(pb.getBody())));
|
|
|
|
+ resultBean.setParentBody(transferFrom(complexRichTextHandler.handle(pb.getParentBody())));
|
|
|
|
+
|
|
|
|
+ resultList.add(resultBean);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return resultList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static OuterSectionCollectionBean transferFrom(SectionCollectionBean sectionCollection) {
|
|
|
|
+ List<SectionBean> sections = sectionCollection.getSections();
|
|
|
|
+ if (null == sections || sections.isEmpty()) {
|
|
|
|
+ return new OuterSectionCollectionBean();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据原始作答类型和学生实际作答推断出真实的作答类型
|
|
|
|
+ *
|
|
|
|
+ * @param answerType 原始作答类型
|
|
|
|
+ * @param questionType 题型
|
|
|
|
+ * @param examId 考试id
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private String getTransformedAnswerType(AnswerType answerType, QuestionType questionType, Long examId) {
|
|
|
|
+ //如果题型为问答题,且作答类型不为音频作答,且开启微信作答,则此题为图片作答题
|
|
|
|
+ if (questionType == QuestionType.ESSAY &&
|
|
|
|
+ (null == answerType || (null != answerType && answerType != AnswerType.SINGLE_AUDIO))) {
|
|
|
|
+ if (ExamCacheTransferHelper.weixinAnswerEnabled(examId)) {
|
|
|
|
+ return "image";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (null != answerType && answerType == AnswerType.SINGLE_AUDIO) {
|
|
|
|
+ return "audio";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return "text";
|
|
|
|
+ }
|
|
|
|
+}
|