|
@@ -2,21 +2,19 @@ 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.basic.api.CourseCloudService;
|
|
|
+import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
|
|
|
+import cn.com.qmth.examcloud.core.basic.api.request.GetCourseReq;
|
|
|
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.base.enums.QuestionCategory;
|
|
|
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.api.request.*;
|
|
|
+import cn.com.qmth.examcloud.exchange.outer.api.response.*;
|
|
|
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;
|
|
@@ -25,11 +23,14 @@ 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.DefaultQuestionStructure;
|
|
|
+import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionUnit;
|
|
|
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.ExamSettingsCacheBean;
|
|
|
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.QuestionCacheBean;
|
|
|
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;
|
|
@@ -52,6 +53,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* @Description 考试作答服务
|
|
@@ -72,6 +74,9 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
@Autowired
|
|
|
private OutletPaperStructService outletPaperStructService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private CourseCloudService courseCloudService;
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
@ApiOperation(value = "获取主观题试卷结构", httpMethod = "POST")
|
|
@@ -99,7 +104,8 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
paperStructList.add(paperStruct);
|
|
|
|
|
|
// 根据考试和课程获取调卷规则下试卷的试题列表
|
|
|
- List<OuterQuestionBean> questions = outletPaperStructService.getPaperStructQuestions(req.getExamId(), course.getCode());
|
|
|
+ List<OuterQuestionBean> questions = outletPaperStructService.getPaperStructQuestions(
|
|
|
+ req.getExamId(), course.getCode(), QuestionCategory.SUBJECTIVE);
|
|
|
if (CollectionUtils.isEmpty(questions)) {
|
|
|
// 当前考试和课程对应的调卷规则不存在时,则获取不到试卷试题
|
|
|
log.warn(String.format("getPaperStructQuestions is empty, examId = %s, courseCode = %s", req.getExamId(), course.getCode()));
|
|
@@ -193,6 +199,88 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
return resp;
|
|
|
}
|
|
|
|
|
|
+ @ApiOperation(value = "获取主观题试卷信息", httpMethod = "POST")
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetSubjectivePaperResp.class),
|
|
|
+ @ApiResponse(code = 500, message = "系统异常(异常信息见响应体)", response = StatusResponse.class)})
|
|
|
+ @PostMapping("/getSubjectivePaper")
|
|
|
+ @Override
|
|
|
+ public OuterGetSubjectivePaperResp getSubjectivePaper(@RequestBody OuterGetSubjectivePaperReq req) {
|
|
|
+ Long examId = req.getExamId();
|
|
|
+ if (null == examId) {
|
|
|
+ throw new StatusException("105001", "考试id不允许为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ String subjectCode = req.getSubjectCode();
|
|
|
+ if (StringUtils.isNullOrEmpty(subjectCode)) {
|
|
|
+ throw new StatusException("105002", "科目代码不允许为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ CourseBean course = getCourse(examId, subjectCode);
|
|
|
+ if (null == course) {
|
|
|
+ throw new StatusException("105003", "找不到科目代码对应的科目信息");
|
|
|
+ }
|
|
|
+
|
|
|
+ OuterGetSubjectivePaperResp resp = new OuterGetSubjectivePaperResp();
|
|
|
+
|
|
|
+ //主观题试题信息
|
|
|
+ List<OuterQuestionBean> subjectiveQuestions = outletPaperStructService.getPaperStructQuestions(
|
|
|
+ req.getExamId(), course.getCode(), QuestionCategory.SUBJECTIVE);
|
|
|
+
|
|
|
+ if (null == subjectiveQuestions) {
|
|
|
+ throw new StatusException("105004", "当前科目无主观题");
|
|
|
+ }
|
|
|
+
|
|
|
+ OuterSubjectivePaperBean osb=new OuterSubjectivePaperBean();
|
|
|
+ osb.setExamId(examId);
|
|
|
+ osb.setSubjectCode(subjectCode);
|
|
|
+ osb.setSubjectName(course.getName());
|
|
|
+
|
|
|
+ List<OuterSubjectivePaperQuestionBean> subPaperQuesList=new ArrayList<>();
|
|
|
+ //所有试题信息
|
|
|
+ List<OuterQuestionBean> allQuestions = outletPaperStructService.getPaperStructQuestions(
|
|
|
+ req.getExamId(), course.getCode(), QuestionCategory.SUBJECTIVE);
|
|
|
+ RichTextHandler complexRichTextHandler = RichTextHandlerFactory.getHandler("complex");
|
|
|
+
|
|
|
+ for (OuterQuestionBean subQues : subjectiveQuestions) {
|
|
|
+ OuterSubjectivePaperQuestionBean subPaperQues=new OuterSubjectivePaperQuestionBean();
|
|
|
+ //获取指定小题的题干相关信息
|
|
|
+ QuestionCacheBean cachedQues = CacheHelper.getQuestion(examId, subjectCode, subQues.getPaperType(), subQues.getQuestionId());
|
|
|
+ String strAnswer=getCorrectAnswer(subQues.getSubNumber(), subQues.getQuestionId(), cachedQues, allQuestions);
|
|
|
+ String strParentBody=getParentBody(cachedQues);
|
|
|
+ String strBody=getBody(subQues.getSubNumber(), subQues.getQuestionId(), cachedQues, allQuestions);
|
|
|
+
|
|
|
+ subPaperQues.setAnswer(transferFrom(complexRichTextHandler.handle(strAnswer)));
|
|
|
+ subPaperQues.setParentBody(transferFrom(complexRichTextHandler.handle(strParentBody)));
|
|
|
+ subPaperQues.setBody(transferFrom(complexRichTextHandler.handle(strBody)));
|
|
|
+
|
|
|
+ subPaperQues.setMainNumber(subQues.getMainNumber());
|
|
|
+ subPaperQues.setSubNumber(subQues.getSubNumber());
|
|
|
+ subPaperQues.setQuestionId(subQues.getQuestionId());
|
|
|
+ subPaperQuesList.add(subPaperQues);
|
|
|
+ }
|
|
|
+ osb.setQuestions(subPaperQuesList);
|
|
|
+
|
|
|
+ resp.setSubjectivePaper(osb);
|
|
|
+
|
|
|
+ return resp;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取课程相关信息
|
|
|
+ *
|
|
|
+ * @param examId
|
|
|
+ * @param subjectCode
|
|
|
+ */
|
|
|
+ private CourseBean getCourse(Long examId, String subjectCode) {
|
|
|
+ ExamSettingsCacheBean examSettings = CacheHelper.getExamSettings(examId);
|
|
|
+ Long rootOrgId = examSettings.getRootOrgId();
|
|
|
+ GetCourseReq courseReq = new GetCourseReq();
|
|
|
+ courseReq.setRootOrgId(rootOrgId);
|
|
|
+ courseReq.setCode(subjectCode);
|
|
|
+ return courseCloudService.getCourse(courseReq).getCourseBean();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
@ApiOperation(value = "获取题目答案", httpMethod = "POST")
|
|
|
@ApiResponses({@ApiResponse(code = 200, message = "成功", response = OuterGetQuestionAnswerResp.class),
|
|
|
@ApiResponse(code = 500, message = "系统异常(异常信息见响应体)", response = StatusResponse.class)})
|
|
@@ -336,7 +424,6 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
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();
|
|
@@ -344,8 +431,6 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
resultBean.setSubNumber(pb.getOrder());
|
|
|
resultBean.setQuestionId(pb.getQuestionId());
|
|
|
|
|
|
- resultBean.setAnswer(transferFrom(complexRichTextHandler.handle(pb.getAnswer())));
|
|
|
-
|
|
|
//格式化学生答案
|
|
|
String transformedAnswerType = getTransformedAnswerType(pb.getAnswerType(), pb.getQuestionType(), examId);
|
|
|
|
|
@@ -406,10 +491,7 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
|
|
|
OuterSectionCollectionBean stuAnswerResult = transferFrom(formattedStudentAnswer);
|
|
|
|
|
|
- resultBean.setStudentAnswer(stuAnswerResult);
|
|
|
-
|
|
|
- resultBean.setBody(transferFrom(complexRichTextHandler.handle(pb.getBody())));
|
|
|
- resultBean.setParentBody(transferFrom(complexRichTextHandler.handle(pb.getParentBody())));
|
|
|
+ resultBean.setAnswer(stuAnswerResult);
|
|
|
|
|
|
resultList.add(resultBean);
|
|
|
}
|
|
@@ -473,4 +555,104 @@ public class ExamQuestionOuterServiceProvider extends ControllerSupport implemen
|
|
|
|
|
|
return "text";
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取套题的主题干
|
|
|
+ *
|
|
|
+ * @param cachedQues
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String getParentBody(QuestionCacheBean cachedQues) {
|
|
|
+
|
|
|
+ DefaultQuestionStructure questionStructure = cachedQues.getDefaultQuestion().getMasterVersion();
|
|
|
+
|
|
|
+ //如果主题干不为空,则认为是套题
|
|
|
+ return questionStructure.getBody();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前小题的题干
|
|
|
+ *
|
|
|
+ * @param curSubNumber 当前小题号
|
|
|
+ * @param questionId 原小题id
|
|
|
+ * @param cachedQues 带题干的试卷结构
|
|
|
+ * @param subjectiveQuesList 主观题集合
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String getBody(Integer curSubNumber, String questionId,
|
|
|
+ QuestionCacheBean cachedQues, List<OuterQuestionBean> subjectiveQuesList) {
|
|
|
+ DefaultQuestionStructure questionStructure = cachedQues.getDefaultQuestion().getMasterVersion();
|
|
|
+
|
|
|
+ //body为空,则说明当前小题为非套题(即questionUnitList集合大小为1),可直接返回小题题干
|
|
|
+ if (StringUtils.isNullOrEmpty(questionStructure.getBody())) {
|
|
|
+ return questionStructure.getQuestionUnitList().get(0).getBody();
|
|
|
+ }
|
|
|
+
|
|
|
+ //同一questionId的主观题集合(不带题干)
|
|
|
+ List<OuterQuestionBean> noBodySubjectiveQuesList = subjectiveQuesList.stream().
|
|
|
+ filter(p -> p.getQuestionId().equals(questionId)).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //同一questionId的主观题集合(带题干)
|
|
|
+ List<DefaultQuestionUnit> haveBodySubjectiveQuesList = questionStructure.getQuestionUnitList().stream()
|
|
|
+ .filter(p -> QuestionType.FILL_UP == p.getQuestionType() || QuestionType.ESSAY == p.getQuestionType())
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (int i = 0; i < noBodySubjectiveQuesList.size(); i++) {
|
|
|
+ //如果小题号相同,则根据相同索引从带题干的集合中取出对应的小题题干
|
|
|
+ if (noBodySubjectiveQuesList.get(i).getSubNumber().intValue() == curSubNumber.intValue()) {
|
|
|
+ return haveBodySubjectiveQuesList.get(i).getBody();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前小题的标准答案
|
|
|
+ *
|
|
|
+ * @param curSubNumber 当前小题号
|
|
|
+ * @param questionId 原小题id
|
|
|
+ * @param cachedQues 带题干的试卷结构
|
|
|
+ * @param allEqList 所有作答集合
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String getCorrectAnswer(Integer curSubNumber, String questionId,
|
|
|
+ QuestionCacheBean cachedQues, List<OuterQuestionBean> allEqList) {
|
|
|
+ QuestionAnswerCacheBean questionAnswerCache = CacheHelper.getQuestionAnswer(questionId);
|
|
|
+ List<String> rightAnswerList = questionAnswerCache.getRightAnswers();
|
|
|
+ DefaultQuestionStructure questionStructure = cachedQues.getDefaultQuestion().getMasterVersion();
|
|
|
+
|
|
|
+
|
|
|
+ //body为空,则说明当前小题为非套题(rightAnswerList集合大小为1),可直接返回
|
|
|
+ if (StringUtils.isNullOrEmpty(questionStructure.getBody())) {
|
|
|
+ return rightAnswerList.get(0);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //同一questionId的主观题集合(不带题干,有小题号)
|
|
|
+ List<OuterQuestionBean> noBodySubjectiveQuesList = allEqList.stream().
|
|
|
+ filter(p -> p.getQuestionId().equals(questionId)).collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (int i = 0; i < noBodySubjectiveQuesList.size(); i++) {
|
|
|
+ //如果小题号相同,则根据相同索引从带题干的集合中取出对应的小题题干
|
|
|
+ if (noBodySubjectiveQuesList.get(i).getSubNumber().intValue() == curSubNumber.intValue()) {
|
|
|
+ return rightAnswerList.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ String str1 ="111";
|
|
|
+ String str2 ="222";
|
|
|
+ String str3 ="111111";
|
|
|
+ String str4 ="222222";
|
|
|
+ String str5 ="222222dfsdffsd234234234234rwefsfsdfsdfaasfdsadfasdfsad";
|
|
|
+ String str6 ="222222dfsdffsd234234234239rwefsfsdfsdfaasfdsadfasdfsad";
|
|
|
+ System.out.println("1001110101011100111001101110101110100100001000000111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".length());
|
|
|
+ System.out.println("9D5CE6EBA420717BE7E7D308B11F8207681B066C951D68F3994D19828F342474".length());
|
|
|
+ System.out.println(String.format("str1=%s,str2=%s,str3=%s,str4=%s,str5=%s,str6=%s",
|
|
|
+ str1.hashCode(),str2.hashCode(),str3.hashCode(),str4.hashCode(),str5.hashCode(),str6.hashCode()));
|
|
|
+ }
|
|
|
}
|