Pārlūkot izejas kodu

给阅卷导出作答信息新加标答和题干字段

lideyin 5 gadi atpakaļ
vecāks
revīzija
c83e2d3421

+ 103 - 36
examcloud-core-oe-admin-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/admin/api/provider/ExamRecordQuestionsCloudServiceProvider.java

@@ -1,22 +1,5 @@
 package cn.com.qmth.examcloud.core.oe.admin.api.provider;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.jsoup.Jsoup;
-import org.jsoup.nodes.Document;
-import org.jsoup.nodes.Element;
-import org.jsoup.select.Elements;
-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 com.mysql.cj.util.StringUtils;
-
 import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordQuestionsCloudService;
 import cn.com.qmth.examcloud.core.oe.admin.api.bean.QuerySubjectiveAnswerBean;
 import cn.com.qmth.examcloud.core.oe.admin.api.bean.SaveSubjectiveQuestionScoreBean;
@@ -35,13 +18,31 @@ import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordQuestionsEntity;
 import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordQuestionsService;
 import cn.com.qmth.examcloud.core.oe.admin.service.bean.SubjectiveQuestionScoreInfo;
 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.QuestionCacheBean;
 import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
+import com.mysql.cj.util.StringUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+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.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author chenken
@@ -144,19 +145,84 @@ public class ExamRecordQuestionsCloudServiceProvider extends ControllerSupport i
             List<ExamQuestionEntity> subjectiveQuestionList = examQuestionList.stream().filter(p -> p.getQuestionType() == QuestionType.ESSAY ||
                     p.getQuestionType() == QuestionType.FILL_UP).collect(Collectors.toList());
 
-            for (ExamQuestionEntity sq : subjectiveQuestionList) {
-                SubjectiveAnswerBean subjectiveAnswerBean = new SubjectiveAnswerBean();
-                subjectiveAnswerBean.setAnswerType(sq.getAnswerType());
-                subjectiveAnswerBean.setRealAnswerType(transformedAnswerType(sq.getAnswerType(),sq.getQuestionType(),record.getExamId()));//实际的作答类型
-                subjectiveAnswerBean.setCourseCode(course.getCode());
-                subjectiveAnswerBean.setExamId(req.getExamId());
-                subjectiveAnswerBean.setExamRecordDataId(record.getId());
-                subjectiveAnswerBean.setExamStudentId(record.getExamStudentId());
-                subjectiveAnswerBean.setMainNumber(sq.getMainNumber());
-                subjectiveAnswerBean.setOrder(sq.getOrder());
-                subjectiveAnswerBean.setQuestionId(sq.getQuestionId());
-                subjectiveAnswerBean.setStudentAnswer(transformedStudentAnswer(sq.getStudentAnswer()));
-                subjectiveAnswerBeanList.add(subjectiveAnswerBean);
+            for (int i = 0; i < subjectiveQuestionList.size(); i++) {
+                ExamQuestionEntity sq = subjectiveQuestionList.get(i);
+
+                SubjectiveAnswerBean subjectiveAnswerBean;
+
+                //集合中是否已存在当前作答结果(因为套题会提前插入部分数据)
+                String questionId = sq.getQuestionId();
+                Integer order = sq.getOrder();
+                List<SubjectiveAnswerBean> existSubjectiveAnswerBeanList = subjectiveAnswerBeanList.stream().filter(p -> questionId.equals(p.getQuestionId())
+                        && order.equals(p.getOrder())).collect(Collectors.toList());
+
+                //如果已经存在,则直接修改,因为套题一次性设置多个小题的题干,所以如果已经设置过就不再设置题干部分
+                if (null != existSubjectiveAnswerBeanList && !existSubjectiveAnswerBeanList.isEmpty()) {
+                    subjectiveAnswerBean = existSubjectiveAnswerBeanList.get(0);
+
+                    subjectiveAnswerBean.setAnswerType(sq.getAnswerType());
+                    subjectiveAnswerBean.setRealAnswerType(transformedAnswerType(sq.getAnswerType(), sq.getQuestionType(), record.getExamId()));//实际的作答类型
+                    subjectiveAnswerBean.setCourseCode(course.getCode());
+                    subjectiveAnswerBean.setExamId(req.getExamId());
+                    subjectiveAnswerBean.setExamRecordDataId(record.getId());
+                    subjectiveAnswerBean.setExamStudentId(record.getExamStudentId());
+                    subjectiveAnswerBean.setMainNumber(sq.getMainNumber());
+                    subjectiveAnswerBean.setOrder(order);
+                    subjectiveAnswerBean.setQuestionId(questionId);
+                    subjectiveAnswerBean.setStudentAnswer(transformedStudentAnswer(sq.getStudentAnswer()));
+                    subjectiveAnswerBean.setAnswer(sq.getCorrectAnswer());
+                }
+
+                //不存在则重新实例化,并添加
+                else {
+                    subjectiveAnswerBean = new SubjectiveAnswerBean();
+
+                    subjectiveAnswerBean.setAnswerType(sq.getAnswerType());
+                    subjectiveAnswerBean.setRealAnswerType(transformedAnswerType(sq.getAnswerType(), sq.getQuestionType(), record.getExamId()));//实际的作答类型
+                    subjectiveAnswerBean.setCourseCode(course.getCode());
+                    subjectiveAnswerBean.setExamId(req.getExamId());
+                    subjectiveAnswerBean.setExamRecordDataId(record.getId());
+                    subjectiveAnswerBean.setExamStudentId(record.getExamStudentId());
+                    subjectiveAnswerBean.setMainNumber(sq.getMainNumber());
+                    subjectiveAnswerBean.setOrder(order);
+                    subjectiveAnswerBean.setQuestionId(questionId);
+                    subjectiveAnswerBean.setStudentAnswer(transformedStudentAnswer(sq.getStudentAnswer()));
+                    subjectiveAnswerBean.setAnswer(sq.getCorrectAnswer());
+
+                    /**题干部分相关处理逻辑**/
+                    //TODO 这是由于历史原因(套题下的小题共享同一个questionId),导致这个恶心的变通实现方式,如果以后优化了套题的结构,可修改
+                    QuestionCacheBean getQuestionResp = CacheHelper.getQuestion(record.getExamId(),
+                            course.getCode(), record.getPaperType(), questionId);
+                    DefaultQuestionStructure questionStructure = getQuestionResp.getDefaultQuestion().getMasterVersion();
+
+                    //所有的小题单元
+                    List<DefaultQuestionUnit> questionUnits = questionStructure.getQuestionUnitList();
+
+                    //如果主题干不为空,则认为是套题(套题需要将大题题干和小题题干拼在一起)
+                    String mainBody = questionStructure.getBody();//主题干
+                    if (!StringUtils.isNullOrEmpty(mainBody)) {
+                        //第1小题的子题干
+                        String subBody0 = questionUnits.get(0).getBody();
+
+                        //首先将本条数据添加(本条数据是完整的)
+                        subjectiveAnswerBean.setBody(mainBody + subBody0);
+                        subjectiveAnswerBeanList.add(subjectiveAnswerBean);
+
+                        //其次,拼装套题的其它几个小题的题干(只初始化题干和唯一标识),并提前添加到结果集中
+                        for (int j = 1; j < questionUnits.size(); j++) {
+                            SubjectiveAnswerBean nextSubjectiveAnswerBean = new SubjectiveAnswerBean();
+                            nextSubjectiveAnswerBean.setQuestionId(questionId);
+                            nextSubjectiveAnswerBean.setOrder(order + j);
+                            nextSubjectiveAnswerBean.setBody(questionUnits.get(j).getBody());
+                            subjectiveAnswerBeanList.add(nextSubjectiveAnswerBean);
+                        }
+                    }
+                    //不是套题,则默认取第一条记录的题干
+                    else {
+                        subjectiveAnswerBean.setBody(questionUnits.get(0).getBody());
+                        subjectiveAnswerBeanList.add(subjectiveAnswerBean);
+                    }
+                }
             }
         }
         ExamRecordDataEntity lastExamRecordData = examRecordDataList.get(examRecordDataList.size() - 1);
@@ -166,27 +232,28 @@ public class ExamRecordQuestionsCloudServiceProvider extends ControllerSupport i
 
     /**
      * 根据原始作答类型和学生实际作答推断出真实的作答类型
-     * @param answerType 原始作答类型
+     *
+     * @param answerType   原始作答类型
      * @param questionType 题型
-     * @param examId 考试id
+     * @param examId       考试id
      * @return
      */
-    private String transformedAnswerType(AnswerType answerType, QuestionType questionType,Long examId) {
+    private String transformedAnswerType(AnswerType answerType, QuestionType questionType, Long examId) {
         //需要图片作答的考试id(以英文逗号分隔)
         Object oExamId = CacheHelper.getSysProperty("oe.imgAnswer.examId").getValue();
-        if (null !=oExamId){
+        if (null != oExamId) {
             String strExamId = String.valueOf(oExamId);
             List<String> examIdList = Arrays.asList(strExamId.split(","));
             //如果题型为问答题,且作答类型不为音频作答,且考试为需要图片作答,则此题为图片作答题
             if (questionType == QuestionType.ESSAY &&
                     (null == answerType || (null != answerType && answerType != AnswerType.SINGLE_AUDIO))) {
-                if (examIdList.stream().anyMatch(eid->eid.equals(String.valueOf(examId)))){
+                if (examIdList.stream().anyMatch(eid -> eid.equals(String.valueOf(examId)))) {
                     return "image";
                 }
             }
         }
 
-        if (null != answerType && answerType==AnswerType.SINGLE_AUDIO){
+        if (null != answerType && answerType == AnswerType.SINGLE_AUDIO) {
             return "audio";
         }