lideyin 5 жил өмнө
parent
commit
cf68972f73

+ 26 - 67
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/api/provider/ExamRecordDataCloudServiceProvider.java

@@ -1,19 +1,21 @@
 package cn.com.qmth.examcloud.core.oe.student.api.provider;
 
-import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.core.oe.student.api.ExamRecordDataCloudService;
-import cn.com.qmth.examcloud.core.oe.student.api.bean.*;
+import cn.com.qmth.examcloud.core.oe.student.api.bean.ExamFaceLivenessVerifyBean;
+import cn.com.qmth.examcloud.core.oe.student.api.bean.FaceBiopsyBean;
+import cn.com.qmth.examcloud.core.oe.student.api.bean.FaceBiopsyItemBean;
+import cn.com.qmth.examcloud.core.oe.student.api.bean.FaceBiopsyItemStepBean;
 import cn.com.qmth.examcloud.core.oe.student.api.request.*;
 import cn.com.qmth.examcloud.core.oe.student.api.response.*;
-import cn.com.qmth.examcloud.support.examing.ExamQuestion;
-import cn.com.qmth.examcloud.support.examing.ExamRecordQuestions;
-import cn.com.qmth.examcloud.support.examing.ExamRecordPaperStruct;
 import cn.com.qmth.examcloud.core.oe.student.dao.*;
-import cn.com.qmth.examcloud.core.oe.student.dao.entity.*;
+import cn.com.qmth.examcloud.core.oe.student.dao.entity.ExamFaceLivenessVerifyEntity;
+import cn.com.qmth.examcloud.core.oe.student.dao.entity.FaceBiopsyEntity;
+import cn.com.qmth.examcloud.core.oe.student.dao.entity.FaceBiopsyItemEntity;
+import cn.com.qmth.examcloud.core.oe.student.dao.entity.FaceBiopsyItemStepEntity;
+import cn.com.qmth.examcloud.core.oe.student.service.ExamControlService;
 import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordDataService;
 import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
 import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -52,6 +54,8 @@ public class ExamRecordDataCloudServiceProvider extends ControllerSupport implem
     private ExamRecordQuestionsService examRecordQuestionsService;
     @Autowired
     private ExamRecordQuestionTempRepo examRecordQuestionTempRepo;
+    @Autowired
+    private ExamControlService examControlService;
 
     @Override
     @ApiOperation(value = "批量获取未同步的考试记录ID")
@@ -228,57 +232,7 @@ public class ExamRecordDataCloudServiceProvider extends ControllerSupport implem
     @PostMapping("/getExamRecordQuestions")
     @Override
     public GetExamRecordQuestionsResp getExamRecordQuestions(@RequestBody GetExamRecordQuestionsReq req) {
-        ExamRecordQuestions examRecordQuestions = examRecordQuestionsService.getExamRecordQuestions(req.getExamRecordDataId());
-
-        if (null == examRecordQuestions) {
-            throw new StatusException("200002", "找不到该考试的作答记录");
-        }
-
-        GetExamRecordQuestionsResp resp = new GetExamRecordQuestionsResp();
-        resp.setExamRecordDataId(examRecordQuestions.getExamRecordDataId());
-        resp.setCreationTime(examRecordQuestions.getCreationTime());
-
-        List<StuExamQuestionBean> beanList = new ArrayList<>();
-        List<ExamQuestion> examQuestions = examRecordQuestions.getExamQuestions();
-
-        for (ExamQuestion examQuestion : examQuestions) {
-            StuExamQuestionBean bean = new StuExamQuestionBean();
-            bean.setInMongo(examQuestion.getIsInMongo());
-            bean.setExamQuestionTempId(examQuestion.getExamQuestionTempId());
-            bean.setExamRecordDataId(examQuestion.getExamRecordDataId());
-            bean.setMainNumber(examQuestion.getMainNumber());
-            bean.setQuestionId(examQuestion.getQuestionId());
-            bean.setOrder(examQuestion.getOrder());
-            bean.setQuestionScore(examQuestion.getQuestionScore());
-            bean.setQuestionType(examQuestion.getQuestionType());
-            bean.setCorrectAnswer(examQuestion.getCorrectAnswer());
-
-            //如果作答记录存在mongo中,需要从mongo中重新获取
-            if (null != examQuestion.getIsInMongo() && examQuestion.getIsInMongo()) {
-                ExamQuestionTempEntity examQuestionTempEntity =
-                        GlobalHelper.getEntity(examRecordQuestionTempRepo, examQuestion.getExamQuestionTempId(), ExamQuestionTempEntity.class);
-                if (null == examQuestionTempEntity) {
-                    throw new StatusException("200003","找不到试题作答结果");
-                }
-
-                bean.setStudentAnswer(examQuestionTempEntity.getStudentAnswer());
-            } else {
-                bean.setStudentAnswer(examQuestion.getStudentAnswer());
-            }
-
-            bean.setStudentScore(examQuestion.getStudentScore());
-            bean.setAnswer(examQuestion.getIsAnswer());
-            bean.setSign(examQuestion.getIsSign());
-            bean.setOptionPermutation(examQuestion.getOptionPermutation());
-            bean.setAudioPlayTimes(examQuestion.getAudioPlayTimes());
-            bean.setAnswerType(examQuestion.getAnswerType());
-
-            beanList.add(bean);
-        }
-
-        resp.setExamQuestions(beanList);
-
-        return resp;
+        return examRecordQuestionsService.getExamRecordQuestions(req);
     }
 
     /**
@@ -291,17 +245,22 @@ public class ExamRecordDataCloudServiceProvider extends ControllerSupport implem
     @PostMapping("/getExamRecordPaperStruct")
     @Override
     public GetExamRecordPaperStructResp getExamRecordPaperStruct(@RequestBody GetExamRecordPaperStructReq req) {
-        ExamRecordPaperStruct examRecordPaperStruct = examRecordPaperStructService.getExamRecordPaperStruct(req.getExamRecordDataId());
 
-        if (null == examRecordPaperStruct) {
-            throw new StatusException("200001", "找不到该考试的试卷结构");
-        }
+        return examRecordPaperStructService.getExamRecordPaperStruct(req);
+    }
 
-        GetExamRecordPaperStructResp resp = new GetExamRecordPaperStructResp();
-        resp.setId(examRecordPaperStruct.getId());
-        resp.setDefaultPaper(examRecordPaperStruct.getDefaultPaper());
+    /**
+     * 交卷
+     *
+     * @param req
+     * @return
+     */
+    @ApiOperation(value = "交卷")
+    @PostMapping("/getExamRecordPaperStruct")
+    @Override
+    public HandInExamResp handInExam(@RequestBody HandInExamReq req) {
+        examControlService.handInExam(req.getExamRecordDataId(), req.getHandInExamType());
 
-        return resp;
+        return new HandInExamResp();
     }
-
 }

+ 10 - 6
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordPaperStructService.java

@@ -1,30 +1,34 @@
 package cn.com.qmth.examcloud.core.oe.student.service;
 
+import cn.com.qmth.examcloud.core.oe.student.api.request.GetExamRecordPaperStructReq;
+import cn.com.qmth.examcloud.core.oe.student.api.response.GetExamRecordPaperStructResp;
 import cn.com.qmth.examcloud.support.examing.ExamRecordPaperStruct;
 
 /**
  * @author chenken
- *
  */
 public interface ExamRecordPaperStructService {
 
     /**
      * 保存
-     * @param timeout   秒
      */
-    public void saveExamRecordPaperStruct(Long examRecordDataId,ExamRecordPaperStruct paper);
+    void saveExamRecordPaperStruct(Long examRecordDataId, ExamRecordPaperStruct paper);
 
     /**
      * 获取
+     *
      * @param examRecordDataId
      * @return
      */
-    public ExamRecordPaperStruct getExamRecordPaperStruct(Long examRecordDataId);
+    ExamRecordPaperStruct getExamRecordPaperStruct(Long examRecordDataId);
 
     /**
      * 删除
+     *
      * @param examRecordDataId
      */
-    public void deleteExamRecordPaperStruct(Long examRecordDataId);
-    
+    void deleteExamRecordPaperStruct(Long examRecordDataId);
+
+    GetExamRecordPaperStructResp getExamRecordPaperStruct(GetExamRecordPaperStructReq req);
+
 }

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

@@ -1,42 +1,48 @@
 package cn.com.qmth.examcloud.core.oe.student.service;
 
-import java.util.List;
-
-import cn.com.qmth.examcloud.support.examing.ExamQuestion;
-import cn.com.qmth.examcloud.support.examing.ExamRecordQuestions;
+import cn.com.qmth.examcloud.core.oe.student.api.request.GetExamRecordQuestionsReq;
+import cn.com.qmth.examcloud.core.oe.student.api.response.GetExamRecordQuestionsResp;
 import cn.com.qmth.examcloud.core.oe.student.bean.ExamStudentQuestionInfo;
 import cn.com.qmth.examcloud.question.commons.core.paper.DefaultPaper;
+import cn.com.qmth.examcloud.support.examing.ExamQuestion;
+import cn.com.qmth.examcloud.support.examing.ExamRecordQuestions;
+
+import java.util.List;
 
 /**
  * @author chenken
- *
  */
 public interface ExamRecordQuestionsService {
 
     /**
      * 保存
-     * @param timeout   秒
+     *
      */
-    public void saveExamQuestion(Long examRecordDataId,Integer order,ExamQuestion questions);
+    void saveExamQuestion(Long examRecordDataId, Integer order, ExamQuestion questions);
 
     /**
      * 获取
+     *
      * @param examRecordDataId
      * @return
      */
-    public ExamQuestion getExamQuestion(Long examRecordDataId,Integer order);
+    ExamQuestion getExamQuestion(Long examRecordDataId, Integer order);
 
     /**
      * 删除
+     *
      * @param examRecordDataId
      */
-    public void deleteExamQuestion(Long examRecordDataId,Integer order);
+    void deleteExamQuestion(Long examRecordDataId, Integer order);
+
+    ExamRecordQuestions createExamRecordQuestions(Long examRecordDataId, DefaultPaper defaultPaper);
+
+    ExamRecordQuestions getExamRecordQuestions(Long examRecordDataId);
+
+    String getQuestionContent(Long studentId, String questionId);
 
-    public ExamRecordQuestions createExamRecordQuestions(Long examRecordDataId, DefaultPaper defaultPaper);
-    
-    public ExamRecordQuestions getExamRecordQuestions(Long examRecordDataId);
+    void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos);
 
-    public String getQuestionContent(Long studentId, String questionId);
+    GetExamRecordQuestionsResp getExamRecordQuestions(GetExamRecordQuestionsReq req);
 
-    public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos);
 }

+ 143 - 73
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamControlServiceImpl.java

@@ -1,71 +1,30 @@
 package cn.com.qmth.examcloud.core.oe.student.service.impl;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.math.RandomUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.time.DateUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.google.common.base.Splitter;
-
 import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.api.commons.security.bean.UserType;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.commons.util.ByteUtil;
-import cn.com.qmth.examcloud.commons.util.JsonUtil;
-import cn.com.qmth.examcloud.commons.util.SHA256;
-import cn.com.qmth.examcloud.commons.util.StringUtil;
 import cn.com.qmth.examcloud.commons.util.UUID;
-import cn.com.qmth.examcloud.commons.util.UrlUtil;
-import cn.com.qmth.examcloud.commons.util.Util;
+import cn.com.qmth.examcloud.commons.util.*;
 import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordCloudService;
+import cn.com.qmth.examcloud.core.oe.admin.api.SyncExamDataCloudService;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamQuestionBean;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordDataBean;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordPaperStructBean;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordQuestionsBean;
 import cn.com.qmth.examcloud.core.oe.admin.api.request.GetPartialExamRecordDataReq;
+import cn.com.qmth.examcloud.core.oe.admin.api.request.SyncExamDataReq;
 import cn.com.qmth.examcloud.core.oe.admin.api.response.GetPartialExamRecordDataResp;
-import cn.com.qmth.examcloud.support.examing.ExamQuestion;
-import cn.com.qmth.examcloud.support.examing.ExamRecordQuestions;
+import cn.com.qmth.examcloud.core.oe.student.api.bean.StuExamQuestionBean;
+import cn.com.qmth.examcloud.core.oe.student.api.request.GetExamRecordPaperStructReq;
+import cn.com.qmth.examcloud.core.oe.student.api.request.GetExamRecordQuestionsReq;
+import cn.com.qmth.examcloud.core.oe.student.api.response.GetExamRecordPaperStructResp;
+import cn.com.qmth.examcloud.core.oe.student.api.response.GetExamRecordQuestionsResp;
 import cn.com.qmth.examcloud.core.oe.student.base.utils.CommonUtil;
 import cn.com.qmth.examcloud.core.oe.student.base.utils.QuestionTypeUtil;
-import cn.com.qmth.examcloud.core.oe.student.bean.CheckExamInProgressInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.CheckQrCodeInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.EndExamInfo;
-import cn.com.qmth.examcloud.support.examing.ExamRecordPaperStruct;
-import cn.com.qmth.examcloud.core.oe.student.bean.GetQrCodeReq;
-import cn.com.qmth.examcloud.core.oe.student.bean.GetUpyunSignatureReq;
-import cn.com.qmth.examcloud.core.oe.student.bean.StartExamInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.UploadedFileAnswerInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.UpyunSignatureInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamBossService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamControlService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamFaceLivenessVerifyService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordDataService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
-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.core.oe.student.service.FaceBiopsyService;
+import cn.com.qmth.examcloud.core.oe.student.bean.*;
+import cn.com.qmth.examcloud.core.oe.student.service.*;
 import cn.com.qmth.examcloud.core.oe.task.api.ExamCaptureCloudService;
 import cn.com.qmth.examcloud.core.oe.task.api.request.SaveExamCaptureSyncCompareResultReq;
 import cn.com.qmth.examcloud.core.oe.task.api.request.UpdateExamCaptureQueuePriorityReq;
@@ -81,27 +40,12 @@ import cn.com.qmth.examcloud.reports.commons.bean.OnlineExamStudentReport;
 import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
 import cn.com.qmth.examcloud.support.Constants;
 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.ExamOrgSettingsCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamPropertyCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamSettingsCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamStudentCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExamStudentSettingsCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigDetailCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.ExtractConfigPaperCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.StudentCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
+import cn.com.qmth.examcloud.support.cache.bean.*;
 import cn.com.qmth.examcloud.support.enums.ExamProperties;
 import cn.com.qmth.examcloud.support.enums.ExamRecordStatus;
 import cn.com.qmth.examcloud.support.enums.FaceBiopsyScheme;
 import cn.com.qmth.examcloud.support.enums.HandInExamType;
-import cn.com.qmth.examcloud.support.examing.ExamBoss;
-import cn.com.qmth.examcloud.support.examing.ExamRecordData;
-import cn.com.qmth.examcloud.support.examing.ExamingActivityTime;
-import cn.com.qmth.examcloud.support.examing.ExamingHeartbeat;
-import cn.com.qmth.examcloud.support.examing.ExamingSession;
-import cn.com.qmth.examcloud.support.examing.ExamingStatus;
+import cn.com.qmth.examcloud.support.examing.*;
 import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
 import cn.com.qmth.examcloud.support.helper.FaceBiopsyHelper;
 import cn.com.qmth.examcloud.support.redis.RedisKeyHelper;
@@ -115,9 +59,26 @@ import cn.com.qmth.examcloud.ws.api.enums.WebSocketEventType;
 import cn.com.qmth.examcloud.ws.api.request.SendFileAnswerMessageReq;
 import cn.com.qmth.examcloud.ws.api.request.SendScanQrCodeMessageReq;
 import cn.com.qmth.examcloud.ws.api.request.SendTextReq;
+import com.google.common.base.Splitter;
 import main.java.com.upyun.Base64Coder;
 import main.java.com.upyun.UpException;
 import main.java.com.upyun.UpYunUtils;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * @author chenken
@@ -166,6 +127,9 @@ public class ExamControlServiceImpl implements ExamControlService {
     @Autowired
     ExamRecordCloudService examRecordCloudService;
 
+    @Autowired
+    SyncExamDataCloudService syncExamDataCloudService;
+
     private static final String SEPARATOR = "/";
 
     private static final String UNDERLINE = "_";
@@ -291,7 +255,7 @@ public class ExamControlServiceImpl implements ExamControlService {
         if (eb == null) {
             throw new StatusException("008001", "ExamBoss is not created");
         }
-        if(eb.getExamRecordDataIds()==null) {
+        if (eb.getExamRecordDataIds() == null) {
             eb.setExamRecordDataIds(new ArrayList<Long>());
         }
         eb.getExamRecordDataIds().add(examRecordData.getId());
@@ -509,6 +473,23 @@ public class ExamControlServiceImpl implements ExamControlService {
             throw new StatusException("201101", "暂不支持的交卷类型");
         }
 
+        //特殊处理:如果考试类型为 在线练习,则需要将部分数据提前入库,并更新相关状态
+        if (ExamType.PRACTICE == examRecordData.getExamType()) {
+
+            // 提前更新考试状态
+            examRecordData.setExamRecordStatus(
+                    examRecordData.getHandInExamType() == HandInExamType.MANUAL
+                            ? ExamRecordStatus.EXAM_END
+                            : ExamRecordStatus.EXAM_OVERDUE);
+
+            //提前同步部分数据
+            SyncExamDataReq syncExamDataReq = new SyncExamDataReq();
+            syncExamDataReq.setExamRecordData(copyExamRecordDataFrom(examRecordData));
+            syncExamDataReq.setExamRecordPaperStruct(getExamRecordPaperStruct(examRecordDataId));
+            syncExamDataReq.setExamRecordQuestions(getExamRecordQuestions(examRecordDataId));
+            syncExamDataCloudService.syncExamData(syncExamDataReq);
+        }
+
         // 保存考试记录
         examRecordDataService.saveExamRecordDataCache(examRecordDataId, examRecordData);
 
@@ -1497,4 +1478,93 @@ public class ExamControlServiceImpl implements ExamControlService {
         return examRecordDataIdObject.getHasValue()
                 && examRecordDataId.equals(Long.valueOf(examRecordDataIdObject.getValue().toString()));
     }
+
+    private ExamRecordDataBean copyExamRecordDataFrom(ExamRecordData examRecordData) {
+        ExamRecordDataBean data = new ExamRecordDataBean();
+        data.setId(examRecordData.getId());
+        data.setExamId(examRecordData.getExamId());
+        data.setExamType(examRecordData.getExamType() == null ? null : examRecordData.getExamType().toString());
+        data.setExamStudentId(examRecordData.getExamStudentId());
+        data.setStudentId(examRecordData.getStudentId());
+        data.setCourseId(examRecordData.getCourseId());
+        data.setOrgId(examRecordData.getOrgId());
+        data.setRootOrgId(examRecordData.getRootOrgId());
+        data.setBasePaperId(examRecordData.getBasePaperId());
+        data.setPaperType(examRecordData.getPaperType());
+        data.setExamRecordStatus(examRecordData.getExamRecordStatus() == null ? null : examRecordData.getExamRecordStatus().toString());
+        data.setStartTime(examRecordData.getStartTime());
+        data.setEndTime(examRecordData.getEndTime());
+        data.setCleanTime(examRecordData.getCleanTime());
+        data.setWarn(examRecordData.getIsWarn() == null ? false : examRecordData.getIsWarn());
+        data.setAudit(examRecordData.getIsAudit() == null ? false : examRecordData.getIsAudit());
+        data.setIllegality(examRecordData.getIsIllegality() == null ? false : examRecordData.getIsIllegality());
+        data.setUsedExamTime(examRecordData.getUsedExamTime());
+        data.setContinued(examRecordData.getIsContinued() == null ? false : examRecordData.getIsContinued());
+        data.setContinuedCount(examRecordData.getContinuedCount());
+        data.setExceed(examRecordData.getIsExceed() == null ? false : examRecordData.getIsExceed());
+        data.setFaceSuccessCount(examRecordData.getFaceSuccessCount());
+        data.setFaceFailedCount(examRecordData.getFaceFailedCount());
+        data.setFaceStrangerCount(examRecordData.getFaceStrangerCount());
+        data.setFaceTotalCount(examRecordData.getFaceTotalCount());
+        data.setFaceSuccessPercent(examRecordData.getFaceSuccessPercent());
+        data.setFaceVerifyResult(examRecordData.getFaceVerifyResult() == null ? null : examRecordData.getFaceVerifyResult().toString());
+        data.setBaiduFaceLivenessSuccessPercent(examRecordData.getBaiduFaceLivenessSuccessPercent());
+        data.setTotalScore(examRecordData.getTotalScore());
+        data.setObjectiveScore(examRecordData.getObjectiveScore());
+        data.setObjectiveAccuracy(examRecordData.getObjectiveAccuracy());
+        data.setSubjectiveScore(examRecordData.getSubjectiveScore());
+        data.setSuccPercent(examRecordData.getSuccPercent());
+
+        return data;
+    }
+
+    private ExamRecordQuestionsBean getExamRecordQuestions(Long examRecordDataId) {
+        GetExamRecordQuestionsReq req = new GetExamRecordQuestionsReq();
+        req.setExamRecordDataId(examRecordDataId);
+        GetExamRecordQuestionsResp resp = examRecordQuestionsService.getExamRecordQuestions(req);
+
+        ExamRecordQuestionsBean bean = new ExamRecordQuestionsBean();
+        bean.setCreationTime(resp.getCreationTime());
+        bean.setExamRecordDataId(resp.getExamRecordDataId());
+
+        List<ExamQuestionBean> examQuestionBeanList = new ArrayList<>();
+        for (StuExamQuestionBean stuExamQuestionBean : resp.getExamQuestions()) {
+            ExamQuestionBean examQuestionBean = new ExamQuestionBean();
+            examQuestionBean.setExamRecordDataId(stuExamQuestionBean.getExamRecordDataId());
+            examQuestionBean.setMainNumber(stuExamQuestionBean.getMainNumber());
+            examQuestionBean.setQuestionId(stuExamQuestionBean.getQuestionId());
+            examQuestionBean.setOrder(stuExamQuestionBean.getOrder());
+            examQuestionBean.setQuestionScore(stuExamQuestionBean.getQuestionScore());
+            examQuestionBean.setQuestionType(stuExamQuestionBean.getQuestionType());
+            examQuestionBean.setCorrectAnswer(stuExamQuestionBean.getCorrectAnswer());
+            examQuestionBean.setStudentAnswer(stuExamQuestionBean.getStudentAnswer());
+            examQuestionBean.setStudentScore(stuExamQuestionBean.getStudentScore());
+            examQuestionBean.setAnswer(stuExamQuestionBean.getAnswer());
+            examQuestionBean.setSign(stuExamQuestionBean.getSign());
+            examQuestionBean.setOptionPermutation(stuExamQuestionBean.getOptionPermutation());
+            examQuestionBean.setAudioPlayTimes(stuExamQuestionBean.getAudioPlayTimes());
+
+            if (null != stuExamQuestionBean.getAnswerType()) {
+                examQuestionBean.setAnswerType(stuExamQuestionBean.getAnswerType().name());
+            }
+
+            examQuestionBeanList.add(examQuestionBean);
+        }
+
+        bean.setExamQuestionBeans(examQuestionBeanList);
+
+        return bean;
+    }
+
+    private ExamRecordPaperStructBean getExamRecordPaperStruct(Long examRecordDataId) {
+        GetExamRecordPaperStructReq req = new GetExamRecordPaperStructReq();
+        req.setExamRecordDataId(examRecordDataId);
+        GetExamRecordPaperStructResp resp = examRecordPaperStructService.getExamRecordPaperStruct(req);
+
+        ExamRecordPaperStructBean bean = new ExamRecordPaperStructBean();
+        bean.setId(resp.getId());
+        bean.setDefaultPaper(resp.getDefaultPaper());
+
+        return bean;
+    }
 }

+ 24 - 7
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordPaperStructServiceImpl.java

@@ -1,12 +1,14 @@
 package cn.com.qmth.examcloud.core.oe.student.service.impl;
 
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import cn.com.qmth.examcloud.support.examing.ExamRecordPaperStruct;
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.oe.student.api.request.GetExamRecordPaperStructReq;
+import cn.com.qmth.examcloud.core.oe.student.api.response.GetExamRecordPaperStructResp;
 import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
+import cn.com.qmth.examcloud.support.examing.ExamRecordPaperStruct;
 import cn.com.qmth.examcloud.support.redis.RedisKeyHelper;
 import cn.com.qmth.examcloud.web.redis.RedisClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 @Service("examRecordPaperStructService")
 public class ExamRecordPaperStructServiceImpl implements ExamRecordPaperStructService {
@@ -18,18 +20,33 @@ public class ExamRecordPaperStructServiceImpl implements ExamRecordPaperStructSe
     @Override
     public void saveExamRecordPaperStruct(Long examRecordDataId, ExamRecordPaperStruct paper) {
         String key = RedisKeyHelper.getBuilder().studentPaperKey(examRecordDataId);
-        redisClient.set(key , paper,2592000);
+        redisClient.set(key, paper, 2592000);
     }
 
     @Override
     public ExamRecordPaperStruct getExamRecordPaperStruct(Long examRecordDataId) {
         String key = RedisKeyHelper.getBuilder().studentPaperKey(examRecordDataId);
-        return redisClient.get(key , ExamRecordPaperStruct.class);
+        return redisClient.get(key, ExamRecordPaperStruct.class);
     }
 
     @Override
     public void deleteExamRecordPaperStruct(Long examRecordDataId) {
         String key = RedisKeyHelper.getBuilder().studentPaperKey(examRecordDataId);
-        redisClient.delete(key );
+        redisClient.delete(key);
+    }
+
+    @Override
+    public GetExamRecordPaperStructResp getExamRecordPaperStruct(GetExamRecordPaperStructReq req) {
+        ExamRecordPaperStruct examRecordPaperStruct = this.getExamRecordPaperStruct(req.getExamRecordDataId());
+
+        if (null == examRecordPaperStruct) {
+            throw new StatusException("200001", "找不到该考试的试卷结构");
+        }
+
+        GetExamRecordPaperStructResp resp = new GetExamRecordPaperStructResp();
+        resp.setId(examRecordPaperStruct.getId());
+        resp.setDefaultPaper(examRecordPaperStruct.getDefaultPaper());
+
+        return resp;
     }
 }

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

@@ -1,23 +1,11 @@
 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.Optional;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.commons.lang.StringUtils;
-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.support.examing.ExamQuestion;
-import cn.com.qmth.examcloud.support.examing.ExamRecordQuestions;
+import cn.com.qmth.examcloud.core.oe.student.api.bean.StuExamQuestionBean;
+import cn.com.qmth.examcloud.core.oe.student.api.request.GetExamRecordQuestionsReq;
+import cn.com.qmth.examcloud.core.oe.student.api.response.GetExamRecordQuestionsResp;
 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;
@@ -32,11 +20,21 @@ import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionStruc
 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.ExamRecordData;
-import cn.com.qmth.examcloud.support.examing.ExamingSession;
-import cn.com.qmth.examcloud.support.examing.ExamingStatus;
+import cn.com.qmth.examcloud.support.examing.*;
 import cn.com.qmth.examcloud.support.redis.RedisKeyHelper;
+import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
 import cn.com.qmth.examcloud.web.redis.RedisClient;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 
 @Service("examRecordQuestionsService")
 public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsService {
@@ -58,26 +56,26 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
 
     @Autowired
     private ExamingSessionService examingSessionService;
-    
+
     @Autowired
     private ExamRecordDataService examRecordDataService;
 
     @Override
     public void saveExamQuestion(Long examRecordDataId, Integer order, ExamQuestion question) {
         String key = RedisKeyHelper.getBuilder().studentAnswerKey(examRecordDataId, order);
-        redisClient.set(key , question, 2592000);
+        redisClient.set(key, question, 2592000);
     }
 
     @Override
     public ExamQuestion getExamQuestion(Long examRecordDataId, Integer order) {
         String key = RedisKeyHelper.getBuilder().studentAnswerKey(examRecordDataId, order);
-        return redisClient.get(key , ExamQuestion.class);
+        return redisClient.get(key, ExamQuestion.class);
     }
 
     @Override
     public void deleteExamQuestion(Long examRecordDataId, Integer order) {
         String key = RedisKeyHelper.getBuilder().studentAnswerKey(examRecordDataId, order);
-        redisClient.delete(key );
+        redisClient.delete(key);
     }
 
     @Override
@@ -123,20 +121,20 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
 
     @Override
     public ExamRecordQuestions getExamRecordQuestions(Long examRecordDataId) {
-        ExamRecordData ed=examRecordDataService.getExamRecordDataCache(examRecordDataId);
-        if(ed==null) {
+        ExamRecordData ed = examRecordDataService.getExamRecordDataCache(examRecordDataId);
+        if (ed == null) {
             throw new StatusException("1001", "考试信息未找到");
         }
-        Integer quesCount=ed.getQuestionCount();
+        Integer quesCount = ed.getQuestionCount();
         ExamRecordQuestions erqs = new ExamRecordQuestions();
         List<ExamQuestion> examQuestions = new ArrayList<ExamQuestion>();
         erqs.setExamQuestions(examQuestions);
         erqs.setExamRecordDataId(examRecordDataId);
         for (int i = 1; i <= quesCount; i++) {
-            ExamQuestion eq=getExamQuestion(examRecordDataId, i);
-            if(eq.getIsInMongo()) {
-                Optional<ExamQuestionTempEntity> op=examRecordQuestionTempRepo.findById(eq.getExamQuestionTempId());
-                if(!op.isPresent()) {
+            ExamQuestion eq = getExamQuestion(examRecordDataId, i);
+            if (eq.getIsInMongo()) {
+                Optional<ExamQuestionTempEntity> op = examRecordQuestionTempRepo.findById(eq.getExamQuestionTempId());
+                if (!op.isPresent()) {
                     throw new StatusException("1002", "试题内容未找到");
                 }
                 copyFromTemp(eq, op.get());
@@ -149,10 +147,10 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
     @Override
     public String getQuestionContent(Long studentId, String questionId) {
         ExamingSession examSessionInfo = examingSessionService.getExamingSession(studentId);
-		if (examSessionInfo == null
-				|| examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)) {
-			throw new StatusException("2001", "考试已结束,不允许获取试题内容");
-		}
+        if (examSessionInfo == null
+                || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)) {
+            throw new StatusException("2001", "考试已结束,不允许获取试题内容");
+        }
 
         // 本地缓存key规则:examId_courseCode_paperType_questionId
         String cacheKey = examSessionInfo.getExamId() + "_" + examSessionInfo.getCourseCode() + "_"
@@ -162,7 +160,7 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
         // 如果本地缓存中存在,则从本地缓存中获取
         if (StringUtils.isNotEmpty(contentJson)) {
             return contentJson;
-        }else {// 如果本地缓存不存在,则从redis中获取, 并在本地缓存存在存储一份
+        } else {// 如果本地缓存不存在,则从redis中获取, 并在本地缓存存在存储一份
             QuestionCacheBean getQuestionResp = CacheHelper.getQuestion(examSessionInfo.getExamId(),
                     examSessionInfo.getCourseCode(), examSessionInfo.getPaperType(), questionId);
             DefaultQuestionStructure questionStructure = getQuestionResp.getDefaultQuestion().getMasterVersion();
@@ -179,19 +177,19 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
             return resultJson;
         }
     }
-    
+
     @Override
     public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos) {
         ExamingSession examSessionInfo = examingSessionService.getExamingSession(studentId);
-		if (examSessionInfo == null
-				|| examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)) {
-			throw new StatusException("3001", "考试会话已过期");
-		}
+        if (examSessionInfo == null
+                || examSessionInfo.getExamingStatus().equals(ExamingStatus.INFORMAL)) {
+            throw new StatusException("3001", "考试会话已过期");
+        }
         long examRecordDataId = examSessionInfo.getExamRecordDataId();
 
         for (ExamStudentQuestionInfo examQuestionInfo : examQuestionInfos) {
-            ExamQuestion eq=getExamQuestion(examRecordDataId, examQuestionInfo.getOrder());
-            if(eq==null) {
+            ExamQuestion eq = getExamQuestion(examRecordDataId, examQuestionInfo.getOrder());
+            if (eq == null) {
                 throw new StatusException("2002", "试题不存在");
             }
             eq.setStudentAnswer(examQuestionInfo.getStudentAnswer());
@@ -199,21 +197,76 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
             eq.setIsAnswer(StringUtils.isNotBlank(eq.getStudentAnswer()));
             eq.setAudioPlayTimes(examQuestionInfo.getAudioPlayTimes());
             //过长存入mongo
-            if(eq.getIsAnswer()&&eq.getStudentAnswer().length()>ANWSER_LENGT) {
+            if (eq.getIsAnswer() && eq.getStudentAnswer().length() > ANWSER_LENGT) {
                 eq.setIsInMongo(true);
-                ExamQuestionTempEntity temp=of(eq);
+                ExamQuestionTempEntity temp = of(eq);
                 examRecordQuestionTempRepo.save(temp);
                 eq.setExamQuestionTempId(temp.getId());
                 eq.setStudentAnswer(null);
-            }else {
+            } else {
                 eq.setIsInMongo(false);
             }
             saveExamQuestion(examRecordDataId, examQuestionInfo.getOrder(), eq);
         }
     }
-    
+
+    @Override
+    public GetExamRecordQuestionsResp getExamRecordQuestions(GetExamRecordQuestionsReq req) {
+        ExamRecordQuestions examRecordQuestions = this.getExamRecordQuestions(req.getExamRecordDataId());
+
+        if (null == examRecordQuestions) {
+            throw new StatusException("200002", "找不到该考试的作答记录");
+        }
+
+        GetExamRecordQuestionsResp resp = new GetExamRecordQuestionsResp();
+        resp.setExamRecordDataId(examRecordQuestions.getExamRecordDataId());
+        resp.setCreationTime(examRecordQuestions.getCreationTime());
+
+        List<StuExamQuestionBean> beanList = new ArrayList<>();
+        List<ExamQuestion> examQuestions = examRecordQuestions.getExamQuestions();
+
+        for (ExamQuestion examQuestion : examQuestions) {
+            StuExamQuestionBean bean = new StuExamQuestionBean();
+            bean.setInMongo(examQuestion.getIsInMongo());
+            bean.setExamQuestionTempId(examQuestion.getExamQuestionTempId());
+            bean.setExamRecordDataId(examQuestion.getExamRecordDataId());
+            bean.setMainNumber(examQuestion.getMainNumber());
+            bean.setQuestionId(examQuestion.getQuestionId());
+            bean.setOrder(examQuestion.getOrder());
+            bean.setQuestionScore(examQuestion.getQuestionScore());
+            bean.setQuestionType(examQuestion.getQuestionType());
+            bean.setCorrectAnswer(examQuestion.getCorrectAnswer());
+
+            //如果作答记录存在mongo中,需要从mongo中重新获取
+            if (null != examQuestion.getIsInMongo() && examQuestion.getIsInMongo()) {
+                ExamQuestionTempEntity examQuestionTempEntity =
+                        GlobalHelper.getEntity(examRecordQuestionTempRepo, examQuestion.getExamQuestionTempId(), ExamQuestionTempEntity.class);
+                if (null == examQuestionTempEntity) {
+                    throw new StatusException("200003", "找不到试题作答结果");
+                }
+
+                bean.setStudentAnswer(examQuestionTempEntity.getStudentAnswer());
+            } else {
+                bean.setStudentAnswer(examQuestion.getStudentAnswer());
+            }
+
+            bean.setStudentScore(examQuestion.getStudentScore());
+            bean.setAnswer(examQuestion.getIsAnswer());
+            bean.setSign(examQuestion.getIsSign());
+            bean.setOptionPermutation(examQuestion.getOptionPermutation());
+            bean.setAudioPlayTimes(examQuestion.getAudioPlayTimes());
+            bean.setAnswerType(examQuestion.getAnswerType());
+
+            beanList.add(bean);
+        }
+
+        resp.setExamQuestions(beanList);
+
+        return resp;
+    }
+
     private ExamQuestionTempEntity of(ExamQuestion eq) {
-        ExamQuestionTempEntity tem=new ExamQuestionTempEntity();
+        ExamQuestionTempEntity tem = new ExamQuestionTempEntity();
         tem.setExamRecordDataId(eq.getExamRecordDataId());
         tem.setMainNumber(eq.getMainNumber());
         tem.setQuestionId(eq.getQuestionId());
@@ -230,8 +283,8 @@ public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsServic
         tem.setAnswerType(eq.getAnswerType());
         return tem;
     }
-    
-    private void copyFromTemp(ExamQuestion eq,ExamQuestionTempEntity temp) {
+
+    private void copyFromTemp(ExamQuestion eq, ExamQuestionTempEntity temp) {
         eq.setExamRecordDataId(temp.getExamRecordDataId());
         eq.setMainNumber(temp.getMainNumber());
         eq.setQuestionId(temp.getQuestionId());