ソースを参照

提交试卷,考试结果明细查看

yangfeng 1 年間 前
コミット
5bb3d4c48a

+ 147 - 63
web/src/main/java/com/ynfy/buss/exam/exam/service/impl/ExamServiceImpl.java

@@ -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;
     }
 
     /**

+ 22 - 3
web/src/main/java/com/ynfy/buss/exam/paperrulegroup/service/impl/PaperRuleGroupServiceImpl.java

@@ -14,6 +14,7 @@ import com.ynfy.buss.exam.paperruledetail.service.IPaperRuleDetailService;
 import com.ynfy.buss.exam.paperrulegroup.entity.PaperRuleGroup;
 import com.ynfy.buss.exam.paperrulegroup.mapper.PaperRuleGroupMapper;
 import com.ynfy.buss.exam.paperrulegroup.service.IPaperRuleGroupService;
+import com.ynfy.buss.exam.question.entity.Question;
 import com.ynfy.buss.exam.question.enums.QuestionType;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
@@ -134,9 +135,27 @@ public class PaperRuleGroupServiceImpl extends ServiceImpl<PaperRuleGroupMapper,
      * @return
      */
     public boolean hasSubjective(List<PaperRuleGroup> groupList) {
-        //主观题
-        long subjectiveNum = groupList.stream().filter(o -> o.getQuestionType().equals(QuestionType.SIMPLE.getCode())).count();
-        return subjectiveNum > 0 ? true : false;
+        boolean subjective = false;
+        for (PaperRuleGroup group : groupList) {
+            if (QuestionType.SIMPLE.getCode().equals(group.getQuestionType())) {
+                subjective = true;
+                break;
+            }
+            if (QuestionType.COMBINATION.getCode().equals(group.getQuestionType())) {
+                for (Question question : group.getQuestionList()) {
+                    long subjectiveNum = question.getSubQuestionList().stream().filter(o -> o.getType()
+                            .equals(QuestionType.SIMPLE.getCode())).count();
+                    if (subjectiveNum > 0) {
+                        subjective = true;
+                        break;
+                    }
+                }
+            }
+            if(subjective){
+                break;
+            }
+        }
+        return subjective;
     }