|
@@ -428,7 +428,7 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
.sorted(Comparator.comparing(UserExamQuestion::getQuestionIndex)).collect(Collectors.toList());
|
|
|
if (!CollectionUtils.isEmpty(rootQuestionList)) {
|
|
|
//获取题目和答案
|
|
|
- getUserExamQuestionMap(userExamId, rootQuestionList, childQuestionList, needAnswerFlag, needAnalysis, false, true, needClearBlankContent);
|
|
|
+ assembleUserExamQuestion(userExamId, rootQuestionList, childQuestionList, needAnswerFlag, needAnalysis, false, true, needClearBlankContent);
|
|
|
|
|
|
//设置题目
|
|
|
setUserExamQuestion(rootQuestionList, needRenderBlank);
|
|
@@ -465,14 +465,28 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
List<UserExamQuestion> userExamQuestionList = userExamDTO.getUserExamQuestionList();
|
|
|
if (!CollectionUtils.isEmpty(userExamQuestionList)) {
|
|
|
userExamQuestionList.forEach(userExamQuestion -> {
|
|
|
- if (QuestionType.RADIO.getCode().equals(userExamQuestion.getQuestionType()) || QuestionType.MULTI.getCode().equals(userExamQuestion.getQuestionType())
|
|
|
- || QuestionType.JUDGE.getCode().equals(userExamQuestion.getQuestionType())) {
|
|
|
- userExamQuestion.setAnswer(generateQuestionAnswerTag(userExamQuestion.getAnswer(), userExamQuestion.getQuestion()));
|
|
|
+ if (QuestionType.COMBINATION.getCode().equals(userExamQuestion.getQuestionType())) {//组合题
|
|
|
+ userExamQuestion.getSubQuestionList().forEach(o -> setTagByAnswerIds(o));
|
|
|
+ } else {
|
|
|
+ setTagByAnswerIds(userExamQuestion);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据单选题/多选题/判断题的答案ID回写tag
|
|
|
+ *
|
|
|
+ * @param userExamQuestion
|
|
|
+ */
|
|
|
+ public void setTagByAnswerIds(UserExamQuestion userExamQuestion) {
|
|
|
+ if (QuestionType.RADIO.getCode().equals(userExamQuestion.getQuestionType())
|
|
|
+ || QuestionType.MULTI.getCode().equals(userExamQuestion.getQuestionType())
|
|
|
+ || QuestionType.JUDGE.getCode().equals(userExamQuestion.getQuestionType())) {
|
|
|
+ userExamQuestion.setAnswer(generateQuestionAnswerTag(userExamQuestion.getAnswer(), userExamQuestion.getQuestion()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 生成单选,单选,填空答案tag
|
|
|
*
|
|
@@ -508,11 +522,11 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
//渲染填空题的题干,填充进答案
|
|
|
if (QuestionType.COMBINATION.getCode().equals(question.getType())) {//组合题
|
|
|
userExamQuestion.getSubQuestionList().forEach(subQuestion -> {
|
|
|
- rendBlank(needRenderBlank, userExamQuestion, subQuestion.getQuestion());
|
|
|
+ rendBlankAnswer(needRenderBlank, subQuestion, subQuestion.getQuestion());
|
|
|
subQuestion.setQuestionTypeName(QuestionType.getByCode(subQuestion.getQuestionType()).getValue());
|
|
|
});
|
|
|
} else {
|
|
|
- rendBlank(needRenderBlank, userExamQuestion, question);
|
|
|
+ rendBlankAnswer(needRenderBlank, userExamQuestion, question);
|
|
|
}
|
|
|
userExamQuestion.setQuestion(question);
|
|
|
userExamQuestion.setQuestionTypeName(QuestionType.getByCode(userExamQuestion.getQuestionType()).getValue());
|
|
@@ -520,13 +534,13 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 渲染填空题
|
|
|
+ * 渲染填空题答案
|
|
|
*
|
|
|
* @param needRenderBlank
|
|
|
* @param userExamQuestion
|
|
|
* @param question
|
|
|
*/
|
|
|
- public void rendBlank(boolean needRenderBlank, UserExamQuestion userExamQuestion, Question question) {
|
|
|
+ public void rendBlankAnswer(boolean needRenderBlank, UserExamQuestion userExamQuestion, Question question) {
|
|
|
if (needRenderBlank && QuestionType.BLANK.getCode().equals(userExamQuestion.getQuestionType())) {
|
|
|
renderBlank(question, userExamQuestion.getAnswer());
|
|
|
}
|
|
@@ -597,6 +611,14 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
throw new JeecgBootException("考题查询失败");
|
|
|
}
|
|
|
|
|
|
+ List<UserExamQuestion> rootQuestionList = userExamQuestionList.stream().filter(r -> !Objects.isNull(r.getChild()) && !r.getChild())
|
|
|
+ .sorted(Comparator.comparing(UserExamQuestion::getQuestionIndex)).collect(Collectors.toList());
|
|
|
+ List<UserExamQuestion> childQuestionList = userExamQuestionList.stream().filter(r -> !Objects.isNull(r.getChild()) && r.getChild())
|
|
|
+ .sorted(Comparator.comparing(UserExamQuestion::getQuestionIndex)).collect(Collectors.toList());
|
|
|
+ if (!CollectionUtils.isEmpty(rootQuestionList)) {
|
|
|
+ //组装题目、子题目和答案
|
|
|
+ assembleUserExamQuestion(dto.getUserExamId(), rootQuestionList, childQuestionList, true, false, true, false, false);
|
|
|
+ }
|
|
|
//如果没有作答
|
|
|
List<ExamAnswerDTO> examAnswers = dto.getExamAnswers();
|
|
|
if (CollectionUtils.isEmpty(examAnswers)) {
|
|
@@ -605,13 +627,10 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
updateObjectiveQuestion(userExamQuestionList);
|
|
|
} else {
|
|
|
//有作答
|
|
|
- Map<Integer, UserExamQuestion> userExamQuestionMap = userExamQuestionList.stream().collect(Collectors.toMap(UserExamQuestion::getQuestionIndex, a -> a, (k1, k2) -> k1));
|
|
|
-
|
|
|
- //获取题目和答案
|
|
|
- getUserExamQuestionMap(dto.getUserExamId(), userExamQuestionList, null, true, false, true, false, false);
|
|
|
+ Map<Integer, UserExamQuestion> userExamQuestionMap = rootQuestionList.stream().collect(Collectors.toMap(UserExamQuestion::getQuestionIndex, a -> a, (k1, k2) -> k1));
|
|
|
|
|
|
//计算客观题得分
|
|
|
- int score = calcObjectiveScore(examAnswers, userExamQuestionMap, null, userExamQuestionList);
|
|
|
+ int score = calcObjectiveScore(examAnswers, userExamQuestionMap, rootQuestionList);
|
|
|
//更新用户考试信息和成绩
|
|
|
updateUserExamAndResult(score, userExam);
|
|
|
}
|
|
@@ -639,11 +658,11 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //获取题目和答案
|
|
|
- public void getUserExamQuestionMap(String userExamId, List<UserExamQuestion> rootExamQuestionList,
|
|
|
- List<UserExamQuestion> childQuestionList, boolean needAnswerFlag,
|
|
|
- boolean needAnalysis, boolean needPathScore, boolean needSubjective,
|
|
|
- boolean needClearBlankContent) {
|
|
|
+ //组装题目、子题目和答案
|
|
|
+ public void assembleUserExamQuestion(String userExamId, List<UserExamQuestion> rootExamQuestionList,
|
|
|
+ List<UserExamQuestion> childQuestionList, boolean needAnswerFlag,
|
|
|
+ boolean needAnalysis, boolean needPathScore, boolean needSubjective,
|
|
|
+ boolean needClearBlankContent) {
|
|
|
List<String> subjectiveList = new ArrayList<>();
|
|
|
if (needSubjective) {//是否需要主观题
|
|
|
List<String> rootSubjectList = getSubjectList(rootExamQuestionList);
|
|
@@ -752,64 +771,129 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IE
|
|
|
*
|
|
|
* @param examAnswers
|
|
|
* @param userExamQuestionMap
|
|
|
- * @param questionMap
|
|
|
* @return
|
|
|
*/
|
|
|
- public int calcObjectiveScore(List<ExamAnswerDTO> examAnswers, Map<Integer, UserExamQuestion> userExamQuestionMap, Map<String, Question> questionMap, List<UserExamQuestion> userExamQuestionList) {
|
|
|
- //最终得分
|
|
|
- int score = 0;
|
|
|
+ public int calcObjectiveScore(List<ExamAnswerDTO> examAnswers, Map<Integer, UserExamQuestion> userExamQuestionMap, List<UserExamQuestion> rootQuestionList) {
|
|
|
if (!CollectionUtils.isEmpty(examAnswers)) {
|
|
|
//对比/计算
|
|
|
for (ExamAnswerDTO o : examAnswers) {
|
|
|
- UserExamQuestion userExamQuestion = userExamQuestionMap.get(o.getIndex());
|
|
|
- userExamQuestion.setAnswered(true);//已答
|
|
|
- //主观题(简答题)
|
|
|
- if (userExamQuestion.getQuestionType().equals(QuestionType.SIMPLE.getCode())) {
|
|
|
- userExamQuestion.setAnswer(o.getSubjectiveAnswer());//答案内容
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- //单选,多选,判断题获取并设置答案
|
|
|
- String[] answers = o.getAnswers();
|
|
|
- if (!userExamQuestion.getQuestionType().equals(QuestionType.BLANK.getCode())) {
|
|
|
- if (!Objects.isNull(answers) && answers.length > 0) {
|
|
|
- userExamQuestion.setAnswer(String.join(",", answers));
|
|
|
+ //根据题型计算客观题得分
|
|
|
+ calcQuestionScoreByType(o, userExamQuestionMap);
|
|
|
+ }
|
|
|
+ List<UserExamQuestion> resultList = new ArrayList<>();
|
|
|
+ rootQuestionList.forEach(root -> {
|
|
|
+ if (QuestionType.COMBINATION.getCode().equals(root.getQuestionType())) {
|
|
|
+ long answerNum = examAnswers.stream().filter(answer -> answer.getIndex().startsWith(root.getQuestionIndex() + ".")).count();
|
|
|
+ if (answerNum > 0) {
|
|
|
+ root.setAnswered(true);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- //填空题获取答案
|
|
|
- String blankAnswer = o.getBlankAnswer();
|
|
|
-
|
|
|
- //提交的答案和题目答案对比
|
|
|
- Question question = questionMap.get(userExamQuestion.getQuestionId());
|
|
|
- switch (QuestionType.getByCode(question.getType())) {
|
|
|
- //单选题和判断题直接答案完全匹配
|
|
|
- case RADIO:
|
|
|
- case JUDGE:
|
|
|
- score += compareToScore(userExamQuestion, answers, question);
|
|
|
- break;
|
|
|
- case MULTI: //多选题
|
|
|
- if (!Objects.isNull(userExamQuestion.getCanMissOption()) && userExamQuestion.getCanMissOption()) {
|
|
|
- score += compareMultiToScore(userExamQuestion, answers, question);
|
|
|
+ root.setActualScore(root.getSubQuestionList().stream().filter(o ->
|
|
|
+ !Objects.isNull(o.getActualScore())).mapToInt(UserExamQuestion::getActualScore).sum());
|
|
|
+ resultList.add(root);
|
|
|
+ root.getSubQuestionList().forEach(subQuestion -> {
|
|
|
+ //是否是没回答的客观题,如果是,是否正确设置为false
|
|
|
+ noAnswerFill(examAnswers, root.getQuestionIndex() + "." + subQuestion.getQuestionIndex(), subQuestion);
|
|
|
+ resultList.add(subQuestion);
|
|
|
+ });
|
|
|
+ //子题目中是否包含简答题,如果包含简答题,需要阅卷
|
|
|
+ long simpleCount = root.getSubQuestionList().stream().filter(o -> o.getQuestionType()
|
|
|
+ .equals(QuestionType.SIMPLE.getCode())).count();
|
|
|
+ if (simpleCount > 0) {
|
|
|
+ root.setIsRight(null);
|
|
|
+ } else {
|
|
|
+ if (root.getActualScore() < root.getQuestionScore()) {
|
|
|
+ root.setIsRight(false);
|
|
|
} else {
|
|
|
- score += compareToScore(userExamQuestion, answers, question);
|
|
|
+ root.setIsRight(true);
|
|
|
}
|
|
|
- break;
|
|
|
- case BLANK: //填空题
|
|
|
- score += compareBlankToScore(userExamQuestion, blankAnswer, question, userExamQuestion.getCanBlankOption());
|
|
|
- break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ noAnswerFill(examAnswers, String.valueOf(root.getQuestionIndex()), root);
|
|
|
+ resultList.add(root);
|
|
|
}
|
|
|
+ });
|
|
|
+ if (!CollectionUtils.isEmpty(resultList)) {
|
|
|
+ userExamQuestionService.updateBatchById(resultList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //最终得分
|
|
|
+ return rootQuestionList.stream().filter(o -> !Objects.isNull(o.getActualScore()))
|
|
|
+ .mapToInt(UserExamQuestion::getActualScore).sum();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否是没回答的客观题,如果是,是否正确设置为false
|
|
|
+ *
|
|
|
+ * @param examAnswers
|
|
|
+ * @param questionIndex
|
|
|
+ * @param userExamQuestion
|
|
|
+ */
|
|
|
+ public void noAnswerFill(List<ExamAnswerDTO> examAnswers, String questionIndex, UserExamQuestion userExamQuestion) {
|
|
|
+ List<String> indexList = examAnswers.stream().map(ExamAnswerDTO::getIndex).collect(toList());
|
|
|
+ if (!indexList.contains(questionIndex) && !userExamQuestion.getQuestionType().equals(QuestionType.SIMPLE.getCode())) {
|
|
|
+ userExamQuestion.setIsRight(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据题型计算客观题得分
|
|
|
+ *
|
|
|
+ * @param o
|
|
|
+ * @param userExamQuestionMap
|
|
|
+ */
|
|
|
+ public void calcQuestionScoreByType(ExamAnswerDTO o, Map<Integer, UserExamQuestion> userExamQuestionMap) {
|
|
|
+ UserExamQuestion userExamQuestion = null;
|
|
|
+ if (o.getIndex().indexOf(".") != -1) {
|
|
|
+ //获取子题目
|
|
|
+ String[] indexArray = o.getIndex().split("\\.");
|
|
|
+ UserExamQuestion userExamRootQuestion = userExamQuestionMap.get(Integer.parseInt(indexArray[0]));
|
|
|
+ if (!Objects.isNull(userExamRootQuestion)) {
|
|
|
+ userExamQuestion = userExamRootQuestion.getSubQuestionList().stream().filter(item -> item.getQuestionIndex()
|
|
|
+ .equals(Integer.parseInt(indexArray[1]))).findFirst().orElse(null);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ userExamQuestion = userExamQuestionMap.get(Integer.parseInt(o.getIndex()));
|
|
|
+ }
|
|
|
+ if (Objects.isNull(userExamQuestion)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ userExamQuestion.setAnswered(true);//已答
|
|
|
+ //主观题(简答题)
|
|
|
+ if (userExamQuestion.getQuestionType().equals(QuestionType.SIMPLE.getCode())) {
|
|
|
+ userExamQuestion.setAnswer(o.getSubjectiveAnswer());//答案内容
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- //获取回答过的题目
|
|
|
- List<String> indexList = examAnswers.stream().map(ExamAnswerDTO::getIndex).collect(toList());
|
|
|
- //获取没回答的客观题题目
|
|
|
- List<UserExamQuestion> objectiveNoAnswerList = userExamQuestionList.stream().filter(o -> !indexList.contains(o.getQuestionIndex())).filter(o -> !o.getQuestionType().equals(QuestionType.SIMPLE.getCode())).collect(Collectors.toList());
|
|
|
- objectiveNoAnswerList.stream().forEach(o -> o.setIsRight(false));
|
|
|
+ //单选,多选,判断题获取并设置答案
|
|
|
+ String[] answers = o.getAnswers();
|
|
|
+ if (!userExamQuestion.getQuestionType().equals(QuestionType.BLANK.getCode())) {
|
|
|
+ if (!Objects.isNull(answers) && answers.length > 0) {
|
|
|
+ userExamQuestion.setAnswer(String.join(",", answers));
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- userExamQuestionService.updateBatchById(userExamQuestionList);
|
|
|
+ //填空题获取答案
|
|
|
+ String blankAnswer = o.getBlankAnswer();
|
|
|
+
|
|
|
+ //提交的答案和题目答案对比
|
|
|
+ Question question = userExamQuestion.getQuestion();
|
|
|
+ switch (QuestionType.getByCode(question.getType())) {
|
|
|
+ //单选题和判断题直接答案完全匹配
|
|
|
+ case RADIO:
|
|
|
+ case JUDGE:
|
|
|
+ compareToScore(userExamQuestion, answers, question);
|
|
|
+ break;
|
|
|
+ case MULTI: //多选题
|
|
|
+ if (!Objects.isNull(userExamQuestion.getCanMissOption()) && userExamQuestion.getCanMissOption()) {
|
|
|
+ compareMultiToScore(userExamQuestion, answers, question);
|
|
|
+ } else {
|
|
|
+ compareToScore(userExamQuestion, answers, question);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case BLANK: //填空题
|
|
|
+ compareBlankToScore(userExamQuestion, blankAnswer, question, userExamQuestion.getCanBlankOption());
|
|
|
+ break;
|
|
|
}
|
|
|
- return score;
|
|
|
}
|
|
|
|
|
|
/**
|