소스 검색

试题接口

xiatian 5 년 전
부모
커밋
8c614c8e52

+ 102 - 0
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/api/controller/ExamQuestionController.java

@@ -0,0 +1,102 @@
+package cn.com.qmth.examcloud.core.oe.student.api.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import cn.com.qmth.examcloud.api.commons.security.bean.User;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.commons.util.JsonUtil;
+import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamQuestion;
+import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamRecordQuestions;
+import cn.com.qmth.examcloud.core.oe.student.base.utils.Check;
+import cn.com.qmth.examcloud.core.oe.student.bean.ExamStudentQuestionInfo;
+import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
+import cn.com.qmth.examcloud.core.oe.student.service.ExamingSessionService;
+import cn.com.qmth.examcloud.support.examing.ExamingSession;
+import cn.com.qmth.examcloud.support.examing.ExamingStatus;
+import cn.com.qmth.examcloud.web.support.ControllerSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * @author  	chenken
+ * @date    	2018年9月5日 下午4:57:05
+ * @company 	QMTH
+ * @description 考试作答记录controller
+ */
+@Api(tags = "考试过程中-试题相关接口")
+@RestController
+@RequestMapping("${app.api.oe.student}/examQuestion")
+public class ExamQuestionController extends ControllerSupport {
+	
+	@Autowired
+	private ExamRecordQuestionsService examRecordQuestionsService;
+	
+	@Autowired
+    private ExamingSessionService examingSessionService;
+	
+	/**
+	 * 将mongodb中的答过的题和redis中的题目列表合并返回给前端
+	 * 返回给前端时注意将正确答案和得分置成null
+	 * @return
+	 */
+	@ApiOperation(value = "考试过程中-获取试题列表")
+	@GetMapping("/findExamQuestionList")
+	public List<ExamQuestion> findExamQuestionList(){
+		User user = getAccessUser();
+		ExamingSession examSessionInfo = examingSessionService.getExamingSession(user.getUserId());
+        if (examSessionInfo == null || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)
+                || examSessionInfo.getCost() >= examSessionInfo.getExamDuration()) {
+			throw new StatusException("1001","考试会话已过期,请重新开考");
+		}
+		ExamRecordQuestions qers = examRecordQuestionsService.getExamRecordQuestions(examSessionInfo.getExamRecordDataId(), examSessionInfo.getQuestionCount());
+		List<ExamQuestion> examQuestionList=qers.getExamQuestions();
+		for(ExamQuestion examQuestion:examQuestionList){
+			examQuestion.setCorrectAnswer(null);
+			examQuestion.setStudentScore(null);
+		}
+		return examQuestionList;
+	}
+
+	/**
+	 * 获取试题内容
+	 * @param questionId
+	 * @return
+	 */
+	@ApiOperation(value = "考试过程中-获取试题内容")
+	@GetMapping("/getQuestionContent")
+	public String getQuestionContent(@RequestParam String questionId){
+		User user = getAccessUser();
+		Check.isBlank(questionId, "questionId不能为空");
+		return examRecordQuestionsService.getQuestionContent(user.getUserId(),questionId);
+	}
+	
+	/**
+	 * 考生作答
+	 * @param examQuestionInfos
+	 */
+	@ApiOperation(value = "考试过程中-考生作答:更新试题作答信息(包括提交试题答案,更新是否标记)")
+	@PostMapping("/submitQuestionAnswer")
+	public void submitQuestionAnswer(@RequestBody List<ExamStudentQuestionInfo> examQuestionInfos){
+		if(log.isDebugEnabled()) {
+			String strJosn=JsonUtil.toJson(examQuestionInfos);
+			log.debug("ExamQuestionController--submitQuestionAnswer参数信息:"+strJosn);
+		}
+		User user = getAccessUser();
+		if(examQuestionInfos!=null && examQuestionInfos.size()>0){
+			for(ExamStudentQuestionInfo examStudentQuestionInfo:examQuestionInfos){
+				if(examStudentQuestionInfo.getOrder() == null){
+					throw new StatusException("2001", "illegal params");
+				}
+			}
+			examRecordQuestionsService.submitQuestionAnswer(user.getUserId(),examQuestionInfos);
+		}
+	}
+}

+ 26 - 0
examcloud-core-oe-student-base/src/main/java/cn/com/qmth/examcloud/core/oe/student/base/bean/ExamQuestion.java

@@ -21,6 +21,16 @@ public class ExamQuestion implements Serializable{
 	 */
 	private static final long serialVersionUID = -6141069483774400912L;
 	
+	/**
+     * 作答记录是否在mongo
+     */
+    private Boolean isInMongo;
+    
+    /**
+     * 作答记录在mongo中的id
+     */
+    private String examQuestionTempId;
+	
 	/**
 	 * 考试记录Data Id
 	 */
@@ -197,6 +207,22 @@ public class ExamQuestion implements Serializable{
 	public void setAnswerType(AnswerType answerType) {
 		this.answerType = answerType;
 	}
+    
+    public String getExamQuestionTempId() {
+        return examQuestionTempId;
+    }
+    
+    public void setExamQuestionTempId(String examQuestionTempId) {
+        this.examQuestionTempId = examQuestionTempId;
+    }
+    
+    public Boolean getIsInMongo() {
+        return isInMongo;
+    }
+    
+    public void setIsInMongo(Boolean isInMongo) {
+        this.isInMongo = isInMongo;
+    }
 
 	
 	

+ 20 - 0
examcloud-core-oe-student-dao/src/main/java/cn/com/qmth/examcloud/core/oe/student/dao/ExamRecordQuestionTempRepo.java

@@ -0,0 +1,20 @@
+package cn.com.qmth.examcloud.core.oe.student.dao;
+
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.data.repository.query.QueryByExampleExecutor;
+import org.springframework.stereotype.Repository;
+
+import cn.com.qmth.examcloud.core.oe.student.dao.entity.ExamQuestionTempEntity;
+
+/**
+ * 
+ * @author  	chenken
+ * @date    	2018年9月3日 上午10:48:39
+ * @company 	QMTH
+ * @description ExamRecordQuestionsRepo.java
+ */
+@Repository
+public interface ExamRecordQuestionTempRepo  extends MongoRepository<ExamQuestionTempEntity, String>,QueryByExampleExecutor<ExamQuestionTempEntity>{
+	
+
+}

+ 217 - 0
examcloud-core-oe-student-dao/src/main/java/cn/com/qmth/examcloud/core/oe/student/dao/entity/ExamQuestionTempEntity.java

@@ -0,0 +1,217 @@
+package cn.com.qmth.examcloud.core.oe.student.dao.entity;
+
+import java.io.Serializable;
+
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
+import cn.com.qmth.examcloud.question.commons.core.question.QuestionType;
+
+/**
+ * @author chenken
+ * @date 2018/8/17 10:18
+ * @company QMTH
+ * @description 考生单题作答记录,存储过长的作答
+ */
+@Document(collection="examRecordQuestionTemp")
+public class ExamQuestionTempEntity implements Serializable{
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = -6141069483774400912L;
+	
+	@Id
+	private String id;
+	/**
+	 * 考试记录Data Id
+	 */
+    private Long examRecordDataId;
+    /**
+     * 大题号
+     */
+    private Integer mainNumber;
+    /**
+     * 原题ID
+     */
+    private String questionId;
+    /**
+     * 顺序
+     */
+    private Integer order;
+    /**
+     * 小题分数
+     */
+    private Double questionScore;
+    /**
+     * 小题类型
+     */
+    private QuestionType questionType;
+    /**
+     * 标准答案
+     */
+    private String correctAnswer;
+    /**
+     * 考生作答
+     */
+    private String studentAnswer;
+    /**
+     * 学生小题得分
+     */
+    private Double studentScore;
+    /**
+     * 是否作答
+     */
+    private Boolean isAnswer;
+    /**
+     * 是否标记
+     */
+    private Boolean isSign;
+    
+    /**
+	 * 选项排序值
+	 */
+	private Integer[] optionPermutation;
+	
+	/**
+	 * 音频播放次数
+	 */
+	private String audioPlayTimes;
+	/**
+	 * 题目作答类型
+	 */
+	@Enumerated(EnumType.STRING)
+	private AnswerType answerType;	
+    
+	public ExamQuestionTempEntity() {}
+	
+	public String getId() {
+		return id;
+	}
+	public void setId(String id) {
+		this.id = id;
+	}
+	public Long getExamRecordDataId() {
+		return examRecordDataId;
+	}
+	public void setExamRecordDataId(Long examRecordDataId) {
+		this.examRecordDataId = examRecordDataId;
+	}
+	public Integer getMainNumber() {
+		return mainNumber;
+	}
+	/**
+	 * 设置 大题号
+	 * @param mainNumber
+	 */
+	public void setMainNumber(Integer mainNumber) {
+		this.mainNumber = mainNumber;
+	}
+	public String getQuestionId() {
+		return questionId;
+	}
+	/**
+	 * 设置题库试题ID
+	 * @param questionId
+	 */
+	public void setQuestionId(String questionId) {
+		this.questionId = questionId;
+	}
+	public Integer getOrder() {
+		return order;
+	}
+	/**
+	 * 设置小题号
+	 * @param order
+	 */
+	public void setOrder(Integer order) {
+		this.order = order;
+	}
+	public String getStudentAnswer() {
+		return studentAnswer;
+	}
+	public void setStudentAnswer(String studentAnswer) {
+		this.studentAnswer = studentAnswer;
+	}
+	public Double getStudentScore() {
+		return studentScore;
+	}
+	/**
+	 * 设置考生得分
+	 * @param studentScore
+	 */
+	public void setStudentScore(Double studentScore) {
+		this.studentScore = studentScore;
+	}
+	public Double getQuestionScore() {
+		return questionScore;
+	}
+	/**
+	 * 设置试题分数
+	 * @param questionScore
+	 */
+	public void setQuestionScore(Double questionScore) {
+		this.questionScore = questionScore;
+	}
+	public QuestionType getQuestionType() {
+		return questionType;
+	}
+	/**
+	 * 设置题型
+	 * @param questionType
+	 */
+	public void setQuestionType(QuestionType questionType) {
+		this.questionType = questionType;
+	}
+	public Boolean getIsAnswer() {
+		return isAnswer;
+	}
+	public void setIsAnswer(Boolean isAnswer) {
+		this.isAnswer = isAnswer;
+	}
+	public Boolean getIsSign() {
+		return isSign;
+	}
+	public void setIsSign(Boolean isSign) {
+		this.isSign = isSign;
+	}
+
+	public String getCorrectAnswer() {
+		return correctAnswer;
+	}
+
+	public void setCorrectAnswer(String correctAnswer) {
+		this.correctAnswer = correctAnswer;
+	}
+
+	public Integer[] getOptionPermutation() {
+		return optionPermutation;
+	}
+
+	public void setOptionPermutation(Integer[] optionPermutation) {
+		this.optionPermutation = optionPermutation;
+	}
+
+	public String getAudioPlayTimes() {
+		return audioPlayTimes;
+	}
+
+	public void setAudioPlayTimes(String audioPlayTimes) {
+		this.audioPlayTimes = audioPlayTimes;
+	}
+
+	public AnswerType getAnswerType() {
+		return answerType;
+	}
+
+	public void setAnswerType(AnswerType answerType) {
+		this.answerType = answerType;
+	}
+
+	
+	
+}

+ 88 - 0
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ExamStudentQuestionInfo.java

@@ -0,0 +1,88 @@
+package cn.com.qmth.examcloud.core.oe.student.bean;
+
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
+
+/**
+ * 
+ * @author  	chenken
+ * @date    	2018年9月25日 上午9:43:19
+ * @company 	QMTH
+ * @description 考生作答信息 
+ */
+public class ExamStudentQuestionInfo implements JsonSerializable{
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 8080615797817377990L;
+
+	/**
+	 * 题目序号
+	 */
+	private Integer order;
+	
+	/**
+	 * 是否标记
+	 */
+	private Boolean isSign;
+	
+	/**
+	 * 考生作答
+	 */
+	private String studentAnswer;
+	
+	/**
+	 * 音频播放次数
+	 */
+	private String audioPlayTimes;
+	/**
+	 * 题目作答类型
+	 */
+	@Enumerated(EnumType.STRING)
+	private AnswerType answerType;
+
+	public Integer getOrder() {
+		return order;
+	}
+
+	public void setOrder(Integer order) {
+		this.order = order;
+	}
+
+	public String getStudentAnswer() {
+		return studentAnswer;
+	}
+
+	public void setStudentAnswer(String studentAnswer) {
+		this.studentAnswer = studentAnswer;
+	}
+
+	public Boolean getIsSign() {
+		return isSign;
+	}
+
+	public void setIsSign(Boolean isSign) {
+		this.isSign = isSign;
+	}
+
+	public String getAudioPlayTimes() {
+		return audioPlayTimes;
+	}
+
+	public void setAudioPlayTimes(String audioPlayTimes) {
+		this.audioPlayTimes = audioPlayTimes;
+	}
+
+	public AnswerType getAnswerType() {
+		return answerType;
+	}
+
+	public void setAnswerType(AnswerType answerType) {
+		this.answerType = answerType;
+	}
+	
+}

+ 9 - 0
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordQuestionsService.java

@@ -1,7 +1,10 @@
 package cn.com.qmth.examcloud.core.oe.student.service;
 
+import java.util.List;
+
 import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamQuestion;
 import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamRecordQuestions;
+import cn.com.qmth.examcloud.core.oe.student.bean.ExamStudentQuestionInfo;
 import cn.com.qmth.examcloud.question.commons.core.paper.DefaultPaper;
 
 /**
@@ -30,4 +33,10 @@ public interface ExamRecordQuestionsService {
     public void deleteExamQuestion(Long examRecordDataId,Integer order);
 
     public ExamRecordQuestions createExamRecordQuestions(Long examRecordDataId, DefaultPaper defaultPaper);
+    
+    public ExamRecordQuestions getExamRecordQuestions(Long examRecordDataId,Integer quesCount);
+
+    public String getQuestionContent(Long studentId, String questionId);
+
+    public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos);
 }

+ 118 - 5
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordQuestionsServiceImpl.java

@@ -3,40 +3,74 @@ package cn.com.qmth.examcloud.core.oe.student.service.impl;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
+import cn.com.qmth.examcloud.api.commons.enums.ExamType;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.commons.util.JsonUtil;
 import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamQuestion;
 import cn.com.qmth.examcloud.core.oe.student.base.bean.ExamRecordQuestions;
+import cn.com.qmth.examcloud.core.oe.student.bean.ExamStudentQuestionInfo;
+import cn.com.qmth.examcloud.core.oe.student.dao.ExamRecordQuestionTempRepo;
+import cn.com.qmth.examcloud.core.oe.student.dao.entity.ExamQuestionTempEntity;
 import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
+import cn.com.qmth.examcloud.core.oe.student.service.ExamingSessionService;
 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.DefaultQuestionStructure;
+import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionUnit;
+import cn.com.qmth.examcloud.support.cache.CacheHelper;
+import cn.com.qmth.examcloud.support.cache.bean.QuestionCacheBean;
+import cn.com.qmth.examcloud.support.examing.ExamingSession;
+import cn.com.qmth.examcloud.support.examing.ExamingStatus;
 import cn.com.qmth.examcloud.support.redis.RedisKeyHelper;
 import cn.com.qmth.examcloud.web.redis.RedisClient;
 
 @Service("examRecordQuestionsService")
 public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsService {
 
+    /**
+     * 考生作答内容长度界限,超过此长度的答案内容存入mongo
+     */
+    private final static int ANWSER_LENGT = 20000;
+
+    // 本地题干缓存,最大200道题,默认缓存120秒
+    private Cache<String, String> questionContentCache = CacheBuilder.newBuilder().maximumSize(200)
+            .expireAfterWrite(120, TimeUnit.SECONDS).build();
+
     @Autowired
     private RedisClient redisClient;
 
+    @Autowired
+    private ExamRecordQuestionTempRepo examRecordQuestionTempRepo;
+
+    @Autowired
+    private ExamingSessionService examingSessionService;
+
     @Override
-    public void saveExamQuestion(Long examRecordDataId,Integer order, ExamQuestion question) {
+    public void saveExamQuestion(Long examRecordDataId, Integer order, ExamQuestion question) {
         String key = RedisKeyHelper.getBuilder().studentAnswerKey(examRecordDataId, order);
-        redisClient.set(key + examRecordDataId, question,-1);
+        redisClient.set(key + examRecordDataId, question, -1);
     }
 
     @Override
-    public ExamQuestion getExamQuestion(Long examRecordDataId,Integer order) {
+    public ExamQuestion getExamQuestion(Long examRecordDataId, Integer order) {
         String key = RedisKeyHelper.getBuilder().studentAnswerKey(examRecordDataId, order);
         return redisClient.get(key + examRecordDataId, ExamQuestion.class);
     }
 
     @Override
-    public void deleteExamQuestion(Long examRecordDataId,Integer order) {
+    public void deleteExamQuestion(Long examRecordDataId, Integer order) {
         String key = RedisKeyHelper.getBuilder().studentAnswerKey(examRecordDataId, order);
         redisClient.delete(key + examRecordDataId);
     }
@@ -58,6 +92,7 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
                 for (DefaultQuestionUnitWrapper defaultQuestionUnitWrapper : questionUnitWrapperList) {
                     ExamQuestion examQuestionEntity = new ExamQuestion();
                     examQuestionEntity.setExamRecordDataId(examRecordDataId);
+                    examQuestionEntity.setIsInMongo(false);
                     examQuestionEntity.setMainNumber(i + 1);
                     examQuestionEntity.setOrder(++order);
                     examQuestionEntity.setQuestionId(defaultQuestionStructureWrapper.getQuestionId());
@@ -75,10 +110,88 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
         examRecordQuestions.setExamQuestions(examQuestionEntityList);
         examRecordQuestions.setExamRecordDataId(examRecordDataId);
         examRecordQuestions.setCreationTime(new Date());
-        for(ExamQuestion eq:examRecordQuestions.getExamQuestions()) {
+        for (ExamQuestion eq : examRecordQuestions.getExamQuestions()) {
             saveExamQuestion(eq.getExamRecordDataId(), eq.getOrder(), eq);
         }
         return examRecordQuestions;
     }
 
+    @Override
+    public ExamRecordQuestions getExamRecordQuestions(Long examRecordDataId, Integer quesCount) {
+        ExamRecordQuestions erqs = new ExamRecordQuestions();
+        List<ExamQuestion> examQuestions = new ArrayList<ExamQuestion>();
+        erqs.setExamQuestions(examQuestions);
+        erqs.setExamRecordDataId(examRecordDataId);
+        for (int i = 1; i <= quesCount; i++) {
+            examQuestions.add(getExamQuestion(examRecordDataId, i));
+        }
+        return erqs;
+    }
+
+    @Override
+    public String getQuestionContent(Long studentId, String questionId) {
+        ExamingSession examSessionInfo = examingSessionService.getExamingSession(studentId);
+        if (examSessionInfo == null || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)
+                || examSessionInfo.getCost() >= examSessionInfo.getExamDuration()) {
+            throw new StatusException("1001", "考试已结束,不允许获取试题内容");
+        }
+
+        // 本地缓存key规则:examId_courseCode_paperType_questionId
+        String cacheKey = examSessionInfo.getExamId() + "_" + examSessionInfo.getCourseCode() + "_"
+                + examSessionInfo.getPaperType() + "_" + questionId;
+        String contentJson = questionContentCache.getIfPresent(cacheKey);
+
+        // 如果本地缓存中存在,则从本地缓存中获取
+        if (StringUtils.isNotEmpty(contentJson)) {
+            return contentJson;
+        }else {// 如果本地缓存不存在,则从redis中获取, 并在本地缓存存在存储一份
+            QuestionCacheBean getQuestionResp = CacheHelper.getQuestion(examSessionInfo.getExamId(),
+                    examSessionInfo.getCourseCode(), examSessionInfo.getPaperType(), questionId);
+            DefaultQuestionStructure questionStructure = getQuestionResp.getDefaultQuestion().getMasterVersion();
+            List<DefaultQuestionUnit> questionUnits = questionStructure.getQuestionUnitList();
+
+            // 在线考试,清除答案
+            if (examSessionInfo.getExamType().equals(ExamType.ONLINE.name())) {
+                for (DefaultQuestionUnit questionUnit : questionUnits) {
+                    questionUnit.setRightAnswer(null);
+                }
+            }
+            String resultJson = JsonUtil.toJson(questionStructure);
+            questionContentCache.put(cacheKey, resultJson);
+            return resultJson;
+        }
+    }
+    
+    @Override
+    public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos) {
+        ExamingSession examSessionInfo = examingSessionService.getExamingSession(studentId);
+        if (examSessionInfo == null || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)
+                || examSessionInfo.getCost() >= examSessionInfo.getExamDuration()) {
+            throw new StatusException("2001", "考试会话已过期");
+        }
+        long examRecordDataId = examSessionInfo.getExamRecordDataId();
+
+        for (ExamStudentQuestionInfo examQuestionInfo : examQuestionInfos) {
+            ExamQuestion eq=getExamQuestion(examRecordDataId, examQuestionInfo.getOrder());
+            if(eq==null) {
+                throw new StatusException("2002", "试题不存在");
+            }
+            eq.setStudentAnswer(examQuestionInfo.getStudentAnswer());
+            eq.setIsSign(examQuestionInfo.getIsSign());
+            eq.setIsAnswer(StringUtils.isNotBlank(eq.getStudentAnswer()));
+            eq.setAudioPlayTimes(examQuestionInfo.getAudioPlayTimes());
+            //过长存入mongo
+            if(eq.getIsAnswer()&&eq.getStudentAnswer().length()>ANWSER_LENGT) {
+                eq.setIsInMongo(true);
+                ExamQuestionTempEntity temp=new ExamQuestionTempEntity();
+                BeanUtils.copyProperties(eq, temp);
+                temp.setId(null);
+                examRecordQuestionTempRepo.save(temp);
+                eq.setExamQuestionTempId(temp.getId());
+            }else {
+                eq.setIsInMongo(false);
+            }
+            saveExamQuestion(examRecordDataId, examQuestionInfo.getOrder(), eq);
+        }
+    }
 }