wangwei před 5 roky
rodič
revize
8997d39f89
82 změnil soubory, kde provedl 0 přidání a 10790 odebrání
  1. 0 407
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/ExamControlController.java
  2. 0 179
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/ExamFaceLivenessVerifyController.java
  3. 0 97
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/ExamQuestionController.java
  4. 0 38
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/ExamRecordPaperStructController.java
  5. 0 40
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/ExamScoreController.java
  6. 0 76
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/ExamSmsController.java
  7. 0 239
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/FaceBiopsyController.java
  8. 0 135
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/OfflineExamController.java
  9. 0 73
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/PracticeController.java
  10. 0 60
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/TestController.java
  11. 0 29
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/BatchGetUpyunSignDomain.java
  12. 0 28
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/BatchGetUpyunSignDomainQuery.java
  13. 0 61
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/GetUpyunSignDomain.java
  14. 0 35
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/GetUpyunSignDomainQuery.java
  15. 0 201
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/ExamRecordCloudServiceProvider.java
  16. 0 37
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/ExamRecordPaperStructProvider.java
  17. 0 74
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeExamRecordForMarkingCloudServiceProvider.java
  18. 0 113
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeExamScoreNoticeQueueCloudServiceProvider.java
  19. 0 84
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeExamScoreObtainQueueCloudServiceProvider.java
  20. 0 39
      examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeHandleByExamCaptureQueueFailedDisposeServiceProvider.java
  21. 0 40
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/CalculateFaceCheckResultInfo.java
  22. 0 89
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/CheckExamInProgressInfo.java
  23. 0 90
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/CheckQrCodeInfo.java
  24. 0 54
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/CleanExamRecordPriorityQueueInfo.java
  25. 0 60
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/EndExamInfo.java
  26. 0 63
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/EndExamPreInfo.java
  27. 0 31
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ExamProcessResultInfo.java
  28. 0 27
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ExamQuestionAnswerExtensionInfo.java
  29. 0 158
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ExamSessionInfo.java
  30. 0 296
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ExamStudentInfo.java
  31. 0 88
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ExamStudentQuestionInfo.java
  32. 0 38
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/FaceBiopsyBaseInfo.java
  33. 0 50
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/FaceBiopsyInfo.java
  34. 0 153
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/FaceBiopsyStepInfo.java
  35. 0 42
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/GetFaceVerifyTokenInfo.java
  36. 0 64
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/GetQrCodeReq.java
  37. 0 22
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/GetUploadedFileAcknowledgeStatusReq.java
  38. 0 24
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/GetUploadedFileAnswerListReq.java
  39. 0 61
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/GetUpyunSignatureReq.java
  40. 0 125
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/ObjectiveScoreInfo.java
  41. 0 202
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/OfflineExamCourseInfo.java
  42. 0 143
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/PaperStructInfo.java
  43. 0 164
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/PracticeCourseInfo.java
  44. 0 73
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/PracticeDetailInfo.java
  45. 0 135
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/PracticeRecordInfo.java
  46. 0 48
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/SaveFaceBiopsyResultReq.java
  47. 0 61
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/SaveFaceBiopsyResultResp.java
  48. 0 63
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/SaveUploadedFileAcknowledgeStatusReq.java
  49. 0 61
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/SaveUploadedFileReq.java
  50. 0 81
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/StartExamInfo.java
  51. 0 52
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/UploadedFileAnswerInfo.java
  52. 0 53
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/bean/UpyunSignatureInfo.java
  53. 0 28
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/processor/HttpMethodProcessorImpl.java
  54. 0 24
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamAuditService.java
  55. 0 169
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamControlService.java
  56. 0 87
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamFaceLivenessVerifyService.java
  57. 0 142
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordDataService.java
  58. 0 29
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordForMarkingService.java
  59. 0 22
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordPaperStructService.java
  60. 0 52
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamRecordQuestionsService.java
  61. 0 42
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamScoreService.java
  62. 0 32
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamSessionInfoService.java
  63. 0 13
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamStudentFinalScoreService.java
  64. 0 43
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/ExamStudentService.java
  65. 0 39
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/FaceBiopsyService.java
  66. 0 43
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/OfflineExamService.java
  67. 0 38
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/PracticeService.java
  68. 0 57
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/CleanExamRecordQueueHolder.java
  69. 0 141
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamAuditServiceImpl.java
  70. 0 1686
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamControlServiceImpl.java
  71. 0 323
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamFaceLivenessVerifyServiceImpl.java
  72. 0 504
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordDataServiceImpl.java
  73. 0 117
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordForMarkingServiceImpl.java
  74. 0 33
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordPaperStructServiceImpl.java
  75. 0 231
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordQuestionsServiceImpl.java
  76. 0 259
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamScoreServiceImpl.java
  77. 0 46
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamSessionInfoServiceImpl.java
  78. 0 134
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamStudentFinalScoreServiceImpl.java
  79. 0 202
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamStudentServiceImpl.java
  80. 0 889
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/FaceBiopsyServiceImpl.java
  81. 0 345
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/OfflineExamServiceImpl.java
  82. 0 264
      examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/PracticeServiceImpl.java

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

@@ -1,407 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-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.Util;
-import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.bean.StudentBean;
-import cn.com.qmth.examcloud.core.basic.api.request.GetStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.response.GetStudentResp;
-import cn.com.qmth.examcloud.core.oe.common.base.Constants;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamFileAnswerTempEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.enums.HandInExamType;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScoreNoticeQueueService;
-import cn.com.qmth.examcloud.core.oe.student.api.request.GetStudentOnlineExamInfoReq;
-import cn.com.qmth.examcloud.core.oe.student.api.response.GetStudentOnlineExamInfoResp;
-import cn.com.qmth.examcloud.core.oe.student.bean.*;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamProcessResultInfo;
-import cn.com.qmth.examcloud.core.oe.student.controller.bean.BatchGetUpyunSignDomain;
-import cn.com.qmth.examcloud.core.oe.student.controller.bean.BatchGetUpyunSignDomainQuery;
-import cn.com.qmth.examcloud.core.oe.student.controller.bean.GetUpyunSignDomain;
-import cn.com.qmth.examcloud.core.oe.student.controller.bean.GetUpyunSignDomainQuery;
-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.ExamSessionInfoService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamStudentService;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
-import cn.com.qmth.examcloud.web.redis.RedisClient;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import cn.com.qmth.examcloud.web.support.Naked;
-import cn.com.qmth.examcloud.web.upyun.UpYunHttpRequest;
-import cn.com.qmth.examcloud.web.upyun.UpyunPathEnvironmentInfo;
-import cn.com.qmth.examcloud.web.upyun.UpyunService;
-import com.mysql.cj.util.StringUtils;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author chenken
- * @date 2018年8月13日 下午2:28:08
- * @company QMTH
- * @description 在线考试控制Controller
- */
-@Api(tags = "在线考试控制")
-@RestController
-@RequestMapping("${app.api.oe.student}/examControl")
-public class ExamControlController extends ControllerSupport {
-    //抓拍照片的又拍云id
-    private static final String CAPTURE_PHOTO_UPYUN_SITEID = "capturePhoto";
-    @Autowired
-    StudentCloudService studentCloudService;
-    @Autowired
-    ExamRecordDataRepo examRecordDataRepo;
-    @Autowired
-    private ExamStudentService examStudentService;
-    @Autowired
-    private ExamControlService examControlService;
-    @Autowired
-    private ExamScoreNoticeQueueService examScoreNoticeQueueService;
-    @Autowired
-    UpyunService upyunService;
-    @Value("${$upyun.site.1.domain}")
-    private String upyunFileUrl;
-    @Autowired
-    RedisClient redisClient;
-    @Autowired
-    ExamRecordDataService examRecordDataService;
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-
-    /**
-     * 获取当前服务器时间
-     *
-     * @return
-     */
-    @ApiOperation(value = "获取当前服务器时间")
-    @GetMapping("/currentTime")
-    public Long getCurrentTime() {
-        return new Date().getTime();
-    }
-
-    /**
-     * 获取在线考试待考列表
-     *
-     * @return
-     */
-    @ApiOperation(value = "获取在线考试待考列表")
-    @GetMapping("/queryExamList")
-    public List<ExamStudentInfo> queryExamList() {
-        User user = getAccessUser();
-        return examStudentService.queryOnlineExamList(user.getUserId());
-    }
-
-    /**
-     * 开始考试
-     */
-    @ApiOperation(value = "开始考试")
-    @GetMapping("/startExam")
-    public StartExamInfo startExam(@RequestParam Long examStudentId) {
-        User user = getAccessUser();
-        String sequenceLockKey = Constants.START_EXAM_LOCK_PREFIX + user.getUserId();
-        StartExamInfo startExamInfo;
-        //开始考试上锁,分布式锁,系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-        Check.isNull(examStudentId, "examStudentId不能为空");
-
-        startExamInfo = examControlService.startExam(examStudentId, user);
-        return startExamInfo;
-    }
-
-    /**
-     * 结束考试:交卷..
-     */
-    @ApiOperation(value = "结束考试:交卷")
-    @GetMapping("/endExam")
-    public void endExam() {
-        User user = getAccessUser();
-        Long studentId = user.getUserId();
-        String sequenceLockKey = Constants.END_EXAM_LOCK_PREFIX + studentId;
-        //系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-
-        long st = System.currentTimeMillis();
-        long startTime = System.currentTimeMillis();
-
-        // 获取考试会话,判断考生是否已结束考试
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("oestudent-100100", "考试会话已过期");
-        }
-
-
-        if (log.isDebugEnabled()) {
-            log.debug("0 [END_EXAM] 交卷前处理耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-        examControlService.handInExam(examSessionInfo.getExamRecordDataId(), HandInExamType.MANUAL);
-        if (log.isDebugEnabled()) {
-            log.debug("1 [END_EXAM]合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
-        }
-    }
-
-    /**
-     * 交卷后续处理,此处仅用于测试,无调用者
-     */
-    @ApiOperation(value = "交卷后续处理")
-    @GetMapping("/processAfterEndExam")
-    public ExamProcessResultInfo processAfterEndExam(@RequestParam Long examRecordDataId) {
-        User user = getAccessUser();
-        ExamProcessResultInfo res = new ExamProcessResultInfo();
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        try {
-            examControlService.processAfterHandInExam(examRecordDataId, examRecordData.getStudentId(), HandInExamType.MANUAL);
-        } catch (StatusException e) {
-            if (e.getCode().equals(Constants.CAPTURE_PROCESSING_STATUS_CODE)) {
-                res.setCode(Constants.PROCESSING_EXAM_RECORD_CODE);
-                return res;
-            }
-            throw e;
-        } catch (Exception e) {
-            throw e;
-        }
-
-
-        //根据相关条件添加推分队列
-        Long examId = examRecordData.getExamId();
-        String isPushScore = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                examRecordData.getStudentId(), ExamProperties.PUSH_SCORE.name()).getValue();
-        if (isPushScore != null && Constants.isTrue.equals(isPushScore)) {
-            //保存分数通知队列(只有考试设置中,配置为允许推分的才发送通知)
-            boolean isExistNoticeQueue = examScoreNoticeQueueService.isExistExamScoreNoticeQueue(user.getRootOrgId());
-            //如果当前组织机构的通知队列数据不存在则保存至队列,否则不作任何处理
-            if (!isExistNoticeQueue) {
-                examScoreNoticeQueueService.addExamScoreNoticeQueue(user.getRootOrgId());
-            }
-        }
-        res.setCode(Constants.COMMON_SUCCESS_CODE);
-        return res;
-    }
-
-    @ApiOperation(value = "获取考试记录信息")
-    @GetMapping("/getEndExamInfo")
-    public EndExamInfo getEndExamInfo(@RequestParam Long examRecordDataId) {
-        return examControlService.getEndExamInfo(examRecordDataId);
-    }
-
-    /**
-     * 考试心跳
-     *
-     * @return 剩余时间
-     */
-    @ApiOperation(value = "考试心跳")
-    @GetMapping("/examHeartbeat")
-    public Long examHeartbeat() {
-        User user = getAccessUser();
-        return examControlService.examHeartbeat(user);
-    }
-
-    /**
-     * 断点续考:检查正在进行中的考试
-     */
-    @ApiOperation(value = "断点续考:检查正在进行中的考试")
-    @GetMapping("/checkExamInProgress")
-    public ExamProcessResultInfo checkExamInProgress() {
-        User user = getAccessUser();
-        String sequenceLockKey = Constants.START_EXAM_LOCK_PREFIX + user.getUserId();
-        //系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-        ExamProcessResultInfo res = new ExamProcessResultInfo();
-        try {
-            CheckExamInProgressInfo info = examControlService.checkExamInProgress(user.getUserId());
-            res.setCode(Constants.COMMON_SUCCESS_CODE);
-            res.setData(info);
-            return res;
-        } catch (StatusException e) {
-            if (e.getCode().equals(Constants.EXAM_RECORD_NOT_END_STATUS_CODE)) {
-                res.setCode(Constants.PROCESSING_EXAM_RECORD_CODE);
-                return res;
-            }
-            throw e;
-        } catch (Exception e) {
-            throw e;
-        }
-    }
-
-    /**
-     * 获取又拍云文件上传签名(微信小程序调用)
-     */
-    @ApiOperation(value = "获取又拍云文件上传签名(微信小程序调用)")
-    @PostMapping("/upyunSignature")
-    public UpyunSignatureInfo getUpyunSignature(@ModelAttribute @Valid GetUpyunSignatureReq req) {
-        return examControlService.getUpyunSignature(req);
-    }
-
-    /**
-     * 校验二维码(微信小程序调用)
-     */
-    @Naked
-    @ApiOperation(value = "校验二维码(微信小程序调用)")
-    @PostMapping("/checkQrCode")
-    public CheckQrCodeInfo checkQrCode(@RequestParam(required = true) String qrCode) {
-        return examControlService.checkQrCode(qrCode);
-    }
-
-    /**
-     * 保存上传的文件(微信小程序调用)
-     */
-    @ApiOperation(value = "保存上传的文件(微信小程序调用)")
-    @PostMapping("/saveUploadedFile")
-    public Long saveUploadedFile(@ModelAttribute @Valid SaveUploadedFileReq req) {
-        User user = getAccessUser();
-        ExamFileAnswerTempEntity examFileAnswerTempEntity = examControlService.saveUploadedFile(req, user);
-        try {
-            String fileUrl = "";
-            if (req.getFilePath().indexOf(",") > -1) {
-                for (String url : req.getFilePath().split(",")) {
-                    fileUrl += upyunFileUrl + url + ",";
-                }
-                fileUrl = fileUrl.substring(0, fileUrl.length() - 1);
-            } else {
-                fileUrl = upyunFileUrl + req.getFilePath();
-            }
-            examControlService.sendFileAnswerToWebSocket(req.getExamRecordDataId(), req.getOrder(),
-                    fileUrl, req.getTransferFileType(), user.getUserId());
-        } catch (Exception e) {
-            examControlService.deleteExamFileAnswerTemp(req);
-            throw new StatusException("100009", "消息通知失败", e);
-        }
-        return examFileAnswerTempEntity.getId();
-    }
-
-    /**
-     * 查询客户端对上传的文件的响应状态(微信小程序调用)
-     */
-    @ApiOperation(value = "查询客户端对上传的文件的响应状态(微信小程序调用)")
-    @PostMapping("/getUploadedFileAcknowledgeStatus")
-    public String getUploadedFileAcknowledgeStatus(@ModelAttribute @Valid GetUploadedFileAcknowledgeStatusReq req) {
-        return examControlService.getUploadedFileAcknowledgeStatus(req);
-    }
-
-    /**
-     * 修改上传音频结果推送状态
-     */
-    @ApiOperation(value = "修改上传音频结果推送状态")
-    @PostMapping("/saveUploadedFileAcknowledgeStatus")
-    public void saveUploadedFileAcknowledgeStatus(@RequestBody @Valid SaveUploadedFileAcknowledgeStatusReq req) {
-        examControlService.saveUploadedFileAcknowledgeStatus(req);
-    }
-
-    @Naked
-    @ApiOperation(value = "获取学生是否有正在进行的网考信息")
-    @PostMapping("/getStudentOnLineExamInfo")
-    public GetStudentOnlineExamInfoResp getStudentOnLineExamInfo(@RequestBody GetStudentOnlineExamInfoReq req) {
-        if (null == req.getRootOrgId()) {
-            throw new StatusException("101001", "组织机构id参数不允许为空");
-        }
-        if (StringUtils.isNullOrEmpty(req.getStudentCode()) && StringUtils.isNullOrEmpty(req.getIdentityNumber())
-                && StringUtils.isNullOrEmpty(req.getPhone())) {
-            throw new StatusException("101002", "学生学号、身份证号或手机号参数至少有一个不为空");
-        }
-        GetStudentReq getStudentReq = new GetStudentReq();
-        getStudentReq.setRootOrgId(req.getRootOrgId());
-        if (!StringUtils.isNullOrEmpty(req.getStudentCode())) {
-            getStudentReq.setStudentCode(req.getStudentCode());
-        }
-        if (!StringUtils.isNullOrEmpty(req.getIdentityNumber())) {
-            getStudentReq.setIdentityNumber(req.getIdentityNumber());
-        }
-        if (!StringUtils.isNullOrEmpty(req.getPhone())) {
-            getStudentReq.setSecurityPhone(req.getPhone());
-        }
-        //此方法内部已作空处理,不需要再判断非空
-        GetStudentResp studentResp = studentCloudService.getStudent(getStudentReq);
-        StudentBean studentInfo = studentResp.getStudentInfo();
-        Long studentId = studentInfo.getId();
-        ExamRecordDataEntity examRecordData = examRecordDataRepo.findOnlineExamingRecordByStudentId(studentId);
-        GetStudentOnlineExamInfoResp resp = new GetStudentOnlineExamInfoResp();
-        if (null != examRecordData && null != examRecordData.getId()) {
-            resp.setExistExamingRecord(true);
-        } else {
-            resp.setExistExamingRecord(false);
-        }
-        return resp;
-    }
-
-    @ApiOperation(value = "获取抓拍照片的又拍云签名")
-    @GetMapping("/getCapturePhotoUpYunSign")
-    public GetUpyunSignDomain getCapturePhotoUpYunSign(GetUpyunSignDomainQuery query) {
-        String fileSuffix = query.getFileSuffix();
-        if (StringUtils.isNullOrEmpty(fileSuffix)) {
-            throw new StatusException("200001", "文件后缀名不允许为空");
-        }
-        fileSuffix = fileSuffix.indexOf(".") == -1 ? "." + fileSuffix : fileSuffix;
-
-        GetUpyunSignDomain result = new GetUpyunSignDomain();
-        User accessUser = this.getAccessUser();
-        String signIdentifier = String.valueOf(System.currentTimeMillis());
-        String upyunSignRedisKey = Constants.EXAM_CAPTURE_PHOTO_UPYUN_SIGN_PREFIX
-                + accessUser.getUserId() + "_" + signIdentifier;
-
-        UpyunPathEnvironmentInfo env = new UpyunPathEnvironmentInfo();
-        env.setRootOrgId(accessUser.getRootOrgId().toString());
-        env.setUserId(accessUser.getUserId().toString());
-        env.setFileSuffix(fileSuffix);
-        UpYunHttpRequest upYunHttpRequest = upyunService.buildUpYunHttpRequest(CAPTURE_PHOTO_UPYUN_SITEID, env, query.getFileMd5());
-        redisClient.set(upyunSignRedisKey, upYunHttpRequest, 60);
-        result.setAccessUrl(upYunHttpRequest.getAccessUrl());
-        result.setFormUrl(upYunHttpRequest.getFormUrl());
-        result.setFormParams(upYunHttpRequest.getFormParams());
-        result.setSignIdentifier(signIdentifier);
-        return result;
-    }
-
-    @ApiOperation(value = "批量获取抓拍照片的又拍云签名")
-    @PostMapping("/batchGetCapturePhotoUpYunSign")
-    public BatchGetUpyunSignDomain batchGetCapturePhotoUpYunSign(@RequestBody BatchGetUpyunSignDomainQuery batchQuery) {
-        if (batchQuery.getQueryList() == null || batchQuery.getQueryList().isEmpty()) {
-            throw new StatusException("200001", "查询条件不允许为空");
-        }
-
-        List<GetUpyunSignDomain> signDomainList = new ArrayList<>();
-        for (GetUpyunSignDomainQuery query : batchQuery.getQueryList()) {
-            String fileSuffix = query.getFileSuffix();
-            if (StringUtils.isNullOrEmpty(fileSuffix)) {
-                throw new StatusException("", "文件后缀名不允许为空");
-            }
-            fileSuffix = fileSuffix.indexOf(".") == -1 ? "." + fileSuffix : fileSuffix;
-
-            GetUpyunSignDomain upyunSignDomain = new GetUpyunSignDomain();
-            User accessUser = this.getAccessUser();
-            String signIdentifier = String.valueOf(System.currentTimeMillis());
-            String upyunSignRedisKey = Constants.EXAM_CAPTURE_PHOTO_UPYUN_SIGN_PREFIX
-                    + accessUser.getUserId() + "_" + signIdentifier;
-
-            UpyunPathEnvironmentInfo env = new UpyunPathEnvironmentInfo();
-            env.setRootOrgId(accessUser.getRootOrgId().toString());
-            env.setUserId(accessUser.getUserId().toString());
-            env.setFileSuffix(fileSuffix);
-            UpYunHttpRequest upYunHttpRequest = upyunService.buildUpYunHttpRequest(CAPTURE_PHOTO_UPYUN_SITEID, env, query.getFileMd5());
-            redisClient.set(upyunSignRedisKey, upYunHttpRequest, 60);
-            upyunSignDomain.setAccessUrl(upYunHttpRequest.getAccessUrl());
-            upyunSignDomain.setFormUrl(upYunHttpRequest.getFormUrl());
-            upyunSignDomain.setFormParams(upYunHttpRequest.getFormParams());
-            upyunSignDomain.setSignIdentifier(signIdentifier);
-
-            signDomainList.add(upyunSignDomain);
-            Util.sleep(TimeUnit.MILLISECONDS, 1);
-        }
-        BatchGetUpyunSignDomain result = new BatchGetUpyunSignDomain();
-        result.setList(signDomainList);
-        return result;
-    }
-}

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

@@ -1,179 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.common.base.Constants;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamFaceLivenessVerifyEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamFaceLivenessVerifyRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.GetFaceVerifyTokenInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamProcessResultInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamFaceLivenessVerifyService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import cn.com.qmth.examcloud.web.support.Naked;
-import cn.com.qmth.examcloud.ws.api.WebsocketCloudService;
-import cn.com.qmth.examcloud.ws.api.request.SendMessageReq;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-
-/**
- * @author chenken
- * @date 2018年9月5日 下午6:28:34
- * @company QMTH
- * @description 活体检测controller
- */
-@Api(tags = "活体检测")
-@RestController
-@RequestMapping("${app.api.oe.student}/examFaceLivenessVerify")
-public class ExamFaceLivenessVerifyController extends ControllerSupport {
-
-    @Autowired
-    private ExamFaceLivenessVerifyService examFaceLivenessVerifyService;
-
-    @Autowired
-    private WebsocketCloudService websocketCloudService;
-
-    @Autowired
-    private ExamFaceLivenessVerifyRepo examFaceLivenessVerifyRepo;
-
-
-    @ApiOperation(value = "检测学生底照是否能获取到faceId验证的token")
-    @GetMapping("/checkFaceLiveness")
-    public GetFaceVerifyTokenInfo checkFaceLiveness() {
-        User user = getAccessUser();
-        String bizNo = user.getUserId().toString();
-        return examFaceLivenessVerifyService.getFaceVerifyToken(user.getUserId(), bizNo);
-    }
-
-    /**
-     * 获得一个faceid用于网页端活体检测的token
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    @ApiOperation(value = "获得一个faceid用于网页端活体检测的token")
-    @GetMapping("/getFaceLivenessVerifyToken/{examRecordDataId}")
-    public GetFaceVerifyTokenInfo getFaceVerifyToken(@PathVariable Long examRecordDataId) {
-        Check.isNull(examRecordDataId, "examRecordDataId不能为空");
-        User user = getAccessUser();
-        ExamFaceLivenessVerifyEntity faceVerify = examFaceLivenessVerifyService.saveFaceVerifyByExamRecordDataId(examRecordDataId);
-        GetFaceVerifyTokenInfo getFaceVerifyTokenInfo = examFaceLivenessVerifyService.getFaceVerifyToken(user.getUserId(), faceVerify.getId().toString());
-        if (!getFaceVerifyTokenInfo.getSuccess()) {
-            faceVerify.setIsError(true);
-            faceVerify.setErrorMsg(getFaceVerifyTokenInfo.getErrorMsg());
-            examFaceLivenessVerifyRepo.save(faceVerify);
-        }
-        return getFaceVerifyTokenInfo;
-    }
-
-    @ApiOperation(value = "更新活体检测结果")
-    @GetMapping("/updateFaceLivenessVerify/{examRecordDataId}")
-    public void updateFaceVerify(@PathVariable Long examRecordDataId, @RequestParam String errorMsg) {
-        Check.isNull(examRecordDataId, "examRecordDataId不能为空");
-        List<ExamFaceLivenessVerifyEntity> examFaceLivenessVerifyEntities = examFaceLivenessVerifyService.listFaceVerifyByExamRecordId(examRecordDataId);
-        if (examFaceLivenessVerifyEntities != null && examFaceLivenessVerifyEntities.size() > 0) {
-            ExamFaceLivenessVerifyEntity examFaceLivenessVerifyEntity = examFaceLivenessVerifyEntities.get(0);
-            examFaceLivenessVerifyEntity.setIsError(true);
-            examFaceLivenessVerifyEntity.setErrorMsg(errorMsg);
-            examFaceLivenessVerifyRepo.save(examFaceLivenessVerifyEntity);
-        }
-    }
-
-    /**
-     * 人脸验证完成后的回调,由faceId调用
-     *
-     * @param data
-     * @throws Exception
-     */
-    @Naked
-    @ApiOperation(value = "人脸验证完成后的回调,由faceId调用")
-    @PostMapping("/faceLivenessVerifyCallback")
-    public void faceLivenessVerifyCallback(@RequestParam String data) throws Exception {
-        log.info("faceId回调,data=" + data);
-
-        JSONObject returnJsonObject = new JSONObject(data);
-        Long faceVerifyId = Long.parseLong(returnJsonObject.get("biz_no") + "");
-        ExamFaceLivenessVerifyEntity currentFaceVerify = examFaceLivenessVerifyService.findFaceVerifyById(faceVerifyId);
-        /**
-         * 如果该检测记录结果已经非空了,直接返回,
-         * 有可能超时程序已经将结果填成TIME_OUT了
-         */
-        if (currentFaceVerify.getVerifyResult() != null) {
-            return;
-        }
-
-        ExamFaceLivenessVerifyEntity faceVerify = examFaceLivenessVerifyService.faceIdNotify(data);
-        List<ExamFaceLivenessVerifyEntity> faceVerifies = examFaceLivenessVerifyService.listFaceVerifyByExamRecordId(faceVerify.getExamRecordDataId());
-        JSONObject jsonObject = new JSONObject();
-        //验证次数
-        jsonObject.put("verifyCount", faceVerifies.size());
-        //取最后一次验证结果
-        jsonObject.put("verifyResult", faceVerifies.get(faceVerifies.size() - 1).getVerifyResult().name());
-        jsonObject.put("examRecordDataId", faceVerify.getExamRecordDataId());
-
-        SendMessageReq sendMessageReq = new SendMessageReq();
-        sendMessageReq.setExamRecordDataId(faceVerify.getExamRecordDataId());
-        sendMessageReq.setReturnMsgJson(jsonObject.toString());
-        websocketCloudService.sendMessage(sendMessageReq);
-    }
-
-    /**
-     * 人脸检测超时处理
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    @ApiOperation(value = "人脸检测超时处理")
-    @GetMapping("/faceLivenessVerifyTimeOut/{examRecordDataId}")
-    public String faceTestTimeOut(@PathVariable Long examRecordDataId) {
-        JSONObject jsonObject = new JSONObject();
-        examFaceLivenessVerifyService.faceTestTimeOut(examRecordDataId);
-        List<ExamFaceLivenessVerifyEntity> faceVerifies = examFaceLivenessVerifyService.listFaceVerifyByExamRecordId(examRecordDataId);
-        //验证次数
-        try {
-            jsonObject.put("verifyCount", faceVerifies.size());
-            //取最后一次验证结果
-            jsonObject.put("verifyResult", faceVerifies.get(faceVerifies.size() - 1).getVerifyResult().name());
-            jsonObject.put("examRecordDataId", examRecordDataId);
-        } catch (JSONException e) {
-            e.printStackTrace();
-        }
-
-        return jsonObject.toString();
-    }
-
-    /**
-     * 人脸活体检测结束处理
-     *
-     * @param examRecordDataId 考试记录id
-     * @param result           活体检测结果
-     * @throws Exception
-     */
-    @ApiOperation(value = "人脸检测结束处理")
-    @GetMapping(value = "faceLivenessVerifyEnd/{examRecordDataId}")
-    public ExamProcessResultInfo faceTestEndHandle(@PathVariable Long examRecordDataId, @RequestParam String result) throws Exception {
-        ExamProcessResultInfo res = new ExamProcessResultInfo();
-        try {
-            User user = getAccessUser();
-            examFaceLivenessVerifyService.faceTestEndHandle(examRecordDataId, user.getUserId(), result);
-            res.setCode(Constants.COMMON_SUCCESS_CODE);
-            return res;
-        } catch (StatusException e) {
-            if (e.getCode().equals(Constants.EXAM_RECORD_NOT_END_STATUS_CODE)) {
-                res.setCode(Constants.PROCESSING_EXAM_RECORD_CODE);
-                return res;
-            }
-            throw e;
-        } catch (Exception e) {
-            throw e;
-        }
-    }
-
-}

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

@@ -1,97 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-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.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamQuestionEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordQuestionsEntity;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamSessionInfo;
-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.ExamSessionInfoService;
-import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionStructure;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * @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 ExamSessionInfoService examSessionInfoService;
-
-	/**
-	 * 将mongodb中的答过的题和redis中的题目列表合并返回给前端
-	 * 返回给前端时注意将正确答案和得分置成null
-	 * @return
-	 */
-	@ApiOperation(value = "考试过程中-获取试题列表")
-	@GetMapping("/findExamQuestionList")
-	public List<ExamQuestionEntity> findExamQuestionList(){
-		User user = getAccessUser();
-		ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(user.getUserId());
-		if (null== examSessionInfo){
-			throw new StatusException("500001","考试会话已过期,请重新开考");
-		}
-		ExamRecordQuestionsEntity examRecordQuestionsEntity = examRecordQuestionsService.
-				getExamRecordQuestionsAndFixExamRecordDataIfNecessary(examSessionInfo.getExamRecordDataId());
-
-		List<ExamQuestionEntity> examQuestionList = examRecordQuestionsEntity.getExamQuestionEntities();
-		for(ExamQuestionEntity 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("examQuestionController-submitQuestionAnswer", "illegal params");
-				}
-			}
-			examRecordQuestionsService.submitQuestionAnswer(user.getUserId(),examQuestionInfos);
-		}
-	}
-}

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

@@ -1,38 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-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.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordPaperStructEntity;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
-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:02:15
- * @company 	QMTH
- * @description 考试记录-试卷结构controller
- */
-@Api(tags = "考试记录-试卷结构")
-@RestController
-@RequestMapping("${app.api.oe.student}/examRecordPaperStruct")
-public class ExamRecordPaperStructController extends ControllerSupport{
-
-	@Autowired
-	private ExamRecordPaperStructService examRecordPaperStructService;
-	
-	@ApiOperation(value = "获取考试记录试卷结构")
-	@GetMapping("/getExamRecordPaperStruct")
-	public ExamRecordPaperStructEntity getExamRecordPaperStruct(@RequestParam Long examRecordDataId){
-		Check.isNull(examRecordDataId, "examRecordDataId不能为空");
-		return examRecordPaperStructService.getExamRecordPaperStruct(examRecordDataId);
-	}
-	
-}

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

@@ -1,40 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import java.util.List;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-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.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.student.bean.ObjectiveScoreInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamScoreService;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年10月20日 下午3:33:26
- * @company 	QMTH
- * @description ExamScoreController.java
- */
-@Api(tags = "分数相关接口")
-@RestController
-@RequestMapping("${app.api.oe.student}/examScore")
-public class ExamScoreController {
-	
-	@Autowired
-	private ExamScoreService examScoreService;
-	
-	@ApiOperation(value = "根据examStudentId获取客观分信息")
-	@GetMapping("/queryObjectiveScoreList")
-	public List<ObjectiveScoreInfo> queryObjectiveScoreList(@RequestParam Long examStudentId){
-		Check.isNull(examStudentId, "examStudentId 不能为空");
-		return examScoreService.queryObjectiveScoreList(examStudentId);
-	}
-	
-}

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

@@ -1,76 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.request.GetStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.response.GetStudentResp;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.exchange.inner.api.SmsCloudService;
-import cn.com.qmth.examcloud.exchange.inner.api.request.CheckSmsCodeReq;
-import cn.com.qmth.examcloud.exchange.inner.api.request.SendSmsCodeReq;
-import cn.com.qmth.examcloud.exchange.inner.api.response.CheckSmsCodeResp;
-import cn.com.qmth.examcloud.exchange.inner.api.response.SendSmsCodeResp;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月5日 下午3:33:26
- * @company 	QMTH
- * @description ExamSmsController.java
- */
-@RestController
-@Api(tags = "考试短信接口")
-@RequestMapping("${app.api.oe.student}/sms")
-public class ExamSmsController extends ControllerSupport{
-
-	@Autowired
-	private StudentCloudService studentCloudService;
-	
-	@Autowired
-//	private SendSmsCloudService sendSmsCloudService;
-	SmsCloudService smsCloudService;
-
-	@ApiOperation(value = "发送短信验证码")
-	@PostMapping("/sendSmsCodeToStudent")
-    public SendSmsCodeResp sendSmsCodeToStudent(){
-    	User user = getAccessUser();
-    	GetStudentReq getStudentReq = new GetStudentReq();
-    	getStudentReq.setStudentId(user.getUserId());
-    	GetStudentResp getStudentResp = studentCloudService.getStudent(getStudentReq);
-
-		SendSmsCodeResp sendSmsResp = new SendSmsCodeResp();
-    	if(StringUtils.isBlank(getStudentResp.getStudentInfo().getPhoneNumber())){
-    		throw new StatusException("100001","系统中手机号码为空,请联系管理员");
-    	}
-    	SendSmsCodeReq sendSmsReq = new SendSmsCodeReq();
-    	sendSmsReq.setPhone(getStudentResp.getStudentInfo().getPhoneNumber());
-    	sendSmsReq.setCode(CommonUtil.makeRandomNum(6));
-
-    	return smsCloudService.sendSmsCode(sendSmsReq);
-    }
-	
-	@ApiOperation(value = "检查验证码是否正确")
-	@PostMapping(value = "/checkSmsCode")
-    public CheckSmsCodeResp checkSmsCode(@RequestParam String phoneNumber, @RequestParam String code){
-		Check.isBlank(phoneNumber, "phoneNumber不能为空");
-		Check.isBlank(code, "code不能为空");
-    	CheckSmsCodeReq checkSmsCodeReq = new CheckSmsCodeReq();
-    	checkSmsCodeReq.setPhone(phoneNumber);
-    	checkSmsCodeReq.setCode(code);
-//    	return sendSmsCloudService.checkSmsCode(checkSmsCodeReq);
-    	return smsCloudService.checkSmsCode(checkSmsCodeReq);
-    }
-	
-}

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

@@ -1,239 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.common.base.Constants;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.FaceBiopsyItemEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.FaceBiopsyItemStepEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyScheme;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyType;
-import cn.com.qmth.examcloud.core.oe.common.enums.HandInExamType;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.FaceBiopsyItemRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.FaceBiopsyItemStepRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.*;
-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.ExamSessionInfoService;
-import cn.com.qmth.examcloud.core.oe.student.service.FaceBiopsyService;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-/**
- * @Description 人脸活体检测接口
- * @Author lideyin
- * @Date 2019/10/14 10:59
- * @Version 1.0
- */
-@Api(tags = "新人脸活体检测接口")
-@RestController
-@RequestMapping("${app.api.oe.student}/faceBiopsy")
-public class FaceBiopsyController extends ControllerSupport {
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-    @Autowired
-    private FaceBiopsyService faceBiopsyService;
-    @Autowired
-    private FaceBiopsyItemRepo faceBiopsyItemRepo;
-    @Autowired
-    private FaceBiopsyItemStepRepo faceBiopsyItemStepRepo;
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamFaceLivenessVerifyService examFaceLivenessVerifyService;
-
-    @Autowired
-    private ExamControlService examControlService;
-
-    @ApiOperation(value = "获取活体检测基本信息")
-    @GetMapping("/getFaceBiopsyBaseInfo")
-    public FaceBiopsyBaseInfo getFaceBiopsyBaseInfo(@RequestParam Long examRecordDataId) {
-        User user = getAccessUser();
-        Long studentId = user.getUserId();
-        String sequenceLockKey = Constants.GET_FACE_BIOPSY_INFO_PREFIX + studentId;
-        //系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-
-        //判断考试记录id是否有效
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        if (examRecordData == null) {
-            throw new StatusException("200101", "无效的考试记录");
-        }
-
-        if (ExamRecordStatus.EXAM_ING != examRecordData.getExamRecordStatus()) {
-            throw new StatusException("200103", "考试已结束");
-        }
-
-        // 获取考试会话,判断考生是否已结束考试
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("200104", "考试会话已过期");
-        }
-
-        //考试未开启人脸活体检测,不允许获取活检信息
-        Long rootOrgId = user.getRootOrgId();
-        Long examId = examRecordData.getExamId();
-        Long orgId = examRecordData.getOrgId();
-
-        if (!FaceBiopsyHelper.isFaceVerify(rootOrgId, examId,  studentId)) {
-            throw new StatusException("200105", "本场考试未开启人脸活体检测");
-        }
-
-        FaceBiopsyScheme faceBiopsyScheme = FaceBiopsyHelper.getFaceBiopsyScheme(user.getRootOrgId());
-
-        Integer faceVerifyMinute = null;
-        // 如果是新活体检测方案,则使用新的计算方案计算活检开始时间
-        if (faceBiopsyScheme == FaceBiopsyScheme.NEW) {
-            faceVerifyMinute = faceBiopsyService.calculateFaceBiopsyStartMinute(examRecordDataId);
-        }
-        // 非新活检,默认使用旧的活检计算方式
-        else {
-            faceVerifyMinute = examFaceLivenessVerifyService.getFaceLivenessVerifyMinute(user.getRootOrgId(),
-                    orgId, examId, studentId, examRecordData.getId(), examSessionInfo.getHeartbeat());
-        }
-
-        FaceBiopsyBaseInfo faceBiopsyBaseInfo = new FaceBiopsyBaseInfo();
-        faceBiopsyBaseInfo.setIdentificationOfLivingBodyScheme(faceBiopsyScheme.getCode());
-        faceBiopsyBaseInfo.setFaceVerifyMinute(faceVerifyMinute);
-        return faceBiopsyBaseInfo;
-    }
-
-    @ApiOperation(value = "获取人脸活体检测详细步骤")
-    @GetMapping("/getFaceBiopsyInfo")
-    public FaceBiopsyInfo getFaceBiopsyInfo(@RequestParam Long examRecordDataId) {
-        User user = getAccessUser();
-        Long studentId = user.getUserId();
-        String sequenceLockKey = Constants.GET_FACE_BIOPSY_INFO_PREFIX + studentId;
-        //系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-
-        //判断考试记录id是否有效
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        if (examRecordData == null) {
-            throw new StatusException("200101", "无效的考试记录");
-        }
-
-        if (ExamRecordStatus.EXAM_ING != examRecordData.getExamRecordStatus()) {
-            throw new StatusException("200102", "考试已结束");
-        }
-
-        // 获取考试会话,判断考生是否已结束考试
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("200103", "考试会话已过期");
-        }
-
-        //考试未开启人脸活体检测,不允许获取活检信息
-        Long rootOrgId = user.getRootOrgId();
-        Long examId = examRecordData.getExamId();
-        Long orgId = examRecordData.getOrgId();
-        if (!FaceBiopsyHelper.isFaceVerify(rootOrgId, examId,  studentId)) {
-            throw new StatusException("200104", "本场考试未开启人脸活体检测");
-        }
-
-        return faceBiopsyService.getFaceBiopsyInfo(user.getRootOrgId(), examRecordDataId, FaceBiopsyType.FACE_MOTION);
-    }
-
-
-    @ApiOperation(value = "保存活体检测结果")
-    @PostMapping("/saveFaceBiopsyResult")
-    public SaveFaceBiopsyResultResp saveFaceBiopsyResult(@RequestBody SaveFaceBiopsyResultReq req) {
-        User user = getAccessUser();
-        Long studentId = user.getUserId();
-        String sequenceLockKey = Constants.GET_FACE_BIOPSY_INFO_PREFIX + studentId;
-        //系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-
-        if (req.getExamRecordDataId() == null) {
-            throw new StatusException("200104", "考试记录id不允许为空");
-        }
-        //判断考试记录id是否有效
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, req.getExamRecordDataId(),
-                ExamRecordDataEntity.class);
-        if (examRecordData == null) {
-            throw new StatusException("200105", "无效的考试记录");
-        }
-
-        if (ExamRecordStatus.EXAM_ING != examRecordData.getExamRecordStatus()) {
-            throw new StatusException("200105", "考试已结束");
-        }
-
-        if (req.getFaceBiopsyItemId() == null) {
-            throw new StatusException("200106", "人脸活体检测明细id不允许为空");
-        }
-        FaceBiopsyItemEntity faceBiopsyItemEntity = GlobalHelper.getEntity(faceBiopsyItemRepo, req.getFaceBiopsyItemId(),
-                FaceBiopsyItemEntity.class);
-        if (faceBiopsyItemEntity == null) {
-            throw new StatusException("200111", "人脸活体检测明细id不存在");
-        }
-
-        if (faceBiopsyItemEntity.getCompleted() == true) {
-            throw new StatusException("200112", "不允许操作已结束的人脸活体检测数据");
-        }
-
-        if (req.getVerifySteps() == null || req.getVerifySteps().isEmpty()) {
-            throw new StatusException("200107", "活体检测步骤不允许为空");
-        }
-
-        if (req.getVerifySteps().stream().anyMatch(p -> p.getStepId() == null)) {
-            throw new StatusException("200108", "活体检测步骤id不允许为空");
-        }
-
-        if (req.getVerifySteps().stream().anyMatch(p -> p.getAction() == null)) {
-            throw new StatusException("200109", "活体检测执行动作不允许为空");
-        }
-
-        if (!verifyStepsAllMatch(req.getFaceBiopsyItemId(), req.getExamRecordDataId(), req.getVerifySteps())) {
-            throw new StatusException("200110", "活体检测步骤与原始定义不匹配");
-        }
-        SaveFaceBiopsyResultResp resp = faceBiopsyService.saveFaceBiopsyResult(req, studentId);
-
-        //如果活检满足交卷条件,则系统自动交卷,自动交卷逻辑不应该影响活检保存结果,所以不能放一个事务中
-        if (resp.getEndExam()) {
-            examSessionInfoService.deleteExamSessionInfo(studentId);
-            examControlService.handInExam(req.getExamRecordDataId(), HandInExamType.AUTO);
-        }
-        return resp;
-    }
-
-    /**
-     * 校验活检步骤和原始步骤是否匹配
-     *
-     * @param faceBiopsyItemId
-     * @param verifySteps
-     * @return
-     */
-    private boolean verifyStepsAllMatch(Long faceBiopsyItemId, Long examRecordDataId, List<FaceBiopsyStepInfo> verifySteps) {
-        List<FaceBiopsyItemStepEntity> originalVerifySteps = faceBiopsyItemStepRepo.findByFaceBiopsyItemId(faceBiopsyItemId);
-
-        if (originalVerifySteps == null || originalVerifySteps.isEmpty() ||
-                originalVerifySteps.size() != verifySteps.size()) {
-            return false;
-        }
-
-        for (int i = 0; i < originalVerifySteps.size(); i++) {
-            FaceBiopsyItemStepEntity originalStep = originalVerifySteps.get(i);
-            FaceBiopsyStepInfo newStep = verifySteps.get(i);
-            //如果步骤id和动作以及考试记录id不同时匹配,则认为不匹配
-            if (!(originalStep.getId().equals(newStep.getStepId()) &&
-                    originalStep.getAction().equals(newStep.getAction()) &&
-                    originalStep.getExamRecordDataId().equals(examRecordDataId))) {
-                return false;
-            }
-        }
-        return true;
-    }
-}

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

@@ -1,135 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamType;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.OfflineExamCourseInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.OfflineExamService;
-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;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import java.io.*;
-import java.util.List;
-
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月5日 下午3:33:26
- * @company 	QMTH
- * @description 离线考试Controller
- */
-@Api(tags = "离线考试控制")
-@RestController
-@RequestMapping("${app.api.oe.student}/offlineExam")
-public class OfflineExamController extends ControllerSupport{
-
-	@Autowired
-	private OfflineExamService offlineExamService;
-
-	@Autowired
-	private ExamRecordDataRepo examRecordDataRepo;
-	/**
-	 * 答案文件最大限制
-	 * 单位:M
-	 */
-	private static int answerMaxsize = 30;
-	
-	
-	public static final String TEMP_FILE_EXP = "offlineExam/";
-	
-	
-	/**
-	 * 获取离线考试列表
-	 * @return
-	 */
-	@ApiOperation(value = "获取离线考试列表")
-	@GetMapping("/getOfflineCourse")
-	public List<OfflineExamCourseInfo> getOfflineCourse(){
-		User user = getAccessUser();
-		List<OfflineExamCourseInfo> offlineExamCourseInfos = offlineExamService.getOfflineCourse(user.getUserId());
-		return offlineExamCourseInfos;
-	}
-	
-	/**
-	 * 开始考试
-	 * @param examStudentId
-	 */
-	@ApiOperation(value = "离线考试:开始考试")
-	@GetMapping("/startOfflineExam")
-	public void startOfflineExam(@RequestParam long examStudentId){
-		Check.isNull(examStudentId, "examStudentId不能为空");
-		offlineExamService.startOfflineExam(examStudentId);
-	}
-	
-	/**
-	 * 交卷
-	 */
-	@ApiOperation(value = "离线考试:交卷")
-	@PostMapping("/submitPaper")
-	public void submitPaper(@RequestParam(value = "file") MultipartFile file,
-							@RequestParam long examRecordDataId)  throws Exception{
-		Check.isNull(file, "file不能为空");
-		Check.isNull(examRecordDataId, "examRecordDataId不能为空");
-		String fileName = file.getOriginalFilename();
-		int index = fileName.lastIndexOf(".");
-		String fileSuffix = fileName.substring(index+1, fileName.length()).toUpperCase();
-		if(!"PDF".equals(fileSuffix) && !"ZIP".equals(fileSuffix)){
-			throw new StatusException("OfflineExamController-submitPaper-001","文件格式不正确"); 
-		}
-		
-		ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo,examRecordDataId,ExamRecordDataEntity.class);
-		if(examRecordData.getExamType() != ExamType.OFFLINE){
-			throw new StatusException("OfflineExamController-submitPaper-002","非离线考试"); 
-		}
-		String offlineUploadFileType = ExamCacheTransferHelper.getCachedExamProperty(examRecordData.getExamId(),
-				examRecordData.getStudentId(),
-				ExamProperties.OFFLINE_UPLOAD_FILE_TYPE.name()).getValue();
-		if(StringUtils.isBlank(offlineUploadFileType) || "[]".equals(offlineUploadFileType)){
-			throw new StatusException("OfflineExamController-submitPaper-003","当前考试设置不允许上传附件"); 
-		}
-		if(offlineUploadFileType.indexOf(fileSuffix)<0){
-			throw new StatusException("OfflineExamController-submitPaper-004","当前考试允许上传文件格式为:" + offlineUploadFileType); 
-		}
-		//判断文件大小
-		long fileSize = file.getSize();
-		if(fileSize > answerMaxsize * 1048576){
-			throw new StatusException("OfflineExamController-submitPaper-005","文件大小不能超过"+answerMaxsize+"M"); 
-		}
-		offlineExamService.submitPaper(examRecordDataId,getUploadFile(file));
-	}
-	
-	private File getUploadFile(MultipartFile file){
-        //建临时文件夹
-		File dirFile = new File(TEMP_FILE_EXP);
-		if(!dirFile.exists()){
-			dirFile.mkdirs();
-		}
-        String fileName = file.getOriginalFilename();
-        File tempFile = new File(TEMP_FILE_EXP + fileName);
-        OutputStream os = null;
-        try {
-			os = new FileOutputStream(tempFile);
-			IOUtils.copyLarge(file.getInputStream(), os);
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}finally{
-			IOUtils.closeQuietly(os);
-		}
-        return tempFile;
-    }
-}

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

@@ -1,73 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.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.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeCourseInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeDetailInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeRecordInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.PracticeService;
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月7日 上午11:12:28
- * @company 	QMTH
- * @description PracticeController.java
- */
-@Api(tags = "练习相关接口")
-@RestController
-@RequestMapping("${app.api.oe.student}/practice")
-public class PracticeController extends ControllerSupport{
-
-	@Autowired
-	private PracticeService practiceService;
-	
-	/**
-	 * 练习课程列表
-	 * @param examId
-	 * @param studentId
-	 * @return
-	 */
-	@ApiOperation(value = "练习课程列表")
-	@GetMapping("/queryPracticeCourseList")
-	public List<PracticeCourseInfo> queryPracticeCourseList(@RequestParam Long examId){
-		Check.isNull(examId, "examId不能为空");
-		User user = getAccessUser();
-		return practiceService.queryPracticeCourseList(examId, user.getUserId());
-	}
-	
-	/**
-	 * 课程练习记录详情
-	 * @param examStudentId
-	 * @return
-	 */
-	@ApiOperation(value = "课程练习记录详情")
-	@GetMapping("/queryPracticeRecordList")
-	public List<PracticeRecordInfo> queryPracticeRecordList(@RequestParam Long examStudentId){
-		Check.isNull(examStudentId, "examStudentId不能为空");
-		return practiceService.queryPracticeRecordList(examStudentId);
-	}
-	
-	/**
-	 * 单次练习答题情况统计
-	 * @return
-	 */
-	@ApiOperation(value = "单次练习答题情况统计")
-	@GetMapping("/getPracticeDetailInfo")
-	public PracticeDetailInfo getPracticeDetailInfo(@RequestParam Long examRecordDataId){
-		Check.isNull(examRecordDataId, "examRecordDataId不能为空");
-		return practiceService.getPracticeDetailInfo(examRecordDataId);
-	}
-	
-}

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

@@ -1,60 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller;
-
-import java.util.Collections;
-
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-
-import cn.com.qmth.examcloud.commons.util.DateUtil;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-
-/**
- * 测试状态.勿修改或删除
- *
- * @author WANGWEI
- * @date 2018年8月23日
- * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
- */
-@RestController
-@RequestMapping("${app.api.oe.student}")
-public class TestController extends ControllerSupport {
-
-	@RequestMapping(value = {"/", ""}, method = RequestMethod.GET)
-	public String get() {
-		return DateUtil.chinaNow();
-	}
-
-	@RequestMapping(value = {"/", ""}, method = RequestMethod.HEAD)
-	public ResponseEntity<?> head() {
-		return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
-	}
-
-	@RequestMapping(value = {"/", ""}, method = RequestMethod.OPTIONS)
-	public HttpEntity<?> options() {
-		HttpHeaders headers = new HttpHeaders();
-		headers.setAllow(Collections.singleton(HttpMethod.GET));
-		return new ResponseEntity<Object>(headers, HttpStatus.OK);
-	}
-
-	@RequestMapping(value = {"/", ""}, method = RequestMethod.POST)
-	public String post() {
-		return DateUtil.chinaNow();
-	}
-
-	@RequestMapping(value = {"/", ""}, method = RequestMethod.PUT)
-	public String put() {
-		return DateUtil.chinaNow();
-	}
-
-	@RequestMapping(value = {"/", ""}, method = RequestMethod.DELETE)
-	public String delete() {
-		return DateUtil.chinaNow();
-	}
-
-}

+ 0 - 29
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/BatchGetUpyunSignDomain.java

@@ -1,29 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-import java.util.Map;
-import java.util.List;
-
-/**
- * @Description 获取又拍云签名实体
- * @Author lideyin
- * @Date 2019/7/29 13:51
- * @Version 1.0
- */
-public class BatchGetUpyunSignDomain implements JsonSerializable {
-
-	private static final long serialVersionUID = -1590654532824096979L;
-
-	@ApiModelProperty("又拍云签名集合")
-	private List<GetUpyunSignDomain> list;
-
-	public List<GetUpyunSignDomain> getList() {
-		return list;
-	}
-
-	public void setList(List<GetUpyunSignDomain> list) {
-		this.list = list;
-	}
-}

+ 0 - 28
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/BatchGetUpyunSignDomainQuery.java

@@ -1,28 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller.bean;
-
-import io.swagger.annotations.ApiModelProperty;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @Description 获取又拍云签名查询实体
- * @Author lideyin
- * @Date 2019/7/29 13:52
- * @Version 1.0
- */
-public class BatchGetUpyunSignDomainQuery implements Serializable {
-
-    private static final long serialVersionUID = 9042153672752879732L;
-
-    @ApiModelProperty("又拍云签名查询参数集合")
-    private List<GetUpyunSignDomainQuery> queryList;
-
-    public List<GetUpyunSignDomainQuery> getQueryList() {
-        return queryList;
-    }
-
-    public void setQueryList(List<GetUpyunSignDomainQuery> queryList) {
-        this.queryList = queryList;
-    }
-}

+ 0 - 61
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/GetUpyunSignDomain.java

@@ -1,61 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller.bean;
-
-import java.util.Map;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-/**
- * @Description 获取又拍云签名实体
- * @Author lideyin
- * @Date 2019/7/29 13:51
- * @Version 1.0
- */
-public class GetUpyunSignDomain implements JsonSerializable {
-	private static final long serialVersionUID = -7428336128716146142L;
-
-	@ApiModelProperty("又拍云读取文件地址")
-	private String accessUrl;
-
-	@ApiModelProperty("又拍云签名唯一标识")
-	private String signIdentifier;
-
-	@ApiModelProperty("又拍云上传form请求地址 POST")
-	private String formUrl;
-
-	@ApiModelProperty("form表单参数(上传文件的参数名为'file')")
-	private Map<String, String> formParams;
-
-	public String getAccessUrl() {
-		return accessUrl;
-	}
-
-	public void setAccessUrl(String accessUrl) {
-		this.accessUrl = accessUrl;
-	}
-
-	public String getSignIdentifier() {
-		return signIdentifier;
-	}
-
-	public void setSignIdentifier(String signIdentifier) {
-		this.signIdentifier = signIdentifier;
-	}
-
-	public String getFormUrl() {
-		return formUrl;
-	}
-
-	public void setFormUrl(String formUrl) {
-		this.formUrl = formUrl;
-	}
-
-	public Map<String, String> getFormParams() {
-		return formParams;
-	}
-
-	public void setFormParams(Map<String, String> formParams) {
-		this.formParams = formParams;
-	}
-
-}

+ 0 - 35
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/controller/bean/GetUpyunSignDomainQuery.java

@@ -1,35 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.controller.bean;
-
-import io.swagger.annotations.ApiModelProperty;
-
-import java.io.Serializable;
-
-/**
- * @Description 获取又拍云签名查询实体
- * @Author lideyin
- * @Date 2019/7/29 13:52
- * @Version 1.0
- */
-public class GetUpyunSignDomainQuery implements Serializable {
-    private static final long serialVersionUID = 6594663402697883755L;
-    @ApiModelProperty("文件后缀名,示例:jpg")
-    private String fileSuffix;
-    @ApiModelProperty("文件md5加密值")
-    private String fileMd5;
-
-    public String getFileSuffix() {
-        return fileSuffix;
-    }
-
-    public void setFileSuffix(String fileSuffix) {
-        this.fileSuffix = fileSuffix;
-    }
-
-    public String getFileMd5() {
-        return fileMd5;
-    }
-
-    public void setFileMd5(String fileMd5) {
-        this.fileMd5 = fileMd5;
-    }
-}

+ 0 - 201
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/ExamRecordCloudServiceProvider.java

@@ -1,201 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.provider;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.basic.api.StudentCloudService;
-import cn.com.qmth.examcloud.core.basic.api.bean.StudentBean;
-import cn.com.qmth.examcloud.core.basic.api.request.GetStudentReq;
-import cn.com.qmth.examcloud.core.basic.api.response.GetStudentResp;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamingRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.HandInExamRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.student.api.OeStudentExamRecordCloudService;
-import cn.com.qmth.examcloud.core.oe.student.api.bean.ExamingRecordBean;
-import cn.com.qmth.examcloud.core.oe.student.api.bean.HandInExamRecordBean;
-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.core.oe.student.bean.ExamSessionInfo;
-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.ExamSessionInfoService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import cn.com.qmth.examcloud.web.support.Naked;
-import com.mysql.cj.util.StringUtils;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-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.List;
-
-@Api(tags = "清理考试记录")
-@RestController
-@RequestMapping("${$rmp.cloud.oe.student}" + "examRecord")
-public class ExamRecordCloudServiceProvider extends ControllerSupport implements OeStudentExamRecordCloudService {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 2873433904730318971L;
-    @Autowired
-    ExamSessionInfoService examSessionInfoService;
-    @Autowired
-    StudentCloudService studentCloudService;
-    @Autowired
-    ExamRecordDataRepo examRecordDataRepo;
-    @Autowired
-    ExamRecordDataService examRecordDataService;
-    @Autowired
-    private ExamControlService examControlService;
-
-    @Naked
-    @PostMapping("/cleanExamingRecord")
-    @Override
-    public void cleanExamingRecord(@RequestBody CleanExamingRecordReq req) {
-        ExamingRecordEntity examingRecordEntity = new ExamingRecordEntity();
-        examingRecordEntity.setExamRecordDataId(req.getExamRecordDataId());
-        examingRecordEntity.setId(req.getId());
-        examingRecordEntity.setStudentId(req.getStudentId());
-        examControlService.cleanExamingRecord(examingRecordEntity);
-    }
-
-    @Naked
-    @PostMapping("/cleanHandInExamRecord")
-    @Override
-    public void cleanHandInExamRecord(@RequestBody CleanHandInExamRecordReq req) {
-        HandInExamRecordEntity handInExamRecordEntity = new HandInExamRecordEntity();
-        handInExamRecordEntity.setExamRecordDataId(req.getExamRecordDataId());
-        handInExamRecordEntity.setId(req.getId());
-        handInExamRecordEntity.setStudentId(req.getStudentId());
-        examControlService.cleanHandInExamRecord(handInExamRecordEntity);
-    }
-
-    @Naked
-    @ApiOperation(value = "获取二维码")
-    @Override
-    @PostMapping("/getQrCode")
-    public GetQrCodeResp getQrCode(@RequestBody GetQrCodeReq req) {
-        log.info("开始调用获取二维码方法---getQrCode");
-        cn.com.qmth.examcloud.core.oe.student.bean.GetQrCodeReq beanReq = new cn.com.qmth.examcloud.core.oe.student.bean.GetQrCodeReq();
-        beanReq.setExamRecordDataId(req.getExamRecordDataId());
-        beanReq.setExamStudentId(req.getExamStudentId());
-        beanReq.setOrder(req.getOrder());
-        beanReq.setTransferFileType(req.getTransferFileType());
-        beanReq.setTestEnv(req.isTestEnv());
-        log.info("参数准备完毕---getQrCode,req.getExamRecordDataId()=" + req.getExamRecordDataId());
-        log.info("参数准备完毕---getQrCode,req.getExamStudentId()=" + req.getExamStudentId());
-        log.info("参数准备完毕---getQrCode,req.getOrder()=" + req.getOrder());
-        log.info("参数准备完毕---getQrCode,req.getTokenKey()=" + req.getTokenKey());
-        String qrCode = examControlService.getQrCode(beanReq, req.getTokenKey());
-        GetQrCodeResp resp = new GetQrCodeResp();
-        resp.setQrCode(qrCode);
-        return resp;
-    }
-
-    @Naked
-    @ApiOperation(value = "获取考试会话")
-    @Override
-    @PostMapping("/getExamSessionInfo")
-    public GetExamSessionInfoResp getExamSessionInfo(@RequestBody GetExamSessionInfoReq req) {
-
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(req.getStudentId());
-        if (null == examSessionInfo) {
-            throw new StatusException("100001", "考试已结束");
-        }
-        GetExamSessionInfoResp resp = new GetExamSessionInfoResp();
-        resp.setExamStudentId(examSessionInfo.getExamStudentId());
-        return resp;
-    }
-
-    @Naked
-    @ApiOperation(value = "获取学生是否有正在进行的网考信息")
-    @Override
-    @PostMapping("/getStudentOnLineExamInfo")
-    public GetStudentOnlineExamInfoResp getStudentOnLineExamInfo(@RequestBody GetStudentOnlineExamInfoReq req) {
-        if (null == req.getRootOrgId()) {
-            throw new StatusException("101001", "组织机构id参数不允许为空");
-        }
-        if (StringUtils.isNullOrEmpty(req.getStudentCode()) && StringUtils.isNullOrEmpty(req.getIdentityNumber())
-                && StringUtils.isNullOrEmpty(req.getPhone())) {
-            throw new StatusException("101002", "学生学号、身份证号或手机号参数至少有一个不为空");
-        }
-        GetStudentReq getStudentReq = new GetStudentReq();
-        getStudentReq.setRootOrgId(req.getRootOrgId());
-        if (!StringUtils.isNullOrEmpty(req.getStudentCode())) {
-            getStudentReq.setStudentCode(req.getStudentCode());
-        }
-        if (!StringUtils.isNullOrEmpty(req.getIdentityNumber())) {
-            getStudentReq.setIdentityNumber(req.getIdentityNumber());
-        }
-        if (!StringUtils.isNullOrEmpty(req.getPhone())) {
-            getStudentReq.setSecurityPhone(req.getPhone());
-        }
-        //此方法内部已作空处理,不需要再判断非空
-        GetStudentResp studentResp = studentCloudService.getStudent(getStudentReq);
-        StudentBean studentInfo = studentResp.getStudentInfo();
-        Long studentId = studentInfo.getId();
-        ExamRecordDataEntity examRecordData = examRecordDataRepo.findOnlineExamingRecordByStudentId(studentId);
-        GetStudentOnlineExamInfoResp resp = new GetStudentOnlineExamInfoResp();
-        if (null != examRecordData && null != examRecordData.getId()) {
-            resp.setExistExamingRecord(true);
-        } else {
-            resp.setExistExamingRecord(false);
-        }
-        return resp;
-    }
-
-    @Naked
-    @PostMapping("/getExamingRecords")
-    @Override
-    public GetExamingRecordResp getExamingRecords(@RequestBody GetExamingRecordReq req) {
-        List<ExamingRecordEntity> examingRecords = examRecordDataService.getLimitExamingRecords(req.getStartId(), req.getLimit());
-        if (null == examingRecords || examingRecords.isEmpty()) {
-            return new GetExamingRecordResp(req.getStartId(), null);
-        }
-
-        List<ExamingRecordBean> examingRecordBeanList = new ArrayList<>();
-        for (ExamingRecordEntity entity : examingRecords) {
-            ExamingRecordBean bean = new ExamingRecordBean();
-            bean.setExamRecordDataId(entity.getExamRecordDataId());
-            bean.setId(entity.getId());
-            bean.setStudentId(entity.getStudentId());
-            examingRecordBeanList.add(bean);
-        }
-        Long nextId = examingRecords.get(examingRecords.size() - 1).getId() + 1;
-        return new GetExamingRecordResp(nextId, examingRecordBeanList);
-    }
-
-
-    @Naked
-    @PostMapping("/getHandInExamRecords")
-    @Override
-    public GetHandInExamRecordResp getHandInExamRecords(@RequestBody GetHandInExamRecordReq req) {
-        List<HandInExamRecordEntity> handInExamRecords = examRecordDataService.getLimitHandInExamRecords(req.getStartId(), req.getLimit());
-        if (null == handInExamRecords || handInExamRecords.isEmpty()) {
-            return new GetHandInExamRecordResp(req.getStartId(), null);
-        }
-
-        List<HandInExamRecordBean> handInExamRecordBeanList = new ArrayList<>();
-        for (HandInExamRecordEntity entity : handInExamRecords) {
-            HandInExamRecordBean bean = new HandInExamRecordBean();
-            bean.setExamRecordDataId(entity.getExamRecordDataId());
-            bean.setId(entity.getId());
-            bean.setStudentId(entity.getStudentId());
-            handInExamRecordBeanList.add(bean);
-        }
-        Long nextId = handInExamRecords.get(handInExamRecords.size() - 1).getId() + 1;
-        return new GetHandInExamRecordResp(nextId, handInExamRecordBeanList);
-    }
-
-    @Naked
-    @ApiOperation(value = "清理考试已结束的文件作答记录")
-    @Override
-    @PostMapping("/cleanTempFileAnswers")
-    public void cleanTempFileAnswers() {
-        examControlService.cleanTempFileAnswers();
-    }
-}

+ 0 - 37
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/ExamRecordPaperStructProvider.java

@@ -1,37 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.provider;
-
-import cn.com.qmth.examcloud.core.oe.admin.api.OeExamStudentCloudService;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordPaperStructEntity;
-import cn.com.qmth.examcloud.core.oe.student.api.OeExamPaperStructCloudService;
-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.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-
-@Api(tags = "考试记录-试卷结构")
-@RestController
-@RequestMapping("${$rmp.cloud.oe.student}" + "examRecordPaperStruct")
-public class ExamRecordPaperStructProvider extends ControllerSupport implements OeExamPaperStructCloudService {
-
-	@Autowired
-	private ExamRecordPaperStructService examRecordPaperStructService;
-	
-	@ApiOperation(value = "获取考试记录试卷结构")
-	@PostMapping("/getExamRecordPaperStruct")
-	@Override
-	public GetExamRecordPaperStructResp getExamRecordPaperStruct(@RequestBody GetExamRecordPaperStructReq req) {
-		Check.isNull(req.getExamRecordDataId(), "考试记录id不能为空");
-		ExamRecordPaperStructEntity examRecordPaperStructEntity = examRecordPaperStructService.getExamRecordPaperStruct(req.getExamRecordDataId());
-		GetExamRecordPaperStructResp resp = new GetExamRecordPaperStructResp();
-		if (null == examRecordPaperStructEntity){
-			return null;
-		}
-		resp.setDefaultPaper(examRecordPaperStructEntity.getDefaultPaper());
-		return resp;
-	}
-}

+ 0 - 74
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeExamRecordForMarkingCloudServiceProvider.java

@@ -1,74 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.provider;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordForMarkingEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordForMarkingRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentFinalScoreRepo;
-import cn.com.qmth.examcloud.core.oe.student.api.OeExamRecordForMarkingCloudService;
-import cn.com.qmth.examcloud.core.oe.student.api.request.SaveExamRecordForMarkingReq;
-import cn.com.qmth.examcloud.core.oe.student.api.request.UpdateExamRecordForMarkingBatchNumReq;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamStudentFinalScoreService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import com.mysql.cj.util.StringUtils;
-import io.swagger.annotations.Api;
-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;
-
-@Api(tags = "保存阅卷数据接口")
-@RestController
-@RequestMapping("${$rmp.cloud.oe.student}" + "examRecordForMarking")
-public class OeExamRecordForMarkingCloudServiceProvider extends ControllerSupport
-        implements OeExamRecordForMarkingCloudService {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 5991001721278000904L;
-
-    @Autowired
-    private ExamRecordQuestionsService examRecordQuestionsService;
-
-    @Autowired
-    private ExamRecordForMarkingRepo examRecordForMarkingRepo;
-
-    @Override
-    @PostMapping("/saveExamRecordForMarking")
-    public void saveExamRecordForMarking(@RequestBody SaveExamRecordForMarkingReq req) {
-        ExamRecordForMarkingEntity examRecordForMarkingExists = examRecordForMarkingRepo.findByExamRecordDataId(req.getExamRecordDataId());
-        if (examRecordForMarkingExists != null) {
-            return;
-        }
-        ExamRecordForMarkingEntity examRecordForMarking = new ExamRecordForMarkingEntity();
-        examRecordForMarking.setExamId(req.getExamId());
-        examRecordForMarking.setExamRecordDataId(req.getExamRecordDataId());
-        examRecordForMarking.setExamStudentId(req.getExamStudentId());
-        examRecordForMarking.setBasePaperId(req.getBasePaperId());
-        examRecordForMarking.setPaperType(req.getPaperType());
-        examRecordForMarking.setCourseId(req.getCourseId());
-        examRecordForMarking.setObjectiveScore(req.getObjectiveScore());
-        int subjectiveAnswerLength = examRecordQuestionsService.calculationSubjectiveAnswerLength(req.getExamRecordDataId());
-        examRecordForMarking.setSubjectiveAnswerLength(subjectiveAnswerLength);
-        examRecordForMarkingRepo.save(examRecordForMarking);
-    }
-
-
-    @Override
-    @PostMapping("/updateExamRecordForMarkingBatchNum")
-    public void updateExamRecordForMarkingBatchNum(@RequestBody UpdateExamRecordForMarkingBatchNumReq req) {
-        if (req.getIdList()==null || req.getIdList().isEmpty()){
-            throw new StatusException("222001","阅卷原始数据表id不允许为空");
-        }
-        if (req.getIdList().size()>100){
-            throw new StatusException("222002","阅卷原始数据表id集合最大不得超过100条");
-        }
-        if (StringUtils.isNullOrEmpty(req.getBatchNum())){
-            throw new StatusException("222003","批次号不允许为空");
-        }
-        examRecordForMarkingRepo.updateBatchNum(req.getIdList(),req.getBatchNum());
-    }
-
-}

+ 0 - 113
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeExamScoreNoticeQueueCloudServiceProvider.java

@@ -1,113 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.provider;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.HttpURLConnection;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Date;
-import java.util.List;
-import java.util.Optional;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import cn.com.qmth.examcloud.commons.util.OKHttpUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreNoticeQueueEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.OrgScoreHandleEntity;
-import cn.com.qmth.examcloud.core.oe.common.info.NotifyUrlInfo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreNoticeQueueRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.OrgScoreHandleRepo;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScoreNoticeQueueService;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScoreObtainQueueService;
-import cn.com.qmth.examcloud.core.oe.student.api.OeExamScoreNoticeQueueCloudService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-@Api(tags = "定时发送获取分数通知接口")
-@RestController
-@RequestMapping("${$rmp.cloud.oe.student}" + "examScoreNoticeQueue")
-public class OeExamScoreNoticeQueueCloudServiceProvider extends ControllerSupport
-		implements OeExamScoreNoticeQueueCloudService {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -2622841462905285211L;
-
-//	@Autowired
-//	private OrgScoreHandleRepo orgScoreHandleRepo;
-	@Autowired
-	private ExamScoreNoticeQueueRepo examScoreNoticeQueueRepo;
-	@Autowired
-	ExamScoreObtainQueueService examScoreObtainQueueService;
-
-	/**
-	 * 定时发送分数获取通知 定时任务每5分钟发送一次
-	 */
-	@ApiOperation(value = "定时发送获取分数通知接口")
-	@PostMapping("/sendObtainScoreNotice")
-	@Override
-	public void sendObtainScoreNotice() {
-		System.out.println("1开始执行sendObtainScoreNotice");
-		log.info("开始执行sendObtainScoreNotice");
-		// 获取所有的通知队列
-		List<ExamScoreNoticeQueueEntity> examScoreNoticeQueueList = examScoreNoticeQueueRepo.findAll();
-		if (examScoreNoticeQueueList == null || examScoreNoticeQueueList.size() == 0) {
-			return;
-		}
-		System.out
-				.println("2执行sendObtainScoreNotice,examScoreNoticeQueueList.size()=" + examScoreNoticeQueueList.size());
-		// 获取所有配置通知路径的组织机构集合
-//		List<OrgScoreHandleEntity> orgScoreHandleList = orgScoreHandleRepo.findEnableNotifyItems();
-//		
-//		if(orgScoreHandleList == null || orgScoreHandleList.size() == 0){
-//			return;
-//		}
-//		System.out.println("3执行sendObtainScoreNotice,orgScoreHandleList.size()="+orgScoreHandleList.size());
-		for (ExamScoreNoticeQueueEntity noticeEntity : examScoreNoticeQueueList) {
-			// 获取当前组织机构的通知对象
-			NotifyUrlInfo notifyUrlInfo = examScoreObtainQueueService.getNotifyUrlInfo(noticeEntity.getRootOrgId());
-//			找到当前组织机构对应的通知队列 ldy20190516代码重构,修改获取通知方式
-//			Optional<OrgScoreHandleEntity> optionalOrgScoreHandle = orgScoreHandleList.stream().filter(org->org.getRootOrgId().equals(noticeEntity.getRootOrgId())).findFirst();
-//			if(optionalOrgScoreHandle.isPresent()) {
-//				OrgScoreHandleEntity orgScoreHandle = optionalOrgScoreHandle.get();
-			// 只有配置了通知接口的才发送通知
-			if (StringUtils.isNotBlank(notifyUrlInfo.getNotifyUrl())) {
-				try {
-					OKHttpUtil.call(notifyUrlInfo.getHttpMethod(), notifyUrlInfo.getNotifyUrl());
-//						this.post(notifyUrlInfo.getNotifyUrl(), null, 2000,15000);
-					// 发送通知没有问题,则清除通知队列中数据
-					examScoreNoticeQueueRepo.deleteById(noticeEntity.getRootOrgId());
-				} catch (Exception e) {
-					if (e instanceof UnknownHostException || e instanceof SocketException) {
-						try {
-							// 如果是由于连接超时,或者读取数据超时导致异常,需要对发送通知失败次数进行累加
-							long failTimes = noticeEntity.getFailTimes() == null ? 0
-									: noticeEntity.getFailTimes().longValue();
-							noticeEntity.setFailTimes(failTimes + 1);
-							noticeEntity.setUpdateTime(new Date());
-							examScoreNoticeQueueRepo.save(noticeEntity);
-						} catch (Exception e1) {
-							log.error("examScoreNoticeQueueRepo.save exception:" + e1.getMessage(), e1);
-						}
-					}
-					log.error("OeExamScoreNoticeQueueCloudServiceProvider-sendObtainScoreNotice:" + e.getMessage(), e);
-				}
-			}
-//			}
-
-		}
-		log.info("结束执行sendObtainScoreNotice");
-		System.out.println("结束执行sendObtainScoreNotice");
-	}
-
-}

+ 0 - 84
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeExamScoreObtainQueueCloudServiceProvider.java

@@ -1,84 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.provider;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import cn.com.qmth.examcloud.core.oe.common.base.utils.DateUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreNoticeQueueEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreObtainQueueEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreNoticeQueueRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreObtainQueueRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.OrgScoreHandleRepo;
-import cn.com.qmth.examcloud.core.oe.student.api.OeExamScoreObtainQueueCloudService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-@Api(tags = "获取分数队列")
-@RestController
-@RequestMapping("${$rmp.cloud.oe.student}" + "examScoreObtainQueue")
-public class OeExamScoreObtainQueueCloudServiceProvider extends ControllerSupport implements OeExamScoreObtainQueueCloudService{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -2622841462905285211L;
-	
-	@Autowired
-	private OrgScoreHandleRepo orgScoreHandleRepo;
-	@Autowired
-	ExamScoreObtainQueueRepo examScoreObtainQueueRepo;
-	@Autowired
-	ExamScoreNoticeQueueRepo examScoreNoticeQueueRepo;
-	
-	/**
-	 * 定时更新获取分数通知队列
-	 * 
-	 */
-	@ApiOperation(value = "定时更新获取分数通知队列")
-	@PostMapping("/updateObtainScoreNodifyQueue")
-	@Override
-	public void updateObtainScoreNodifyQueue() {
-		Date now = new Date();
-		Date twoHoursBefore= DateUtils.addHours(now, -2);
-		//1.查找超过创建超过2小时,且通知队列中不存在的待获取的数据
-		List<ExamScoreObtainQueueEntity> toObtainQueueList = examScoreObtainQueueRepo.findByCreationTimeLessThanEquals(twoHoursBefore);
-		//1.1如果不存在,不作任何处理
-		if(toObtainQueueList==null || toObtainQueueList.isEmpty()) {
-			return;
-		}
-		//1.2如果存在,则创建相应组织机构的通知队列
-		List<Long> rootOrgList = toObtainQueueList.stream().map(ExamScoreObtainQueueEntity::getRootOrgId).distinct().collect(Collectors.<Long>toList());
-		List<ExamScoreNoticeQueueEntity> noticeQueueEntityList= new ArrayList<ExamScoreNoticeQueueEntity>(); 
-		rootOrgList.forEach(ro->{
-			ExamScoreNoticeQueueEntity noticeQueueEntity = new ExamScoreNoticeQueueEntity();
-			noticeQueueEntity.setRootOrgId(ro);
-			noticeQueueEntity.setCreationTime(now);
-			noticeQueueEntityList.add(noticeQueueEntity);
-		});
-		//批量插入通知队列
-		examScoreNoticeQueueRepo.saveAll(noticeQueueEntityList);
-//		List<OrgScoreHandleEntity> orgScoreHandleList = orgScoreHandleRepo.findEnableNotifyItems();
-//		if(orgScoreHandleList == null || orgScoreHandleList.size() == 0){
-//			return;
-//		}
-//		for(OrgScoreHandleEntity orgScoreHandle:orgScoreHandleList){
-//			if(StringUtils.isNotBlank(orgScoreHandle.getNotifyUrl())){
-//				try{
-//					HttpClientUtil.post(orgScoreHandle.getNotifyUrl(), null, 2000);
-//				}catch(Exception e){
-//					log.error("ExamScoreObtainQueueServiceImpl-sendNotifyError:"+e.getMessage(),e);
-//				}
-//			}
-//		}
-	}
-
-}

+ 0 - 39
examcloud-core-oe-student-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/student/provider/OeHandleByExamCaptureQueueFailedDisposeServiceProvider.java

@@ -1,39 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.provider;
-
-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 cn.com.qmth.examcloud.core.oe.common.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.student.api.OeHandleByExamCaptureQueueFailedDisposeService;
-import cn.com.qmth.examcloud.core.oe.student.api.request.HandleByExamCaptureQueueFailedDisposeReq;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamControlService;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-
-
-@Api(tags = "抓拍照片失败处理")
-@RestController
-@RequestMapping("${$rmp.cloud.oe.student}" + "handleByExamCaptureQueueFailedDispose")
-public class OeHandleByExamCaptureQueueFailedDisposeServiceProvider extends ControllerSupport implements OeHandleByExamCaptureQueueFailedDisposeService{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 4864914290302594216L;
-
-	@Autowired
-	private ExamControlService examControlService;
-	
-	@ApiOperation(value = "抓拍照片失败处理")
-	@Override
-	@PostMapping
-	public void handleByExamCaptureQueueFailedDispose(@RequestBody HandleByExamCaptureQueueFailedDisposeReq req) {
-		Check.isNull(req.getExamRecordDataId(), "examRecordDataId 不能为空");
-		examControlService.handleByExamCaptureQueueFailedDispose(req.getExamRecordDataId());
-	}
-
-}

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

@@ -1,40 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-public class CalculateFaceCheckResultInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 5045871814686279423L;
-
-	private ExamRecordDataEntity examRecordData;
-	
-	/**
-	 * 无照片违纪
-	 */
-	private Boolean isNoPhotoAndIllegality;
-
-	public ExamRecordDataEntity getExamRecordData() {
-		return examRecordData;
-	}
-
-	public void setExamRecordData(ExamRecordDataEntity examRecordData) {
-		this.examRecordData = examRecordData;
-	}
-
-	public Boolean getIsNoPhotoAndIllegality() {
-		return isNoPhotoAndIllegality;
-	}
-	
-	/**
-	 * 设置无照片违纪
-	 * @param isNoPhotoAndIllegality
-	 */
-	public void setIsNoPhotoAndIllegality(Boolean isNoPhotoAndIllegality) {
-		this.isNoPhotoAndIllegality = isNoPhotoAndIllegality;
-	}
-
-}

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

@@ -1,89 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-public class CheckExamInProgressInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 5411680698118472710L;
-
-	//已断点次数
-	private Integer interruptNum;
-	
-	//最大断点次数限制
-	private Integer maxInterruptNum;
-	
-	//是否达到最大断点限制
-	private Boolean isExceed;
-	
-	private Long examRecordDataId;
-	
-	private Long examId;
-	/**
-	 * 使用时间
-	 */
-	private Integer usedTime;
-	/**
-	 * 活体检测启动分钟数
-	 */
-	private Integer faceVerifyMinute;
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Long getExamId() {
-		return examId;
-	}
-
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
-
-	public Integer getUsedTime() {
-		return usedTime;
-	}
-
-	public void setUsedTime(Integer usedTime) {
-		this.usedTime = usedTime;
-	}
-
-	public Integer getFaceVerifyMinute() {
-		return faceVerifyMinute;
-	}
-
-	public void setFaceVerifyMinute(Integer faceVerifyMinute) {
-		this.faceVerifyMinute = faceVerifyMinute;
-	}
-
-	public Integer getInterruptNum() {
-		return interruptNum;
-	}
-
-	public void setInterruptNum(Integer interruptNum) {
-		this.interruptNum = interruptNum;
-	}
-
-	public Integer getMaxInterruptNum() {
-		return maxInterruptNum;
-	}
-
-	public void setMaxInterruptNum(Integer maxInterruptNum) {
-		this.maxInterruptNum = maxInterruptNum;
-	}
-
-	public Boolean getIsExceed() {
-		return isExceed;
-	}
-
-	public void setIsExceed(Boolean isExceed) {
-		this.isExceed = isExceed;
-	}
-
-}

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

@@ -1,90 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-public class CheckQrCodeInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 7830558100815856011L;
-	@ApiModelProperty(value = "登录信息key")
-	private String key;
-	@ApiModelProperty(value = "登录信息token")
-	private String token;
-	@ApiModelProperty(value = "考生ID")
-	private Long examStudentId;
-	@ApiModelProperty(value = "考试记录DataID")
-	private Long examRecordDataId;
-	@ApiModelProperty(value = "考试试题题序")
-	private Integer questionOrder;
-	@ApiModelProperty(value = "考试试题大题号")
-    private Integer questionMainNumber;
-	@ApiModelProperty(value = "课程ID")
-	private Long courseId;
-	@ApiModelProperty(value = "课程名称")
-	private String courseName;
-	@ApiModelProperty(value = "小题显示序号")
-    private Integer subNumber;
-	public String getKey() {
-		return key;
-	}
-	public void setKey(String key) {
-		this.key = key;
-	}
-	public String getToken() {
-		return token;
-	}
-	public void setToken(String token) {
-		this.token = token;
-	}
-
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Long getCourseId() {
-		return courseId;
-	}
-	public void setCourseId(Long courseId) {
-		this.courseId = courseId;
-	}
-	public String getCourseName() {
-		return courseName;
-	}
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-	public Integer getQuestionOrder() {
-		return questionOrder;
-	}
-	public void setQuestionOrder(Integer questionOrder) {
-		this.questionOrder = questionOrder;
-	}
-	public Integer getQuestionMainNumber() {
-		return questionMainNumber;
-	}
-	public void setQuestionMainNumber(Integer questionMainNumber) {
-		this.questionMainNumber = questionMainNumber;
-	}
-	public Integer getSubNumber() {
-		return subNumber;
-	}
-	public void setSubNumber(Integer subNumber) {
-		this.subNumber = subNumber;
-	}
-	
-}

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

@@ -1,54 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamingRecordEntity;
-
-/**
- * @Description 清理考试记录优先级队列实体
- * @Author lideyin
- * @Date 2019/8/11 13:51
- * @Version 1.0
- */
-public class CleanExamRecordPriorityQueueInfo implements Comparable<CleanExamRecordPriorityQueueInfo> {
-
-    private int priority;
-    private ExamingRecordEntity examingRecord;
-
-    public CleanExamRecordPriorityQueueInfo() {
-    }
-    public CleanExamRecordPriorityQueueInfo(int priority, ExamingRecordEntity examingRecord) {
-        this.priority = priority;
-        this.examingRecord = examingRecord;
-    }
-
-    public int getPriority() {
-        return priority;
-    }
-
-    public void setPriority(int priority) {
-        this.priority = priority;
-    }
-
-    public ExamingRecordEntity getExamingRecord() {
-        return examingRecord;
-    }
-
-    public void setExamingRecord(ExamingRecordEntity examingRecord) {
-        this.examingRecord = examingRecord;
-    }
-
-    //升序
-    @Override
-    public int compareTo(CleanExamRecordPriorityQueueInfo data) {
-        return this.priority > data.priority ? -1 : this.priority == data.priority ? 0 : 1;
-    }
-
-    //考试记录id 相同则认为是同一个对象
-    @Override
-    public boolean equals(Object o) {
-        if (this.examingRecord==null){
-            return false;
-        }
-        return this.examingRecord.getId()
-                .equals(((CleanExamRecordPriorityQueueInfo) o).getExamingRecord().getId());
-    }
-}

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

@@ -1,60 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月27日 下午4:44:09
- * @company 	QMTH
- * @description EndExamInfo.java
- */
-public class EndExamInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 3567311334163339241L;
-
-	private Long examRecordDataId;
-	
-	private Boolean isWarn;
-	
-	private Double objectiveScore;
-	
-	private Double objectiveAccuracy;
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Boolean getIsWarn() {
-		return isWarn;
-	}
-
-	public void setIsWarn(Boolean isWarn) {
-		this.isWarn = isWarn;
-	}
-
-	public Double getObjectiveScore() {
-		return objectiveScore;
-	}
-
-	public void setObjectiveScore(Double objectiveScore) {
-		this.objectiveScore = objectiveScore;
-	}
-
-	public Double getObjectiveAccuracy() {
-		return objectiveAccuracy;
-	}
-
-	public void setObjectiveAccuracy(Double objectiveAccuracy) {
-		this.objectiveAccuracy = objectiveAccuracy;
-	}
-	
-	
-}

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

@@ -1,63 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年11月9日 下午4:52:40
- * @company 	QMTH
- * @description 交卷前置处理info
- */
-public class EndExamPreInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -8434235190113801338L;
-
-	private ExamRecordDataEntity examRecordData;
-	
-	private Long studentId;
-	
-	private Long usedExamTime;
-	
-	/**
-	 * 无照片违纪
-	 */
-	private Boolean isNoPhotoAndIllegality;
-
-	public ExamRecordDataEntity getExamRecordData() {
-		return examRecordData;
-	}
-
-	public void setExamRecordData(ExamRecordDataEntity examRecordData) {
-		this.examRecordData = examRecordData;
-	}
-
-	public Long getUsedExamTime() {
-		return usedExamTime;
-	}
-
-	public void setUsedExamTime(Long usedExamTime) {
-		this.usedExamTime = usedExamTime;
-	}
-
-	public Long getStudentId() {
-		return studentId;
-	}
-
-	public void setStudentId(Long studentId) {
-		this.studentId = studentId;
-	}
-
-	public Boolean getIsNoPhotoAndIllegality() {
-		return isNoPhotoAndIllegality;
-	}
-
-	public void setIsNoPhotoAndIllegality(Boolean isNoPhotoAndIllegality) {
-		this.isNoPhotoAndIllegality = isNoPhotoAndIllegality;
-	}
-	
-}

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

@@ -1,31 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * @Description 考试处理结果
- * @Author lideyin
- * @Date 2019/8/9 19:49
- * @Version 1.0
- */
-public class ExamProcessResultInfo implements JsonSerializable {
-    private String code;
-
-    private Object data;
-
-    public String getCode() {
-        return code;
-    }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
-
-    public Object getData() {
-        return data;
-    }
-
-    public void setData(Object data) {
-        this.data = data;
-    }
-}

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

@@ -1,27 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import java.io.Serializable;
-
-import io.swagger.annotations.ApiModelProperty;
-/**
- * 考生作答记录扩展类
- * @author lideyin
- * @date 2019年5月14日 下午3:29:59
- * @description
- */
-public class ExamQuestionAnswerExtensionInfo implements Serializable {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 6459207019695307248L;
-	@ApiModelProperty(value = "小题显示序号")
-    private Integer subNumber;
-	public Integer getSubNumber() {
-		return subNumber;
-	}
-	public void setSubNumber(Integer subNumber) {
-		this.subNumber = subNumber;
-	}
-	
-}

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

@@ -1,158 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * @author chenken
- * @date 2018/8/14 16:27
- * @company QMTH
- * @description 考试会话信息
- */
-public class ExamSessionInfo implements JsonSerializable {
-
-    /**
-	 * 
-	 */
-	private static final long serialVersionUID = 7271713913526550662L;
-	private Long examId;
-    /**
-     * 考试记录DataID
-     */
-    private Long examRecordDataId;
-    /**
-     * 考生ID
-     */
-    private Long examStudentId;
-    /**
-     * 考试开始时间
-     */
-    private Long startTime;
-    /**
-     * 考试时长:毫秒
-     */
-    private Long examDuration;
-    /**
-     * 冻结时间:分钟
-     */
-    private Integer freezeTime;
-    /**
-     * 心跳次数
-     */
-    private Integer heartbeat;
-    /**
-     * 最后一次心跳时间
-     */
-    private Long lastHeartbeat;
-    /**
-     * 考试类型
-     */
-    private String examType;
-    /**
-     * 断点续考时间:分钟
-     */
-    private Integer examReconnectTime;
-    /**
-     * 课程代码
-     */
-    private String courseCode;
-    /**
-     * 试卷类型
-     */
-    private String paperType;
-    public Long getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(Long startTime) {
-        this.startTime = startTime;
-    }
-
-    public Long getExamDuration() {
-        return examDuration;
-    }
-
-    public void setExamDuration(Long examDuration) {
-        this.examDuration = examDuration;
-    }
-
-    public Integer getHeartbeat() {
-        return heartbeat;
-    }
-
-    public void setHeartbeat(Integer heartbeat) {
-        this.heartbeat = heartbeat;
-    }
-
-    public String getExamType() {
-        return examType;
-    }
-
-    public void setExamType(String examType) {
-        this.examType = examType;
-    }
-
-    public Integer getExamReconnectTime() {
-        return examReconnectTime;
-    }
-
-    public void setExamReconnectTime(Integer examReconnectTime) {
-        this.examReconnectTime = examReconnectTime;
-    }
-
-    public Long getLastHeartbeat() {
-        return lastHeartbeat;
-    }
-
-    public void setLastHeartbeat(Long lastHeartbeat) {
-        this.lastHeartbeat = lastHeartbeat;
-    }
-
-    public Integer getFreezeTime() {
-        return freezeTime;
-    }
-
-    public void setFreezeTime(Integer freezeTime) {
-        this.freezeTime = freezeTime;
-    }
-
-    public Long getExamRecordDataId() {
-        return examRecordDataId;
-    }
-
-    public void setExamRecordDataId(Long examRecordDataId) {
-        this.examRecordDataId = examRecordDataId;
-    }
-
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-
-	public Long getExamId() {
-		return examId;
-	}
-
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
-
-    public String getCourseCode() {
-        return courseCode;
-    }
-
-    public void setCourseCode(String courseCode) {
-        this.courseCode = courseCode;
-    }
-
-    public String getPaperType() {
-        return paperType;
-    }
-
-    public void setPaperType(String paperType) {
-        this.paperType = paperType;
-    }
-}

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

@@ -1,296 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import java.util.Date;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * @author  	chenken
- * @date    	2018年8月13日 下午3:18:45
- * @company 	QMTH
- * @description ExamStudentInfo.java
- */
-public class ExamStudentInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 6364550318267288565L;
-
-	private Long examStudentId;//考试报考ID
-	
-	private Long examId;//网考批次ID
-	
-	private String examName;//批次名称
-	
-	private String studentName;//考生名称
-	
-	private String studentCode;//考生学号
-	
-	private String identityNumber;//身份证号码
-	
-	private String specialtyName;//专业名称
-	
-	private String specialtyLevel;//层次
-	
-	private Long courseId;//课程ID
-	
-	private String courseName;//课程名称
-	
-	private String courseCode;//课程代码
-	
-	private String courseLevel;//课程层次
-	
-	private Long orgId;//学校中心ID
-	
-	private String orgName;//学习中心名称
-	
-	private String isPhotoUpload;//是否上传照片
-	
-	private int paperMins;//考试时长
-	
-	private int allowExamCount;//允许考试次数
-	
-	private Date startTime;//考试时间范围开始时间
-	
-	private Date endTime; //考试时间范围结束时间
-	
-	private Long rootOrgId;//机构ID
-	
-	private String isFinished;//是否缺考
-	
-	/**
-	 * 考试状态
-	 */
-	private String examStatus;
-
-	/**
-	 * 是否有效
-	 */
-	//private Boolean isvalid;
-	/**
-	 * 是否启用人脸识别
-	 */
-	private Boolean faceEnable;
-	/**
-	 * 进入考试是否验证人脸识别(强制、非强制)
-	 */
-	private Boolean faceCheck;
-	
-	/**
-	 * 是否显示客观分
-	 */
-	private Boolean isObjScoreView;
-
-
-	public String getStudentName() {
-		return studentName;
-	}
-
-	public void setStudentName(String studentName) {
-		this.studentName = studentName;
-	}
-	
-	public String getStudentCode() {
-		return studentCode;
-	}
-
-	public void setStudentCode(String studentCode) {
-		this.studentCode = studentCode;
-	}
-
-	public String getSpecialtyName() {
-		return specialtyName;
-	}
-
-	public void setSpecialtyName(String specialtyName) {
-		this.specialtyName = specialtyName;
-	}
-
-	public String getSpecialtyLevel() {
-		return specialtyLevel;
-	}
-
-	public void setSpecialtyLevel(String specialtyLevel) {
-		this.specialtyLevel = specialtyLevel;
-	}
-
-	public Long getCourseId() {
-		return courseId;
-	}
-
-	public void setCourseId(Long courseId) {
-		this.courseId = courseId;
-	}
-
-	public String getCourseName() {
-		return courseName;
-	}
-
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-
-	public String getCourseCode() {
-		return courseCode;
-	}
-
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-
-
-	public String getIsPhotoUpload() {
-		return isPhotoUpload;
-	}
-
-	public void setIsPhotoUpload(String isPhotoUpload) {
-		this.isPhotoUpload = isPhotoUpload;
-	}
-
-	public int getPaperMins() {
-		return paperMins;
-	}
-
-	public void setPaperMins(int paperMins) {
-		this.paperMins = paperMins;
-	}
-
-	public int getAllowExamCount() {
-		return allowExamCount;
-	}
-
-	public void setAllowExamCount(int allowExamCount) {
-		this.allowExamCount = allowExamCount;
-	}
-
-	public Date getStartTime() {
-		return startTime;
-	}
-
-	public void setStartTime(Date startTime) {
-		this.startTime = startTime;
-	}
-
-	public Date getEndTime() {
-		return endTime;
-	}
-
-	public void setEndTime(Date endTime) {
-		this.endTime = endTime;
-	}
-
-	public String getIsFinished() {
-		return isFinished;
-	}
-
-	public void setIsFinished(String isFinished) {
-		this.isFinished = isFinished;
-	}
-
-	public String getExamStatus() {
-		return examStatus;
-	}
-
-	public void setExamStatus(String examStatus) {
-		this.examStatus = examStatus;
-	}
-
-	public String getIdentityNumber() {
-		return identityNumber;
-	}
-
-	public void setIdentityNumber(String identityNumber) {
-		this.identityNumber = identityNumber;
-	}
-
-	public String getCourseLevel() {
-		return courseLevel;
-	}
-
-	public void setCourseLevel(String courseLevel) {
-		this.courseLevel = courseLevel;
-	}
-
-	/*public Boolean getIsvalid() {
-		return isvalid;
-	}
-
-	public void setIsvalid(Boolean isvalid) {
-		this.isvalid = isvalid;
-	}*/
-
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-
-	public Long getExamId() {
-		return examId;
-	}
-
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
-
-	public String getExamName() {
-		return examName;
-	}
-
-	public void setExamName(String examName) {
-		this.examName = examName;
-	}
-
-	public Long getOrgId() {
-		return orgId;
-	}
-
-	public void setOrgId(Long orgId) {
-		this.orgId = orgId;
-	}
-
-	public String getOrgName() {
-		return orgName;
-	}
-
-	public void setOrgName(String orgName) {
-		this.orgName = orgName;
-	}
-
-	public Long getRootOrgId() {
-		return rootOrgId;
-	}
-
-	public void setRootOrgId(Long rootOrgId) {
-		this.rootOrgId = rootOrgId;
-	}
-
-	public Boolean getFaceEnable() {
-		return faceEnable;
-	}
-
-	public void setFaceEnable(Boolean faceEnable) {
-		this.faceEnable = faceEnable;
-	}
-
-	public Boolean getFaceCheck() {
-		return faceCheck;
-	}
-
-	public void setFaceCheck(Boolean faceCheck) {
-		this.faceCheck = faceCheck;
-	}
-
-	public Boolean getIsObjScoreView() {
-		return isObjScoreView;
-	}
-
-	public void setIsObjScoreView(Boolean isObjScoreView) {
-		this.isObjScoreView = isObjScoreView;
-	}
-	
-}
-

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

@@ -1,88 +0,0 @@
-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;
-	}
-	
-}

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

@@ -1,38 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-import java.util.List;
-
-/**
- * @Description 人脸活体检测基础信息信息
- * @Author lideyin
- * @Date 2019/10/14 11:21
- * @Version 1.0
- */
-public class FaceBiopsyBaseInfo implements JsonSerializable {
-    private static final long serialVersionUID = 3639013689409712841L;
-
-    @ApiModelProperty(value = "活体检测方案", notes = "S1:旧方案;S2:新方案", required = true)
-    private String identificationOfLivingBodyScheme;
-
-    @ApiModelProperty(value = "活体检测开始分钟数", required = true)
-    private Integer faceVerifyMinute;
-
-    public String getIdentificationOfLivingBodyScheme() {
-        return identificationOfLivingBodyScheme;
-    }
-
-    public void setIdentificationOfLivingBodyScheme(String identificationOfLivingBodyScheme) {
-        this.identificationOfLivingBodyScheme = identificationOfLivingBodyScheme;
-    }
-
-    public Integer getFaceVerifyMinute() {
-        return faceVerifyMinute;
-    }
-
-    public void setFaceVerifyMinute(Integer faceVerifyMinute) {
-        this.faceVerifyMinute = faceVerifyMinute;
-    }
-}

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

@@ -1,50 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * @Description 人脸活体检测基本信息
- * @Author lideyin
- * @Date 2019/10/14 11:21
- * @Version 1.0
- */
-public class FaceBiopsyInfo implements JsonSerializable {
-    private static final long serialVersionUID = -8323306595159483818L;
-
-    @ApiModelProperty(value = "活体检测开始分钟数", required = true)
-    private Integer faceVerifyMinute;
-
-    @ApiModelProperty(value = "人脸活体检测明细id", required = true)
-    private Long faceBiopsyItemId;
-
-    @ApiModelProperty(value = "人脸活体检测步骤", required = true)
-    private List<FaceBiopsyStepInfo> verifySteps;
-
-    public Integer getFaceVerifyMinute() {
-        return faceVerifyMinute;
-    }
-
-    public void setFaceVerifyMinute(Integer faceVerifyMinute) {
-        this.faceVerifyMinute = faceVerifyMinute;
-    }
-
-    public Long getFaceBiopsyItemId() {
-        return faceBiopsyItemId;
-    }
-
-    public void setFaceBiopsyItemId(Long faceBiopsyItemId) {
-        this.faceBiopsyItemId = faceBiopsyItemId;
-    }
-
-    public List<FaceBiopsyStepInfo> getVerifySteps() {
-        return verifySteps;
-    }
-
-    public void setVerifySteps(List<FaceBiopsyStepInfo> verifySteps) {
-        this.verifySteps = verifySteps;
-    }
-}

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

@@ -1,153 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyAction;
-import cn.com.qmth.examcloud.core.oe.common.enums.ResourceType;
-import io.swagger.annotations.ApiModelProperty;
-
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-
-/**
- * @Description 人脸活体检测步骤
- * @Author lideyin
- * @Date 2019/10/14 11:21
- * @Version 1.0
- */
-public class FaceBiopsyStepInfo implements JsonSerializable {
-	private static final long serialVersionUID = -2108253508943543996L;
-
-	@ApiModelProperty(value = "步骤id",required = true)
-	private Long stepId;
-
-	@ApiModelProperty(value = "具体动作",required = true)
-	@Enumerated(EnumType.STRING)
-	private FaceBiopsyAction action;
-
-	@ApiModelProperty(value = "动作时长")
-	private Integer stay;
-
-	@ApiModelProperty(value = "资源文件路径")
-	private String resourceUrl;
-
-	@ApiModelProperty(value = "资源文件类型")
-	@Enumerated(EnumType.STRING)
-	private ResourceType resourceType;
-
-	@ApiModelProperty(value = "执行结果")
-	private Boolean result;
-
-	@ApiModelProperty(value = "指令是否超时")
-	private Boolean timeout;
-
-	@ApiModelProperty(value = "是否有陌生人脸即多张人脸")
-	private Boolean stranger;
-
-	@ApiModelProperty(value = "是否晃出摄像头")
-	private Boolean waggleOutCamera;
-
-	@ApiModelProperty(value = "是否检测到人脸")
-	private Boolean hasFace;
-
-	@ApiModelProperty(value = "指令执行结果json串")
-	private String resultJson;
-
-	@ApiModelProperty(value = "错误描述")
-	private String errorMsg;
-
-	public Long getStepId() {
-		return stepId;
-	}
-
-	public void setStepId(Long stepId) {
-		this.stepId = stepId;
-	}
-
-	public FaceBiopsyAction getAction() {
-		return action;
-	}
-
-	public void setAction(FaceBiopsyAction action) {
-		this.action = action;
-	}
-
-	public Integer getStay() {
-		return stay;
-	}
-
-	public void setStay(Integer stay) {
-		this.stay = stay;
-	}
-
-	public String getResourceUrl() {
-		return resourceUrl;
-	}
-
-	public void setResourceUrl(String resourceUrl) {
-		this.resourceUrl = resourceUrl;
-	}
-
-	public ResourceType getResourceType() {
-		return resourceType;
-	}
-
-	public void setResourceType(ResourceType resourceType) {
-		this.resourceType = resourceType;
-	}
-
-	public Boolean getResult() {
-		return result;
-	}
-
-	public void setResult(Boolean result) {
-		this.result = result;
-	}
-
-	public String getResultJson() {
-		return resultJson;
-	}
-
-	public void setResultJson(String resultJson) {
-		this.resultJson = resultJson;
-	}
-
-	public String getErrorMsg() {
-		return errorMsg;
-	}
-
-	public void setErrorMsg(String errorMsg) {
-		this.errorMsg = errorMsg;
-	}
-
-	public Boolean getTimeout() {
-		return timeout;
-	}
-
-	public void setTimeout(Boolean timeout) {
-		this.timeout = timeout;
-	}
-
-	public Boolean getStranger() {
-		return stranger;
-	}
-
-	public void setStranger(Boolean stranger) {
-		this.stranger = stranger;
-	}
-
-	public Boolean getWaggleOutCamera() {
-		return waggleOutCamera;
-	}
-
-	public void setWaggleOutCamera(Boolean waggleOutCamera) {
-		this.waggleOutCamera = waggleOutCamera;
-	}
-
-	public Boolean getHasFace() {
-		return hasFace;
-	}
-
-	public void setHasFace(Boolean hasFace) {
-		this.hasFace = hasFace;
-	}
-}

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

@@ -1,42 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-public class GetFaceVerifyTokenInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -4053674655722904852L;
-
-	private Boolean success;
-	
-	private String faceLivenessToken;
-	
-	private String errorMsg;
-
-	public Boolean getSuccess() {
-		return success;
-	}
-
-	public void setSuccess(Boolean success) {
-		this.success = success;
-	}
-
-	public String getFaceLivenessToken() {
-		return faceLivenessToken;
-	}
-
-	public void setFaceLivenessToken(String faceLivenessToken) {
-		this.faceLivenessToken = faceLivenessToken;
-	}
-
-	public String getErrorMsg() {
-		return errorMsg;
-	}
-
-	public void setErrorMsg(String errorMsg) {
-		this.errorMsg = errorMsg;
-	}
-	
-}

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

@@ -1,64 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import javax.validation.constraints.NotNull;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-public class GetQrCodeReq implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -8684452576786540515L;
-	@NotNull(message = "考生ID不能为空")
-	@ApiModelProperty(required = true,value = "考生ID")
-	private Long examStudentId;
-	@NotNull(message = "考试记录DataID不能为空")
-	@ApiModelProperty(required = true,value = "考试记录DataID")
-	private Long examRecordDataId;
-	@NotNull(message = "题号不能为空")
-	@ApiModelProperty(required = true,value = "考试试题号")
-	private Integer order;
-	@ApiModelProperty(required = true,value = "传输文件类型")
-	private String transferFileType;
-
-	@ApiModelProperty(required = true,value = "是否用来测试环境")
-	private boolean testEnv;
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Integer getOrder() {
-		return order;
-	}
-	public void setOrder(Integer order) {
-		this.order = order;
-	}
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-
-	public String getTransferFileType() {
-		return transferFileType;
-	}
-
-	public void setTransferFileType(String transferFileType) {
-		this.transferFileType = transferFileType;
-	}
-
-	public boolean isTestEnv() {
-		return testEnv;
-	}
-
-	public void setTestEnv(boolean testEnv) {
-		this.testEnv = testEnv;
-	}
-}

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

@@ -1,22 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-import javax.validation.constraints.NotNull;
-
-public class GetUploadedFileAcknowledgeStatusReq implements JsonSerializable {
-
-    private static final long serialVersionUID = 2015767610417418141L;
-    @NotNull(message = "响应id不允许为空")
-    @ApiModelProperty(required = true, value = "响应id不允许为空")
-    private Long acknowledgeId;
-
-    public Long getAcknowledgeId() {
-        return acknowledgeId;
-    }
-
-    public void setAcknowledgeId(Long acknowledgeId) {
-        this.acknowledgeId = acknowledgeId;
-    }
-}

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

@@ -1,24 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import javax.validation.constraints.NotNull;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-public class GetUploadedFileAnswerListReq implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 2015767610417418141L;
-	@NotNull(message = "考试记录DataID不能为空")
-	@ApiModelProperty(required = true,value = "考试记录DataID")
-	private Long examRecordDataId;
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-	
-}

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

@@ -1,61 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import javax.validation.constraints.NotNull;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-public class GetUpyunSignatureReq implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -3761016079101373608L;
-	@NotNull(message = "考试记录DataID不能为空")
-	@ApiModelProperty(required = true,value = "考试记录DataID")
-	private Integer examRecordDataId;
-	@NotNull(message = "题号不能为空")
-	@ApiModelProperty(required = true,value = "考试试题号")
-	private Integer order;
-	@NotNull(message = "文件MD5不能为空")
-	@ApiModelProperty(required = true,value = "文件MD5")
-	private String fileMd5;
-	@NotNull(message = "文件后缀不能为空")
-	@ApiModelProperty(required = true,value = "文件后缀")
-	private String fileSuffix;
-	@ApiModelProperty(value = "文件名自定义参数")
-	private String ext;
-
-	public Integer getExamRecordDataId() {
-		return examRecordDataId;
-	}
-	public void setExamRecordDataId(Integer examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Integer getOrder() {
-		return order;
-	}
-	public void setOrder(Integer order) {
-		this.order = order;
-	}
-	public String getFileMd5() {
-		return fileMd5;
-	}
-	public void setFileMd5(String fileMd5) {
-		this.fileMd5 = fileMd5;
-	}
-	public String getFileSuffix() {
-		return fileSuffix;
-	}
-	public void setFileSuffix(String fileSuffix) {
-		this.fileSuffix = fileSuffix;
-	}
-	public String getExt() {
-		return ext;
-	}
-	public void setExt(String ext) {
-		this.ext = ext;
-	}
-	
-}

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

@@ -1,125 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-
-import java.util.Date;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月27日 下午3:45:58
- * @company 	QMTH
- * @description 客观分信息
- */
-public class ObjectiveScoreInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 3722050952090373601L;
-
-	/**
-	 * 考试记录ID
-	 */
-	private Long examRecordDataId;
-	
-	/**
-	 * 客观分总分
-	 */
-	private Double objectiveScore;
-	
-	/**
-	 * 第几次考
-	 */
-	private Integer examOrder;
-	
-	/**
-	 * 开始时间
-	 */
-	private Date startTime;
-	
-	/**
-	 * 交卷时间
-	 */
-	private Date endTime;
-	
-	/**
-	 * 是否待审核
-	 */
-	private Boolean isAuditing;
-	
-	/**
-	 * 是否违纪
-	 */
-	private Boolean isIllegality;
-
-	/**
-	 * 考试是否已结束
-	 */
-	private Boolean isExamEnded;
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Double getObjectiveScore() {
-		return objectiveScore;
-	}
-
-	public void setObjectiveScore(Double objectiveScore) {
-		this.objectiveScore = objectiveScore;
-	}
-
-	public Integer getExamOrder() {
-		return examOrder;
-	}
-
-	public void setExamOrder(Integer examOrder) {
-		this.examOrder = examOrder;
-	}
-
-	public Date getStartTime() {
-		return startTime;
-	}
-
-	public void setStartTime(Date startTime) {
-		this.startTime = startTime;
-	}
-
-	public Date getEndTime() {
-		return endTime;
-	}
-
-	public void setEndTime(Date endTime) {
-		this.endTime = endTime;
-	}
-
-	public Boolean getIsAuditing() {
-		return isAuditing;
-	}
-
-	public void setIsAuditing(Boolean isAuditing) {
-		this.isAuditing = isAuditing;
-	}
-
-	public Boolean getIsIllegality() {
-		return isIllegality;
-	}
-
-	public void setIsIllegality(Boolean isIllegality) {
-		this.isIllegality = isIllegality;
-	}
-
-	public Boolean getIsExamEnded() {
-		return isExamEnded;
-	}
-
-	public void setIsExamEnded(Boolean examEnded) {
-		isExamEnded = examEnded;
-	}
-}

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

@@ -1,202 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import java.io.Serializable;
-import java.util.Date;
-
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-
-
-
-/**
- * 离线考试课程
- * @author ting.yin
- *
- */
-public class OfflineExamCourseInfo implements Serializable {
-
-	private static final long serialVersionUID = 4102608764528925537L;
-
-	private Long examId;
-
-	private String examName;
-	
-	private String orgName;//学校名称
-
-	private Long examStudentId;
-
-	private String courseName;
-
-	private String courseCode;
-
-	private String courseLevel;
-
-	private String studentCode;
-
-	private String studentName;
-
-	private Date startTime;// 考试时间范围开始时间
-
-	private Date endTime; // 考试时间范围结束时间
-
-	private String specialtyName;
-
-	private Long examRecordDataId;
-	
-	private ExamRecordStatus status;//用于判断是否上传
-	
-	private String paperId;
-	
-	/**
-	 * 是否有效
-	 */
-	private Boolean isvalid;
-	
-	private String offlineFileUrl;//答卷地址
-	
-	private String fileName;//答卷文件名
-
-	public Long getExamId() {
-		return examId;
-	}
-
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
-
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-
-	public String getCourseName() {
-		return courseName;
-	}
-
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-
-	public String getCourseCode() {
-		return courseCode;
-	}
-
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-
-	public String getStudentCode() {
-		return studentCode;
-	}
-
-	public void setStudentCode(String studentCode) {
-		this.studentCode = studentCode;
-	}
-
-	public String getStudentName() {
-		return studentName;
-	}
-
-	public void setStudentName(String studentName) {
-		this.studentName = studentName;
-	}
-
-	public Date getStartTime() {
-		return startTime;
-	}
-
-	public void setStartTime(Date startTime) {
-		this.startTime = startTime;
-	}
-
-	public Date getEndTime() {
-		return endTime;
-	}
-
-	public void setEndTime(Date endTime) {
-		this.endTime = endTime;
-	}
-
-	public String getExamName() {
-		return examName;
-	}
-
-	public void setExamName(String examName) {
-		this.examName = examName;
-	}
-
-	public String getCourseLevel() {
-		return courseLevel;
-	}
-
-	public void setCourseLevel(String courseLevel) {
-		this.courseLevel = courseLevel;
-	}
-
-	public String getSpecialtyName() {
-		return specialtyName;
-	}
-
-	public void setSpecialtyName(String specialtyName) {
-		this.specialtyName = specialtyName;
-	}
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Boolean getIsvalid() {
-		return isvalid;
-	}
-
-	public void setIsvalid(Boolean isvalid) {
-		this.isvalid = isvalid;
-	}
-
-	public String getPaperId() {
-		return paperId;
-	}
-
-	public void setPaperId(String paperId) {
-		this.paperId = paperId;
-	}
-
-	public ExamRecordStatus getStatus() {
-		return status;
-	}
-
-	public void setStatus(ExamRecordStatus status) {
-		this.status = status;
-	}
-
-	public String getOrgName() {
-		return orgName;
-	}
-
-	public void setOrgName(String orgName) {
-		this.orgName = orgName;
-	}
-
-	public String getOfflineFileUrl() {
-		return offlineFileUrl;
-	}
-
-	public void setOfflineFileUrl(String offlineFileUrl) {
-		this.offlineFileUrl = offlineFileUrl;
-	}
-
-	public String getFileName() {
-		return fileName;
-	}
-
-	public void setFileName(String fileName) {
-		this.fileName = fileName;
-	}
-
-}

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

@@ -1,143 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.core.oe.common.enums.QuesStructType;
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-
-/**
- * 试卷结构。一套试卷结构包含多条数据,即多个大题
- * Created by zhengmin on 2016/8/18.
- */
-public class PaperStructInfo implements JsonSerializable{
-
-    private static final long serialVersionUID = 3386140600282845440L;
-
-    /**
-     * 序号
-     */
-    private int index;
-
-    /**
-     * 试题类型
-     */
-    private QuesStructType questionType;
-
-    /**
-     * 标题
-     */
-    private String title;
-
-    /**
-     * 总分
-     */
-    private double totalScore;
-
-    /**
-     * 题量,套题则算1题
-     */
-    private int count;
-
-    /**
-     * 试卷结构下的题目总量,套题和套题下的子题都算
-     */
-    private int questionCount;
-
-    /**
-     * 每小题分
-     */
-    private String score;
-    
-	/**
-	 * 答对数量
-	 */
-	private int succQuestionNum;
-	/**
-	 * 答错数量
-	 */
-	private int failQuestionNum;
-	/**
-	 * 未作答
-	 */
-	private Integer notAnsweredCount;
-
-    public int getIndex() {
-        return index;
-    }
-
-    public void setIndex(int index) {
-        this.index = index;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public double getTotalScore() {
-        return totalScore;
-    }
-
-    public void setTotalScore(double totalScore) {
-        this.totalScore = totalScore;
-    }
-
-    public int getCount() {
-        return count;
-    }
-
-    public void setCount(int count) {
-        this.count = count;
-    }
-
-    public String getScore() {
-        return score;
-    }
-
-    public void setScore(String score) {
-        this.score = score;
-    }
-
-    public QuesStructType getQuestionType() {
-        return questionType;
-    }
-
-    public void setQuestionType(QuesStructType questionType) {
-        this.questionType = questionType;
-    }
-
-    public int getQuestionCount() {
-        return questionCount;
-    }
-
-    public void setQuestionCount(int questionCount) {
-        this.questionCount = questionCount;
-    }
-
-	public int getSuccQuestionNum() {
-		return succQuestionNum;
-	}
-
-	public void setSuccQuestionNum(int succQuestionNum) {
-		this.succQuestionNum = succQuestionNum;
-	}
-
-	public int getFailQuestionNum() {
-		return failQuestionNum;
-	}
-
-	public void setFailQuestionNum(int failQuestionNum) {
-		this.failQuestionNum = failQuestionNum;
-	}
-
-	public Integer getNotAnsweredCount() {
-		return notAnsweredCount;
-	}
-
-	public void setNotAnsweredCount(Integer notAnsweredCount) {
-		this.notAnsweredCount = notAnsweredCount;
-	}
-    
-}

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

@@ -1,164 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import java.util.Date;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-public class PracticeCourseInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 3648502707781974505L;
-
-	private Long examId;
-	    
-    private String examName;
-    
-    private String examType;
-
-    private Long examStudentId;
-
-    private String courseName;
-
-    private String courseCode;
-
-    private String studentCode;
-
-    private String studentName;
-
-    /**
-     * 练习次数
-     */
-    private long practiceCount;
-    /**
-     * 最高正确率
-     */
-    private double maxObjectiveAccuracy;
-    /**
-     * 平均正确率
-     */
-    private double aveObjectiveAccuracy;
-
-    /**
-     * 最近正确率
-     */
-    private double recentObjectiveAccuracy;
-
-    private Date startTime;//考试时间范围开始时间
-
-    private Date endTime; //考试时间范围结束时间
-
-	public Long getExamId() {
-		return examId;
-	}
-
-	public void setExamId(Long examId) {
-		this.examId = examId;
-	}
-
-	public String getExamName() {
-		return examName;
-	}
-
-	public void setExamName(String examName) {
-		this.examName = examName;
-	}
-
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-
-	public String getCourseName() {
-		return courseName;
-	}
-
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-
-	public String getCourseCode() {
-		return courseCode;
-	}
-
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-
-	public String getStudentCode() {
-		return studentCode;
-	}
-
-	public void setStudentCode(String studentCode) {
-		this.studentCode = studentCode;
-	}
-
-	public String getStudentName() {
-		return studentName;
-	}
-
-	public void setStudentName(String studentName) {
-		this.studentName = studentName;
-	}
-
-	public long getPracticeCount() {
-		return practiceCount;
-	}
-
-	public void setPracticeCount(long practiceCount) {
-		this.practiceCount = practiceCount;
-	}
-
-	public double getMaxObjectiveAccuracy() {
-		return maxObjectiveAccuracy;
-	}
-
-	public void setMaxObjectiveAccuracy(double maxObjectiveAccuracy) {
-		this.maxObjectiveAccuracy = maxObjectiveAccuracy;
-	}
-
-	public double getAveObjectiveAccuracy() {
-		return aveObjectiveAccuracy;
-	}
-
-	public void setAveObjectiveAccuracy(double aveObjectiveAccuracy) {
-		this.aveObjectiveAccuracy = aveObjectiveAccuracy;
-	}
-
-	public double getRecentObjectiveAccuracy() {
-		return recentObjectiveAccuracy;
-	}
-
-	public void setRecentObjectiveAccuracy(double recentObjectiveAccuracy) {
-		this.recentObjectiveAccuracy = recentObjectiveAccuracy;
-	}
-
-	public Date getStartTime() {
-		return startTime;
-	}
-
-	public void setStartTime(Date startTime) {
-		this.startTime = startTime;
-	}
-
-	public Date getEndTime() {
-		return endTime;
-	}
-
-	public void setEndTime(Date endTime) {
-		this.endTime = endTime;
-	}
-
-	public String getExamType() {
-		return examType;
-	}
-
-	public void setExamType(String examType) {
-		this.examType = examType;
-	}
-
-}

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

@@ -1,73 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import java.util.List;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月7日 上午10:23:19
- * @company 	QMTH
- * @description 答题情况统计
- */
-public class PracticeDetailInfo implements JsonSerializable {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1712307616138306152L;
-
-	private Long id;
-
-	private String courseName;
-
-	private String courseCode;
-	/**
-	 * 客观题正确率
-	 */
-	private double objectiveAccuracy;
-	
-	private List<PaperStructInfo> paperStructInfos;
-	
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getCourseName() {
-		return courseName;
-	}
-
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-
-	public String getCourseCode() {
-		return courseCode;
-	}
-
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-
-	public double getObjectiveAccuracy() {
-		return objectiveAccuracy;
-	}
-
-	public void setObjectiveAccuracy(double objectiveAccuracy) {
-		this.objectiveAccuracy = objectiveAccuracy;
-	}
-
-	public List<PaperStructInfo> getPaperStructInfos() {
-		return paperStructInfos;
-	}
-
-	public void setPaperStructInfos(List<PaperStructInfo> paperStructInfos) {
-		this.paperStructInfos = paperStructInfos;
-	}
-
-}

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

@@ -1,135 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import java.util.Date;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-public class PracticeRecordInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -5420413503946583744L;
-
-	private Long id;
-
-	private String examName;
-
-	private String courseName;
-
-	private String courseCode;
-
-	private Date startTime;
-
-	private Date endTime;
-
-	/**
-	 * 考生考试使用的考试时长
-	 */
-	private Long usedExamTime;
-
-	/**
-	 * 题目数量
-	 */
-	private Integer totalQuestionCount;
-	/**
-	 * 答对数量
-	 */
-	private Integer succQuestionNum;
-	/**
-	 * 答错数量
-	 */
-	private Integer failQuestionNum;
-	/**
-	 * 未作答
-	 */
-	private Integer notAnsweredCount;
-	/**
-	 * 客观题正确率
-	 */
-	private Double objectiveAccuracy;
-	/**
-	 * 客观题数量
-	 */
-	private Integer objectiveNum;
-	
-	public Long getId() {
-		return id;
-	}
-	public void setId(Long id) {
-		this.id = id;
-	}
-	public String getExamName() {
-		return examName;
-	}
-	public void setExamName(String examName) {
-		this.examName = examName;
-	}
-	public String getCourseName() {
-		return courseName;
-	}
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-	public String getCourseCode() {
-		return courseCode;
-	}
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-	public Date getStartTime() {
-		return startTime;
-	}
-	public void setStartTime(Date startTime) {
-		this.startTime = startTime;
-	}
-	public Date getEndTime() {
-		return endTime;
-	}
-	public void setEndTime(Date endTime) {
-		this.endTime = endTime;
-	}
-	public Long getUsedExamTime() {
-		return usedExamTime;
-	}
-	public void setUsedExamTime(Long usedExamTime) {
-		this.usedExamTime = usedExamTime;
-	}
-	public Integer getTotalQuestionCount() {
-		return totalQuestionCount;
-	}
-	public void setTotalQuestionCount(Integer totalQuestionCount) {
-		this.totalQuestionCount = totalQuestionCount;
-	}
-	public Integer getSuccQuestionNum() {
-		return succQuestionNum;
-	}
-	public void setSuccQuestionNum(Integer succQuestionNum) {
-		this.succQuestionNum = succQuestionNum;
-	}
-	public Integer getFailQuestionNum() {
-		return failQuestionNum;
-	}
-	public void setFailQuestionNum(Integer failQuestionNum) {
-		this.failQuestionNum = failQuestionNum;
-	}
-	public Integer getNotAnsweredCount() {
-		return notAnsweredCount;
-	}
-	public void setNotAnsweredCount(Integer notAnsweredCount) {
-		this.notAnsweredCount = notAnsweredCount;
-	}
-	public Double getObjectiveAccuracy() {
-		return objectiveAccuracy;
-	}
-	public void setObjectiveAccuracy(Double objectiveAccuracy) {
-		this.objectiveAccuracy = objectiveAccuracy;
-	}
-	public Integer getObjectiveNum() {
-		return objectiveNum;
-	}
-	public void setObjectiveNum(Integer objectiveNum) {
-		this.objectiveNum = objectiveNum;
-	}
-	
-}

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

@@ -1,48 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import java.util.List;
-import io.swagger.annotations.ApiModelProperty;
-
-/**
- * @Description 保存人脸活体检测结果请求对象
- * @Author lideyin
- * @Date 2019/10/14 11:21
- * @Version 1.0
- */
-public class SaveFaceBiopsyResultReq implements JsonSerializable {
-	private static final long serialVersionUID = 3996944262550668002L;
-
-	@ApiModelProperty(value = "考试记录id",required = true)
-	private Long examRecordDataId;
-
-	@ApiModelProperty(value = "人脸活体检测明细id",required = true)
-	private Long faceBiopsyItemId;
-
-	@ApiModelProperty(value = "实际活体检测步骤",required = true)
-	private List<FaceBiopsyStepInfo> verifySteps;
-
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Long getFaceBiopsyItemId() {
-		return faceBiopsyItemId;
-	}
-
-	public void setFaceBiopsyItemId(Long faceBiopsyItemId) {
-		this.faceBiopsyItemId = faceBiopsyItemId;
-	}
-
-	public List<FaceBiopsyStepInfo> getVerifySteps() {
-		return verifySteps;
-	}
-
-	public void setVerifySteps(List<FaceBiopsyStepInfo> verifySteps) {
-		this.verifySteps = verifySteps;
-	}
-}

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

@@ -1,61 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * @Description 人脸活体检测结果
- * @Author lideyin
- * @Date 2019/10/14 11:21
- * @Version 1.0
- */
-public class SaveFaceBiopsyResultResp implements JsonSerializable {
-	private static final long serialVersionUID = 3996944262550668002L;
-
-	@ApiModelProperty(value = "检测结果",required = true)
-	private Boolean verifyResult;
-
-	@ApiModelProperty(value = "错误消息",required = false)
-	private String errorMessage;
-
-	@ApiModelProperty(value = "是否结束考试",required = true)
-	private Boolean  endExam;
-
-	@ApiModelProperty(value = "是否需要下一次活检",required = true)
-	private Boolean  needNextVerify;
-
-	public Boolean getVerifyResult() {
-		return verifyResult;
-	}
-
-	public void setVerifyResult(Boolean verifyResult) {
-		this.verifyResult = verifyResult;
-	}
-
-	public String getErrorMessage() {
-		return errorMessage;
-	}
-
-	public void setErrorMessage(String errorMessage) {
-		this.errorMessage = errorMessage;
-	}
-
-	public Boolean getEndExam() {
-		return endExam;
-	}
-
-	public void setEndExam(Boolean endExam) {
-		this.endExam = endExam;
-	}
-
-	public Boolean getNeedNextVerify() {
-		return needNextVerify;
-	}
-
-	public void setNeedNextVerify(Boolean needNextVerify) {
-		this.needNextVerify = needNextVerify;
-	}
-}

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

@@ -1,63 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.validation.constraints.NotNull;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import cn.com.qmth.examcloud.core.oe.common.enums.FileAnswerAcknowledgeStatus;
-import io.swagger.annotations.ApiModelProperty;
-
-public class SaveUploadedFileAcknowledgeStatusReq implements JsonSerializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 2015767610417418141L;
-    @NotNull(message = "考试记录DataID不能为空")
-    @ApiModelProperty(required = true, value = "考试记录DataID")
-    private Long examRecordDataId;
-    @NotNull(message = "题号不能为空")
-    @ApiModelProperty(required = true, value = "考试试题号")
-    private Integer order;
-    @NotNull(message = "文件路径(含文件名)不能为空")
-    @ApiModelProperty(required = true, value = "文件路径(含文件名)")
-    private String filePath;
-
-    @NotNull(message = "答复状态不请允许为空")
-    @ApiModelProperty(required = true,value = "答复状态(CONFIRMED:已确认,DISCARDED:已弃用)")
-    private String acknowledgeStatus;
-
-    public Long getExamRecordDataId() {
-        return examRecordDataId;
-    }
-
-    public void setExamRecordDataId(Long examRecordDataId) {
-        this.examRecordDataId = examRecordDataId;
-    }
-
-
-    public Integer getOrder() {
-        return order;
-    }
-
-    public void setOrder(Integer order) {
-        this.order = order;
-    }
-
-    public String getFilePath() {
-        return filePath;
-    }
-
-    public void setFilePath(String filePath) {
-        this.filePath = filePath;
-    }
-
-    public String getAcknowledgeStatus() {
-        return acknowledgeStatus;
-    }
-
-    public void setAcknowledgeStatus(String acknowledgeStatus) {
-        this.acknowledgeStatus = acknowledgeStatus;
-    }
-}

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

@@ -1,61 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import javax.validation.constraints.NotNull;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-public class SaveUploadedFileReq implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 5983488494596822561L;
-	@NotNull(message = "考生ID不能为空")
-	@ApiModelProperty(required = true,value = "考生ID")
-	private Long examStudentId;
-	@NotNull(message = "考试记录DataID不能为空")
-	@ApiModelProperty(required = true,value = "考试记录DataID")
-	private Long examRecordDataId;
-	@NotNull(message = "题号不能为空")
-	@ApiModelProperty(required = true,value = "考试试题号")
-	private Integer order;
-	@NotNull(message = "文件路径(含文件名)不能为空")
-	@ApiModelProperty(required = true,value = "文件路径(含文件名)")
-	private String filePath;
-	@ApiModelProperty(required = true,value = "传输文件类型(用于标识,通过二维码传输文件的类型)")
-	private String transferFileType;
-	public Long getExamStudentId() {
-		return examStudentId;
-	}
-	public void setExamStudentId(Long examStudentId) {
-		this.examStudentId = examStudentId;
-	}
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-
-	public Integer getOrder() {
-		return order;
-	}
-	public void setOrder(Integer order) {
-		this.order = order;
-	}
-	public String getFilePath() {
-		return filePath;
-	}
-	public void setFilePath(String filePath) {
-		this.filePath = filePath;
-	}
-
-	public String getTransferFileType() {
-		return transferFileType;
-	}
-
-	public void setTransferFileType(String transferFileType) {
-		this.transferFileType = transferFileType;
-	}
-}

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

@@ -1,81 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月27日 下午4:44:15
- * @company 	QMTH
- * @description StartExamInfo.java
- */
-public class StartExamInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 7964522965649314640L;
-	
-	private Long examRecordDataId;
-	
-	private String courseCode;
-	
-	private String courseName;
-	
-	private String studentCode;
-	
-	private String studentName;
-	
-	/**
-	 * 考试时长
-	 */
-	private Integer duration;
-	/**
-	 * 活体检测开始分钟数
-	 */
-	private Integer faceVerifyMinute;
-	
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-	public Integer getDuration() {
-		return duration;
-	}
-	public void setDuration(Integer duration) {
-		this.duration = duration;
-	}
-	public Integer getFaceVerifyMinute() {
-		return faceVerifyMinute;
-	}
-	public void setFaceVerifyMinute(Integer faceVerifyMinute) {
-		this.faceVerifyMinute = faceVerifyMinute;
-	}
-	public String getCourseCode() {
-		return courseCode;
-	}
-	public void setCourseCode(String courseCode) {
-		this.courseCode = courseCode;
-	}
-	public String getCourseName() {
-		return courseName;
-	}
-	public void setCourseName(String courseName) {
-		this.courseName = courseName;
-	}
-	public String getStudentCode() {
-		return studentCode;
-	}
-	public void setStudentCode(String studentCode) {
-		this.studentCode = studentCode;
-	}
-	public String getStudentName() {
-		return studentName;
-	}
-	public void setStudentName(String studentName) {
-		this.studentName = studentName;
-	}
-	
-}

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

@@ -1,52 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import io.swagger.annotations.ApiModelProperty;
-
-public class UploadedFileAnswerInfo extends ExamQuestionAnswerExtensionInfo{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -8684452576786540515L;
-	@ApiModelProperty(value = "考试记录DataID")
-	private Long examRecordDataId;
-//	@ApiModelProperty(value = "考试试题ID")
-//	private String questionId;
-	@ApiModelProperty(value = "考生答案")
-	private String studentAnswer;
-	@ApiModelProperty(value = "大题号")
-	private Integer mainNumber;
-	@ApiModelProperty(value = "小题号")
-    private Integer order;
-	
-	public Long getExamRecordDataId() {
-		return examRecordDataId;
-	}
-	public void setExamRecordDataId(Long examRecordDataId) {
-		this.examRecordDataId = examRecordDataId;
-	}
-//	public String getQuestionId() {
-//		return questionId;
-//	}
-//	public void setQuestionId(String questionId) {
-//		this.questionId = questionId;
-//	}
-	public String getStudentAnswer() {
-		return studentAnswer;
-	}
-	public void setStudentAnswer(String studentAnswer) {
-		this.studentAnswer = studentAnswer;
-	}
-	public Integer getMainNumber() {
-		return mainNumber;
-	}
-	public void setMainNumber(Integer mainNumber) {
-		this.mainNumber = mainNumber;
-	}
-	public Integer getOrder() {
-		return order;
-	}
-	public void setOrder(Integer order) {
-		this.order = order;
-	}
-}

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

@@ -1,53 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.bean;
-
-import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
-import io.swagger.annotations.ApiModelProperty;
-
-public class UpyunSignatureInfo implements JsonSerializable{
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = -2401837848131443152L;
-	@ApiModelProperty(value = "上传到又拍云的url")
-	private String uploadUrl;
-	@ApiModelProperty(value = "又拍云签名")
-	private String signature;
-	@ApiModelProperty(value = "又拍云policy")
-	private String policy;
-	@ApiModelProperty(value = "上传到又拍云的文件路径(含文件名)")
-	private String filePath;
-	@ApiModelProperty(value = "取又拍云文件时的域名")
-	private String upyunFileDomain;
-	public String getSignature() {
-		return signature;
-	}
-	public void setSignature(String signature) {
-		this.signature = signature;
-	}
-	public String getPolicy() {
-		return policy;
-	}
-	public void setPolicy(String policy) {
-		this.policy = policy;
-	}
-	public String getFilePath() {
-		return filePath;
-	}
-	public void setFilePath(String filePath) {
-		this.filePath = filePath;
-	}
-	public String getUploadUrl() {
-		return uploadUrl;
-	}
-	public void setUploadUrl(String uploadUrl) {
-		this.uploadUrl = uploadUrl;
-	}
-	public String getUpyunFileDomain() {
-		return upyunFileDomain;
-	}
-	public void setUpyunFileDomain(String upyunFileDomain) {
-		this.upyunFileDomain = upyunFileDomain;
-	}
-	
-}

+ 0 - 28
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/processor/HttpMethodProcessorImpl.java

@@ -1,28 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.processor;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.springframework.stereotype.Component;
-
-import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
-import cn.com.qmth.examcloud.web.support.HttpMethodProcessor;
-
-@Component
-public class HttpMethodProcessorImpl implements HttpMethodProcessor {
-
-	@Override
-	public void beforeMethod(HttpServletRequest request, Object[] args) {
-
-	}
-
-	@Override
-	public void onSuccess(HttpServletRequest request, Object[] args, Object ret) {
-		ReportsUtil.sendReport(false);
-	}
-
-	@Override
-	public void onException(HttpServletRequest request, Object[] args, Throwable e) {
-		ReportsUtil.sendReport(true);
-	}
-
-}

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

@@ -1,24 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月5日 下午3:25:40
- * @company 	QMTH
- * @description 学生端-考试记录审核接口
- */
-public interface ExamAuditService {
-
-	/**
-	 * 活体检测失败,系统审核
-	 * @param examRecordDataId
-	 * @param rootOrgId
-	 */
-	public void saveExamAuditByFaceVerifyFailed(Long examRecordDataId,Long rootOrgId);
-	
-	/**
-	 * 抓拍照片为0,系统审核
-	 * @param examRecordDataId
-	 */
-	public void saveExamAuditByNoPhoto(Long examRecordDataId);
-}

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

@@ -1,169 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-
-import cn.com.qmth.examcloud.api.commons.security.bean.User;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamFileAnswerTempEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamingRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.HandInExamRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.HandInExamType;
-import cn.com.qmth.examcloud.core.oe.student.bean.*;
-
-import javax.validation.Valid;
-import java.util.List;
-
-/**
- * @author chenken
- * @date 2018年8月13日 下午2:09:38
- * @company QMTH
- * @description 在线考试控制服务接口
- */
-public interface ExamControlService {
-
-    /**
-     * 开始考试
-     *
-     * @param examStudentId
-     * @param user
-     */
-    public StartExamInfo startExam(Long examStudentId, User user);
-
-    /**
-     * 考试心跳
-     *
-     * @param
-     */
-    public long examHeartbeat(User user);
-
-    /**
-     * 断点续考:检查正在进行中的考试
-     *
-     * @param studentId
-     */
-    public CheckExamInProgressInfo checkExamInProgress(Long studentId);
-
-    /**
-     * 获取考试记录信息
-     *
-     * @param examRecordDataId
-     */
-    public EndExamInfo getEndExamInfo(Long examRecordDataId);
-
-    /**
-     * 照片失败扫描处理
-     */
-    public void handleByExamCaptureQueueFailedDispose(Long examRecordDataId);
-
-    /**
-     * 获取上传考试音频所需的又拍云签名
-     *
-     * @param req
-     * @return
-     */
-    UpyunSignatureInfo getUpyunSignature(GetUpyunSignatureReq req);
-
-    /**
-     * 发送消息到websocket
-     *
-     * @param examRecordDataId 考试记录id
-     * @param order            题序号
-     * @param fileUrl          文件路径
-     * @param transferFileType 传输文件类型
-     * @throws Exception
-     */
-    public void sendFileAnswerToWebSocket(Long examRecordDataId, Integer order,
-                                          String fileUrl, String transferFileType, Long userId) throws Exception;
-
-    public String getQrCode(GetQrCodeReq req, String key);
-
-    /**
-     * 校验二维码
-     *
-     * @param param
-     * @return
-     */
-    public CheckQrCodeInfo checkQrCode(String param);
-
-    /**
-     * 成功上传音频结果推送(微信小程序调用)
-     *
-     * @param req
-     */
-    public ExamFileAnswerTempEntity saveUploadedFile(SaveUploadedFileReq req, User user);
-
-    /**
-     * 查询上传音频结果推送状态(微信小程序调用)
-     *
-     * @param req
-     */
-    public String getUploadedFileAcknowledgeStatus(GetUploadedFileAcknowledgeStatusReq req);
-
-    public void saveUploadedFileAcknowledgeStatus(SaveUploadedFileAcknowledgeStatusReq req);
-
-    /**
-     * 通过websocket发送二维码扫描信息
-     *
-     * @param examRecordDataId
-     * @param clientId
-     * @throws Exception
-     */
-    public void sendScanQrCodeToWebSocket(String clientId, Long examRecordDataId, Integer order) throws Exception;
-
-    /**
-     * 获取已上传的文件答案列表(微信小程序调用)
-     *
-     * @param req
-     * @return
-     */
-    public List<UploadedFileAnswerInfo> getUploadedFileAnswerList(@Valid GetUploadedFileAnswerListReq req);
-
-    String getQrCode(GetQrCodeReq req, User user);
-
-    void deleteExamFileAnswerTemp(SaveUploadedFileReq req);
-
-    /**
-     * 计算考试已用时间(毫秒)
-     *
-     * @param examSessionInfo 考试会话对象
-     * @return
-     */
-    Long calculateExamUsedMilliseconds(ExamSessionInfo examSessionInfo);
-
-    /**
-     * 交卷
-     *
-     * @param examRecordDataId 考试记录id
-     * @param handInExamType   交卷类型
-     */
-    void handInExam(Long examRecordDataId, HandInExamType handInExamType);
-
-    /**
-     * 交卷的后续处理
-     *
-     * @param examRecordDataId 考试记录id
-     * @param handInExamType   交卷类型
-     * @param studentId        学生id
-     * @return boolean
-     */
-    boolean processAfterHandInExam(Long examRecordDataId, Long studentId, HandInExamType handInExamType);
-
-    /**
-     * 清理考试已结束的文件作答记录
-     */
-    void cleanTempFileAnswers();
-
-    /**
-     * 清理考试中的考试记录
-     *
-     * @param examingRecordEntity
-     */
-    void cleanExamingRecord(ExamingRecordEntity examingRecordEntity);
-
-    /**
-     * 清理已交卷的考试记录
-     *
-     * @param handInExamRecordEntity
-     */
-    void cleanHandInExamRecord(HandInExamRecordEntity handInExamRecordEntity);
-
-}

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

@@ -1,87 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamFaceLivenessVerifyEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.student.bean.GetFaceVerifyTokenInfo;
-
-import java.util.List;
-
-
-/**
- * @author chenken
- * @date 2018年2月5日 上午8:44:19
- * @company QMTH
- * @description 活体检测服务接口
- */
-public interface ExamFaceLivenessVerifyService {
-
-    /**
-     * 保存活体检测信息
-     *
-     * @param examRecordDataId
-     */
-    public ExamFaceLivenessVerifyEntity saveFaceVerify(Long examRecordDataId);
-
-    /**
-     * 使用考试记录id查询人脸活体检测信息
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    public List<ExamFaceLivenessVerifyEntity> listFaceVerifyByExamRecordId(Long examRecordDataId);
-
-    /**
-     * 人脸检测完成后回调处理
-     *
-     * @param resultJson
-     * @return
-     */
-    public ExamFaceLivenessVerifyEntity faceIdNotify(String resultJson);
-
-    /**
-     * 向faceId发起检测请求,返回token
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    public GetFaceVerifyTokenInfo getFaceVerifyToken(Long studentId, String bizNo);
-
-    public ExamFaceLivenessVerifyEntity saveFaceVerifyByExamRecordDataId(Long examRecordDataId);
-
-    /**
-     * 根据ID查询
-     *
-     * @param id
-     * @return
-     */
-    public ExamFaceLivenessVerifyEntity findFaceVerifyById(Long id);
-
-    /**
-     * 人脸检测超时处理
-     *
-     * @param examRecordDataId
-     */
-    public void faceTestTimeOut(Long examRecordDataId);
-
-    /**
-     * 人脸活体检测结束处理
-     *
-     * @param examRecordDataId
-     * @param studentId
-     * @param result
-     */
-    public void faceTestEndHandle(Long examRecordDataId, Long studentId, String result);
-
-    /**
-     * 断点续考,获取活体检测开启时间
-     *
-     * @param examId
-     * @param examRecordDataId
-     * @param heartbeat
-     * @return
-     */
-    public Integer getFaceLivenessVerifyMinute(Long rootOrgId, Long orgId, Long examId,
-                                               Long studentId, Long examRecordDataId, Integer heartbeat);
-
-}
-

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

@@ -1,142 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamingRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.HandInExamRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamType;
-import cn.com.qmth.examcloud.core.oe.student.bean.CalculateFaceCheckResultInfo;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-
-import java.util.List;
-
-/**
- * @author chenken
- * @date 2018/8/15 11:16
- * @company QMTH
- * @description 考试记录数据服务接口
- */
-public interface ExamRecordDataService {
-
-    /**
-     * 创建ExamRecordDataEntity
-     * @param examedTimes 已考次数
-     * @param canExamTimes 可考次数
-     * @param isReExamine 本次考试是否为重考
-     * @param isFullyObjetive 是否全客观题
-     * @return
-     */
-    ExamRecordDataEntity createExamRecordData(ExamStudentEntity examStudent,
-                                              ExamBean examBean,
-                                              CourseBean courseBean,
-                                              String basePaperId,
-                                              String paperStructId, Integer examedTimes, Long canExamTimes,
-                                              Boolean isReExamine, Boolean isFullyObjetive);
-
-    List<ExamRecordDataEntity> findByStatusAndExamTypeIn(ExamRecordStatus examRecordStatus, List<String> examTypeList);
-
-    /**
-     * 根据考生ID查询所有有效考试记录
-     *
-     * @param examStudentId
-     * @return
-     */
-    List<ExamRecordDataEntity> findValidExamRecordDataByExamStudentId(Long examStudentId);
-
-    /**
-     * 计算人脸检测结果
-     *
-     * @param examRecordDataEntity
-     * @return
-     */
-    CalculateFaceCheckResultInfo calculateFaceCheckResult(ExamRecordDataEntity examRecordDataEntity);
-
-    /**
-     * 创建进行中的考试记录
-     *
-     * @param examRecordDataId
-     * @param studentId
-     */
-    void createExamingRecord(Long examRecordDataId, Long studentId, ExamType examType);
-
-    /**
-     * 创建已交卷的考试记录
-     *
-     * @param examRecordDataId
-     * @param studentId
-     */
-    void createHandInExamRecord(Long examRecordDataId, Long studentId);
-
-    /**
-     * 删除进行中考试记录id
-     *
-     * @param examRecordDataId
-     */
-    void deleteExamingRecord(Long examRecordDataId);
-
-    void deleteHandInExamRecord(Long examRecordDataId);
-
-    /**
-     * 获取指定数量的考试中的数据
-     *
-     * @param startId
-     * @param limit
-     * @return
-     */
-    List<ExamingRecordEntity> getLimitExamingRecords(Long startId, int limit);
-
-    /**
-     * 获取指定数量的已交卷的考试数据
-     *
-     * @param startId
-     * @param limit
-     * @return
-     */
-    List<HandInExamRecordEntity> getLimitHandInExamRecords(Long startId, int limit);
-
-    /**
-     * 计算活体检测结果
-     *
-     * @param examRecordDataEntity
-     */
-    void calculateFaceLivenessVerifyResult(ExamRecordDataEntity examRecordDataEntity);
-
-    /**
-     * 创建离线考试记录
-     *
-     * @param examRecord
-     * @param fullyObjective
-     * @return
-     */
-    ExamRecordDataEntity createOfflineExamRecordData(ExamStudentEntity examStudent,
-                                                     ExamBean examBean,
-                                                     CourseBean courseBean,
-                                                     String basePaperId,
-                                                     String paperStructId, Boolean fullyObjective);
-
-    /**
-     * 违纪自动审核
-     *
-     * @return
-     */
-    ExamRecordDataEntity examRecordAutoAudit(Boolean isNoPhotoAndIllegality, ExamRecordDataEntity examRecordData);
-
-    /**
-     * 考试记录是否已结束
-     *
-     * @param examRecordData 考试记录
-     * @return boolean
-     */
-    boolean isExamRecordEnded(ExamRecordDataEntity examRecordData);
-
-    /**
-     * 考试记录是否已结束
-     *
-     * @param examRecordDataId 考试记录id
-     * @return boolean
-     */
-    boolean isExamRecordEnded(Long examRecordDataId);
-
-}

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

@@ -1,29 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-
-
-public interface ExamRecordForMarkingService {
-
-	/**
-	 * 保存阅卷相关数据-对外
-	 * @param examRecordData
-	 * @param objectiveQuestionTotalScore
-	 */
-	public void saveExamRecordForMarking(Long examRecordDataId);
-	
-	/**
-	 * 在线考试-保存阅卷相关数据-对内
-	 * @param examRecordData
-	 * @param objectiveQuestionTotalScore
-	 */
-	public void saveExamRecordForMarking(ExamRecordDataEntity examRecordData,double objectiveQuestionTotalScore);
-	
-	/**
-	 * 离线考试-保存阅卷相关数据-对内
-	 * @param examRecordData
-	 * @param fileName
-	 * @param fileUrl
-	 */
-	public void saveOffLineExamRecordForMarking(ExamRecordDataEntity examRecordData,String fileName,String fileUrl);
-}

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

@@ -1,22 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordPaperStructEntity;
-
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月1日 上午10:48:31
- * @company 	QMTH
- * @description 考试记录-试卷结构服务接口
- */
-public interface ExamRecordPaperStructService {
-	
-	/**
-	 * 根据examRecordDataId查询考试记录试卷结构
-	 * @param examRecordDataId
-	 * @return
-	 */
-	public ExamRecordPaperStructEntity getExamRecordPaperStruct(Long examRecordDataId);
-	
-}

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

@@ -1,52 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordQuestionsEntity;
-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.question.commons.core.question.DefaultQuestionStructure;
-
-import java.util.List;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月3日 上午10:56:56
- * @company 	QMTH
- * @description 考试记录-作答归档服务接口
- */
-public interface ExamRecordQuestionsService {
-
-	/**
-	 * 计算主观题作答总长度
-	 * @param examRecordDataId
-	 * @return
-	 */
-	Integer calculationSubjectiveAnswerLength(Long examRecordDataId);
-
-	/**
-	 * 初始化ExamQuestion
-	 * @param examRecordDataId
-	 * @param paperStructByReorder
-	 */
-	ExamRecordQuestionsEntity createExamRecordQuestions(Long examRecordDataId, DefaultPaper paperStructByReorder);
-
-	/**
-	 * 获取考试作答记录并修复考试记录表的数据(如有必要)
-	 * @param examRecordData 考试记录
-	 * @return
-	 */
-    ExamRecordQuestionsEntity getExamRecordQuestionsAndFixExamRecordDataIfNecessary(ExamRecordDataEntity examRecordData);
-
-	/**
-	 *  获取考试作答记录并修复考试记录表的数据(如有必要)
-	 * @param examRecordDataId 考试记录id
-	 * @return
-	 */
-	ExamRecordQuestionsEntity getExamRecordQuestionsAndFixExamRecordDataIfNecessary(Long examRecordDataId);
-
-	void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos);
-
-	String getQuestionContent(Long studentId, String questionId);
-}

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

@@ -1,42 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreEntity;
-import cn.com.qmth.examcloud.core.oe.student.bean.ObjectiveScoreInfo;
-
-import java.util.List;
-
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月3日 上午9:54:31
- * @company 	QMTH
- * @description 考试分数接口
- */
-public interface ExamScoreService {
-
-	
-	public ExamScoreEntity saveExamScore(ExamRecordDataEntity examRecordData);
-	
-	/**
-	 * 离线考试初始化得分
-	 * @param examRecordDataId
-	 */
-	public void createExamScoreWithOffline(Long examRecordDataId);
-	
-	/**
-	 * 使用考生ID查询有效考试记录的成绩
-	 * @return
-	 */
-	public List<ExamScoreEntity> queryExamScoreListByExamStudentId(Long examStudentId);
-	
-	/**
-	 * 使用考生ID查询客观分信息 
-	 * 客观分是指考生完成过一次考试后,有效的客观分,
-	 * 如此条考试记录需要监考审核则显示为"待审",客观分显示时,展示次数(第几次考试)、开始时间、交卷时间,客观分;
-	 * @return
-	 */
-	public List<ObjectiveScoreInfo> queryObjectiveScoreList(Long examStudentId);
-	
-}

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

@@ -1,32 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamSessionInfo;
-
-/**
- * @author chenken
- * @date 2018/8/15 9:24
- * @company QMTH
- * @description 考试会话接口
- */
-public interface ExamSessionInfoService {
-
-    /**
-     * 保存
-     * @param examSessionInfo
-     * @param timeout   秒
-     */
-    public void saveExamSessionInfo(Long studentId,ExamSessionInfo examSessionInfo,int timeout);
-
-    /**
-     * 获取
-     * @param studentId
-     * @return
-     */
-    public ExamSessionInfo getExamSessionInfo(Long studentId);
-
-    /**
-     * 删除
-     * @param studentId
-     */
-    public void deleteExamSessionInfo(Long studentId);
-}

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

@@ -1,13 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentFinalScoreEntity;
-
-/**
- * @Description 考生最终成绩接口
- * @Author lideyin
- * @Date 2019/11/7 18:19
- * @Version 1.0
- */
-public interface ExamStudentFinalScoreService {
-    void calculateFinalScore(Long examStudentId);
-}

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

@@ -1,43 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import java.util.List;
-
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamStudentInfo;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentEntity;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年8月13日 下午2:45:21
- * @company 	QMTH
- * @description 考生服务接口
- */
-public interface ExamStudentService {
-
-	/**
-	 * 获取在线考试待考列表
-	 * @param studentId
-	 * @return
-	 */
-	public List<ExamStudentInfo> queryOnlineExamList(Long studentId);
-	
-	/**
-	 * 统计剩余考试次数
-	 * @param examStudentInfo
-	 * @return
-	 */
-	public Integer countExamTimes(ExamStudentEntity examStudentInfo,ExamBean examBean);
-
-	/**
-	 * 开始考试时,更新考生信息,并返回已考的考试次数
-	 * @param id 考生主键id
-	 * @param isReExamine 是否重考
-	 * @param reExamineCompleted 重考是否完成
-	 * @param normalExamTimes 已考次数
-	 * @param examBean 考试实体
-	 * @return int 已考的考试次数
-	 */
-	public int updateExamStudentByStartExam(Long id,Boolean isReExamine,Boolean reExamineCompleted,
-														  Integer normalExamTimes, final ExamBean examBean);
-}

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

@@ -1,39 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyType;
-import cn.com.qmth.examcloud.core.oe.student.bean.FaceBiopsyInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.SaveFaceBiopsyResultReq;
-import cn.com.qmth.examcloud.core.oe.student.bean.SaveFaceBiopsyResultResp;
-
-import java.util.Date;
-
-/**
- * @Description 人脸活体检测接口
- * @Author lideyin
- * @Date 2019/10/14 10:54
- * @Version 1.0
- */
-public interface FaceBiopsyService {
-
-    /**
-     * 获取人脸活体检测基本信息
-     *
-     * @param rootOrgId        学校id
-     * @param examRecordDataId 考试记录id
-     */
-    FaceBiopsyInfo getFaceBiopsyInfo(Long rootOrgId, Long examRecordDataId,FaceBiopsyType faceBiopsyType);
-
-    /**
-     * 保存活体检测结果
-     * @param req
-     * @return
-     */
-    SaveFaceBiopsyResultResp saveFaceBiopsyResult(SaveFaceBiopsyResultReq req,Long studentId);
-
-    /**
-     * 获取人脸活体检测开始分钟数
-     * @param examRecordDataId 考试记录id
-     * @return Integer
-     */
-    Integer calculateFaceBiopsyStartMinute(Long examRecordDataId);
-}

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

@@ -1,43 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import java.io.File;
-import java.util.List;
-
-import cn.com.qmth.examcloud.core.oe.student.bean.OfflineExamCourseInfo;
-
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月5日 上午10:35:18
- * @company 	QMTH
- * @description 离线考试服务接口
- */
-public interface OfflineExamService {
-	
-	/**
-	 * 获取待考课程列表
-	 * @param studentId
-	 * @return
-	 */
-	public List<OfflineExamCourseInfo> getOfflineCourse(Long studentId);
-
-	/**
-	 * 开始离线考试
-	 * @param token
-	 * @param examStudentId
-	 * @param studentId
-	 * @return
-	 */
-	public void startOfflineExam(Long examStudentId);
-	
-	/**
-	 * 上传作答
-	 * @param examRecordDataId
-	 * @param tempFile
-	 * @param fileType
-	 */
-	public void submitPaper(Long examRecordDataId,File tempFile)  throws Exception;
-
-	public void downOfflineExam();
-}

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

@@ -1,38 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service;
-
-import java.util.List;
-
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeCourseInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeDetailInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeRecordInfo;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月7日 上午11:04:59
- * @company 	QMTH
- * @description PracticeService.java
- */
-public interface PracticeService {
-
-	/**
-	 * 练习课程列表
-	 * @param examId
-	 * @param studentId
-	 * @return
-	 */
-	public List<PracticeCourseInfo> queryPracticeCourseList(Long examId,Long studentId);
-	
-	/**
-	 * 课程练习记录详情
-	 * @param examStudentId
-	 * @return
-	 */
-	public List<PracticeRecordInfo> queryPracticeRecordList(Long examStudentId);
-	
-	/**
-	 * 单次练习答题情况统计
-	 * @return
-	 */
-	public PracticeDetailInfo getPracticeDetailInfo(Long examRecordDataId);
-}

+ 0 - 57
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/CleanExamRecordQueueHolder.java

@@ -1,57 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamingRecordEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamingRecordRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.CleanExamRecordPriorityQueueInfo;
-import cn.com.qmth.examcloud.web.support.SpringContextHolder;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-public class CleanExamRecordQueueHolder {
-    public static final int HIGH_PRIORITY=1;
-    public static final int LOW_PRIORITY=0;
-    private static final BlockingQueue<CleanExamRecordPriorityQueueInfo> priorityQueue = new PriorityBlockingQueue<>();
-
-    /**
-     * 如果队列中数据不存在,则向队列添加数据,默认超时时间10秒
-     *
-     * @param element 数据对象
-     * @return boolean
-     */
-    public static boolean offer(CleanExamRecordPriorityQueueInfo element) throws InterruptedException {
-        return priorityQueue.offer(element, 10, TimeUnit.SECONDS);
-    }
-
-//    /**
-//     * 从队列中获取指定数量的考试记录id
-//     * @param limitNum 数量
-//     * @return List<ExamRecordDataEntity>
-//     */
-//    public static List<ExamingRecordEntity> getLimtExamRecordDataListFromQueue(int limitNum) throws InterruptedException {
-//        //如果除外中不足 limitNum条数据,则从数据库中查询limitNum条数据至队列中
-//        if (priorityQueue.size()<limitNum){
-//            ExamingRecordRepo examingRecordRepo = SpringContextHolder.getBean(ExamingRecordRepo.class);
-//            List<ExamingRecordEntity> examingRecordList = examingRecordRepo.findLimitExamingRecordList(limitNum);
-//            for (ExamingRecordEntity record:examingRecordList){
-//                CleanExamRecordPriorityQueueInfo info = new CleanExamRecordPriorityQueueInfo();
-//                //数据库中取出来的数据,默认低优先级处理
-//                info.setPriority(LOW_PRIORITY);
-//                info.setExamingRecord(record);
-//                if (!offer(info)){
-//                    throw new StatusException("100001","向清理考试队列中添加数据失败");
-//                }
-//            }
-//        }
-//        List<CleanExamRecordPriorityQueueInfo> priorityQueueInfoList = new ArrayList<>();
-//        priorityQueue.drainTo(priorityQueueInfoList,limitNum);
-//        return priorityQueueInfoList.stream()
-//                .map(CleanExamRecordPriorityQueueInfo::getExamingRecord)
-//                .collect(Collectors.toList());
-//    }
-}

+ 0 - 141
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamAuditServiceImpl.java

@@ -1,141 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamAuditEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamFaceLivenessVerifyEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.FaceBiopsyItemEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.AuditStatus;
-import cn.com.qmth.examcloud.core.oe.common.enums.DisciplineType;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyScheme;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceVerifyResult;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamAuditRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamFaceLivenessVerifyRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.FaceBiopsyItemRepo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamAuditService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-/**
- * @author chenken
- * @date 2018年9月5日 下午3:25:06
- * @company QMTH
- * @description 学生端-考试记录审核服务实现
- */
-@Service("examAuditService")
-public class ExamAuditServiceImpl implements ExamAuditService {
-
-    //private static final Logger log = LoggerFactory.getLogger(ExamAuditServiceImpl.class);
-
-    /**
-     * 活体检测失败自动审核
-     */
-    private static final String FACE_LIVENESS_VERIFY_AUTO_AUDIT = "FACE_LIVENESS_VERIFY_AUTO_AUDIT";
-
-    /**
-     * 无照片自动审核
-     */
-    private static final String NOPHOTO_VERIFY_AUTO_AUDIT = "NOPHOTO_VERIFY_AUTO_AUDIT";
-
-    /**
-     * 系统审核
-     */
-    private static final String AUDIT_USER_NAME = "SYSTEM";
-
-    @Autowired
-    private ExamFaceLivenessVerifyRepo examFaceLivenessVerifyRepo;
-
-    @Autowired
-    private ExamAuditRepo examAuditRepo;
-
-    @Autowired
-    private FaceBiopsyItemRepo faceBiopsyItemRepo;
-
-    @Override
-    public void saveExamAuditByFaceVerifyFailed(Long examRecordDataId, Long rootOrgId) {
-        ExamAuditEntity examAudit = examAuditRepo.findByExamRecordDataId(examRecordDataId);
-        if (examAudit != null) {
-            return;
-        }
-        ExamAuditEntity examAuditEntity = new ExamAuditEntity();
-        examAuditEntity.setExamRecordDataId(examRecordDataId);
-        examAuditEntity.setDisciplineType(DisciplineType.ACTION_FAILURE);
-        examAuditEntity.setUserId(FACE_LIVENESS_VERIFY_AUTO_AUDIT);//活体检测自动审核
-        examAuditEntity.setAuditUserName(AUDIT_USER_NAME);
-        examAuditEntity.setDisciplineDetail(getFaceVerifyDisciplineDetail(examRecordDataId, rootOrgId));//计算违纪描述
-        examAuditEntity.setStatus(AuditStatus.UN_PASS);
-        examAuditRepo.save(examAuditEntity);
-    }
-
-    //获取活检违纪详情
-    private String getFaceVerifyDisciplineDetail(Long examRecordDataId, Long rootOrgId) {
-        FaceBiopsyScheme faceBiopsyScheme = FaceBiopsyHelper.getFaceBiopsyScheme(rootOrgId);
-
-        //新活体检测方案从新表中取相关数据
-        if (faceBiopsyScheme == FaceBiopsyScheme.NEW) {
-            List<FaceBiopsyItemEntity> faceBiopsyItems = faceBiopsyItemRepo.findByExamRecordDataIdOrderByIdAsc(examRecordDataId);
-            //从未调过人脸检测接口,或者只调过接口但是未保存过结果(即未完成活检),则提示未进行人脸活体检测
-            if (faceBiopsyItems == null ||
-                    (faceBiopsyItems.size() == 1 && !faceBiopsyItems.get(0).getCompleted())) {
-                return "未进行人脸活体检测";
-            }
-
-            StringBuffer sbBuffer = new StringBuffer("");
-            for (FaceBiopsyItemEntity item : faceBiopsyItems) {
-                String startTime = CommonUtil.getDateStrWithSecond(item.getCreationTime());
-                String resultMsg = "";
-                if (null != item.getCompleted() && !item.getCompleted()) {
-                    resultMsg = "活检未完成";
-                } else {
-                    if (null != item.getResult() && item.getResult()) {
-                        resultMsg = "活检成功";
-                    } else {
-                        resultMsg = item.getErrorMsg() == null ? "" : item.getErrorMsg();
-                    }
-                }
-                sbBuffer.append(startTime + ":" + resultMsg);
-                sbBuffer.append("&&");
-            }
-            return sbBuffer.toString();
-        }
-        //旧活体检测方案从旧表中取相关数据
-        else {
-            List<ExamFaceLivenessVerifyEntity> faceVerifies =
-                    examFaceLivenessVerifyRepo.findByExamRecordDataIdOrderById(examRecordDataId);
-            if (faceVerifies == null || faceVerifies.size() == 0) {
-                return "未进行人脸动作检测";
-            } else {
-                StringBuffer sbBuffer = new StringBuffer("");
-                for (ExamFaceLivenessVerifyEntity faceVerify : faceVerifies) {
-                    String startTime = CommonUtil.getDateStrWithSecond(faceVerify.getStartTime());
-                    sbBuffer.append(startTime + ":" + FaceVerifyResult.getDescByName(faceVerify.getVerifyResult()));
-                    sbBuffer.append("&&");
-                }
-                String disciplineDetail = sbBuffer.toString();
-                if (disciplineDetail.length() > 500) {
-                    disciplineDetail = disciplineDetail.substring(0, 500);
-                }
-                return disciplineDetail;
-            }
-        }
-    }
-
-    @Override
-    public void saveExamAuditByNoPhoto(Long examRecordDataId) {
-        ExamAuditEntity examAudit = examAuditRepo.findByExamRecordDataId(examRecordDataId);
-        if (examAudit != null) {
-            return;
-        }
-        ExamAuditEntity examAuditEntity = new ExamAuditEntity();
-        examAuditEntity.setExamRecordDataId(examRecordDataId);
-        examAuditEntity.setDisciplineType(DisciplineType.OTHER);
-        examAuditEntity.setDisciplineDetail("抓拍照片数量为0");
-        examAuditEntity.setUserId(NOPHOTO_VERIFY_AUTO_AUDIT);//抓拍照片为0自动审核
-        examAuditEntity.setAuditUserName(AUDIT_USER_NAME);
-        examAuditEntity.setStatus(AuditStatus.UN_PASS);
-        examAuditRepo.save(examAuditEntity);
-    }
-
-}

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

@@ -1,1686 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
-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.ByteUtil;
-import cn.com.qmth.examcloud.commons.util.SHA256;
-import cn.com.qmth.examcloud.commons.util.UrlUtil;
-import cn.com.qmth.examcloud.commons.util.Util;
-import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
-import cn.com.qmth.examcloud.core.oe.common.base.Constants;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.QuestionTypeUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.*;
-import cn.com.qmth.examcloud.core.oe.common.enums.*;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.*;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScoreObtainQueueService;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScorePushQueueService;
-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.examwork.api.ExamCloudService;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-import cn.com.qmth.examcloud.examwork.api.request.GetExamPropertyReq;
-import cn.com.qmth.examcloud.examwork.api.response.GetExamPropertyResp;
-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.QuestionType;
-import cn.com.qmth.examcloud.reports.commons.bean.OnlineExamStudentReport;
-import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
-import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.*;
-import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
-import cn.com.qmth.examcloud.web.exception.SequenceLockException;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import cn.com.qmth.examcloud.web.helpers.SequenceLockHelper;
-import cn.com.qmth.examcloud.web.redis.RedisClient;
-import cn.com.qmth.examcloud.ws.api.FileAnswerWebsocketCloudService;
-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 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.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.validation.Valid;
-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
- * @date 2018年8月13日 下午2:09:08
- * @company QMTH
- * @description 在线考试控制服务实现
- */
-@Service("examControlService")
-public class ExamControlServiceImpl implements ExamControlService {
-
-    private static final String SESSION_TIMEOUT = "$core.basic.sessionTimeout";
-
-    // 又拍云签名有效时间(秒)
-    private static final Integer SIGN_TIMEOUT = 60;
-
-    private static final String SEPARATOR = "/";
-
-    private static final String UNDERLINE = "_";
-
-    // 又拍云音频答案上传目录
-    private static final String OE_ANSWER_FILE_PATH = "oe-answer-file";
-
-    private static final Logger log = LoggerFactory.getLogger(ExamControlServiceImpl.class);
-
-    private static final Log cleanExamRecordTaskLog = LogFactory.getLog("CLEAN_EXAM_RECORD_TASK_LOGGER");
-
-    @Autowired
-    private ExamStudentService examStudentService;
-
-    @Autowired
-    private ExamCloudService examCloudService;
-
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-
-    @Autowired
-    private ExamRecordDataService examRecordDataService;
-
-    @Autowired
-    private ExamRecordQuestionsService examRecordQuestionsService;
-
-    @Autowired
-    private ExamScoreService examScoreService;
-
-    @Autowired
-    private ExamFaceLivenessVerifyService examFaceLivenessVerifyService;
-
-    @Autowired
-    private ExamRecordForMarkingService examRecordForMarkingService;
-
-    @Autowired
-    private ExamStudentRepo examStudentRepo;
-
-    @Autowired
-    private ExamScoreRepo examScoreRepo;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamingRecordRepo examingRecordRepo;
-
-    @Autowired
-    private ExamRecordPaperStructRepo examRecordPaperStructRepo;
-
-    @Autowired
-    private RedisClient redisClient;
-
-    @Autowired
-    private ExamScorePushQueueService examScorePushQueueService;
-
-    @Autowired
-    private ExamScoreObtainQueueService examScoreObtainQueueService;
-
-    @Autowired
-    private ExamFileAnswerTempRepo examFileAnswerTempRepo;
-
-    @Autowired
-    private FileAnswerWebsocketCloudService fileAnswerWebsocketCloudService;
-
-    @Autowired
-    private ExamCaptureQueueRepo examCaptureQueueRepo;
-
-    @Autowired
-    private ExamCaptureCloudService examCaptureCloudService;
-
-    @Autowired
-    FaceBiopsyService faceBiopsyService;
-
-    @Value("${audio.app.url}")
-    private String audioAppUrl;
-
-    @Value("${$upyun.site.1.bucketName}")
-    private String bucketName;
-
-    @Value("${$upyun.site.1.userName}")
-    private String userName;
-
-    @Value("${$upyun.site.1.password}")
-    private String password;
-
-    @Value("https://v0.api.upyun.com")
-    private String bucketUrl;
-
-    @Value("${$upyun.site.1.domain}")
-    private String upyunFileUrl;
-
-    @Transactional
-    @Override
-    public StartExamInfo startExam(Long examStudentId, User user) {
-        long st = System.currentTimeMillis();
-        SysPropertyCacheBean stuClientLoginLimit = CacheHelper.getSysProperty("STU_CLIENT_LOGIN_LIMIT");
-        Boolean stuClientLoginLimitBoolean = false;
-        if (stuClientLoginLimit.getHasValue()) {
-            stuClientLoginLimitBoolean = Boolean.valueOf(stuClientLoginLimit.getValue().toString());
-        }
-        if (stuClientLoginLimitBoolean) {
-            throw new StatusException("OE-001505", "系统维护中... ...");
-        }
-
-        // try {
-        long startTime = System.currentTimeMillis();
-        // 获取原始考生信息
-        ExamStudentEntity originalExamStudent = examStudentRepo.findByExamStudentId(examStudentId);
-        if (log.isDebugEnabled()) {
-            log.debug("1 获取考生信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-        if (originalExamStudent == null) {
-            throw new StatusException("ExamControlServiceImpl-startExam-exception", "考生不存在");
-        }
-        if (originalExamStudent.getStudentId().longValue() != user.getUserId().longValue()) {
-            throw new StatusException("ExamControlServiceImpl-startExam-exception", "考生与当前用户不吻合");
-        }
-        // 检查redis session
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(originalExamStudent.getStudentId());
-        if (examSessionInfo != null) {
-            throw new StatusException("ExamControlServiceImpl-startExam-exception", "已经有考试中的科目");
-        }
-        // 检查并获取考试信息
-        startTime = System.currentTimeMillis();
-        ExamBean examBean = checkExam(originalExamStudent);
-        if (log.isDebugEnabled()) {
-            log.debug("2 检查并获取考试信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 检查并获取课程信息
-        startTime = System.currentTimeMillis();
-        CourseBean courseBean = checkCourse(originalExamStudent);
-        if (log.isDebugEnabled()) {
-            log.debug("3 检查并获取课程信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 获取题库试卷结构(由于存在随机抽卷,所以不能缓存 )
-        startTime = System.currentTimeMillis();
-
-        // 获取题库调卷规则
-        ExtractConfigCacheBean extractConfig = CacheHelper.getExtractConfig(originalExamStudent.getExamId(),
-                courseBean.getCode());
-        // 随机生成试卷
-        Map<String, String> paperTypeMaps = getExamPaperByProbability(extractConfig.getDetails());
-        if (paperTypeMaps.isEmpty()) {
-            throw new StatusException("100001", "生成试卷失败");
-        }
-
-        String paperId = paperTypeMaps.get(originalExamStudent.getPaperType());
-        if (StringUtils.isEmpty(paperId)) {
-            throw new StatusException("100002", "获取试卷失败");
-        }
-        // 生成试卷结构
-        ExtractConfigPaperCacheBean extractConfigPaper = CacheHelper.getExtractConfigPaper(
-                originalExamStudent.getExamId(), courseBean.getCode(), originalExamStudent.getPaperType(), paperId);
-        if (log.isDebugEnabled()) {
-            log.debug("4 获取题库试卷结构耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 小题乱序,选项乱序
-        startTime = System.currentTimeMillis();
-        reorderPaperStruct(extractConfig, extractConfigPaper);
-        if (log.isDebugEnabled()) {
-            log.debug("5 小题乱序耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 保存考试试卷结构
-        startTime = System.currentTimeMillis();
-        ExamRecordPaperStructEntity examRecordPaperStruct = new ExamRecordPaperStructEntity();
-        examRecordPaperStruct.setDefaultPaper(extractConfigPaper.getDefaultPaper());
-        examRecordPaperStruct = examRecordPaperStructRepo.save(examRecordPaperStruct);
-        if (log.isDebugEnabled()) {
-            log.debug("6 保存考试试卷结构耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 更新考生信息,并返回已考的考试次数
-        startTime = System.currentTimeMillis();
-
-        int examedTimes = examStudentService.updateExamStudentByStartExam(originalExamStudent.getId(),
-                originalExamStudent.getIsReExamine(), originalExamStudent.getReExamineCompleted(),
-                originalExamStudent.getNormalExamTimes(), examBean);
-        if (log.isDebugEnabled()) {
-            log.debug("7 更新考生信息耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 生成考试记录
-        startTime = System.currentTimeMillis();
-        ExamRecordDataEntity examRecordData = examRecordDataService.createExamRecordData(originalExamStudent, examBean,
-                courseBean, paperId, examRecordPaperStruct.getId(), examedTimes, examBean.getExamTimes(),
-                originalExamStudent.getIsReExamine(), extractConfigPaper.getDefaultPaper().getFullyObjective());
-
-        // 生成进行中的考试记录
-        Long studentId = examRecordData.getStudentId();
-        examRecordDataService.createExamingRecord(examRecordData.getId(), studentId,
-                examRecordData.getExamType());
-
-        // 如果开启人脸比对,将同步人脸比对结果存储到抓后结果表中
-        Long rootOrgId = examRecordData.getRootOrgId();
-        Long examId = examRecordData.getExamId();
-        Long orgId = examRecordData.getOrgId();
-
-        if (FaceBiopsyHelper.isFaceEnable(rootOrgId, examId, studentId)) {
-            SaveExamCaptureSyncCompareResultReq req = new SaveExamCaptureSyncCompareResultReq();
-            req.setExamRecordDataId(examRecordData.getId());
-            req.setStudentId(user.getUserId());
-            examCaptureCloudService.saveExamCaptureSyncCompareResult(req);
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("8 生成考试记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 创建考试作答记录
-        startTime = System.currentTimeMillis();
-        ExamRecordQuestionsEntity examRecordQuestions = examRecordQuestionsService
-                .createExamRecordQuestions(examRecordData.getId(), extractConfigPaper.getDefaultPaper());
-        if (log.isDebugEnabled()) {
-            log.debug("9 创建考试作答记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 更新考试记录(冗余考试记录id)
-        startTime = System.currentTimeMillis();
-        examRecordData.setExamRecordQuestionsId(examRecordQuestions.getId());
-        examRecordDataRepo.updateExamRecordDataQuestionIdById(examRecordQuestions.getId(), examRecordData.getId());
-        if (log.isDebugEnabled()) {
-            log.debug("10 更新考试记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 创建考试会话
-        startTime = System.currentTimeMillis();
-
-        initializeExamRecordSession(originalExamStudent, examRecordData, examBean);
-        if (log.isDebugEnabled()) {
-            log.debug("11 创建考试会话耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("12 合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
-        }
-        // 在线考生开考打点
-        ReportsUtil.report(
-                new OnlineExamStudentReport(user.getRootOrgId(), user.getUserId(), examBean.getId(), examStudentId));
-        return buildStartExamInfo(examRecordData.getId(), originalExamStudent, examBean, courseBean);
-        // } finally {
-        //
-        // }
-
-    }
-
-    /**
-     * 每个试卷类型取出一套试卷 {A:paperId,B:paperId} A是试卷类型,paperId是A类型下选定的试卷ID
-     */
-    private Map<String, String> getExamPaperByProbability(List<ExtractConfigDetailCacheBean> examPapers) {
-        if (CollectionUtils.isEmpty(examPapers)) {
-            throw new StatusException("500", "可供抽取的试卷集合为空!");
-        }
-
-        Map<String, List<ExtractConfigDetailCacheBean>> examPaperMaps = new HashMap<>();
-        for (ExtractConfigDetailCacheBean examPaper : examPapers) {
-            if (examPaperMaps.containsKey(examPaper.getGroupCode())) {
-                examPaperMaps.get(examPaper.getGroupCode()).add(examPaper);
-            } else {
-                List<ExtractConfigDetailCacheBean> list = new ArrayList<>();
-                list.add(examPaper);
-                examPaperMaps.put(examPaper.getGroupCode(), list);
-            }
-        }
-
-        Map<String, String> paperTypeMaps = new HashMap<>();
-        for (Map.Entry<String, List<ExtractConfigDetailCacheBean>> entry : examPaperMaps.entrySet()) {
-            List<ExtractConfigDetailCacheBean> list = examPaperMaps.get(entry.getKey());
-
-            String paperId = this.getPaperByProbability(list);
-            if (StringUtils.isEmpty(paperId)) {
-                continue;
-            }
-
-            paperTypeMaps.put(entry.getKey(), paperId);
-        }
-
-        return paperTypeMaps;
-    }
-
-    /**
-     * 根据设定几率取出一套试卷
-     */
-    private String getPaperByProbability(List<ExtractConfigDetailCacheBean> examPapers) {
-        int sum = 0;
-        for (ExtractConfigDetailCacheBean examPaper : examPapers) {
-            sum += examPaper.getWeight();
-        }
-
-        // 从1开始
-        int r = new Random().nextInt(sum) + 1;
-        for (ExtractConfigDetailCacheBean examPaper : examPapers) {
-            r -= examPaper.getWeight();
-            if (r <= 0) {
-                return examPaper.getPaperId();// 选中
-            }
-        }
-
-        return null;
-    }
-
-    private StartExamInfo buildStartExamInfo(Long examRecordDataId, ExamStudentEntity examStudentEntity,
-                                             ExamBean examBean, CourseBean courseBean) {
-        StartExamInfo startExamInfo = new StartExamInfo();
-        startExamInfo.setExamRecordDataId(examRecordDataId);
-        startExamInfo.setStudentCode(examStudentEntity.getStudentCode());
-        startExamInfo.setStudentName(examStudentEntity.getStudentName());
-        startExamInfo.setCourseCode(examStudentEntity.getCourseCode());
-        startExamInfo.setCourseName(courseBean.getName());
-        startExamInfo.setDuration(examBean.getDuration());
-        startExamInfo.setFaceVerifyMinute(getFaceVerifyMinute(examStudentEntity.getRootOrgId(), examBean.getId(), examStudentEntity.getOrgId(),
-                examStudentEntity.getStudentId()));
-        return startExamInfo;
-    }
-
-    /**
-     * 确定活体检测开始分钟数
-     *
-     * @param examId
-     * @return
-     */
-    private Integer getFaceVerifyMinute(Long rootOrgId, Long examId, Long orgId, Long studentId) {
-        // 如果开启了活体检测
-        if (FaceBiopsyHelper.isFaceVerify(rootOrgId, examId, studentId)) {
-            // 开始分钟数
-            String startMinuteStr = ExamCacheTransferHelper
-                    .getCachedExamProperty(examId, studentId, ExamProperties.FACE_VERIFY_START_MINUTE.name()).getValue();
-            if (CommonUtil.isBlank(startMinuteStr)) {
-                throw new StatusException("ExamControlServiceImpl-getFaceVerifyMinute-001",
-                        ExamProperties.FACE_VERIFY_START_MINUTE.getDesc() + "未设置");
-            }
-            Integer faceVerifyStartMinute = Integer.valueOf(startMinuteStr);
-
-            // 结束分钟数
-            String endMinuteStr = ExamCacheTransferHelper
-                    .getCachedExamProperty(examId, studentId, ExamProperties.FACE_VERIFY_END_MINUTE.name()).getValue();
-            if (CommonUtil.isBlank(endMinuteStr)) {
-                throw new StatusException("ExamControlServiceImpl-getFaceVerifyMinute-002",
-                        ExamProperties.FACE_VERIFY_END_MINUTE.getDesc() + "未设置");
-            }
-            Integer faceVerifyEndMinute = Integer.valueOf(endMinuteStr);
-            return CommonUtil.calculationRandomNumber(faceVerifyStartMinute, faceVerifyEndMinute);
-        }
-        return null;
-    }
-
-    private CourseBean checkCourse(ExamStudentEntity examStudentEntity) {
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudentEntity.getCourseId());
-        if (!courseBean.getEnable()) {
-            throw new StatusException("ExamControlServiceImpl-checkCourse-exception", "该课程已被禁用");
-        }
-        return courseBean;
-    }
-
-    /**
-     * 检查并返回考试 开考条件 1.enable为true 2.开始时间和结束时间判断 3.examLimit为null或false
-     * 4.剩余考试次数>0
-     *
-     * @param examStudentEntity
-     * @return
-     */
-    private ExamBean checkExam(ExamStudentEntity examStudentEntity) {
-        Long examId = examStudentEntity.getExamId();
-        Long studentId = examStudentEntity.getStudentId();
-
-        // 学习中心特殊考试配置(是否禁考,开考时间可以特殊设置)
-        ExamBean examBean = ExamCacheTransferHelper.getCachedExam(examId, studentId);
-
-        //如果启用了了特殊设置,并且无特殊设置时结束考试 配置 设置为true..且实际未设置特殊设置则不允许考试
-        ExamPropertyCacheBean limitedIfNoSpecialSettings = ExamCacheTransferHelper.getDefaultCachedExamProperty(examId,
-                ExamProperties.LIMITED_IF_NO_SPECIAL_SETTINGS.toString());
-        if (examBean.getSpecialSettingsEnabled() &&
-                (limitedIfNoSpecialSettings.getHasValue() && Boolean.valueOf(limitedIfNoSpecialSettings.getValue()))) {
-
-            //学生特殊设置开启未配置,不允许考试
-            if (examBean.getSpecialSettingsType() == ExamSpecialSettingsType.STUDENT_BASED) {
-                ExamStudentSettingsCacheBean specialSettings = CacheHelper.getExamStudentSettings(examId, studentId);
-                if (!specialSettings.getHasValue()) {
-                    throw new StatusException("100014", "考试配置未完成,不允许考试");
-                }
-            }
-
-            //机构特殊设置开启未配置,不允许考试
-            if (examBean.getSpecialSettingsType() == ExamSpecialSettingsType.ORG_BASED) {
-                //需求调整,所有的组织机构取学生表所关联的orgId
-                Long orgId = CacheHelper.getStudent(studentId).getOrgId();
-                ExamOrgSettingsCacheBean specialSettings = CacheHelper.getExamOrgSettings(examId, orgId);
-                if (!specialSettings.getHasValue()) {
-                    throw new StatusException("100015", "考试配置未完成,不允许考试");
-                }
-            }
-
-        }
-
-        if (!examBean.getEnable() || (examBean.getExamLimit() != null && examBean.getExamLimit())) {
-            throw new StatusException("ExamControlServiceImpl-checkExam-exception-01", "暂无考试资格,请与学校老师联系");
-        }
-        if (new Date().before(examBean.getBeginTime())) {
-            throw new StatusException("ExamControlServiceImpl-checkExam-exception-02", "考试未开始");
-        }
-        if (examBean.getEndTime().before(new Date())) {
-            throw new StatusException("ExamControlServiceImpl-checkExam-exception-03", "本次考试已结束");
-        }
-        if (ExamType.ONLINE.name().equals(examBean.getExamType())
-                || ExamType.PRACTICE.name().equals(examBean.getExamType())) {
-            if (examBean.getExamTimes() == null
-                    || examStudentService.countExamTimes(examStudentEntity, examBean) <= 0) {
-                throw new StatusException("ExamControlServiceImpl-checkExam-exception-04", "无剩余考试次数可用");
-            }
-        }
-        return examBean;
-    }
-
-    /**
-     * 创建考试会话
-     *
-     * @param examRecordData
-     * @param examBean
-     */
-    public void initializeExamRecordSession(final ExamStudentEntity examStudent,
-                                            final ExamRecordDataEntity examRecordData, final ExamBean examBean) {
-        ExamSessionInfo examSessionInfo = new ExamSessionInfo();
-        examSessionInfo.setExamRecordDataId(examRecordData.getId());
-        examSessionInfo.setExamStudentId(examStudent.getExamStudentId());
-        examSessionInfo.setStartTime(examRecordData.getStartTime().getTime());
-        long examDuration = examBean.getDuration() * 60 * 1000;
-        examSessionInfo.setExamDuration(examDuration);
-        examSessionInfo.setHeartbeat(-1);
-        examSessionInfo.setExamType(examBean.getExamType());
-        examSessionInfo.setExamId(examBean.getId());
-        examSessionInfo.setCourseCode(examStudent.getCourseCode());
-        examSessionInfo.setPaperType(examStudent.getPaperType());
-        // EXAM_RECONNECT_TIME:断点续考时间
-        String examReconnectTimeStr = ExamCacheTransferHelper
-                .getCachedExamProperty(examBean.getId(), examStudent.getStudentId(),
-                        ExamProperties.EXAM_RECONNECT_TIME.name()).getValue();
-        log.debug("11.2 断点时间:" + examReconnectTimeStr);
-        if (CommonUtil.isBlank(examReconnectTimeStr)) {
-            throw new StatusException("ExamControlServiceImpl-initializeExamRecordSession-001",
-                    ExamProperties.EXAM_RECONNECT_TIME.getDesc() + "未设置");
-        }
-        examSessionInfo.setExamReconnectTime(Integer.valueOf(examReconnectTimeStr));
-        // FREEZE_TIME:冻结时间
-        String freezeTimeStr = ExamCacheTransferHelper
-                .getCachedExamProperty(examBean.getId(), examStudent.getStudentId(),
-                        ExamProperties.FREEZE_TIME.name()).getValue();
-        log.debug("11.3 冻结时间:" + freezeTimeStr);
-        if (CommonUtil.isBlank(freezeTimeStr)) {
-            throw new StatusException("ExamControlServiceImpl-initializeExamRecordSession-002",
-                    ExamProperties.FREEZE_TIME.getDesc() + "未设置");
-        }
-        examSessionInfo.setFreezeTime(Integer.valueOf(freezeTimeStr));
-
-        log.debug("11.4 开始保存考试会话...studentId=" + examStudent.getStudentId() + ",timeOut="
-                + examSessionInfo.getExamReconnectTime() * 60);
-        // 过期时间=断点续考时间
-        examSessionInfoService.saveExamSessionInfo(examStudent.getStudentId(), examSessionInfo,
-                examSessionInfo.getExamReconnectTime() * 60);
-        log.debug("11.5 保存考试会话结束 ");
-    }
-
-    /**
-     * 获取试卷结构 小题乱序、选项乱序
-     *
-     * @param extractConfig 调卷规则对象
-     * @param paperStruct   试卷结构对象
-     */
-    private void reorderPaperStruct(ExtractConfigCacheBean extractConfig, ExtractConfigPaperCacheBean paperStruct) {
-        // 小题乱序
-        if (extractConfig.getSortQuestionOrder() != null && extractConfig.getSortQuestionOrder()) {
-            reorderQuestion(paperStruct.getDefaultPaper());
-        }
-        // 选项乱序
-        if (extractConfig.getSortOptionOrder() != null && extractConfig.getSortOptionOrder()) {
-            reorderOption(paperStruct.getDefaultPaper());
-        }
-    }
-
-    /**
-     * 小题乱序
-     *
-     * @param defaultPaper
-     */
-    private void reorderQuestion(DefaultPaper defaultPaper) {
-        List<DefaultQuestionGroup> defaultQuestionGroupList = defaultPaper.getQuestionGroupList();
-        for (int i = 0; i < defaultQuestionGroupList.size(); i++) {
-            DefaultQuestionGroup defaultQuestionGroup = defaultQuestionGroupList.get(i);
-            if (checkObjectiveQuestionByGroup(defaultQuestionGroup)) {
-                List<DefaultQuestionStructureWrapper> questionStructureWrapperList = defaultQuestionGroup
-                        .getQuestionWrapperList();
-                Collections.shuffle(questionStructureWrapperList);
-            }
-        }
-    }
-
-    /**
-     * 选项乱序
-     *
-     * @param defaultPaper
-     */
-    private void reorderOption(DefaultPaper defaultPaper) {
-        List<DefaultQuestionGroup> defaultQuestionGroupList = defaultPaper.getQuestionGroupList();
-        // 遍历大题
-        for (int i = 0; i < defaultQuestionGroupList.size(); i++) {
-            DefaultQuestionGroup defaultQuestionGroup = defaultQuestionGroupList.get(i);
-            List<DefaultQuestionStructureWrapper> questionStructureWrapperList = defaultQuestionGroup
-                    .getQuestionWrapperList();
-            // 遍历小题
-            for (DefaultQuestionStructureWrapper defaultQuestionStructureWrapper : questionStructureWrapperList) {
-                List<DefaultQuestionUnitWrapper> questionUnitWrapperList = defaultQuestionStructureWrapper
-                        .getQuestionUnitWrapperList();
-                // 遍历题单元
-                for (DefaultQuestionUnitWrapper defaultQuestionUnitWrapper : questionUnitWrapperList) {
-                    if (QuestionTypeUtil.isChoiceQuestion(defaultQuestionUnitWrapper.getQuestionType())) {
-                        Integer[] optionPermutation = defaultQuestionUnitWrapper.getOptionPermutation();
-                        defaultQuestionUnitWrapper.setOptionPermutation(CommonUtil.reorderArray(optionPermutation));
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * 小题乱序条件:一个大题下全是单一的客观题,例如全是单选,全是多选,全是判断 判断一个大题下是否是单一的客观题
-     *
-     * @return
-     */
-    private boolean checkObjectiveQuestionByGroup(DefaultQuestionGroup defaultQuestionGroup) {
-        Set<QuestionType> questionTypes = new HashSet<QuestionType>();
-        List<DefaultQuestionStructureWrapper> questionWrapperList = defaultQuestionGroup.getQuestionWrapperList();
-        for (int i = 0; i < questionWrapperList.size(); i++) {
-            List<DefaultQuestionUnitWrapper> questionUnitWrapperList = questionWrapperList.get(i)
-                    .getQuestionUnitWrapperList();
-            if (questionUnitWrapperList.size() > 1) {
-                return false;
-            } else {
-                questionTypes.add(questionUnitWrapperList.get(0).getQuestionType());
-            }
-        }
-        if (questionTypes.size() > 1) {
-            return false;
-        }
-        QuestionType questionType = questionTypes.iterator().next();
-        if (QuestionTypeUtil.isObjectiveQuestion(questionType)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * 计算考试时长 校验是否达到冻结时间
-     *
-     * @param studentId 学生id
-     * @return
-     */
-    private Long checkAndComputeExamDuration(Long studentId) {
-
-        // 获取考试会话,判断考生是否已结束考试(二次校验)
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("oestudent-100100", "考试会话已过期");
-        }
-        Long usedTime = calculateExamUsedMilliseconds(examSessionInfo);
-        // 如果没有超过冻结时间,抛出异常
-        if (examSessionInfo.getExamType().equals(ExamType.ONLINE.name())) {
-            ExamingRecordEntity rec = GlobalHelper.getEntity(examingRecordRepo, examSessionInfo.getExamRecordDataId(),
-                    ExamingRecordEntity.class);
-
-            if (rec != null && rec.getIsExceed() != null && rec.getIsExceed()) {// 超过断点最大次数的不校验冻结时间
-                return usedTime;
-            }
-            long freezeTime = examSessionInfo.getFreezeTime() * 60 * 1000;
-            if (usedTime < freezeTime) {
-                throw new StatusException("ExamControlServiceImpl-checkAndComputeExamDuration-exception",
-                        "开考" + examSessionInfo.getFreezeTime() + "分钟后才能交卷");
-            }
-        }
-
-        return usedTime;
-    }
-
-    /**
-     * 计算考试已用时间(毫秒)
-     *
-     * @param examSessionInfo 考试会话对象
-     * @return
-     */
-    @Override
-    public Long calculateExamUsedMilliseconds(ExamSessionInfo examSessionInfo) {
-        if (examSessionInfo == null) {
-            throw new StatusException("oestudent-100100", "考试会话已过期");
-        }
-        long now = System.currentTimeMillis();
-        Long lastHeartbeat = examSessionInfo.getLastHeartbeat();
-        long usedTime = examSessionInfo.getHeartbeat() * 60 * 1000;// 考试时长=心跳次数*60*1000
-        if (lastHeartbeat == null) {
-            lastHeartbeat = now;
-            usedTime = 1 * 60 * 1000;// 算作1分钟
-        }
-
-        if (now - lastHeartbeat < 60 * 1000) {
-            // 如果最后一次心跳和当前时间小于1分钟,则把零碎的时间也加进去
-            usedTime += now - lastHeartbeat;
-        }
-        return usedTime;
-    }
-
-    /**
-     * @param examRecordDataId 考试记录id
-     * @param handInExamType   交卷类型
-     */
-    @Override
-    @Transactional
-    public void handInExam(Long examRecordDataId, HandInExamType handInExamType) {
-        // 此锁是为了避免自动交卷服务与断点续考交卷或活检失败交卷,同一时刻交卷争抢资源导致死锁
-        String sequenceLockKey = Constants.HAND_IN_EXAM_LOCK_PREFIX + examRecordDataId;
-        // 系统在请求结束后会,自动释放锁,无需手动解锁
-        SequenceLockHelper.getLock(sequenceLockKey);
-
-        // //如果当前考试记录状态不为考试中,则直接返回
-        // if (examRecordData.getExamRecordStatus() !=
-        // ExamRecordStatus.EXAM_ING) {
-        // return;
-        // }
-        long st = System.currentTimeMillis();
-        long startTime = System.currentTimeMillis();
-
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        if (log.isDebugEnabled()) {
-            log.debug("1  [HAND_IN_EXAM]获取考试记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        Long studentId = examRecordData.getStudentId();
-        if (handInExamType == HandInExamType.MANUAL) {
-            startTime = System.currentTimeMillis();
-
-            // 得到考试时长,校验是否达到冻结时间
-            long usedExamTime = checkAndComputeExamDuration(studentId);
-            examRecordData.setUsedExamTime(usedExamTime);
-            examRecordData.setExamRecordStatus(ExamRecordStatus.EXAM_HAND_IN);
-            examRecordData.setEndTime(new Date());
-
-            // 手工手卷时,如果开启人脸检测,则更新抓拍队列优先级
-            Long rootOrgId = examRecordData.getRootOrgId();
-            Long examId = examRecordData.getExamId();
-
-            if (FaceBiopsyHelper.isFaceEnable(rootOrgId, examId, studentId)) {
-                // 更新照片抓拍队列优先级为高优先级
-                examCaptureQueueRepo.updateExamCaptureQueuePriority(Constants.PROCESS_CAPTURE_HIGH_PRIORITY,
-                        examRecordData.getId());
-                if (log.isDebugEnabled()) {
-                    log.debug("2.1  [HAND_IN_EXAM]更新照片抓拍队列优先级为高优先级耗时:" + (System.currentTimeMillis() - startTime)
-                            + " ms");
-                }
-            }
-        } else if (handInExamType == HandInExamType.AUTO) {
-            examRecordData.setExamRecordStatus(ExamRecordStatus.EXAM_AUTO_HAND_IN);
-            examRecordData.setCleanTime(new Date());
-        } else {
-            throw new StatusException("201101", "暂不支持的交卷类型");
-        }
-
-        startTime = System.currentTimeMillis();
-        // 将考试中的断点相关信息更新到考试记录表中
-        ExamingRecordEntity examingRecord = GlobalHelper.getEntity(examingRecordRepo, examRecordData.getId(),
-                ExamingRecordEntity.class);
-        examRecordData.setIsContinued(examingRecord.getIsContinued());
-        examRecordData.setContinuedCount(examingRecord.getContinuedCount());
-        examRecordData.setIsExceed(examingRecord.getIsExceed());
-
-        // 保存考试记录
-        examRecordData = examRecordDataRepo.save(examRecordData);
-        if (log.isDebugEnabled()) {
-            log.debug("2.2 [HAND_IN_EXAM]保存考试记录 耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        startTime = System.currentTimeMillis();
-        // 计算保存考试分数
-        examScoreService.saveExamScore(examRecordData);
-        if (log.isDebugEnabled()) {
-            log.debug("3 [HAND_IN_EXAM]计算保存考试分数耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        startTime = System.currentTimeMillis();
-        // 把进行中的考试记录放入交卷队列中
-        examRecordDataService.createHandInExamRecord(examRecordData.getId(), studentId);
-        if (log.isDebugEnabled()) {
-            log.debug("4 [HAND_IN_EXAM]把进行中的考试记录放入交卷队列中耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        startTime = System.currentTimeMillis();
-        // 删除进行中的考试记录数据
-        examRecordDataService.deleteExamingRecord(examRecordData.getId());
-        if (log.isDebugEnabled()) {
-            log.debug("5 [HAND_IN_EXAM]删除进行中的考试记录数据耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        startTime = System.currentTimeMillis();
-        // 删除redis会话
-        examSessionInfoService.deleteExamSessionInfo(studentId);
-        if (log.isDebugEnabled()) {
-            log.debug("6 [HAND_IN_EXAM]删除redis会话:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("7 [HAND_IN_EXAM]合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
-        }
-    }
-
-    @Override
-    @Transactional
-    public boolean processAfterHandInExam(Long examRecordDataId, Long studentId, HandInExamType handInExamType) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-
-        // 如果考试记录状态为已处理,则直接返回true.
-        if (examRecordDataService.isExamRecordEnded(examRecordData)) {
-            return true;
-        }
-
-        // 判断是否存在未处理的图片
-        boolean existUnhandledExamCaptureQueue = (examCaptureQueueRepo
-                .existsUnhandledByExamRecordDataId(examRecordDataId) != null);
-        if (existUnhandledExamCaptureQueue) {
-            throw new StatusException(Constants.CAPTURE_PROCESSING_STATUS_CODE, "PROCESSING");
-        }
-
-        // 处理照片上锁,处理抓拍照片已经完成,此时不允许再次上传抓拍照片,锁默认存在2分钟
-        redisClient.set(Constants.EXAM_CAPTURE_PHOTO_LOCK_PREFIX + examRecordDataId, 1, 120);
-
-        // 计算人脸检测结果(根据已检测出照片数据更新考试记录中的相关人脸检测的统计字段)
-        CalculateFaceCheckResultInfo calculateFaceCheckResultInfo = examRecordDataService
-                .calculateFaceCheckResult(examRecordData);
-        examRecordData = calculateFaceCheckResultInfo.getExamRecordData();
-        // 计算活体检测结果(根据已检测出照片数据更新考试记录中的相关人脸检测的统计字段)
-        examRecordDataService.calculateFaceLivenessVerifyResult(examRecordData);
-        // 违纪自动审核
-        examRecordData = examRecordDataService
-                .examRecordAutoAudit(calculateFaceCheckResultInfo.getIsNoPhotoAndIllegality(), examRecordData);
-
-        final ExamScoreEntity examScore = examScoreRepo.findByExamRecordDataId(examRecordData.getId());
-        // 保存阅卷相关数据
-        examRecordForMarkingService.saveExamRecordForMarking(examRecordData, examScore.getObjectiveScore());
-
-        // 更新考试记录相关数据,
-        // 手工交卷,更新考试状态
-        if (handInExamType == HandInExamType.MANUAL) {
-            examRecordData.setExamRecordStatus(ExamRecordStatus.EXAM_END);
-            // 经产品确认,自动服务清理时,不再更新考试结束时间,以交卷时的时间为准。
-            // examRecordData.setEndTime(new Date());
-        }
-        //自动交卷,更新考试状态和清理时间
-        else if (handInExamType == HandInExamType.AUTO) {
-            examRecordData.setExamRecordStatus(ExamRecordStatus.EXAM_OVERDUE);
-            examRecordData.setCleanTime(new Date());
-        } else {
-            throw new StatusException("201101", "暂不支持的交卷类型");
-        }
-
-        examRecordDataRepo.save(examRecordData);
-
-        // 保存考试分数数据到推分队列
-        examScorePushQueueService.saveScoreDataInfoToQueue(examRecordData, examScore.getId());
-
-        // 保存考试分数数据到分数获取队列
-        examScoreObtainQueueService.saveExamScoreObtainQueue(examRecordData);
-
-        // 删除已交卷的考试记录数据
-        examRecordDataService.deleteHandInExamRecord(examRecordData.getId());
-
-        return true;
-    }
-
-    @Override
-    public void cleanTempFileAnswers() {
-        // 默认删除1天以前的数据
-        int days = PropertyHolder.getInt("oe.cleanTempFileAnswer.thresholdDays", 1);
-        Date dateBeforeDays = DateUtils.addDays(new Date(), -1 * days);
-        examFileAnswerTempRepo.deleteByCreationTime(dateBeforeDays);
-    }
-
-    /**
-     * 考试心跳每分钟调用一次
-     *
-     * @param user 学生
-     */
-    @Override
-    public long examHeartbeat(User user) {
-        Long studentId = user.getUserId();
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("ExamControlServiceImpl-examHeartbeat-exception", "会话已过期,请离开考试!");
-        }
-        long now = System.currentTimeMillis();
-        if (examSessionInfo.getLastHeartbeat() != null) {
-            if (now - examSessionInfo.getLastHeartbeat() >= examSessionInfo.getExamReconnectTime() * 60 * 1000) {
-                // 如果当前时间和上一次心跳间隔超过了断点续考时间,则删除考试会话,并停止心跳
-                examSessionInfoService.deleteExamSessionInfo(studentId);
-                return 0L;
-            }
-        }
-        // 记录最后心跳时间
-        examSessionInfo.setLastHeartbeat(now);
-        // 更新心跳次数
-        examSessionInfo.setHeartbeat(examSessionInfo.getHeartbeat() + 1);
-        // 会话过期时间:秒
-        int expireTime = (examSessionInfo.getExamReconnectTime() + 1) * 60;
-        // 更新考试会话过期时间
-        examSessionInfoService.saveExamSessionInfo(studentId, examSessionInfo, expireTime);
-        // 在线考生心跳打点
-        ReportsUtil.report(new OnlineExamStudentReport(user.getRootOrgId(), user.getUserId(),
-                examSessionInfo.getExamId(), examSessionInfo.getExamStudentId()));
-        // 返回考试剩余时间 :考试时长-心跳次数*60000
-        return examSessionInfo.getExamDuration() - (examSessionInfo.getHeartbeat() * 60 * 1000);
-    }
-
-    @Override
-    public CheckExamInProgressInfo checkExamInProgress(Long studentId) {
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        // 检查考试会话是否存在,或者是否失效,如果没有失效,则返回考试中的考试记录实体,否则直接返回null
-        ExamingRecordEntity examingRecord = checkExamSession(examSessionInfo, studentId);
-        if (examingRecord == null) {
-            return null;
-        } else {
-            ExamStudentEntity examStudentEntity = examStudentRepo
-                    .findByExamStudentId(examSessionInfo.getExamStudentId());
-            Integer maxInterruptNum = getMaxInterruptNum(examStudentEntity.getExamId(),
-                    examStudentEntity.getRootOrgId(), examStudentEntity.getOrgId());
-            CheckExamInProgressInfo checkExamInProgressInfo = new CheckExamInProgressInfo();
-
-            if ((examingRecord.getIsExceed() == null || !examingRecord.getIsExceed())
-                    && examingRecord.getContinuedCount().intValue() < maxInterruptNum.intValue()) {// 未达到最大断点次数,可继续断点一次
-                // 断点续考次数自增
-                int continutedCount = examingRecord.getContinuedCount() == null ? 0
-                        : examingRecord.getContinuedCount().intValue();
-                examingRecord.setContinuedCount(continutedCount + 1);
-                examingRecord.setIsContinued(true);
-                examingRecord.setIsExceed(false);
-                checkExamInProgressInfo.setIsExceed(false);
-            } else {
-                examingRecord.setIsExceed(true);
-                checkExamInProgressInfo.setIsExceed(true);
-            }
-            // 更新考试中的断点续考属性
-            examingRecordRepo.save(examingRecord);
-
-            checkExamInProgressInfo.setExamRecordDataId(examingRecord.getExamRecordDataId());
-            checkExamInProgressInfo.setExamId(examSessionInfo.getExamId());
-            checkExamInProgressInfo.setUsedTime(examSessionInfo.getHeartbeat() * 60 * 1000);
-            checkExamInProgressInfo.setMaxInterruptNum(maxInterruptNum);
-            checkExamInProgressInfo.setInterruptNum(examingRecord.getContinuedCount());
-
-            // 断点续考时重新计算活体检测的分钟数
-            Integer faceVerifyMinute = null;
-            FaceBiopsyScheme faceBiopsyScheme = FaceBiopsyHelper.getFaceBiopsyScheme(examStudentEntity.getRootOrgId());
-
-            // 如果是新活体检测方案,则使用新的计算方案计算活检开始时间
-            if (faceBiopsyScheme == FaceBiopsyScheme.NEW) {
-                faceVerifyMinute = faceBiopsyService.calculateFaceBiopsyStartMinute(examingRecord.getExamRecordDataId());
-            }
-            // 非新活检,默认使用旧的活检计算方式
-            else {
-                faceVerifyMinute = examFaceLivenessVerifyService.getFaceLivenessVerifyMinute(
-                        examStudentEntity.getRootOrgId(), examStudentEntity.getOrgId(),
-                        examStudentEntity.getExamId(), studentId,
-                        examingRecord.getExamRecordDataId(), examSessionInfo.getHeartbeat());
-            }
-
-            checkExamInProgressInfo.setFaceVerifyMinute(faceVerifyMinute);
-            return checkExamInProgressInfo;
-        }
-    }
-
-    private ExamingRecordEntity checkExamSession(ExamSessionInfo examSessionInfo, Long studentId) {
-        ExamingRecordEntity examingRecord = examingRecordRepo.findOnlineExamingRecord(studentId);
-        // 如果考试记录不存在,清除会话
-        if (examingRecord == null) {
-            examSessionInfoService.deleteExamSessionInfo(studentId);
-            return null;
-        }
-
-        // 如果会话不存在,自动交卷
-        if (examSessionInfo == null) {
-            delayHandInExamIfLocked(examingRecord.getExamRecordDataId());
-            return null;
-        }
-
-        // 如果已经过了断点续考时间,清除考试记录,清除会话
-        Long lastHeartbeat = examSessionInfo.getLastHeartbeat();
-        if (lastHeartbeat == null) {
-            lastHeartbeat = examSessionInfo.getStartTime();
-        }
-        long now = System.currentTimeMillis();
-        if (now - lastHeartbeat >= examSessionInfo.getExamReconnectTime().intValue() * 60 * 1000) {
-            examSessionInfoService.deleteExamSessionInfo(studentId);
-            delayHandInExamIfLocked(examingRecord.getExamRecordDataId());
-            return null;
-        }
-        return examingRecord;
-    }
-
-    /**
-     * 如果有序列化锁,则延迟交卷
-     *
-     * @param examRecordDataId 考试记录id
-     * @return
-     */
-    private void delayHandInExamIfLocked(Long examRecordDataId) {
-        try {
-            handInExam(examRecordDataId, HandInExamType.AUTO);
-        } catch (SequenceLockException e) {
-            // 如果发现自动服务正在交卷,则重试1500毫秒获取考试记录状态,判断是否已交卷
-            int loopTimes = 0;
-            while (loopTimes <= 15) {
-                loopTimes++;
-                ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                        ExamRecordDataEntity.class);
-
-                // 1500毫秒内如果交卷成功,则退出循环
-                if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
-                    return;
-                }
-                Util.sleep(TimeUnit.MILLISECONDS, 100);
-            }
-            throw e;
-        }
-    }
-
-    @Override
-    public void cleanExamingRecord(ExamingRecordEntity examingRecord) {
-
-        // 只有考试会话结束的考试才执行清理动作
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(examingRecord.getStudentId());
-        if (examSessionInfo != null) {
-            cleanExamRecordTaskLog
-                    .debug("[CLEAN_EXAMING_RECORD_" + examingRecord.getExamRecordDataId() + "]考试未结束,不执行清理.");
-            return;
-        }
-
-        // 只有考试状态为考试中,系统才需要执行交卷动作,因为有可能已经手动交卷,所以这里再做一次判断
-        // if (examRecordData.getExamRecordStatus() ==
-        // ExamRecordStatus.EXAM_ING) {
-        cleanExamRecordTaskLog
-                .debug("[CLEAN_EXAMING_RECORD_" + examingRecord.getExamRecordDataId() + "]状态为进行中考试,执行交卷[handInExam],.");
-        handInExam(examingRecord.getExamRecordDataId(), HandInExamType.AUTO);
-        // }
-
-        cleanExamRecordTaskLog.debug("[CLEAN_EXAMING_RECORD_" + examingRecord.getExamRecordDataId() + "]考试记录交卷完成.");
-    }
-
-    @Override
-    public void cleanHandInExamRecord(HandInExamRecordEntity handInExamRecord) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo,
-                handInExamRecord.getExamRecordDataId(), ExamRecordDataEntity.class);
-
-        // 只清理状态为已交卷的数据,才能执行交卷后续动作
-        if (examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_AUTO_HAND_IN
-                || examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_HAND_IN) {
-            // 默认自动交卷
-            HandInExamType handInExamType = HandInExamType.AUTO;
-            if (examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_AUTO_HAND_IN) {
-                handInExamType = HandInExamType.AUTO;
-            } else if (examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_HAND_IN) {
-                handInExamType = HandInExamType.MANUAL;
-            }
-            cleanExamRecordTaskLog.debug("[CLEAN_HAND_IN_EXAM_RECORD_" + examRecordData.getId() + "]开始执行交卷后续动作,.");
-            try {
-                processAfterHandInExam(handInExamRecord.getExamRecordDataId(), examRecordData.getStudentId(),
-                        handInExamType);
-            } catch (StatusException e) {
-                if (e.getCode().equals(Constants.CAPTURE_PROCESSING_STATUS_CODE)) {
-                    cleanExamRecordTaskLog
-                            .debug("[CLEAN_HAND_IN_EXAM_RECORD_" + examRecordData.getId() + "]有未处理完成的图片,稍侯重试...");
-                    return;
-                }
-                throw e;
-            } catch (Exception e) {
-                throw e;
-            }
-        }
-
-        cleanExamRecordTaskLog.debug("[CLEAN_HAND_IN_EXAM_RECORD_" + examRecordData.getId() + "]考试记录交卷后续动作完成.");
-    }
-
-    @Override
-    public EndExamInfo getEndExamInfo(Long examRecordDataId) {
-        ExamScoreEntity examScore = examScoreRepo.findByExamRecordDataId(examRecordDataId);
-        if (examScore == null) {
-            return null;
-        }
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        // 如果考试没有最终结束,则返回空值
-        if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_END
-                && examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_OVERDUE) {
-            return null;
-        }
-        EndExamInfo endExamInfo = new EndExamInfo();
-        endExamInfo.setExamRecordDataId(examRecordDataId);
-        endExamInfo.setIsWarn(examRecordData.getIsWarn());// 是否异常数据
-        endExamInfo.setObjectiveScore(examScore.getObjectiveScore());// 客观题总分
-        endExamInfo.setObjectiveAccuracy(examScore.getObjectiveAccuracy());// 客观点答对比率
-        return endExamInfo;
-    }
-
-    @Override
-    public void handleByExamCaptureQueueFailedDispose(Long examRecordDataId) {
-        // 查询考试记录
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        // 计算人脸检测结果
-        CalculateFaceCheckResultInfo calculateFaceCheckResultInfo = examRecordDataService
-                .calculateFaceCheckResult(examRecordData);
-        examRecordData = calculateFaceCheckResultInfo.getExamRecordData();
-        examRecordDataRepo.save(examRecordData);
-        // 保存阅卷相关数据
-        ExamScoreEntity examScore = examScoreRepo.findByExamRecordDataId(examRecordDataId);
-        examRecordForMarkingService.saveExamRecordForMarking(examRecordData, examScore.getObjectiveScore());
-        // 保存考试分数数据到推分队列
-        examScorePushQueueService.saveScoreDataInfoToQueue(examRecordData, examScore.getId());
-        // 保存考试分数数据到分数获取队列
-        examScoreObtainQueueService.saveExamScoreObtainQueue(examRecordData);
-        // 发送获取分数通知
-        examScoreObtainQueueService.sendObtainScoreNotify(examRecordData.getRootOrgId());
-    }
-
-    @Override
-    public UpyunSignatureInfo getUpyunSignature(GetUpyunSignatureReq req) {
-        UpyunSignatureInfo u = new UpyunSignatureInfo();
-        try {
-            ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo,
-                    Long.valueOf(req.getExamRecordDataId()), ExamRecordDataEntity.class);
-            String md5 = req.getFileMd5();
-            Date signDate = null;
-            Date now = new Date();
-            Date expirationDate = DateUtils.addSeconds(now, SIGN_TIMEOUT);
-
-            StringBuffer filePath = new StringBuffer();
-
-            filePath.append(SEPARATOR).append(OE_ANSWER_FILE_PATH).append(SEPARATOR)
-                    .append(examRecordData.getExamStudentId()).append(SEPARATOR).append(req.getExamRecordDataId())
-                    .append(SEPARATOR).append(req.getOrder()).append(SEPARATOR)
-                    .append(examRecordData.getExamStudentId()).append(UNDERLINE).append(req.getExamRecordDataId())
-                    .append(UNDERLINE).append(req.getOrder()).append(UNDERLINE).append(System.currentTimeMillis())
-                    .append(RandomUtils.nextInt(8999) + 1000);
-
-            if (StringUtils.isNotEmpty(req.getExt())) {
-                filePath.append(UNDERLINE).append(req.getExt());
-            }
-            filePath.append(".").append(req.getFileSuffix());
-
-            long expiration = expirationDate.getTime() / 1000;
-            String policy = policy(bucketName, expiration, filePath.toString(), signDate, md5);
-            String sign = sign("POST", getGMTDate(signDate), bucketName, policy, userName, UpYunUtils.md5(password),
-                    md5);
-            u.setPolicy(policy);
-            u.setSignature(sign);
-            u.setFilePath(filePath.toString());
-            u.setUploadUrl(UrlUtil.joinUrl(bucketUrl, bucketName));
-            u.setUpyunFileDomain(upyunFileUrl);
-        } catch (UpException e) {
-            throw new StatusException("100003", "获取又拍云签名失败");
-        }
-        return u;
-    }
-
-    private String getGMTDate(Date d) {
-        if (d == null) {
-            return null;
-        }
-        SimpleDateFormat formater = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
-        formater.setTimeZone(TimeZone.getTimeZone("GMT+8"));
-        return formater.format(d);
-    }
-
-    /**
-     * @param bucketName //不能为空
-     * @param expiration //不能为空
-     * @param filePath   //不能为空
-     * @param date       为空时,以又怕云时间和expiration比较,不为空时以此date和expiration比较
-     * @param md5        //可以为空
-     * @return
-     */
-    private String policy(String bucketName, Long expiration, String filePath, Date date, String md5) {
-        Map<String, Object> paramMap = new HashMap<String, Object>();
-        // 不能为空
-        paramMap.put("bucket", bucketName);
-        Date expirationDate = DateUtils.addSeconds(new Date(), SIGN_TIMEOUT);
-        // 不能为空
-        paramMap.put("expiration", expirationDate.getTime() / 1000);
-        paramMap.put("save-key", filePath);
-        // 为空时,以又怕云时间和expiration比较,不为空时以此date和expiration比较
-        paramMap.put("date", date);
-        // 可以为空
-        paramMap.put("content-md5", md5);
-        String policy = UpYunUtils.getPolicy(paramMap);
-        return policy;
-    }
-
-    /**
-     * 必须和policy中date一致,可以都为空.GMTDate
-     *
-     * @param method
-     * @param date
-     * @param bucketName
-     * @param policy
-     * @param userName
-     * @param password
-     * @param md5
-     * @return
-     * @throws UpException
-     */
-    private String sign(String method, String date, String bucketName, String policy, String userName, String password,
-                        String md5) throws UpException {
-
-        StringBuilder sb = new StringBuilder();
-        String sp = "&";
-        sb.append(method);
-        sb.append(sp);
-        sb.append(SEPARATOR + bucketName);
-        if (date != null) {
-            sb.append(sp);
-            sb.append(date);
-        }
-        sb.append(sp);
-        sb.append(policy);
-        if (md5 != null && md5.length() > 0) {
-            sb.append(sp);
-            sb.append(md5);
-        }
-        String raw = sb.toString().trim();
-        byte[] hmac = null;
-        try {
-            hmac = UpYunUtils.calculateRFC2104HMACRaw(password, raw);
-        } catch (Exception e) {
-            throw new UpException("calculate SHA1 wrong.");
-        }
-
-        if (hmac != null) {
-            return "UPYUN " + userName + ":" + Base64Coder.encodeLines(hmac).trim();
-        }
-
-        return null;
-    }
-
-    @Override
-    public String getQrCode(@Valid GetQrCodeReq req, String key) {
-        int sessionTimeout = PropertyHolder.getInt(SESSION_TIMEOUT, 3600);
-        User user = redisClient.get(key, User.class, sessionTimeout);
-        if (null == user) {
-            throw new StatusException("100007", "登录信息已失效");
-        }
-        return getQrCode(req, user);
-    }
-
-    @Override
-    public String getQrCode(GetQrCodeReq req, User user) {
-        if (user == null) {
-            throw new StatusException("100002", "登录信息错误");
-        }
-
-        // 如果是调用环境监测的接口,不用做如下校验
-        if (!req.isTestEnv()) {
-            ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(user.getUserId());
-
-            ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(req.getExamStudentId());
-            if (examStudentEntity == null) {
-                throw new StatusException("100012", "考生不存在");
-            }
-            if (!user.getUserId().equals(examStudentEntity.getStudentId())) {
-                throw new StatusException("100013", "无效的请求");
-            }
-            if (examSessionInfo == null) {
-                throw new StatusException("100006", "考试已结束");
-            }
-            if (examSessionInfo.getExamRecordDataId().longValue() != req.getExamRecordDataId().longValue()
-                    || examSessionInfo.getExamStudentId().longValue() != req.getExamStudentId().longValue()) {
-                throw new StatusException("100008", "无效的请求");
-            }
-        } else {
-            // 环境检测时,需要重新给考生id赋值
-            ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, req.getExamRecordDataId(),
-                    ExamRecordDataEntity.class);
-            req.setExamStudentId(examRecordData.getExamStudentId());
-        }
-        String key = user.getKey();
-        StringBuffer param = new StringBuffer();
-        String transferFileType = StringUtils.isBlank(req.getTransferFileType()) ? "" : req.getTransferFileType();
-        param.append("examStudentId=").append(req.getExamStudentId()).append("&examRecordDataId=")
-                .append(req.getExamRecordDataId()).append("&order=").append(req.getOrder()).append("&transferFileType=")
-                .append(transferFileType).append("&key=").append(key);
-        // 需要签名的参数
-        StringBuffer sourStr = new StringBuffer();
-        sourStr.append(req.getOrder()).append(UNDERLINE).append(req.getExamRecordDataId()).append(UNDERLINE).append(key)
-                .append(UNDERLINE).append(req.getExamStudentId());
-        // 签名
-        byte[] bytes = SHA256.encode(sourStr.toString());
-        String hexAscii = ByteUtil.toHexAscii(bytes);
-        param.append("&token=").append(hexAscii);
-        String qrStr;
-        try {
-            qrStr = audioAppUrl + SEPARATOR + URLEncoder.encode(param.toString(), "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            throw new StatusException("100001", "参数编码异常");
-        }
-        return qrStr;
-    }
-
-    /**
-     * 通过websocket发送消息
-     *
-     * @param examRecordDataId 考试记录id
-     * @param order            题序号
-     * @param fileUrl          文件路径
-     * @param transferFileType 传输文件类型
-     * @param userId
-     * @throws Exception
-     */
-    @Override
-    public void sendFileAnswerToWebSocket(Long examRecordDataId, Integer order, String fileUrl, String transferFileType,
-                                          Long userId) throws Exception {
-        Map<String, Object> data = new HashMap<String, Object>();
-        data.put("examRecordDataId", examRecordDataId);
-        data.put("order", order);
-        data.put("fileUrl", fileUrl);
-        data.put("transferFileType", transferFileType);
-
-        SendFileAnswerMessageReq sendMessageReq = new SendFileAnswerMessageReq();
-        Long clientId;
-        // 如果是环境检测,则使用用户id(即学生id)作为clientId
-        if (isTestDev(examRecordDataId)) {
-            clientId = userId;
-        }
-        // 不是环境检测,仍然使用考试记录id作为clientId
-        else {
-            clientId = examRecordDataId;
-        }
-        sendMessageReq.setClientId(clientId);
-        sendMessageReq.setEventType(WebSocketEventType.GET_FILE_ANSWER.toString());
-        sendMessageReq.setIsSuccess(true);
-        sendMessageReq.setData(data);
-        fileAnswerWebsocketCloudService.sendFileAnswerMessage(sendMessageReq);
-    }
-
-    /**
-     * 通过websocket发送二维码扫描信息
-     *
-     * @param clientId
-     * @param examRecordDataId
-     * @param order
-     * @throws Exception
-     */
-    @Override
-    public void sendScanQrCodeToWebSocket(String clientId, Long examRecordDataId, Integer order) throws Exception {
-        Map<String, Object> data = new HashMap<String, Object>();
-        data.put("examRecordDataId", examRecordDataId);
-        data.put("order", order);
-        data.put("scanStatus", "SCANNED");
-        SendScanQrCodeMessageReq sendScanQrCodeMessageReq = new SendScanQrCodeMessageReq();
-        sendScanQrCodeMessageReq.setExamRecordDataId(examRecordDataId);
-        sendScanQrCodeMessageReq.setEventType(WebSocketEventType.SCAN_QR_CODE.toString());
-        sendScanQrCodeMessageReq.setIsSuccess(true);
-        sendScanQrCodeMessageReq.setClientId(clientId);
-        sendScanQrCodeMessageReq.setData(data);
-        fileAnswerWebsocketCloudService.sendScanQrCodeMessage(sendScanQrCodeMessageReq);
-    }
-
-    @Override
-    public CheckQrCodeInfo checkQrCode(String param) {
-        long st = System.currentTimeMillis();
-
-        long startTime = System.currentTimeMillis();
-        String str;
-        str = UrlUtil.decode(param);
-        Map<String, String> map = Splitter.on("&").withKeyValueSeparator("=").split(str);
-        String examStudentId = map.get("examStudentId");
-        String examRecordDataId = map.get("examRecordDataId");
-        String order = map.get("order");
-        String key = map.get("key");
-        String token = map.get("token");
-        // 需要签名的参数
-        StringBuffer sourStr = new StringBuffer();
-        sourStr.append(order).append(UNDERLINE).append(examRecordDataId).append(UNDERLINE).append(key).append(UNDERLINE)
-                .append(examStudentId);
-        // 签名
-        byte[] bytes = SHA256.encode(sourStr.toString());
-        String hexAscii = ByteUtil.toHexAscii(bytes);
-        if (!hexAscii.equals(token)) {
-            throw new StatusException("100005", "无效的二维码");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("1 签名校验耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        startTime = System.currentTimeMillis();
-        // 判断考生是否存在
-        ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(Long.valueOf(examStudentId));
-        if (examStudentEntity == null) {
-            throw new StatusException("100012", "考生不存在");
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("2 考生是否存在校验耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        String clientId;
-        // 未开启环境检测,才进行如下校验
-        if (!isTestDev(Long.valueOf(examRecordDataId))) {
-            // 非环境检测,clientId即examRecordDataId
-            clientId = examRecordDataId;
-            // 判断考试是否结束
-            ExamSessionInfo examSessionInfo = examSessionInfoService
-                    .getExamSessionInfo(examStudentEntity.getStudentId());
-            if (examSessionInfo == null) {
-                throw new StatusException("100006", "考试已结束");
-            }
-            if (examSessionInfo.getExamRecordDataId().longValue() != Long.valueOf(examRecordDataId).longValue()
-                    || examSessionInfo.getExamStudentId().longValue() != Long.valueOf(examStudentId).longValue()) {
-                throw new StatusException("100008", "无效的二维码");
-            }
-        } else {
-            // 环境检测时,clientId即用户id
-            clientId = key.substring(key.lastIndexOf("_") + 1);
-        }
-
-        // 校验通过
-        CheckQrCodeInfo res = new CheckQrCodeInfo();
-        res.setExamRecordDataId(Long.valueOf(examRecordDataId));
-        res.setExamStudentId(Long.valueOf(examStudentId));
-        res.setKey(key);
-        int sessionTimeout = PropertyHolder.getInt(SESSION_TIMEOUT, 3600);
-        User user = redisClient.get(key, User.class, sessionTimeout);
-        if (null == user) {
-            throw new StatusException("100007", "登录信息已失效");
-        }
-        res.setToken(user.getToken());
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudentEntity.getCourseId());
-
-        res.setCourseId(courseBean.getId());
-        res.setCourseName(courseBean.getName());
-
-        startTime = System.currentTimeMillis();
-        ExamRecordQuestionsEntity examRecordQuestionsEntity = examRecordQuestionsService
-                .getExamRecordQuestionsAndFixExamRecordDataIfNecessary(Long.valueOf(examRecordDataId));
-        if (log.isDebugEnabled()) {
-            log.debug("3 获取作答记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        List<ExamQuestionEntity> examQuestionList = examRecordQuestionsEntity.getExamQuestionEntities();
-
-        if (examRecordQuestionsEntity == null || examQuestionList == null || examQuestionList.isEmpty()) {
-            throw new StatusException("100008", "无效的二维码");
-        }
-        List<ExamQuestionEntity> filterList = examQuestionList.stream()
-                .filter(p -> p.getOrder().equals(Integer.valueOf(order))).collect(Collectors.toList());
-        if (filterList == null || filterList.isEmpty()) {
-            throw new StatusException("100008", "无效的二维码");
-        }
-        ExamQuestionEntity eqe = filterList.get(0);
-
-        res.setQuestionOrder(eqe.getOrder());
-        res.setQuestionMainNumber(eqe.getMainNumber());
-        res.setSubNumber(getSubNumber(examRecordQuestionsEntity, Integer.valueOf(order)));
-        startTime = System.currentTimeMillis();
-        try {
-            this.sendScanQrCodeToWebSocket(clientId, Long.valueOf(examRecordDataId), Integer.valueOf(order));
-        } catch (Exception e) {
-            throw new StatusException("100011", "消息通知失败", e);
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("4 发websocket耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("5 合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
-        }
-        return res;
-    }
-
-    private Integer getSubNumber(ExamRecordQuestionsEntity examRecordQuestionsEntity, Integer order) {
-        List<UploadedFileAnswerInfo> list = getReSortedQuestionList(examRecordQuestionsEntity);
-        for (UploadedFileAnswerInfo info : list) {
-            if (order.intValue() == info.getOrder().intValue()) {
-                return info.getSubNumber();
-            }
-        }
-        return null;
-    }
-
-    @Override
-    @Transactional
-    public ExamFileAnswerTempEntity saveUploadedFile(SaveUploadedFileReq req, User user) {
-        long st = System.currentTimeMillis();
-
-        long startTime = System.currentTimeMillis();
-        // 判断考试是否结束
-        ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(req.getExamStudentId());
-        if (examStudentEntity == null) {
-            throw new StatusException("100012", "考生不存在");
-        }
-
-        // 开启了环境检测,则不需要进行如下的校验
-        if (!isTestDev(req.getExamRecordDataId())) {
-            if (!user.getUserId().equals(examStudentEntity.getStudentId())) {
-                throw new StatusException("100013", "无效的请求");
-            }
-            ExamSessionInfo examSessionInfo = examSessionInfoService
-                    .getExamSessionInfo(examStudentEntity.getStudentId());
-            if (examSessionInfo == null) {
-                throw new StatusException("100006", "考试已结束");
-            }
-            if (examSessionInfo.getExamRecordDataId().longValue() != req.getExamRecordDataId().longValue()
-                    || examSessionInfo.getExamStudentId().longValue() != req.getExamStudentId().longValue()) {
-                throw new StatusException("100008", "考试已结束");
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("1 判断考试是否结束耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        startTime = System.currentTimeMillis();
-        ExamFileAnswerTempEntity et = new ExamFileAnswerTempEntity();
-        et.setExamRecordDataId(req.getExamRecordDataId());
-        et.setExamStudentId(req.getExamStudentId());
-        et.setQuestionOrder(req.getOrder());
-        et.setFilePath(req.getFilePath());
-        et.setStatus(FileAnswerAcknowledgeStatus.UNCONFIRMED);
-        et.setTransferFileType(req.getTransferFileType());
-        ExamFileAnswerTempEntity result = examFileAnswerTempRepo.save(et);
-        if (log.isDebugEnabled()) {
-            log.debug("2 保存文件临时作答记录耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("3 合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
-        }
-        return result;
-
-    }
-
-    @Override
-    public String getUploadedFileAcknowledgeStatus(GetUploadedFileAcknowledgeStatusReq req) {
-        ExamFileAnswerTempEntity et = GlobalHelper.getEntity(examFileAnswerTempRepo, req.getAcknowledgeId(),
-                ExamFileAnswerTempEntity.class);
-        if (et != null) {
-            return et.getStatus().toString();
-        }
-        return FileAnswerAcknowledgeStatus.UNCONFIRMED.toString();
-    }
-
-    @Override
-    @Transactional
-    public void saveUploadedFileAcknowledgeStatus(SaveUploadedFileAcknowledgeStatusReq req) {
-        ExamFileAnswerTempEntity et = examFileAnswerTempRepo.findByExamRecordDataIdAndQuestionOrderAndFilePath(
-                req.getExamRecordDataId(), req.getOrder(), req.getFilePath().replace(upyunFileUrl, ""));
-        if (et == null) {
-            throw new StatusException("100010", "无效的数据");
-        }
-        et.setStatus(FileAnswerAcknowledgeStatus.valueOf(req.getAcknowledgeStatus()));
-        examFileAnswerTempRepo.save(et);
-    }
-
-    @Override
-    @Transactional
-    public void deleteExamFileAnswerTemp(SaveUploadedFileReq req) {
-        examFileAnswerTempRepo.delete(req.getExamRecordDataId(), req.getExamStudentId(), req.getOrder(),
-                req.getFilePath());
-    }
-
-    @Override
-    public List<UploadedFileAnswerInfo> getUploadedFileAnswerList(@Valid GetUploadedFileAnswerListReq req) {
-        List<UploadedFileAnswerInfo> resultList = new ArrayList<UploadedFileAnswerInfo>();
-        /*
-         * //未分组集合 List<ExamFileAnswerTempEntity> uploadedFileAnswerList =
-         * examFileAnswerTempRepo
-         * .findByExamRecordDataIdAndStatus(req.getExamRecordDataId(),
-         * FileAnswerAcknowledgeStatus.CONFIRMED); if (null ==
-         * uploadedFileAnswerList || uploadedFileAnswerList.isEmpty()) { return
-         * resultList; } else { //新集合,只取同一考试记录id和题号下的最新记录
-         * List<ExamFileAnswerTempEntity> newestUploadedFileAnswerList = new
-         * ArrayList<>(); for (ExamFileAnswerTempEntity temp :
-         * uploadedFileAnswerList) { boolean existData =
-         * newestUploadedFileAnswerList.stream().anyMatch(p ->
-         * p.getQuestionOrder().equals(temp.getQuestionOrder()) &&
-         * p.getExamRecordDataId().equals(temp.getExamRecordDataId())); if
-         * (!existData) { newestUploadedFileAnswerList.add(temp); } else {
-         * ExamFileAnswerTempEntity currentTemp =
-         * newestUploadedFileAnswerList.stream().filter(p ->
-         * p.getQuestionOrder().equals(temp.getQuestionOrder()) &&
-         * p.getExamRecordDataId().equals(temp.getExamRecordDataId())).collect(
-         * Collectors.toList()).get(0); //集合中取id最大的值 if (currentTemp.getId() <
-         * temp.getId()) { newestUploadedFileAnswerList.remove(currentTemp);
-         * newestUploadedFileAnswerList.add(temp); } } }
-         *
-         * //按大题号给所有的小题定义序号 List<UploadedFileAnswerInfo> allQuestionAnswerList =
-         * getReSortedQuestionList(req.getExamRecordDataId()); //当前考生已作答的题目集合
-         * List<ExamQuestionEntity> examQuestionsInMongo =
-         * examQuestionRepo.findByExamRecordDataId(req.getExamRecordDataId());
-         * newestUploadedFileAnswerList.forEach(p -> { //过滤出所有的音频题
-         * List<UploadedFileAnswerInfo> uploadedFileAnswerInfoList =
-         * allQuestionAnswerList.stream().filter(pa ->
-         * pa.getOrder().equals(p.getQuestionOrder())).collect(Collectors.toList
-         * ()); if (null != uploadedFileAnswerInfoList &&
-         * !uploadedFileAnswerInfoList.isEmpty()) { UploadedFileAnswerInfo info
-         * = uploadedFileAnswerInfoList.get(0); // //过滤掉重置过答案的数据 case 1
-         * 采用case1还是case2需要找张营确认一下 //
-         * if(!examQuestionsInMongo.stream().anyMatch(pm->pm.getOrder().equals(
-         * info.getOrder()) // && StringUtils.isEmpty(pm.getStudentAnswer()))) {
-         * // info.setExamRecordDataId(p.getExamRecordDataId()); //
-         * //由于有可能学生答案在PC端展示时还未提交到服务器,所以必须用临时表中的数据 //
-         * info.setStudentAnswer(upyunFileUrl+ p.getFilePath()); //
-         * resultList.add(info); // } //必须是考生作答过,且答案不为空,才能展示 case 2 if
-         * (examQuestionsInMongo.stream().anyMatch(pm ->
-         * pm.getOrder().equals(info.getOrder()) &&
-         * !StringUtils.isEmpty(pm.getStudentAnswer()))) {
-         * info.setExamRecordDataId(p.getExamRecordDataId());
-         * //由于有可能学生答案在PC端展示时还未提交到服务器,所以必须用临时表中的数据
-         * info.setStudentAnswer(upyunFileUrl + p.getFilePath());
-         * resultList.add(info); } } }); } //最后按序号从小到大再排一次
-         * resultList.sort(Comparator.comparing(UploadedFileAnswerInfo::getOrder
-         * ));
-         */
-        return resultList;
-    }
-
-    /**
-     * 根据考试记录id获取所有已经重排序号的考试列表
-     *
-     * @param examRecordQuestionsEntity
-     * @return
-     */
-    private List<UploadedFileAnswerInfo> getReSortedQuestionList(ExamRecordQuestionsEntity examRecordQuestionsEntity) {
-        // 所有试题集合,包括非音频题
-        List<UploadedFileAnswerInfo> resultList = new ArrayList<UploadedFileAnswerInfo>();
-
-        if (null == examRecordQuestionsEntity || null == examRecordQuestionsEntity.getExamQuestionEntities()
-                || examRecordQuestionsEntity.getExamQuestionEntities().isEmpty()) {
-            return resultList;
-        }
-
-        List<ExamQuestionEntity> examQuestionAnswerList = examRecordQuestionsEntity.getExamQuestionEntities();
-        // 按大题号分组并排序
-        Map<Integer, List<ExamQuestionEntity>> sortedMainNumberList = examQuestionAnswerList.stream()
-                .sorted(Comparator.comparing(ExamQuestionEntity::getMainNumber))
-                .collect(Collectors.groupingBy(ExamQuestionEntity::getMainNumber, Collectors.toList()));
-        for (Integer mainNum : sortedMainNumberList.keySet()) {
-            // 当前大题下的小题集合
-            List<ExamQuestionEntity> subEmptyExamQuestionAnswerList = sortedMainNumberList.get(mainNum);
-            // 按order对小题进行重新排序
-            subEmptyExamQuestionAnswerList.sort(Comparator.comparing(ExamQuestionEntity::getOrder));
-            for (int i = 0; i < subEmptyExamQuestionAnswerList.size(); i++) {
-                ExamQuestionEntity curExamQuestion = subEmptyExamQuestionAnswerList.get(i);
-                UploadedFileAnswerInfo info = new UploadedFileAnswerInfo();
-                info.setExamRecordDataId(curExamQuestion.getExamRecordDataId());
-                info.setMainNumber(curExamQuestion.getMainNumber());
-                info.setOrder(curExamQuestion.getOrder());
-                // info.setQuestionId(curExamQuestion.getQuestionId());
-                info.setSubNumber(i + 1);// 每个大题下,给小题序号重新赋值
-                resultList.add(info);
-            }
-        }
-        return resultList;
-    }
-
-    private Integer getMaxInterruptNum(Long examId, Long rootOrgId, Long orgId) {
-        GetExamPropertyReq req = new GetExamPropertyReq();
-        req.setExamId(examId);
-        req.setRootOrgId(rootOrgId);
-        req.setOrgId(orgId);
-        req.setKey(ExamProperties.MAX_INTERRUPT_NUM.name());
-        GetExamPropertyResp res = examCloudService.getExamProperty(req);
-        Integer ret = 100;
-        if (StringUtils.isNoneBlank(res.getValue())) {
-            try {
-                ret = Integer.valueOf(res.getValue());
-            } catch (NumberFormatException e) {
-                log.error("MaxInterruptNum is not a number,return default value:100", e);
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * 根据考试记录id判断是否开启环境检测
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    private boolean isTestDev(Long examRecordDataId) {
-        // 用于环境检测的考试记录id
-        SysPropertyCacheBean examRecordDataIdObject = CacheHelper.getSysProperty("oe.testDev.examRecordDataId");
-        // 是否开启了环境检测(请求的考试记录id等于用于环境检测的考试记录时,则认为开启了环境检测)
-        return examRecordDataIdObject.getHasValue()
-                && examRecordDataId.equals(Long.valueOf(examRecordDataIdObject.getValue().toString()));
-    }
-
-}

+ 0 - 323
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamFaceLivenessVerifyServiceImpl.java

@@ -1,323 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.FileDisposeUtil;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.HttpPoolUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamFaceLivenessVerifyEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceVerifyResult;
-import cn.com.qmth.examcloud.core.oe.common.enums.HandInExamType;
-import cn.com.qmth.examcloud.core.oe.common.enums.IsSuccess;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamFaceLivenessVerifyRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.service.GainBaseDataService;
-import cn.com.qmth.examcloud.core.oe.student.bean.GetFaceVerifyTokenInfo;
-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.ExamSessionInfoService;
-import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.StudentCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.SysPropertyCacheBean;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-
-/**
- * @author chenken
- * @date 2018/8/15 15:57
- * @company QMTH
- * @description 活体检测服务实现
- */
-@Service("examFaceLivenessVerifyService")
-public class ExamFaceLivenessVerifyServiceImpl implements ExamFaceLivenessVerifyService {
-
-    private static final Logger log = LoggerFactory.getLogger(ExamFaceLivenessVerifyServiceImpl.class);
-
-    @Autowired
-    private ExamFaceLivenessVerifyRepo examFaceLivenessVerifyRepo;
-
-    @Autowired
-    private ExamRecordDataService examRecordDataService;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-
-    @Autowired
-    private GainBaseDataService gainBaseDataService;
-
-    @Autowired
-    private ExamControlService examControlService;
-
-    @Value("${$facepp.faceid.api_key}")
-    private String faceIdApiKey;
-
-    @Value("${$facepp.faceid.api_secret}")
-    private String faceIdApiSecret;
-
-    @Value("${app.faceid.get_token_url}")
-    private String faceIdGetTokenUrl;
-
-    /**
-     * 第二次人脸检测时间范围
-     */
-    private static final int secondFaceCheckMinute = 4;
-
-    @Override
-    public ExamFaceLivenessVerifyEntity saveFaceVerify(Long examRecordDataId) {
-        ExamFaceLivenessVerifyEntity faceVerify = new ExamFaceLivenessVerifyEntity();
-        faceVerify.setExamRecordDataId(examRecordDataId);
-        faceVerify.setStartTime(new Date());
-        faceVerify.setIsError(false);
-        faceVerify.setOperateNum(1);
-        return examFaceLivenessVerifyRepo.save(faceVerify);
-    }
-
-    @Override
-    public List<ExamFaceLivenessVerifyEntity> listFaceVerifyByExamRecordId(Long examRecordDataId) {
-        if (examRecordDataId == null) {
-            return new ArrayList<ExamFaceLivenessVerifyEntity>();
-        }
-        return examFaceLivenessVerifyRepo.findByExamRecordDataIdOrderById(examRecordDataId);
-    }
-
-    @Override
-    public ExamFaceLivenessVerifyEntity faceIdNotify(String faceIdResultJson) {
-        JSONObject faceIdResultJsonObject;
-        Long faceVerifyId;
-        ExamFaceLivenessVerifyEntity faceVerify = new ExamFaceLivenessVerifyEntity();
-        try {
-            faceIdResultJsonObject = new JSONObject(faceIdResultJson);
-            faceVerifyId = faceIdResultJsonObject.getLong("biz_no");
-            faceVerify = findFaceVerifyById(faceVerifyId);
-            if (faceIdResultJsonObject.has("verify_result")
-                    && faceIdResultJsonObject.get("verify_result") != null
-                    && !"null".equals(faceIdResultJsonObject.get("verify_result") + "")) {
-                JSONObject verifyResultJson = faceIdResultJsonObject.getJSONObject("verify_result");
-                JSONObject result_ref1 = verifyResultJson.getJSONObject("result_ref1");
-                double confidence = result_ref1.getDouble("confidence");
-                //人脸相似度
-                if (confidence > 50D) {
-                    JSONObject livenessResultJson = faceIdResultJsonObject.getJSONObject("liveness_result");
-                    if (livenessResultJson.has("result") && "success".equals(livenessResultJson.getString("result"))) {
-                        faceVerify.setVerifyResult(FaceVerifyResult.VERIFY_SUCCESS);
-                    }
-                } else {
-                    faceVerify.setVerifyResult(FaceVerifyResult.NOT_ONESELF);
-                }
-            } else {
-                faceVerify.setVerifyResult(FaceVerifyResult.VERIFY_FAILED);
-            }
-            faceVerify.setResultJson(faceIdResultJsonObject.toString());
-            faceVerify.setBizId(faceIdResultJsonObject.getString("biz_id"));
-        } catch (Exception e) {
-            log.error("faceIdNotify error", e);
-            faceVerify.setVerifyResult(FaceVerifyResult.VERIFY_FAILED);
-        }
-        long usedTime = System.currentTimeMillis() - faceVerify.getStartTime().getTime();
-        faceVerify.setUsedTime(usedTime);
-        return examFaceLivenessVerifyRepo.save(faceVerify);
-    }
-
-    @Override
-    public GetFaceVerifyTokenInfo getFaceVerifyToken(Long studentId, String bizNo) {
-        GetFaceVerifyTokenInfo getFaceVerifyTokenInfo = new GetFaceVerifyTokenInfo();
-        CloseableHttpResponse httpResponse = null;
-        CloseableHttpClient httpClient = null;
-        try {
-            httpClient = HttpPoolUtil.getHttpClient();
-            HttpPost httpPost = new HttpPost(faceIdGetTokenUrl);
-            File basePhotoFile = getStudentBasePhotoFile(studentId);
-            MultipartEntityBuilder multipartEntityBuilder = getMultipartEntityBuilder(bizNo, basePhotoFile);
-            HttpEntity httpEntity = multipartEntityBuilder.build();
-            httpPost.setEntity(httpEntity);
-            httpResponse = httpClient.execute(httpPost);
-            HttpEntity responseEntity = httpResponse.getEntity();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
-            StringBuffer buffer = new StringBuffer();
-            String str = "";
-            while (StringUtils.isNoneBlank((str = reader.readLine()))) {
-                buffer.append(str);
-            }
-            String result = buffer.toString();
-            basePhotoFile.delete();
-            JSONObject jsonObject = new JSONObject(result);
-            if (jsonObject.has("error_message")) {
-                getFaceVerifyTokenInfo.setSuccess(false);
-                getFaceVerifyTokenInfo.setErrorMsg(jsonObject.getString("error_message"));
-                log.error("getFaceVerifyToken error", result);
-            } else if (jsonObject.has("error")) {
-                getFaceVerifyTokenInfo.setSuccess(false);
-                getFaceVerifyTokenInfo.setErrorMsg(jsonObject.getString("error"));
-                log.error("getFaceVerifyToken error", result);
-            } else if (jsonObject.has("token")) {
-                getFaceVerifyTokenInfo.setSuccess(true);
-                getFaceVerifyTokenInfo.setFaceLivenessToken(jsonObject.getString("token"));
-            }
-            httpPost.abort();
-        } catch (Exception e) {
-            log.error("getFaceVerifyToken error", e);
-            getFaceVerifyTokenInfo.setSuccess(false);
-            getFaceVerifyTokenInfo.setErrorMsg(e.getMessage());
-        } finally {
-            if (httpResponse != null) {
-                try {
-                    httpResponse.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        return getFaceVerifyTokenInfo;
-    }
-
-    @Override
-    public ExamFaceLivenessVerifyEntity findFaceVerifyById(Long id) {
-        if (id == null) {
-            return null;
-        }
-        return GlobalHelper.getEntity(examFaceLivenessVerifyRepo, id, ExamFaceLivenessVerifyEntity.class);
-    }
-
-    @Override
-    public void faceTestTimeOut(Long examRecordDataId) {
-        List<ExamFaceLivenessVerifyEntity> faceVerifies = examFaceLivenessVerifyRepo.findByExamRecordDataIdOrderById(examRecordDataId);
-        ExamFaceLivenessVerifyEntity faceVerify = faceVerifies.get(faceVerifies.size() - 1);
-        if (faceVerify.getVerifyResult() == null) {
-            faceVerify.setVerifyResult(FaceVerifyResult.TIME_OUT);
-            examFaceLivenessVerifyRepo.save(faceVerify);
-        }
-    }
-
-    @Override
-    public void faceTestEndHandle(Long examRecordDataId, Long studentId, String result) {
-        //保存活体检测的结果
-        ExamRecordDataEntity examRecordDataEntity = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        examRecordDataEntity.setFaceVerifyResult(IsSuccess.strToEnum(result) == IsSuccess.FAILED ? IsSuccess.FAILED : IsSuccess.SUCCESS);
-        examRecordDataRepo.save(examRecordDataEntity);
-
-        //如果活体检失败,需要清除会话并自动交卷
-        if (IsSuccess.strToEnum(result) == IsSuccess.FAILED) {
-            examSessionInfoService.deleteExamSessionInfo(studentId);
-            examControlService.handInExam(examRecordDataId, HandInExamType.AUTO);
-        }
-    }
-
-    @Override
-    public ExamFaceLivenessVerifyEntity saveFaceVerifyByExamRecordDataId(Long examRecordDataId) {
-        ExamFaceLivenessVerifyEntity examFaceVerifyEntity = examFaceLivenessVerifyRepo.findErrorFaceVerifyByExamRecordDataId(examRecordDataId);
-        if (examFaceVerifyEntity != null) {
-            examFaceVerifyEntity.setStartTime(new Date());
-            examFaceVerifyEntity.setIsError(false);
-            examFaceVerifyEntity.setErrorMsg(null);
-            examFaceVerifyEntity.setOperateNum(examFaceVerifyEntity.getOperateNum().intValue() + 1);
-            return examFaceLivenessVerifyRepo.save(examFaceVerifyEntity);
-        } else {
-            examFaceVerifyEntity = saveFaceVerify(examRecordDataId);
-        }
-        return examFaceVerifyEntity;
-    }
-
-    private MultipartEntityBuilder getMultipartEntityBuilder(String bizNo, File basePhotoFile) {
-        SysPropertyCacheBean sysProperty = CacheHelper.getSysProperty("app.faceid.notify_url");
-        if (!sysProperty.getHasValue()) {
-            throw new StatusException("200001", "未找到活体检测回调地址的配置信息");
-        }
-        String faceidNotifyUrl = sysProperty.getValue().toString();
-        //详见:https://faceid.com/pages/documents/5680502
-        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
-        multipartEntityBuilder.addTextBody("api_key", faceIdApiKey);
-        multipartEntityBuilder.addTextBody("api_secret", faceIdApiSecret);
-        multipartEntityBuilder.addTextBody("comparison_type", "0");
-        multipartEntityBuilder.addTextBody("return_url", faceidNotifyUrl);
-        multipartEntityBuilder.addTextBody("notify_url", faceidNotifyUrl);
-        multipartEntityBuilder.addTextBody("biz_no", bizNo);
-        multipartEntityBuilder.addTextBody("uuid", bizNo);
-
-        multipartEntityBuilder.addBinaryBody("image_ref1", basePhotoFile);
-        return multipartEntityBuilder;
-    }
-
-    /**
-     * 获取学生底照文件
-     *
-     * @param studentId
-     * @return
-     */
-    private File getStudentBasePhotoFile(Long studentId) {
-        StudentCacheBean studentBean = CacheHelper.getStudent(studentId);
-        String photoUrl = studentBean.getPhotoPath();
-        String photoName = photoUrl.substring(photoUrl.lastIndexOf("/") + 1, photoUrl.length());
-        FileDisposeUtil.saveUrlAs(photoUrl, photoName);
-        return new File(photoName);
-    }
-
-    @Override
-    public Integer getFaceLivenessVerifyMinute(Long rootOrgId, Long orgId, Long examId, Long studentId,
-                                               Long examRecordDataId, Integer heartbeat) {
-        //开启了人脸检测
-        if (FaceBiopsyHelper.isFaceVerify(rootOrgId, examId, studentId)) {
-
-            List<ExamFaceLivenessVerifyEntity> faceLivenessVerifys = listFaceVerifyByExamRecordId(examRecordDataId);
-            //如果没有进行过人脸检测
-            if (faceLivenessVerifys.size() == 0) {
-
-                String faceVerifyStartMinuteStr = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                        studentId, ExamProperties.FACE_VERIFY_START_MINUTE.name()).getValue();
-                Integer faceVerifyStartMinute = Integer.valueOf(faceVerifyStartMinuteStr);
-
-                String faceVerifyEndMinuteStr = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                        studentId, ExamProperties.FACE_VERIFY_END_MINUTE.name()).getValue();
-                Integer faceVerifyEndMinute = Integer.valueOf(faceVerifyEndMinuteStr);
-                //	case1.如果考生已使用的考试时间(即心跳时间)还未达到系统设置的活体检测开始时间,则实际活体检测时间=random(配置结束时间-配置结束时间)-考试已用时间
-                if (heartbeat < faceVerifyStartMinute) {
-                    return CommonUtil.calculationRandomNumber(faceVerifyStartMinute, faceVerifyEndMinute) - heartbeat;
-                }
-                //	case2如果配置开始时间<考生已使用的考试时间<配置结束时间,则实际活体检测时间=random(配置结束时间-考试已用时间)-考试已用时间,如果结果小于1分钟则默认1分钟
-                else if (heartbeat >= faceVerifyStartMinute && heartbeat < faceVerifyEndMinute) {
-                    int verifyTime = CommonUtil.calculationRandomNumber(heartbeat, faceVerifyEndMinute) - heartbeat;
-                    return verifyTime < 1 ? 1 : verifyTime;
-                }
-                //case3如果考试已用时间>配置结束时间,则默认random(1,4)分钟后开始人脸检测
-                else if (heartbeat >= faceVerifyEndMinute) {
-                    return CommonUtil.calculationRandomNumber(1, secondFaceCheckMinute);
-                }
-            } else if (faceLivenessVerifys.size() == 1) {
-                //如果已经人脸检测过一次且未成功,再安排一次检测
-                ExamFaceLivenessVerifyEntity faceVerify = faceLivenessVerifys.get(0);
-                if (faceVerify.getVerifyResult() == null
-                        || faceVerify.getVerifyResult() != FaceVerifyResult.VERIFY_SUCCESS) {
-                    return CommonUtil.calculationRandomNumber(1, secondFaceCheckMinute);
-                }
-            }
-        }
-
-        return null;
-    }
-}

+ 0 - 504
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordDataServiceImpl.java

@@ -1,504 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
-import cn.com.qmth.examcloud.core.oe.common.base.jpa.Searcher;
-import cn.com.qmth.examcloud.core.oe.common.base.jpa.SpecUtils;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.*;
-import cn.com.qmth.examcloud.core.oe.common.enums.*;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.*;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScoreObtainQueueService;
-import cn.com.qmth.examcloud.core.oe.common.service.ExamScorePushQueueService;
-import cn.com.qmth.examcloud.core.oe.common.service.GainBaseDataService;
-import cn.com.qmth.examcloud.core.oe.student.bean.CalculateFaceCheckResultInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.*;
-import cn.com.qmth.examcloud.core.oe.task.api.ExamCaptureQueueCloudService;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import org.apache.commons.lang3.StringUtils;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Service;
-
-import java.math.BigDecimal;
-import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * @author chenken
- * @date 2018/8/15 11:16
- * @company QMTH
- * @description 考试记录数据服务实现
- */
-@Service("examRecordDataService")
-public class ExamRecordDataServiceImpl implements ExamRecordDataService {
-
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-
-    @Autowired
-    private ExamAuditService examAuditService;
-
-    @Autowired
-    private ExamScoreService examScoreService;
-
-    @Autowired
-    private ExamRecordQuestionsService examRecordQuestionsService;
-
-    @Autowired
-    private ExamRecordForMarkingService examRecordForMarkingService;
-
-    @Autowired
-    private ExamCaptureQueueCloudService examCaptureQueueCloudService;
-
-    @Autowired
-    private GainBaseDataService gainBaseDataService;
-
-    @Autowired
-    private ExamScorePushQueueService examScorePushQueueService;
-
-    @Autowired
-    private ExamScoreObtainQueueService examScoreObtainQueueService;
-
-    @Autowired
-    private ExamFaceLivenessVerifyRepo examFaceLivenessVerifyRepo;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamCaptureRepo examCaptureRepo;
-
-    @Autowired
-    private ExamingRecordRepo examingRecordRepo;
-    @Autowired
-    private HandInExamRecordRepo handInExamRecordRepo;
-
-    @Autowired
-    FaceBiopsyRepo faceBiopsyRepo;
-
-    private static final Logger log = LoggerFactory.getLogger(ExamRecordDataServiceImpl.class);
-
-    @Override
-    public ExamRecordDataEntity createExamRecordData(ExamStudentEntity examStudent,
-                                                     ExamBean examBean,
-                                                     CourseBean courseBean,
-                                                     String basePaperId,
-                                                     String paperStructId, Integer examedTimes, Long canExamTimes,
-                                                     Boolean isReExamine, Boolean isFullyObjetive) {
-        ExamRecordDataEntity examRecordData = new ExamRecordDataEntity();
-        examRecordData.setExamId(examBean.getId());
-        examRecordData.setExamType(ExamType.strToEnum(examBean.getExamType()));
-
-        examRecordData.setExamStudentId(examStudent.getExamStudentId());
-        examRecordData.setStudentId(examStudent.getStudentId());
-        examRecordData.setStudentCode(examStudent.getStudentCode());
-        examRecordData.setStudentName(examStudent.getStudentName());
-        examRecordData.setIdentityNumber(examStudent.getIdentityNumber());
-        examRecordData.setOrgId(examStudent.getOrgId());
-        examRecordData.setRootOrgId(examStudent.getRootOrgId());
-
-        examRecordData.setCourseId(courseBean.getId());
-        examRecordData.setCourseLevel(examStudent.getCourseLevel());
-        examRecordData.setBasePaperId(basePaperId);
-
-        examRecordData.setPaperType(examStudent.getPaperType());
-        examRecordData.setPaperStructId(paperStructId);
-
-        examRecordData.setInfoCollector(examStudent.getInfoCollector());
-
-//        examRecordData.setExamRecordDataId(examRecord.getId());
-        examRecordData.setStartTime(new Date());
-        examRecordData.setExamRecordStatus(ExamRecordStatus.EXAM_ING);
-        //已考的考试次数
-        int finalExamedTimes = examedTimes == null ? 0 : examedTimes.intValue();
-        //考试机会
-        int finalCanExamTimes = canExamTimes == null ? 0 : canExamTimes.intValue();
-        boolean finalIsReExamine = isReExamine == null ? false : isReExamine;
-        //如果是重考,则考试次数加1
-        if (finalIsReExamine && finalExamedTimes >= finalCanExamTimes) {
-            finalExamedTimes = finalCanExamTimes + 1;
-        }
-        examRecordData.setExamOrder(finalExamedTimes);
-        examRecordData.setIsAllObjectivePaper(isFullyObjetive);
-        examRecordData.setIsWarn(false);
-        examRecordData.setIsAudit(false);
-        examRecordData.setIsIllegality(false);
-        examRecordData.setIsContinued(false);
-        examRecordData.setIsReexamine(false);
-        examRecordData.setContinuedCount(0);
-        examRecordData.setFaceSuccessCount(0);
-        examRecordData.setFaceTotalCount(0);
-        examRecordData.setFaceFailedCount(0);
-        examRecordData.setFaceStrangerCount(0);
-        if (finalIsReExamine && finalCanExamTimes <= finalExamedTimes) {
-            examRecordData.setIsReexamine(true);
-        }
-        return examRecordDataRepo.save(examRecordData);
-    }
-
-    @Override
-    public void createExamingRecord(Long examRecordDataId, Long studentId, ExamType examType) {
-        ExamingRecordEntity examingRecord = new ExamingRecordEntity();
-        examingRecord.setStudentId(studentId);
-        examingRecord.setId(examRecordDataId);
-        examingRecord.setExamRecordDataId(examRecordDataId);
-        examingRecord.setExamType(examType);
-        examingRecord.setIsContinued(false);
-        examingRecord.setContinuedCount(0);
-        examingRecordRepo.save(examingRecord);
-    }
-
-    @Override
-    public void createHandInExamRecord(Long examRecordDataId, Long studentId) {
-        HandInExamRecordEntity handInExamRecord = new HandInExamRecordEntity();
-        handInExamRecord.setStudentId(studentId);
-        handInExamRecord.setId(examRecordDataId);
-        handInExamRecord.setExamRecordDataId(examRecordDataId);
-        handInExamRecordRepo.save(handInExamRecord);
-    }
-
-    @Override
-    public void deleteExamingRecord(Long examRecordDataId) {
-        examingRecordRepo.deleteById(examRecordDataId);
-    }
-
-    @Override
-    public void deleteHandInExamRecord(Long examRecordDataId) {
-        handInExamRecordRepo.deleteById(examRecordDataId);
-    }
-
-    @Override
-    public List<ExamingRecordEntity> getLimitExamingRecords(Long startId, int limit) {
-        return examingRecordRepo.getLimitExamingRecords(startId, limit);
-    }
-
-    @Override
-    public List<HandInExamRecordEntity> getLimitHandInExamRecords(Long startId, int limit) {
-        return handInExamRecordRepo.getLimitHandInExamRecords(startId, limit);
-    }
-
-    /**
-     * 计算活体检测结果
-     *
-     * @return
-     */
-    @Override
-    public void calculateFaceLivenessVerifyResult(ExamRecordDataEntity examRecordDataEntity) {
-        //活体检测结果
-        IsSuccess faceVerifyResult = examRecordDataEntity.getFaceVerifyResult();
-
-        //如果活检结果不为空,且活检失败,需要更新考试记录的其它状态信息
-        if (faceVerifyResult != null) {
-            if (faceVerifyResult == IsSuccess.FAILED) {
-                setExamRecordByFaceVerifyResult(examRecordDataEntity, IsSuccess.FAILED);
-            }
-            return;
-        }
-
-        //如果考试记录中的活检记录为空,需要再次计算一次,并更新到考试记录中
-        Long examId = examRecordDataEntity.getExamId();
-        Long rootOrgId = examRecordDataEntity.getRootOrgId();
-        Long studentId = examRecordDataEntity.getStudentId();
-
-        //是否进行活体检测
-        if (FaceBiopsyHelper.isFaceVerify(rootOrgId, examId, studentId)) {
-            FaceBiopsyScheme faceBiopsyScheme = FaceBiopsyHelper.getFaceBiopsyScheme(rootOrgId);
-            //新活体检测方案
-            if (faceBiopsyScheme == FaceBiopsyScheme.NEW) {
-                FaceBiopsyEntity faceBiopsy = faceBiopsyRepo.findByExamRecordDataId(examRecordDataEntity.getId());
-
-                //如果活检结果最终为true,则更新考试记录相关属性
-                if (faceBiopsy != null && faceBiopsy.getResult() != null && faceBiopsy.getResult()) {
-                    setExamRecordByFaceVerifyResult(examRecordDataEntity, IsSuccess.SUCCESS);
-                    return;
-                }
-            }
-            //旧活体检测方案
-            else {
-                List<ExamFaceLivenessVerifyEntity> faceVerifies =
-                        examFaceLivenessVerifyRepo.findByExamRecordDataIdOrderById(examRecordDataEntity.getId());
-                if (faceVerifies != null && faceVerifies.size() > 0) {
-                    ExamFaceLivenessVerifyEntity latestFaceVerify = faceVerifies.get(faceVerifies.size() - 1);
-                    //最后一次活检成功,则认为成功,并更新考试记录相关属性
-                    if (latestFaceVerify != null && latestFaceVerify.getVerifyResult() != null &&
-                            latestFaceVerify.getVerifyResult() == FaceVerifyResult.VERIFY_SUCCESS) {
-                        setExamRecordByFaceVerifyResult(examRecordDataEntity, IsSuccess.SUCCESS);
-                        return;
-                    }
-                }
-            }
-            //默认更新为失败
-            setExamRecordByFaceVerifyResult(examRecordDataEntity, IsSuccess.FAILED);
-        }
-    }
-
-    /**
-     * 根据活体检测检测结果设置考试记录相关属性
-     *
-     * @param examRecordDataEntity
-     */
-    private void setExamRecordByFaceVerifyResult(ExamRecordDataEntity examRecordDataEntity, IsSuccess faceVerifyResult) {
-        examRecordDataEntity.setFaceVerifyResult(faceVerifyResult);
-        if (faceVerifyResult == IsSuccess.FAILED) {
-            examRecordDataEntity.setIsIllegality(true);//判定为违纪
-            examRecordDataEntity.setIsWarn(true);    //有警告
-        }
-    }
-
-    /**
-     * 计算人脸检测结果
-     * 相片数=0,系统判断为违纪,自动审核
-     * 考试记录为异常逻辑(进入待审):
-     * 1.陌生人次数>0
-     * 2.face++阈值 = 0 && 百度真实性阈值 > 0
-     * 真实性百分比<百度真实性阈值
-     * 3.face++阈值 > 0 && 百度真实性阈值 = 0
-     * face++成功率<face++阈值
-     * 4.face++阈值 > 0 && 百度真实性阈值 > 0
-     * face++成功率<face++阈值 ||
-     * 真实性百分比<百度真实性阈值
-     *
-     * @param examRecordData
-     * @return
-     */
-    @Override
-    public CalculateFaceCheckResultInfo calculateFaceCheckResult(ExamRecordDataEntity examRecordData) {
-        CalculateFaceCheckResultInfo calculateFaceCheckResultInfo = new CalculateFaceCheckResultInfo();
-        Long rootOrgId = examRecordData.getRootOrgId();
-        Long examId = examRecordData.getExamId();
-        Long orgId = examRecordData.getOrgId();
-        Long studentId = examRecordData.getStudentId();
-
-        //未开启人脸检测
-        if (!FaceBiopsyHelper.isFaceEnable(rootOrgId, examId, studentId)) {
-            examRecordData.setIsWarn(false);
-            calculateFaceCheckResultInfo.setExamRecordData(examRecordData);
-            return calculateFaceCheckResultInfo;
-        }
-        List<ExamCaptureEntity> examCaptureList = examCaptureRepo.findByExamRecordDataId(examRecordData.getId());
-        if (examCaptureList == null || examCaptureList.size() == 0) {
-            examRecordData.setIsWarn(true);//有异常
-            examRecordData.setIsIllegality(true);//违纪
-            calculateFaceCheckResultInfo.setExamRecordData(examRecordData);
-            calculateFaceCheckResultInfo.setIsNoPhotoAndIllegality(true);
-            return calculateFaceCheckResultInfo;
-        }
-        //计算
-        examRecordData = computeFaceCheckData(examRecordData, examCaptureList);
-        //陌生人个数>0
-        if (examRecordData.getFaceStrangerCount() > 0) {
-            examRecordData.setIsWarn(true);
-            calculateFaceCheckResultInfo.setExamRecordData(examRecordData);
-            return calculateFaceCheckResultInfo;
-        }
-        //人脸识别阀值
-        String warnThresholdStr = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                studentId, ExamProperties.WARN_THRESHOLD.name()).getValue();
-        if (CommonUtil.isBlank(warnThresholdStr)) {
-            throw new StatusException("ExamRecordDataServiceImpl-calculateFaceCheckResult-001", ExamProperties.WARN_THRESHOLD.getDesc() + "未设置");
-        }
-        double warnThreshold = Double.parseDouble(warnThresholdStr);
-        //人脸真实性(百度活体检测)通过阀值
-        String liveWarnThresholdStr = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                studentId, ExamProperties.LIVING_WARN_THRESHOLD.name()).getValue();
-        if (CommonUtil.isBlank(liveWarnThresholdStr)) {
-            throw new StatusException("ExamRecordDataServiceImpl-calculateFaceCheckResult-002", ExamProperties.LIVING_WARN_THRESHOLD.getDesc() + "未设置");
-        }
-        double livenessThreshold = Double.parseDouble(liveWarnThresholdStr);
-
-        if (warnThreshold == 0d && livenessThreshold > 0d) {
-            examRecordData.setIsWarn(examRecordData.getBaiduFaceLivenessSuccessPercent() < livenessThreshold);
-        } else if (warnThreshold > 0d && livenessThreshold == 0d) {
-            examRecordData.setIsWarn(examRecordData.getFaceSuccessPercent() < warnThreshold);
-        } else if (warnThreshold > 0d && livenessThreshold > 0d) {
-            boolean isWarn = examRecordData.getFaceSuccessPercent() < warnThreshold ||
-                    examRecordData.getBaiduFaceLivenessSuccessPercent() < livenessThreshold;
-            examRecordData.setIsWarn(isWarn);
-        }
-        calculateFaceCheckResultInfo.setExamRecordData(examRecordData);
-        return calculateFaceCheckResultInfo;
-    }
-
-    /**
-     * 计算人脸检测数据
-     * 陌生人记录数、成功次数、失败次数、成功率
-     *
-     * @param examRecordData
-     * @param examCaptureEntityList
-     * @return
-     */
-    private ExamRecordDataEntity computeFaceCheckData(ExamRecordDataEntity examRecordData, List<ExamCaptureEntity> examCaptureEntityList) {
-        int strangerCount = 0;    // 人脸比较陌生人记录数
-        int succCount = 0;        // 人脸比较成功次数
-        int falseCount = 0;        // 人脸比较失败次数
-        double succPercent = 0d;    // 人脸比较成功率
-        int livenessSuccessCount = 0;//百度活体检测成功次数
-        double livenessSuccessPercent = 0D;//百度活体检测成功率
-        for (ExamCaptureEntity examCaptureEntity : examCaptureEntityList) {
-            if (examCaptureEntity.getIsPass() != null && examCaptureEntity.getIsPass()) {
-                succCount++;
-            } else {
-                falseCount++;
-            }
-            if (examCaptureEntity.getIsStranger() != null && examCaptureEntity.getIsStranger()) {
-                strangerCount++;
-            }
-            livenessSuccessCount += isFacelivenessSuccess(examCaptureEntity);
-        }
-        int allNum = examCaptureEntityList.size();
-        BigDecimal bg = new BigDecimal(((double) succCount / allNum) * 100);
-        succPercent = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();// 人脸比较成功率
-        examRecordData.setFaceTotalCount(allNum);//检测总次数
-        examRecordData.setFaceSuccessPercent(succPercent);//成功率
-        examRecordData.setFaceStrangerCount(strangerCount);//有陌生人的次数
-        examRecordData.setFaceSuccessCount(succCount);//成功次数
-        examRecordData.setFaceFailedCount(falseCount);//失败次数
-        //人脸关键点坐标相似比率-废弃
-        //examRecordDataEntity.setFaceLandmarkVal(analyseLankmark(examCaptureEntityList));
-        BigDecimal livenessSuccessBg = new BigDecimal(((double) livenessSuccessCount / allNum) * 100);
-        livenessSuccessPercent = livenessSuccessBg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();//百度活体检测成功率
-        examRecordData.setBaiduFaceLivenessSuccessPercent(livenessSuccessPercent);
-        return examRecordData;
-    }
-
-    private int isFacelivenessSuccess(ExamCaptureEntity examCapture) {
-        if (StringUtils.isNotBlank(examCapture.getFacelivenessResult())) {
-            String livenessJson = examCapture.getFacelivenessResult();
-            JSONObject jsonObject;
-            try {
-                jsonObject = new JSONObject(livenessJson);
-                if (jsonObject.has("error_code") && jsonObject.getInt("error_code") == 0 && jsonObject.has("result")) {
-                    JSONObject resultJson = jsonObject.getJSONObject("result");
-                    if (resultJson.has("face_liveness")) {
-                        double faceLivenessVal = resultJson.getDouble("face_liveness");
-                        double baiduFacelivenessThreshold = Double.parseDouble(PropertyHolder.getString("$baidu.faceliveness.threshold"));
-                        if (faceLivenessVal > baiduFacelivenessThreshold) {
-                            return 1;
-                        }
-                    }
-                }
-            } catch (JSONException e) {
-                e.printStackTrace();
-                return 0;
-            }
-
-        }
-        return 0;
-    }
-
-    @Override
-    public List<ExamRecordDataEntity> findByStatusAndExamTypeIn(ExamRecordStatus examRecordStatus, List<String> examTypeList) {
-        Searcher searchers = new Searcher().in("examRecord.examType", examTypeList)
-                .eq("examRecordStatus", examRecordStatus.name());
-        Specification<ExamRecordDataEntity> spec = SpecUtils.buildSearchers(ExamRecordDataEntity.class, searchers.build());
-        return examRecordDataRepo.findAll(spec);
-    }
-
-    @Override
-    public List<ExamRecordDataEntity> findValidExamRecordDataByExamStudentId(Long examStudentId) {
-        Searcher searchers = new Searcher().eq("examRecord.examStudentId", examStudentId);
-        Specification<ExamRecordDataEntity> spec = SpecUtils.buildSearchers(ExamRecordDataEntity.class, searchers.build());
-        List<ExamRecordDataEntity> examRecordDataList = examRecordDataRepo.findAll(spec);
-        //第一次过滤:正常结束或者被系统处理的
-        List<ExamRecordDataEntity> firstFilteredexamRecordDataList = examRecordDataList.stream().filter(examRecordData -> {
-            return examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_END
-                    || examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_OVERDUE;
-        }).collect(Collectors.toList());
-        /**
-         * 第二次过滤:
-         * 1.没有违纪的
-         * 2.无异常或有异常已审核通过
-         */
-        if (firstFilteredexamRecordDataList != null && firstFilteredexamRecordDataList.size() > 0) {
-            return firstFilteredexamRecordDataList.stream().filter(examRecordData -> {
-                return !examRecordData.getIsIllegality() &&
-                        (!examRecordData.getIsWarn() || (examRecordData.getIsWarn() && examRecordData.getIsAudit()));
-            }).collect(Collectors.toList());
-        }
-
-        return null;
-    }
-
-    @Override
-    public ExamRecordDataEntity createOfflineExamRecordData(ExamStudentEntity examStudent,
-                                                            ExamBean examBean,
-                                                            CourseBean courseBean,
-                                                            String basePaperId,
-                                                            String paperStructId, Boolean fullyObjective) {
-        ExamRecordDataEntity examRecordDataEntity = new ExamRecordDataEntity();
-        examRecordDataEntity.setExamId(examBean.getId());
-        examRecordDataEntity.setExamType(ExamType.strToEnum(examBean.getExamType()));
-
-        examRecordDataEntity.setExamStudentId(examStudent.getExamStudentId());
-        examRecordDataEntity.setStudentId(examStudent.getStudentId());
-        examRecordDataEntity.setStudentCode(examStudent.getStudentCode());
-        examRecordDataEntity.setStudentName(examStudent.getStudentName());
-        examRecordDataEntity.setIdentityNumber(examStudent.getIdentityNumber());
-        examRecordDataEntity.setOrgId(examStudent.getOrgId());
-        examRecordDataEntity.setRootOrgId(examStudent.getRootOrgId());
-
-        examRecordDataEntity.setCourseId(courseBean.getId());
-        examRecordDataEntity.setCourseLevel(examStudent.getCourseLevel());
-        examRecordDataEntity.setBasePaperId(basePaperId);
-
-        examRecordDataEntity.setPaperType(examStudent.getPaperType());
-        examRecordDataEntity.setPaperStructId(paperStructId);
-
-        examRecordDataEntity.setInfoCollector(examStudent.getInfoCollector());
-//        examRecordDataEntity.setExamRecordDataId(examRecord.getId());
-        examRecordDataEntity.setStartTime(new Date());
-        examRecordDataEntity.setExamRecordStatus(ExamRecordStatus.EXAM_ING);
-        examRecordDataEntity.setExamOrder(1);
-        examRecordDataEntity.setIsAllObjectivePaper(fullyObjective);
-        return examRecordDataRepo.save(examRecordDataEntity);
-    }
-
-    @Override
-    public ExamRecordDataEntity examRecordAutoAudit(Boolean isNoPhotoAndIllegality, ExamRecordDataEntity examRecordData) {
-        //无照片违纪自动审核
-        if (isNoPhotoAndIllegality != null && isNoPhotoAndIllegality) {
-            examAuditService.saveExamAuditByNoPhoto(examRecordData.getId());
-            examRecordData.setIsAudit(true);
-        } else {
-            //活体检测失败违纪自动审核
-            if (examRecordData.getFaceVerifyResult() != null
-                    && examRecordData.getFaceVerifyResult() == IsSuccess.FAILED
-                    && examRecordData.getIsIllegality()) {
-                examAuditService.saveExamAuditByFaceVerifyFailed(examRecordData.getId(), examRecordData.getRootOrgId());
-                examRecordData.setIsAudit(true);
-            }
-        }
-        return examRecordData;
-    }
-
-    @Override
-    public boolean isExamRecordEnded(ExamRecordDataEntity examRecordData) {
-        //如果考试记录状态为已处理,则直接返回true.
-        if (examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_END ||
-                examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_OVERDUE ||
-                examRecordData.getExamRecordStatus() == ExamRecordStatus.EXAM_INVALID) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean isExamRecordEnded(Long examRecordDataId) {
-        log.debug("进入isExamRecordEnded方法,examRecordDataId=" + examRecordDataId);
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        if (examRecordData == null) {
-            throw new StatusException("", "找不到id为:" + examRecordDataId + "的考试记录");
-        }
-        return isExamRecordEnded(examRecordData);
-    }
-}

+ 0 - 117
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamRecordForMarkingServiceImpl.java

@@ -1,117 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordForMarkingEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordForMarkingRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreRepo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordForMarkingService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import main.java.com.UpYun;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import java.util.Date;
-
-@Service("examRecordForMarkingService")
-public class ExamRecordForMarkingServiceImpl implements ExamRecordForMarkingService {
-
-	@Autowired
-	private ExamRecordQuestionsService examRecordQuestionsService;
-	
-	@Autowired
-	private ExamRecordForMarkingRepo examRecordForMarkingRepo;
-	
-	@Autowired
-	private ExamRecordDataRepo examRecordDataRepo;
-	
-	@Autowired
-	private ExamScoreRepo examScoreRepo;
-
-	@Value("${$upyun.site.1.bucketName}")
-    private String bucketName;
-	
-	@Value("${$upyun.site.1.userName}")
-	private String userName;
-	
-	@Value("${$upyun.site.1.password}")
-	private String password;
-
-	@Value("${$upyun.site.1.domain}")
-	private String upyunFileUrl;
-
-	@Override
-	public void saveExamRecordForMarking(Long examRecordDataId) {
-		ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-		ExamScoreEntity examScore = examScoreRepo.findByExamRecordDataId(examRecordDataId);
-		saveExamRecordForMarking(examRecordData, examScore.getObjectiveScore());
-	}
-
-	@Override
-	public void saveExamRecordForMarking(ExamRecordDataEntity examRecordData,double objectiveQuestionTotalScore) {
-		//全客观题卷
-    	if(examRecordData.getIsAllObjectivePaper()){
-    		return;
-    	}
-    	//违纪
-    	if(examRecordData.getIsIllegality()){
-    		return;
-    	}
-    	//有警告未审核
-    	if(examRecordData.getIsWarn()&&!examRecordData.getIsAudit()){
-    		return;
-    	}
-    	//已经存在
-    	ExamRecordForMarkingEntity examRecordForMarkingExists = examRecordForMarkingRepo.findByExamRecordDataId(examRecordData.getId());
-    	if(examRecordForMarkingExists != null){
-    		return;
-    	}
-
-
-		ExamRecordForMarkingEntity examRecordForMarking = new ExamRecordForMarkingEntity();
-        examRecordForMarking.setExamId(examRecordData.getExamId());
-        examRecordForMarking.setExamRecordDataId(examRecordData.getId());
-        examRecordForMarking.setExamStudentId(examRecordData.getExamStudentId());
-        examRecordForMarking.setBasePaperId(examRecordData.getBasePaperId());
-        examRecordForMarking.setPaperType(examRecordData.getPaperType());
-        examRecordForMarking.setCourseId(examRecordData.getCourseId());
-        examRecordForMarking.setObjectiveScore(objectiveQuestionTotalScore);
-
-        int subjectiveAnswerLength = examRecordQuestionsService.calculationSubjectiveAnswerLength(examRecordData.getId());
-        examRecordForMarking.setSubjectiveAnswerLength(subjectiveAnswerLength);
-
-        examRecordForMarkingRepo.save(examRecordForMarking);
-	}
-
-	@Override
-	public void saveOffLineExamRecordForMarking(ExamRecordDataEntity examRecordData,String offlineFileName,String fileUrl) {
-		ExamRecordForMarkingEntity examRecordForMarking = examRecordForMarkingRepo.findByExamRecordDataId(examRecordData.getId());
-		if(examRecordForMarking == null){
-			examRecordForMarking = new ExamRecordForMarkingEntity();
-			examRecordForMarking.setCreationTime(new Date());
-		}else{
-			//将原文件删掉
-			UpYun upyun = new UpYun(bucketName,userName,password);
-			String offlineFileUrl = examRecordForMarking.getOfflineFileUrl();
-			offlineFileUrl = offlineFileUrl.replace(upyunFileUrl,"");
-			upyun.deleteFile(offlineFileUrl);
-		}
-
-        examRecordForMarking.setExamId(examRecordData.getExamId());
-        examRecordForMarking.setExamRecordDataId(examRecordData.getId());
-        examRecordForMarking.setExamStudentId(examRecordData.getExamStudentId());
-        examRecordForMarking.setCourseId(examRecordData.getCourseId());
-        examRecordForMarking.setOfflineFileUrl(fileUrl);
-        examRecordForMarking.setOfflineFileName(offlineFileName);
-        examRecordForMarking.setObjectiveScore(0D);
-        examRecordForMarking.setSubjectiveAnswerLength(0);
-        examRecordForMarking.setBasePaperId(examRecordData.getBasePaperId());
-        examRecordForMarking.setPaperType(examRecordData.getPaperType());
-        examRecordForMarking.setUpdateTime(new Date());
-        examRecordForMarkingRepo.save(examRecordForMarking);
-	}
-	
-}

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

@@ -1,33 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordPaperStructEntity;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordPaperStructRepo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-/**
- * 
- * @author  	chenken
- * @date    	2018年9月1日 下午3:01:30
- * @company 	QMTH
- * @description 考试记录-试卷结构服务实现
- */
-@Service("examRecordPaperStructService")
-public class ExamRecordPaperStructServiceImpl implements ExamRecordPaperStructService{
-
-	@Autowired
-	private ExamRecordDataRepo examRecordDataRepo;
-	
-	@Autowired
-	private ExamRecordPaperStructRepo examRecordPaperStructRepo;
-	@Override
-	public ExamRecordPaperStructEntity getExamRecordPaperStruct(Long examRecordDataId) {
-		ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo,examRecordDataId,ExamRecordDataEntity.class);
-		return GlobalHelper.getEntity(examRecordPaperStructRepo,examRecordData.getPaperStructId(),ExamRecordPaperStructEntity.class);
-	}
-
-}

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

@@ -1,231 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.commons.util.JsonUtil;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.QuestionTypeUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamQuestionEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordQuestionsEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamType;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordQuestionsRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamSessionInfo;
-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.ExamSessionInfoService;
-import cn.com.qmth.examcloud.core.questions.api.ExtractConfigCloudService;
-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.web.helpers.GlobalHelper;
-import com.alibaba.fastjson.JSON;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author chenken
- * @date 2018年9月5日 下午3:23:26
- * @company QMTH
- * @description 考试作答归档服务实现
- */
-@Service("examRecordQuestionsService")
-public class ExamRecordQuestionsServiceImpl implements ExamRecordQuestionsService {
-
-    @Autowired
-    private ExamRecordQuestionsRepo examRecordQuestionsRepo;
-
-    @Autowired
-    private ExamScoreRepo examScoreRepo;
-
-    @Autowired
-    private RedisTemplate<String, Object> redisTemplate;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-
-    @Autowired
-    private ExtractConfigCloudService extractConfigCloudService;
-
-    @Autowired
-    private ExamStudentRepo examStudentRepo;
-
-    //本地题干缓存,最大200道题,默认缓存120秒
-    private Cache<String, String> questionContentCache = CacheBuilder.newBuilder().maximumSize(200)
-            .expireAfterWrite(120, TimeUnit.SECONDS).build();
-
-//    @Value("${exam_question_key_prefix}")
-//    private String examQuestionKeyPrefix;
-
-    @Override
-    public Integer calculationSubjectiveAnswerLength(Long examRecordDataId) {
-        ExamRecordQuestionsEntity examRecordQuesitonsEntity = getExamRecordQuestionsAndFixExamRecordDataIfNecessary(examRecordDataId);
-        if (examRecordQuesitonsEntity == null || examRecordQuesitonsEntity.getExamQuestionEntities() == null ||
-                examRecordQuesitonsEntity.getExamQuestionEntities().isEmpty()) {
-            return 0;
-        }
-        List<ExamQuestionEntity> examQuestionList = examRecordQuesitonsEntity.getExamQuestionEntities();
-
-		/*ExamRecordQuestionsEntity examRecordQuestions = examRecordQuestionsRepo.findByExamRecordDataId(examRecordDataId);
-		List<ExamQuestionEntity> examQuestionEntities = examRecordQuestions.getExamQuestionEntities();*/
-        int answerLength = 0;
-        for (ExamQuestionEntity examQuestionEntity : examQuestionList) {
-            if (!QuestionTypeUtil.isObjectiveQuestion(examQuestionEntity.getQuestionType())
-                    && examQuestionEntity.getStudentAnswer() != null) {
-                answerLength += examQuestionEntity.getStudentAnswer().length();
-            }
-        }
-        return answerLength;
-    }
-
-    @Override
-    public ExamRecordQuestionsEntity createExamRecordQuestions(Long examRecordDataId, DefaultPaper defaultPaper) {
-        ExamRecordQuestionsEntity examRecordQuestionsEntity = new ExamRecordQuestionsEntity();
-
-        List<ExamQuestionEntity> examQuestionEntityList = new ArrayList<ExamQuestionEntity>();
-        List<DefaultQuestionGroup> defaultQuestionGroups = defaultPaper.getQuestionGroupList();
-        int order = 0;
-        for (int i = 0; i < defaultQuestionGroups.size(); i++) {
-            DefaultQuestionGroup defaultQuestionGroup = defaultQuestionGroups.get(i);
-            List<DefaultQuestionStructureWrapper> defaultQuestionStructureWrappers = defaultQuestionGroup.getQuestionWrapperList();
-            for (DefaultQuestionStructureWrapper defaultQuestionStructureWrapper : defaultQuestionStructureWrappers) {
-                List<DefaultQuestionUnitWrapper> questionUnitWrapperList = defaultQuestionStructureWrapper.getQuestionUnitWrapperList();
-                for (DefaultQuestionUnitWrapper defaultQuestionUnitWrapper : questionUnitWrapperList) {
-                    ExamQuestionEntity examQuestionEntity = new ExamQuestionEntity();
-                    examQuestionEntity.setExamRecordDataId(examRecordDataId);
-                    examQuestionEntity.setMainNumber(i + 1);
-                    examQuestionEntity.setOrder(++order);
-                    examQuestionEntity.setQuestionId(defaultQuestionStructureWrapper.getQuestionId());
-                    examQuestionEntity.setQuestionScore(defaultQuestionUnitWrapper.getQuestionScore());
-                    examQuestionEntity.setQuestionType(defaultQuestionUnitWrapper.getQuestionType());
-                    examQuestionEntity.setOptionPermutation(defaultQuestionUnitWrapper.getOptionPermutation());
-                    examQuestionEntity.setAudioPlayTimes(null);
-                    examQuestionEntity.setAnswerType(defaultQuestionUnitWrapper.getAnswerType());
-
-                    examQuestionEntityList.add(examQuestionEntity);
-                }
-            }
-        }
-
-        examRecordQuestionsEntity.setExamQuestionEntities(examQuestionEntityList);
-        examRecordQuestionsEntity.setExamRecordDataId(examRecordDataId);
-        examRecordQuestionsEntity.setCreationTime(new Date());
-        ExamRecordQuestionsEntity saveResult = examRecordQuestionsRepo.save(examRecordQuestionsEntity);
-//        redisTemplate.opsForList().leftPushAll(examQuestionKeyPrefix+examRecordDataId,examQuestionEntityList);
-        return saveResult;
-    }
-
-    /**
-     * 获取考试作答记录并修复考试记录数据(如有必要)
-     *
-     * @param examRecordData 考试记录
-     * @return
-     */
-    @Override
-    public ExamRecordQuestionsEntity getExamRecordQuestionsAndFixExamRecordDataIfNecessary(ExamRecordDataEntity examRecordData) {
-        if (examRecordData == null) {
-            throw new StatusException("201101", "examRecordData参数不允许为空");
-        }
-        Long examRecordDataId = examRecordData.getId();
-        String examRecordQuestionId = examRecordData.getExamRecordQuestionsId();
-
-        //如果考试作答记录id不为空,则根据id查询考试作答记录
-        if (StringUtils.isNotEmpty(examRecordQuestionId)) {
-            return GlobalHelper.getEntity(examRecordQuestionsRepo, examRecordQuestionId,
-                    ExamRecordQuestionsEntity.class);
-        }
-        //如果考试作答记录id为空,则根据考试记录id获取考试作答记录,并将考试作答记录id保存至examRecordData表中
-        else {
-            ExamRecordQuestionsEntity examRecordQuestionsEntity = examRecordQuestionsRepo.findByExamRecordDataId(examRecordDataId);
-
-            //将考试作答记录id保存至examRecordData表中,目的:纠正历史数据
-            examRecordDataRepo.updateExamRecordDataQuestionIdById(examRecordQuestionsEntity.getId(), examRecordData.getId());
-            return examRecordQuestionsEntity;
-        }
-    }
-
-    @Override
-    public ExamRecordQuestionsEntity getExamRecordQuestionsAndFixExamRecordDataIfNecessary(Long examRecordDataId) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo,
-                examRecordDataId, ExamRecordDataEntity.class);
-        return getExamRecordQuestionsAndFixExamRecordDataIfNecessary(examRecordData);
-    }
-
-    @Override
-    public void submitQuestionAnswer(Long studentId, List<ExamStudentQuestionInfo> examQuestionInfos) {
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (null == examSessionInfo) {
-            throw new StatusException("200001", "考试会话已过期");
-        }
-        long examRecordDataId = examSessionInfo.getExamRecordDataId();
-
-        ExamRecordQuestionsEntity examRecordQuesitonsEntity = getExamRecordQuestionsAndFixExamRecordDataIfNecessary(examRecordDataId);
-        List<ExamQuestionEntity> examQuestionEntities = examRecordQuesitonsEntity.getExamQuestionEntities();
-
-        for (ExamStudentQuestionInfo examQuestionInfo : examQuestionInfos) {
-            for (ExamQuestionEntity examQuestion : examQuestionEntities) {
-                if (examQuestion.getOrder().equals(examQuestionInfo.getOrder())) {
-                    examQuestion.setStudentAnswer(examQuestionInfo.getStudentAnswer());
-                    examQuestion.setIsSign(examQuestionInfo.getIsSign());
-                    examQuestion.setIsAnswer(StringUtils.isNotBlank(examQuestion.getStudentAnswer()));
-                    examQuestion.setAudioPlayTimes(examQuestionInfo.getAudioPlayTimes());
-                    break;
-                }
-            }
-        }
-        examRecordQuestionsRepo.save(examRecordQuesitonsEntity);
-    }
-
-    @Override
-    public String getQuestionContent(Long studentId, String questionId) {
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("100002", "考试已结束,不允许获取试题内容");
-        }
-
-        //本地缓存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;
-        }
-        //如果本地缓存不存在,则从redis中获取, 并在本地缓存存在存储一份
-        else {
-            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;
-        }
-    }
-}

+ 0 - 259
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamScoreServiceImpl.java

@@ -1,259 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.oe.common.base.utils.QuestionTypeUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamQuestionEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordQuestionsEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordQuestionsRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamSessionInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.ObjectiveScoreInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordDataService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordQuestionsService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamScoreService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamSessionInfoService;
-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.QuestionAnswerCacheBean;
-import cn.com.qmth.examcloud.web.redis.RedisClient;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-
-/**
- * @author chenken
- * @date 2018年9月3日 上午10:02:38
- * @company QMTH
- * @description 考试记录得分(总分)服务实现
- */
-@Service("examScoreService")
-public class ExamScoreServiceImpl implements ExamScoreService {
-
-    @Autowired
-    private ExamScoreRepo examScoreRepo;
-
-    @Autowired
-    private ExamRecordQuestionsService examRecordQuestionsService;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamRecordDataService examRecordDataService;
-
-    @Autowired
-    private RedisTemplate redisTemplate;
-    @Autowired
-    RedisClient redisClient;
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-    @Autowired
-    private ExamRecordQuestionsRepo examRecordQuestionsRepo;
-
-    private static final Logger log = LoggerFactory.getLogger(ExamScoreServiceImpl.class);
-
-    /**
-     * 保存考试总成绩
-     *
-     * @param examRecordData
-     * @return
-     */
-    @Override
-    public ExamScoreEntity saveExamScore(ExamRecordDataEntity examRecordData) {
-        long st = System.currentTimeMillis();
-        long startTime = System.currentTimeMillis();
-        //获取考试作答记录并修复考试记录数据(如有必要)
-        ExamRecordQuestionsEntity examRecordQuestionsEntity = examRecordQuestionsService.
-                getExamRecordQuestionsAndFixExamRecordDataIfNecessary(examRecordData);
-        if (log.isDebugEnabled()) {
-            log.debug("1 [SAVE_EXAM_SCORE]获取考试作答记录并修复考试记录数据耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        // 考生作答记录明细
-        List<ExamQuestionEntity> examQuestionList = examRecordQuestionsEntity.getExamQuestionEntities();
-
-        double studentObjectiveScoreTotal = 0d;//客观题总分
-        int succQuestionNum = 0;//答题正确数
-        int objectiveQuestionsNum = 0;//客观题总数
-        //是否需要更新客观题答案
-        Boolean needUpdateObjectiveAnswer=false;
-        //获取考试会话
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(examRecordData.getStudentId());
-        for (int i = 0; i < examQuestionList.size(); i++) {
-            ExamQuestionEntity examQuestionEntity = examQuestionList.get(i);
-            String courseCode;
-            //自动服务交卷时,会话可能已经过期,需要重新查询课程
-            if (examSessionInfo == null) {
-                CourseCacheBean courseCache = CacheHelper.getCourse(examRecordData.getCourseId());
-                courseCode = courseCache.getCode();
-            }
-            //会话未过期,可以直接从会话中获取
-            else {
-                courseCode = examSessionInfo.getCourseCode();
-            }
-
-            //只计算客观点题分数
-            if (QuestionTypeUtil.isObjectiveQuestion(examQuestionEntity.getQuestionType())) {
-                objectiveQuestionsNum++;
-
-                //如果标准答案为空,则更新标准答案
-                if (StringUtils.isEmpty(examQuestionEntity.getCorrectAnswer())) {
-                    needUpdateObjectiveAnswer=true;
-                    updateCorrectAnswer(examRecordData.getExamId(),courseCode,examRecordData.getPaperType(),
-                            examQuestionEntity.getQuestionId(),examRecordQuestionsEntity);
-                }
-
-                if (examQuestionEntity.getStudentAnswer() != null
-                        && examQuestionEntity.getCorrectAnswer() != null
-                        && examQuestionEntity.getStudentAnswer().equals(examQuestionEntity.getCorrectAnswer())) {
-                    //小题分数
-                    double questionScore = examQuestionEntity.getQuestionScore().doubleValue();
-                    BigDecimal bigDecimalQuestionScore = new BigDecimal(Double.toString(questionScore));
-                    BigDecimal bigDecimalObjectiveScoreTotal = new BigDecimal(Double.toString(studentObjectiveScoreTotal));
-                    studentObjectiveScoreTotal = bigDecimalQuestionScore.add(bigDecimalObjectiveScoreTotal).doubleValue();
-                    succQuestionNum++;
-                }
-            }
-        }
-        if (needUpdateObjectiveAnswer){
-            examRecordQuestionsRepo.save(examRecordQuestionsEntity);
-        }
-
-        double objectiveAccuracy = 0;//客观题答题正确率
-        if (succQuestionNum > 0 && objectiveQuestionsNum > 0) {
-            objectiveAccuracy = Double.valueOf(new DecimalFormat("#.00").format(succQuestionNum * 100D / objectiveQuestionsNum));
-        }
-
-        Long examRecordDataId = examRecordData.getId();
-
-        startTime = System.currentTimeMillis();
-        //如果考试成绩不存在,则新增,否则更新数据
-        ExamScoreEntity examScoreEntity = examScoreRepo.findByExamRecordDataId(examRecordDataId);
-        if (log.isDebugEnabled()) {
-            log.debug("2 [SAVE_EXAM_SCORE]根据考试记录id获取考试分数数据耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        if (examScoreEntity == null) {
-            examScoreEntity = new ExamScoreEntity();
-            examScoreEntity.setExamRecordDataId(examRecordDataId);
-        }
-        examScoreEntity.setObjectiveScore(studentObjectiveScoreTotal);
-        examScoreEntity.setObjectiveAccuracy(objectiveAccuracy);
-        examScoreEntity.setTotalScore(studentObjectiveScoreTotal);//交卷时,总分=客观分得分
-
-        startTime = System.currentTimeMillis();
-        //保存考试成绩
-        ExamScoreEntity resultEntity = examScoreRepo.save(examScoreEntity);
-        if (log.isDebugEnabled()) {
-            log.debug("3 [SAVE_EXAM_SCORE]保存考试成绩耗时:" + (System.currentTimeMillis() - startTime) + " ms");
-        }
-
-        log.debug("4 [SAVE_EXAM_SCORE]合计 耗时:" + (System.currentTimeMillis() - st) + " ms");
-
-        return resultEntity;
-    }
-
-    /**
-     * 更新客观题答案
-     * @param examId
-     * @param courseCode
-     * @param paperType
-     * @param questionId
-     * @param examRecordQuestionsEntity
-     * @return
-     */
-    private void updateCorrectAnswer(Long examId, String courseCode, String paperType,
-                                    String questionId,ExamRecordQuestionsEntity examRecordQuestionsEntity) {
-        //更新客观题答案
-        QuestionAnswerCacheBean questionAnswerCache = CacheHelper.getQuestionAnswer(questionId);
-        List<String> rightAnswerList = questionAnswerCache.getRightAnswers();
-        //最小维度的小题单元集合
-        List<ExamQuestionEntity> questionUnitList = examRecordQuestionsEntity.getExamQuestionEntities().stream().
-                filter(p -> p.getQuestionId().equals(questionId)).
-                sorted((o1, o2) -> o1.getOrder().intValue() - o2.getOrder().intValue()).collect(Collectors.toList());
-
-        for (int i = 0; i < questionUnitList.size(); i++) {
-            ExamQuestionEntity examQuestionEntity = questionUnitList.get(i);
-            examQuestionEntity.setCorrectAnswer(rightAnswerList.get(i));
-        }
-    }
-
-    @Override
-    public void createExamScoreWithOffline(Long examRecordDataId) {
-        ExamScoreEntity examScoreEntity = new ExamScoreEntity();
-        examScoreEntity.setExamRecordDataId(examRecordDataId);
-        examScoreEntity.setObjectiveScore(0D);
-        examScoreEntity.setSubjectiveScore(0D);
-        examScoreEntity.setTotalScore(0D);
-        examScoreRepo.save(examScoreEntity);
-    }
-
-    @Override
-    public List<ExamScoreEntity> queryExamScoreListByExamStudentId(Long examStudentId) {
-        List<ExamRecordDataEntity> examRecordDataEntities = examRecordDataService.findValidExamRecordDataByExamStudentId(examStudentId);
-        if (examRecordDataEntities == null || examRecordDataEntities.size() == 0) {
-            return null;
-        }
-        List<Long> examRecordDataIds = examRecordDataEntities.stream().map(ExamRecordDataEntity::getId).collect(Collectors.toList());
-        return examScoreRepo.findByExamRecordDataIdIn(examRecordDataIds);
-    }
-
-    @Override
-    public List<ObjectiveScoreInfo> queryObjectiveScoreList(Long examStudentId) {
-        List<ExamRecordDataEntity> examRecordDataList = examRecordDataRepo.findByExamStudentId(examStudentId);
-        //过滤已完成的考试记录(包括违纪的)
-        examRecordDataList = examRecordDataList.stream().filter((o -> {
-            return o.getExamRecordStatus() == ExamRecordStatus.EXAM_END ||
-                    o.getExamRecordStatus() == ExamRecordStatus.EXAM_OVERDUE ||
-                    o.getExamRecordStatus() == ExamRecordStatus.EXAM_HAND_IN ||
-                    o.getExamRecordStatus() == ExamRecordStatus.EXAM_AUTO_HAND_IN;
-        })).collect(Collectors.toList());
-
-        List<ObjectiveScoreInfo> objectiveScoreInfoList = new ArrayList<ObjectiveScoreInfo>();
-        for (ExamRecordDataEntity examRecordDataEntity : examRecordDataList) {
-            ObjectiveScoreInfo objectiveScoreInfo = new ObjectiveScoreInfo();
-            objectiveScoreInfo.setExamRecordDataId(examRecordDataEntity.getId());
-            objectiveScoreInfo.setExamOrder(examRecordDataEntity.getExamOrder());
-            objectiveScoreInfo.setStartTime(examRecordDataEntity.getStartTime());
-            objectiveScoreInfo.setEndTime(examRecordDataEntity.getEndTime());
-
-            //如果考试没有结束,则只能返回部分数据
-            if (!examRecordDataService.isExamRecordEnded(examRecordDataEntity)) {
-                objectiveScoreInfo.setIsExamEnded(false);
-                objectiveScoreInfoList.add(objectiveScoreInfo);
-                continue;
-            } else {
-                objectiveScoreInfo.setIsExamEnded(true);
-            }
-
-            if (!examRecordDataEntity.getIsIllegality()) {
-                if (examRecordDataEntity.getIsWarn() && !examRecordDataEntity.getIsAudit()) {
-                    objectiveScoreInfo.setIsAuditing(true);
-                } else if (!examRecordDataEntity.getIsWarn() || (examRecordDataEntity.getIsWarn() && examRecordDataEntity.getIsAudit())) {
-                    ExamScoreEntity examScore = examScoreRepo.findByExamRecordDataId(examRecordDataEntity.getId());
-                    objectiveScoreInfo.setIsAuditing(false);
-                    objectiveScoreInfo.setObjectiveScore(examScore.getObjectiveScore());
-                }
-                objectiveScoreInfo.setIsIllegality(false);
-            } else {
-                objectiveScoreInfo.setIsIllegality(true);
-            }
-            objectiveScoreInfoList.add(objectiveScoreInfo);
-        }
-        return objectiveScoreInfoList;
-    }
-
-}

+ 0 - 46
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamSessionInfoServiceImpl.java

@@ -1,46 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamSessionInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamSessionInfoService;
-import cn.com.qmth.examcloud.web.redis.RedisClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-/**
- * @author chenken
- * @date 2018/8/15 9:24
- * @company QMTH
- * @description 考试会话服务实现
- */
-@Service("examSessionInfoService")
-public class ExamSessionInfoServiceImpl implements ExamSessionInfoService {
-
-    @Autowired
-    private RedisClient redisClient;
-    
-    @Value("${exam_redis_key_prefix}")
-    private String examRedisKeyPrefix;
-
-    private static final Logger log = LoggerFactory.getLogger(ExamSessionInfoServiceImpl.class);
-
-    @Override
-    public void saveExamSessionInfo(Long studentId, ExamSessionInfo examSessionInfo, int timeout) {
-        log.debug("11.4.1 进入开始保存考试会话方法,redisKey="+examRedisKeyPrefix+studentId);
-        redisClient.set(examRedisKeyPrefix+studentId,examSessionInfo,timeout);
-        ExamSessionInfo sessionInfo =redisClient.get(examRedisKeyPrefix+studentId,ExamSessionInfo.class);
-        log.debug("11.4.2 保存考试会话方法完成,尝试取一下值 ="+sessionInfo.getExamRecordDataId());
-    }
-
-    @Override
-    public ExamSessionInfo getExamSessionInfo(Long studentId) {
-        return redisClient.get(examRedisKeyPrefix+studentId,ExamSessionInfo.class);
-    }
-
-    @Override
-    public void deleteExamSessionInfo(Long studentId) {
-        redisClient.delete(examRedisKeyPrefix+studentId);
-    }
-}

+ 0 - 134
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamStudentFinalScoreServiceImpl.java

@@ -1,134 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamScoreEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentFinalScoreEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-import cn.com.qmth.examcloud.core.oe.common.enums.MarkingType;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentFinalScoreRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamStudentFinalScoreService;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * @Description 考生最终分数实现类
- * @Author lideyin
- * @Date 2019/11/11 14:30
- * @Version 1.0
- */
-@Service("examStudentFinalScoreService")
-public class ExamStudentFinalScoreServiceImpl implements ExamStudentFinalScoreService {
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-    @Autowired
-    private ExamScoreRepo examScoreRepo;
-    @Autowired
-    private ExamStudentRepo examStudentRepo;
-    @Autowired
-    private ExamStudentFinalScoreRepo examStudentFinalScoreRepo;
-
-    @Override
-    public void calculateFinalScore(Long examStudentId) {
-        ExamStudentEntity examStudent = examStudentRepo.findByExamStudentId(examStudentId);
-        String markingType = ExamCacheTransferHelper.
-                getDefaultCachedExamProperty(examStudent.getExamId(), ExamProperties.MARKING_TYPE.name()).getValue();
-        String examType = ExamCacheTransferHelper.getDefaultCachedExam(examStudent.getExamId()).getExamType();
-        List<ExamRecordDataEntity> allExamRecordDataList = examRecordDataRepo.findByExamStudentId(examStudentId);
-
-        //得到最终考试结果
-        ExamScoreEntity finalEffectiveExamScore = getFinalEffectiveExamScore(allExamRecordDataList, examType, markingType);
-
-        //保存最终考试结果
-        ExamStudentFinalScoreEntity finalScoreEntity = copyExamStudentFinalScoreEntityFrom(finalEffectiveExamScore);
-        examStudentFinalScoreRepo.save(finalScoreEntity);
-    }
-
-    private ExamStudentFinalScoreEntity copyExamStudentFinalScoreEntityFrom(ExamScoreEntity finalEffectiveExamScore) {
-        ExamStudentFinalScoreEntity finalScoreEntity = new ExamStudentFinalScoreEntity();
-
-        finalScoreEntity.setExamRecordDataId(finalEffectiveExamScore.getExamRecordDataId());
-        finalScoreEntity.setExamStudentId(finalEffectiveExamScore.getExamRecordDataId());
-        finalScoreEntity.setObjectiveAccuracy(finalEffectiveExamScore.getObjectiveAccuracy());
-        finalScoreEntity.setObjectiveScore(finalEffectiveExamScore.getObjectiveScore());
-        finalScoreEntity.setSubjectiveScore(finalEffectiveExamScore.getSubjectiveScore());
-        finalScoreEntity.setSuccPercent(finalEffectiveExamScore.getSuccPercent());
-        finalScoreEntity.setTotalScore(finalEffectiveExamScore.getTotalScore());
-
-        return finalScoreEntity;
-    }
-
-
-    /**
-     * 计算得出最终有效成绩
-     */
-    private ExamScoreEntity getFinalEffectiveExamScore(List<ExamRecordDataEntity> examRecordAllList, String examType, String markingType) {
-        /*
-         * 第一次过滤考试记录:
-         * 状态为EXAM_END或EXAM_OVERDUE
-         */
-        List<ExamRecordDataEntity> firstFilterExamRecordList = examRecordAllList.stream().filter(examRecord -> {
-            return examRecord.getExamRecordStatus() == ExamRecordStatus.EXAM_END ||
-                    examRecord.getExamRecordStatus() == ExamRecordStatus.EXAM_OVERDUE;
-        }).collect(Collectors.toList());
-
-        if (firstFilterExamRecordList == null || firstFilterExamRecordList.size() == 0) {
-            return null;
-        }
-
-        /*
-         * 第二次过滤考试记录:
-         * 没有违纪的&&(没有警告或有警告已审核通过的)
-         */
-        Stream<ExamRecordDataEntity> secondFilterExamRecordStream = firstFilterExamRecordList.stream().filter(examRecord -> {
-            return !examRecord.getIsIllegality() && (!examRecord.getIsWarn() || (examRecord.getIsWarn() && examRecord.getIsAudit()));
-        });
-
-        List<ExamRecordDataEntity> secondFilterExamRecords = secondFilterExamRecordStream.collect(Collectors.toList());
-        if (secondFilterExamRecords == null || secondFilterExamRecords.size() == 0) {
-            return null;
-        }
-
-        //取出有效记录的成绩
-        List<Long> examRecordDataIds = new ArrayList<>();
-        for (int i = 0; i < secondFilterExamRecords.size(); i++) {
-            examRecordDataIds.add(secondFilterExamRecords.get(i).getId());
-        }
-        List<ExamScoreEntity> effectiveExamScoreList = examScoreRepo.findByExamRecordDataIdIn(examRecordDataIds);
-        if (effectiveExamScoreList == null || effectiveExamScoreList.size() == 0) {
-            return null;
-        }
-        //离线考试
-        if ("OFFLINE".equals(examType)) {
-            return effectiveExamScoreList.get(0);
-        } else {
-            if (markingType.equals(MarkingType.ALL.name()) || markingType.equals(MarkingType.OBJECT_SCORE_MAX.name())) {
-                //全部评阅规则或客观分最高规则:取总分最高
-                List<ExamScoreEntity> examScores = effectiveExamScoreList
-                        .stream()
-                        .sorted((o1, o2) -> o2.getTotalScore().compareTo(o1.getTotalScore()))
-                        .collect(Collectors.toList());
-                return examScores.get(0);
-            } else if (markingType.equals(MarkingType.LAST_SUBMIT.name())) {
-                //最后一次提交规则:取最后一次的成绩
-                List<ExamScoreEntity> examScores = effectiveExamScoreList
-                        .stream()
-                        .sorted((o1, o2) -> o2.getId().compareTo(o1.getId()))
-                        .collect(Collectors.toList());
-                return examScores.get(0);
-            }
-        }
-        return null;
-    }
-}

+ 0 - 202
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/ExamStudentServiceImpl.java

@@ -1,202 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.CourseLevel;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamType;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.oe.common.service.GainBaseDataService;
-import cn.com.qmth.examcloud.core.oe.student.bean.ExamStudentInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamStudentService;
-import cn.com.qmth.examcloud.examwork.api.ExamCloudService;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamSpecialSettingsBean;
-import cn.com.qmth.examcloud.examwork.api.request.GetOngoingExamListReq;
-import cn.com.qmth.examcloud.examwork.api.response.GetOngoingExamListResp;
-import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.OrgCacheBean;
-import cn.com.qmth.examcloud.support.cache.bean.StudentCacheBean;
-import org.apache.commons.lang3.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.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * @author chenken
- * @date 2018年8月13日 下午2:46:10
- * @company QMTH
- * @description 考生服务实现
- */
-@Service("examStudentService")
-public class ExamStudentServiceImpl implements ExamStudentService {
-
-    @Autowired
-    private ExamStudentRepo examStudentRepo;
-
-    @Autowired
-    private ExamCloudService examCloudService;
-
-    @Autowired
-    private GainBaseDataService gainBaseDataService;
-
-    /**
-     * 根据学生id获取考试列表
-     *
-     * @param studentId 学生id
-     */
-    @Override
-    public List<ExamStudentInfo> queryOnlineExamList(Long studentId) {
-        StudentCacheBean studentBean = CacheHelper.getStudent(studentId);
-
-        //获取可以考的和即将考的考试Id
-        GetOngoingExamListReq getOngoingExamListReq = new GetOngoingExamListReq();
-        getOngoingExamListReq.setExamType(ExamType.ONLINE.name());
-        getOngoingExamListReq.setRootOrgId(studentBean.getRootOrgId());
-        getOngoingExamListReq.setOrgId(studentBean.getOrgId());
-        getOngoingExamListReq.setStudentId(studentId);
-        GetOngoingExamListResp getOngoingExamListResp = examCloudService.getOngoingExamList(getOngoingExamListReq);
-
-        //获取学生所在组织机构的所有考试列表集合(虽然名字起的特殊考试设置,事实上取的就是实际的可考的考试列表,可能是考试中心特殊设置的考试时间,也可能不是)
-        List<ExamSpecialSettingsBean> examSpecialSettingsBeanList = getOngoingExamListResp.getExamSpecialSettingsList();
-        if (examSpecialSettingsBeanList == null || examSpecialSettingsBeanList.size() == 0) {
-            return null;
-        }
-        List<Long> examIds = examSpecialSettingsBeanList.stream().map(ExamSpecialSettingsBean::getExamId).collect(Collectors.toList());
-
-        //根据studentId和考试Id查询考生()
-//		List<ExamStudentEntity> examStudents = examStudentRepo.findByStudentIdAndExamIdIn(studentId, examIds);
-        //只查没有禁用的考生
-        List<ExamStudentEntity> examStudents = examStudentRepo.findByStudentIdAndEnableAndExamIdIn(studentId, true, examIds);
-        List<ExamStudentInfo> examStudentDtoList = new ArrayList<ExamStudentInfo>();
-        for (ExamStudentEntity examStudent : examStudents) {
-            Stream<ExamSpecialSettingsBean> examSpecialSettingsBeanStream = examSpecialSettingsBeanList.stream().filter(examSpecialSettingsBean -> {
-                return examSpecialSettingsBean.getExamId().longValue() == examStudent.getExamId().longValue();
-            });
-            if (examSpecialSettingsBeanStream != null) {
-                ExamSpecialSettingsBean examSpecialSettingsBean = examSpecialSettingsBeanStream.findFirst().get();
-                examStudentDtoList.add(assemblingExamStudentDto(examStudent, examSpecialSettingsBean));
-            }
-        }
-        return examStudentDtoList;
-    }
-
-    private ExamStudentInfo assemblingExamStudentDto(ExamStudentEntity examStudent, ExamSpecialSettingsBean examSpecialSettingsBean) {
-        ExamStudentInfo examStudentInfo = new ExamStudentInfo();
-        examStudentInfo.setExamStudentId(examStudent.getExamStudentId());
-        examStudentInfo.setStudentCode(examStudent.getStudentCode());
-        examStudentInfo.setStudentName(examStudent.getStudentName());
-        Long rootOrgId = examStudent.getRootOrgId();
-        examStudentInfo.setRootOrgId(rootOrgId);
-        examStudentInfo.setIdentityNumber(examStudent.getIdentityNumber());
-
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudent.getCourseId());
-        examStudentInfo.setCourseName(courseBean.getName());
-        examStudentInfo.setCourseCode(courseBean.getCode());
-        examStudentInfo.setCourseLevel(CourseLevel.getCourseLevel(courseBean.getLevel()).getTitle());
-        examStudentInfo.setCourseId(examStudent.getCourseId());
-        examStudentInfo.setSpecialtyName(examStudent.getSpecialtyName());
-        Long orgId = examStudent.getOrgId();
-        examStudentInfo.setOrgId(orgId);
-
-        OrgCacheBean orgBean = gainBaseDataService.getOrgBean(orgId);
-        Long studentId = examStudent.getStudentId();
-        ExamBean examBean = ExamCacheTransferHelper.getCachedExam(examStudent.getExamId(),
-                 studentId);
-
-        examStudentInfo.setOrgName(orgBean.getName());
-        Long examId = examBean.getId();
-        examStudentInfo.setExamId(examId);
-        examStudentInfo.setExamName(examBean.getName());
-        examStudentInfo.setStartTime(examSpecialSettingsBean.getBeginTime());//考试开始时间设置
-        examStudentInfo.setEndTime(examSpecialSettingsBean.getEndTime());//考试结束时间设置
-        examStudentInfo.setAllowExamCount(countExamTimes(examStudent, examBean));
-        examStudentInfo.setPaperMins(examBean.getDuration());
-        //是否启用人脸识别
-        examStudentInfo.setFaceEnable(FaceBiopsyHelper.isFaceEnable(rootOrgId, examId,  studentId));
-        //进入考试是否验证人脸识别(强制、非强制)
-        examStudentInfo.setFaceCheck(FaceBiopsyHelper.isFaceCheck(examId, studentId));
-        //是否显示客观分
-        String isObjScoreView = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                studentId, ExamProperties.IS_OBJ_SCORE_VIEW.name()).getValue();
-        if (StringUtils.isBlank(isObjScoreView)) {
-            examStudentInfo.setIsObjScoreView(false);
-        } else {
-            examStudentInfo.setIsObjScoreView(Boolean.valueOf(isObjScoreView));
-        }
-        return examStudentInfo;
-    }
-
-    @Override
-    public Integer countExamTimes(ExamStudentEntity examStudentInfo, ExamBean examBean) {
-        if (ExamType.OFFLINE.name().equals(examBean.getExamType())) {
-            return 1;
-        }
-        //考试批次中设置的考试次数
-        int canExamTimes = examBean.getExamTimes().intValue();
-        //正常考试的次数
-        int normalExamTimes = examStudentInfo.getNormalExamTimes();
-        /**
-         * 如果设置了重考,重考未完成;
-         * 且正常考试的次数大于等于设定的次数
-         * 将考试剩余次数设置为1
-         */
-        if (reexamineNotCompleted(examStudentInfo) && normalExamTimes >= canExamTimes) {
-            return 1;
-        }
-        int allowExamCount = canExamTimes - normalExamTimes;
-        return allowExamCount < 0 ? 0 : allowExamCount;
-    }
-
-    /**
-     * 设置了重考,且重考未完成
-     *
-     * @param examStudentInfo
-     * @return
-     */
-    private boolean reexamineNotCompleted(ExamStudentEntity examStudentInfo) {
-        if (examStudentInfo.getIsReExamine() != null && examStudentInfo.getIsReExamine()
-                && (examStudentInfo.getReExamineCompleted() == null || !examStudentInfo.getReExamineCompleted())) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public int updateExamStudentByStartExam(Long id, Boolean isReExamine, Boolean reExamineCompleted,
-                                            Integer normalExamTimes, final ExamBean examBean) {
-        //考试完的最终状态
-        Boolean finalIsReExamine = isReExamine;
-        Boolean finalReExamineCompleted = reExamineCompleted;
-        //考生的已考次数(不包括重考)
-        int finalNormalExamTimes = normalExamTimes == null ? 0 : normalExamTimes;
-        //考试机会,即可考次数
-        long canExamTimes = examBean.getExamTimes();
-        //有可能中途改变考试次数
-        if (canExamTimes > finalNormalExamTimes) {
-            finalNormalExamTimes = finalNormalExamTimes + 1;
-            finalIsReExamine = null;
-            finalReExamineCompleted = null;
-        }
-
-        // 考生开始重考时,将重考已完成设置为true,并重置是否重考
-        if (CommonUtil.isTrue(finalIsReExamine)) {
-            finalIsReExamine = false;
-            finalReExamineCompleted = true;
-            finalNormalExamTimes = finalNormalExamTimes + 1;
-        }
-        Date now = new Date();
-        //更新相关属性
-        examStudentRepo.updateExamStudentStartExamStatusInfo(id, true,
-                finalNormalExamTimes, finalIsReExamine, finalReExamineCompleted, now);
-        return finalNormalExamTimes;
-    }
-}

+ 0 - 889
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/FaceBiopsyServiceImpl.java

@@ -1,889 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.commons.util.JsonUtil;
-import cn.com.qmth.examcloud.core.oe.common.base.Constants;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.CommonUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.FaceBiopsyEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.FaceBiopsyItemEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.FaceBiopsyItemStepEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyAction;
-import cn.com.qmth.examcloud.core.oe.common.enums.FaceBiopsyType;
-import cn.com.qmth.examcloud.core.oe.common.enums.IsSuccess;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.helper.FaceBiopsyHelper;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.FaceBiopsyItemRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.FaceBiopsyItemStepRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.FaceBiopsyRepo;
-import cn.com.qmth.examcloud.core.oe.student.bean.*;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamControlService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamSessionInfoService;
-import cn.com.qmth.examcloud.core.oe.student.service.FaceBiopsyService;
-import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import com.google.common.collect.Lists;
-import com.mysql.cj.util.StringUtils;
-import org.apache.commons.lang3.RandomUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @Description 人脸活体检测接口实现类
- * @Author lideyin
- * @Date 2019/10/14 10:56
- * @Version 1.0
- */
-@Service("faceBiopsyService")
-public class FaceBiopsyServiceImpl implements FaceBiopsyService {
-
-    @Autowired
-    private FaceBiopsyRepo faceBiopsyRepo;
-    @Autowired
-    private FaceBiopsyItemRepo faceBiopsyItemRepo;
-    @Autowired
-    private FaceBiopsyItemStepRepo faceBiopsyItemStepRepo;
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-    @Autowired
-    private ExamSessionInfoService examSessionInfoService;
-    @Autowired
-    private ExamControlService examControlService;
-
-    @Override
-    @Transactional
-    public FaceBiopsyInfo getFaceBiopsyInfo(Long rootOrgId, Long examRecordDataId, FaceBiopsyType faceBiopsyType) {
-        //如果是第一次进行人脸活体检测,则初始化相关信息保存并返回
-        FaceBiopsyEntity faceBiopsyEntity = faceBiopsyRepo.findByExamRecordDataId(examRecordDataId);
-        if (faceBiopsyEntity == null) {
-            return addFirstFaceBiopsy(rootOrgId, examRecordDataId, faceBiopsyType);
-        }
-
-        //如果不是第一次人脸活体检测,判断是否有未检测完的记录,
-        FaceBiopsyInfo result = new FaceBiopsyInfo();
-        // 未完成的活体检测列表
-        List<FaceBiopsyItemEntity> unCompletedFaceBiopsyItemList =
-                faceBiopsyItemRepo.findByExamRecordDataIdAndCompleted(examRecordDataId, false);
-
-        //如果存在未完成的活体检测信息,则直接返回上次未完成的活检记录
-        if (unCompletedFaceBiopsyItemList != null && !unCompletedFaceBiopsyItemList.isEmpty()) {
-            FaceBiopsyItemEntity faceBiopsyItemEntity = unCompletedFaceBiopsyItemList.get(0);
-            result.setFaceBiopsyItemId(faceBiopsyItemEntity.getId());
-            result.setFaceVerifyMinute(calculateFaceBiopsyStartMinute(examRecordDataId));
-
-            List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList =
-                    faceBiopsyItemStepRepo.findByFaceBiopsyItemId(faceBiopsyItemEntity.getId());
-            result.setVerifySteps(copyFaceBiopsyStepDomainListFrom(faceBiopsyItemStepEntityList));
-            return result;
-        }
-
-        //不存在未完成的活检的校验逻辑
-        // 已活检次数
-        int verifiedTimes = faceBiopsyEntity.getVerifiedTimes();
-
-        if (verifiedTimes == 1) {
-            FaceBiopsyItemEntity firstFaceBiopsyItem =
-                    faceBiopsyItemRepo.findFirstByFaceBiopsyIdOrderByIdAsc(faceBiopsyEntity.getId());
-            if (null != firstFaceBiopsyItem.getResult() && firstFaceBiopsyItem.getResult()) {
-                //第一次活检成功,且未开启追加新活检,再次调用,则抛出异常
-                if (!isAddFaceVerifyOutFreezeTime(examRecordDataId)) {
-                    throw new StatusException("201006", "非法请求,无活体检测机会");
-                }
-                //第一次活检成功,且开启追加新活检,再次调用,按冻结时间外生成新的活检步骤
-                return appendFaceBiopsy(faceBiopsyEntity.getId(), verifiedTimes, examRecordDataId, faceBiopsyType, false);
-            }
-
-            //如果第一次活检失败,再次调用,按冻结时间内生成新的活检步骤
-            return appendFaceBiopsy(faceBiopsyEntity.getId(), verifiedTimes, examRecordDataId, faceBiopsyType, true);
-        }
-
-        if (verifiedTimes == 2) {
-            FaceBiopsyItemEntity secondFaceBiopsyItem =
-                    faceBiopsyItemRepo.findFirstByFaceBiopsyIdOrderByIdDesc(faceBiopsyEntity.getId());
-
-            //如果是第二次活检为冻结时间外的活检记录,再次调用,则直接抛出异常
-            if (!secondFaceBiopsyItem.getInFreezeTime()) {
-                throw new StatusException("201007", "非法请求,无活体检测机会");
-            }
-
-            //如果第二次活检也失败,再次调用,则抛出异常
-            if (!secondFaceBiopsyItem.getResult()) {
-                throw new StatusException("201008", "非法请求,无活体检测机会");
-            }
-
-            //否则追加冻结时间外的活检
-            return appendFaceBiopsy(faceBiopsyEntity.getId(), verifiedTimes, examRecordDataId, faceBiopsyType, false);
-        }
-
-        //三交活检已完成,则抛出异常
-        throw new StatusException("201009", "非法请求,无活体检测机会");
-    }
-
-    @Override
-    @Transactional
-    public SaveFaceBiopsyResultResp saveFaceBiopsyResult(SaveFaceBiopsyResultReq req, Long studentId) {
-        // 检测结果至少有一条检测结果不允许为空
-        if (!req.getVerifySteps().stream().anyMatch(p -> null != p.getResult())) {
-            throw new StatusException("201005", "检测结果不允许为空");
-        }
-
-        //构建业务实体
-        SaveFaceBiopsyResultResp resp = buildSaveFaceBiopsyResultResp(req);
-
-        //更新人脸活体检测结果至数据库
-        updateFaceBiopsyResult(req.getExamRecordDataId(), req.getFaceBiopsyItemId(), req.getVerifySteps(),
-                resp.getVerifyResult(), resp.getErrorMessage());
-
-        //同步更新考试记录表中的活体检测结果
-        IsSuccess faceVerifyResult = resp.getVerifyResult() ? IsSuccess.SUCCESS : IsSuccess.FAILED;
-        examRecordDataRepo.updateFaceVerifyResult(faceVerifyResult.toString(), req.getExamRecordDataId());
-
-        return resp;
-    }
-
-    /**
-     * 计算人脸活体检测开始分钟数
-     *
-     * @param examRecordDataId 考试记录id
-     * @return Integer
-     */
-    @Override
-    public Integer calculateFaceBiopsyStartMinute(Long examRecordDataId) {
-        //如果未开启人脸活体检测,则返回null
-        if (!getIsFaceVerify(examRecordDataId)) {
-            return null;
-        }
-
-        /**
-         * case0.首次调用或超过3次调用的特殊处理
-         * case0.1.第一次调用,无冻结时间内还是冻结时间外,均按照冻结时间内的算法计算下次活检时间(相当于补偿措施)
-         * case0.2.超过3次调用,
-         * case0.2.1.如果第三次活检未完成,再次调用,则按活检外计算方式,返回下次活检时间
-         * case0.2.2.如果第三次活检已完成,则直接返回null
-         */
-        FaceBiopsyEntity faceBiopsy = faceBiopsyRepo.findByExamRecordDataId(examRecordDataId);
-        if (faceBiopsy == null) {
-            return generateInFreezeTimeFaceBiopsyStartMinute(examRecordDataId);
-        }
-
-        //超过三次的特殊处理
-        if (faceBiopsy.getVerifiedTimes() >= 3) {
-            FaceBiopsyItemEntity lastFaceBiopsyItem =
-                    faceBiopsyItemRepo.findFirstByFaceBiopsyIdOrderByIdDesc(faceBiopsy.getId());
-
-            //如果第三次活检已完成,则直接返回null
-            if (lastFaceBiopsyItem.getCompleted()) {
-                return null;
-            }
-
-            //如果第三次活检未完成,再次调用,则按活检外计算方式,返回下次活检时间
-            return generateOutFreezeTimeFaceBiopsyStartMinute(examRecordDataId);
-        }
-
-        //按id升序排列的活检集合
-        List<FaceBiopsyItemEntity> sortedFaceBiopsyItems =
-                faceBiopsyItemRepo.findByFaceBiopsyIdOrderByIdAsc(faceBiopsy.getId());
-
-        //第一次活检明细
-        FaceBiopsyItemEntity firstFaceBiopsyItem = sortedFaceBiopsyItems.get(0);
-
-        //第一次活检未完成,再次调用,继续按冻结时间内方式计算活检开始时间
-        if (!firstFaceBiopsyItem.getCompleted()) {
-            return generateInFreezeTimeFaceBiopsyStartMinute(examRecordDataId);
-        }
-
-        //第一次活体检测完成且成功,再次调用时根据是否开启追加活检判断相关逻辑
-        if (firstFaceBiopsyItem.getResult()) {
-            //如果未开启冻结时间外人脸活体检测,则无需求下次活检,故直接返回null
-            if (!isAddFaceVerifyOutFreezeTime(examRecordDataId)) {
-                return null;
-            }
-
-            //如果开启冻结时间外人脸活体检测,则直接返回冻结时间外的活检开始时间
-            return generateOutFreezeTimeFaceBiopsyStartMinute(examRecordDataId);
-        }
-
-        //第一次活检完成且失败,那么第二次调用或者第N(N>=2)次调用且第二次活检未完成,采用活检内计算方式
-        if (faceBiopsy.getVerifiedTimes() == 1 ||
-                (faceBiopsy.getVerifiedTimes() == 2 && !sortedFaceBiopsyItems.get(1).getCompleted())) {
-            return generateInFreezeTimeFaceBiopsyStartMinute(examRecordDataId);
-        }
-
-        //其它情况,采用冻结时间外活检计算方式
-        return generateOutFreezeTimeFaceBiopsyStartMinute(examRecordDataId);
-    }
-
-    /**
-     * 构建保存人脸检测结果的业务实体
-     *
-     * @param req
-     * @return
-     */
-    private SaveFaceBiopsyResultResp buildSaveFaceBiopsyResultResp(SaveFaceBiopsyResultReq req) {
-        //构建业务实体
-        SaveFaceBiopsyResultResp resp = new SaveFaceBiopsyResultResp();
-
-        Boolean finalIsSuccess = calculateIsSuccess(req.getVerifySteps());
-        resp.setVerifyResult(finalIsSuccess);
-
-        Boolean isEndExam = calculateIsEndExam(req.getVerifySteps(), req.getExamRecordDataId(), finalIsSuccess);
-        resp.setEndExam(isEndExam);
-
-        resp.setNeedNextVerify(calculateNeedNextVerify(isEndExam, finalIsSuccess, req.getExamRecordDataId()));
-        resp.setErrorMessage(getErrorMsg(req.getVerifySteps()));
-        return resp;
-    }
-
-    /**
-     * 更新人脸活体检测结果至数据库
-     *
-     * @param examRecordDataId
-     * @param faceBiopsyItemId
-     * @param verifySteps
-     * @param finalIsSuccess
-     * @param errorMsg
-     */
-    public void updateFaceBiopsyResult(Long examRecordDataId, Long
-            faceBiopsyItemId, List<FaceBiopsyStepInfo> verifySteps,
-                                       boolean finalIsSuccess, String errorMsg) {
-        List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList =
-                faceBiopsyItemStepRepo.findByFaceBiopsyItemId(faceBiopsyItemId);
-        for (FaceBiopsyStepInfo stepInfo : verifySteps) {
-            //循环更新新活体检测每步的执行结果
-            FaceBiopsyItemStepEntity faceBiopsyItemStepEntity = faceBiopsyItemStepEntityList.stream().
-                    filter(p -> p.getId().equals(stepInfo.getStepId())).findFirst().get();
-            faceBiopsyItemStepEntity.setErrorMsg(stepInfo.getErrorMsg());
-            faceBiopsyItemStepEntity.setResourceType(stepInfo.getResourceType());
-            faceBiopsyItemStepEntity.setResourceRelativePath(getRelativePath(stepInfo.getResourceUrl()));
-            faceBiopsyItemStepEntity.setExt1(stepInfo.getResultJson());//存储动作执行结果
-            faceBiopsyItemStepEntity.setResult(stepInfo.getResult());
-
-            if (null != stepInfo.getTimeout()) {
-                faceBiopsyItemStepEntity.setExt2(stepInfo.getTimeout().toString());//指令是否超时
-            }
-
-            if (null != stepInfo.getStranger()) {
-                faceBiopsyItemStepEntity.setExt3(stepInfo.getStranger().toString());//是否有陌生人脸
-            }
-
-            if (null != stepInfo.getWaggleOutCamera()) {
-                faceBiopsyItemStepEntity.setExt3(stepInfo.getWaggleOutCamera().toString());//是否晃同摄像头
-            }
-
-            if (null != stepInfo.getHasFace()) {
-                faceBiopsyItemStepEntity.setExt4(stepInfo.getHasFace().toString());//是否有人脸
-            }
-
-        }
-        //批量更新活检步骤执行结果
-        faceBiopsyItemStepRepo.saveAll(faceBiopsyItemStepEntityList);
-        //更新人脸活体检测最终结果
-        faceBiopsyItemRepo.updateFaceBiopsyItemResult(faceBiopsyItemId, finalIsSuccess, errorMsg, true);
-        faceBiopsyRepo.updateFaceBiopsyResult(examRecordDataId, finalIsSuccess, errorMsg);
-    }
-
-
-    /**
-     * 计算活检是否成功
-     *
-     * @param verifySteps
-     * @return
-     */
-    private boolean calculateIsSuccess(List<FaceBiopsyStepInfo> verifySteps) {
-        for (FaceBiopsyStepInfo stepInfo : verifySteps) {
-            //如果当前步骤为超时,则直接返回失败或者整个检测步骤中只要有一次失败,则认为整个活检失败
-            if ((null != stepInfo.getTimeout() && stepInfo.getTimeout()) ||
-                    (null != stepInfo.getResult() && !stepInfo.getResult())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * 获取错误信息
-     *
-     * @param verifySteps
-     * @return
-     */
-    private String getErrorMsg(List<FaceBiopsyStepInfo> verifySteps) {
-        for (FaceBiopsyStepInfo stepInfo : verifySteps) {
-            //如果当前步骤为超时,则直接跳出循环
-            if ((null != stepInfo.getTimeout() && stepInfo.getTimeout())) {
-                return "超时未完成";
-            }
-
-            //整个检测步骤中只要有一次失败,则认为整个活检失败
-            if (null != stepInfo.getResult() && !stepInfo.getResult()) {
-                return stepInfo.getErrorMsg();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * 计算是否结束考试
-     *
-     * @param verifySteps
-     * @param examRecordDataId
-     * @param finalIsSuccess
-     * @return
-     */
-    private boolean calculateIsEndExam(List<FaceBiopsyStepInfo> verifySteps, Long examRecordDataId, Boolean finalIsSuccess) {
-        /**
-         * 指定指令失败,(多人脸,人脸晃出摄像头,无人脸)直接结束考试
-         */
-        for (FaceBiopsyStepInfo stepInfo : verifySteps) {
-            switch (stepInfo.getAction()) {
-                case FACE_COMPARE:
-                    //如果有陌生人脸或晃出摄像头或无人脸,直接结束考试
-                    if ((null != stepInfo.getStranger() && stepInfo.getStranger()) ||
-                            (null != stepInfo.getWaggleOutCamera() && stepInfo.getWaggleOutCamera()) ||
-                            (null != stepInfo.getHasFace() && !stepInfo.getHasFace())) {
-                        return true;
-                    }
-
-                    //如果第一步检测部分失败(照片非本人或检测中多人脸),需要结束考试
-                    Map faceCompareResult = JsonUtil.fromJson(stepInfo.getResultJson(), Map.class);
-                    if (null != faceCompareResult) {
-                        if (null == faceCompareResult.get("isPass") ||
-                                null == faceCompareResult.get("existsSystemError")) {
-                            throw new StatusException("201007", "活体检测第一步检测结果的json串格式不正确");
-                        }
-
-                        Boolean isStranger;
-                        if (null == faceCompareResult.get("isStranger")) {
-                            isStranger = false;
-                        } else {
-                            isStranger = Boolean.valueOf(faceCompareResult.get("isStranger").toString());
-                        }
-
-                        Boolean isPass = Boolean.valueOf(faceCompareResult.get("isPass").toString());
-                        Boolean existsSystemError = Boolean.valueOf(faceCompareResult.get("existsSystemError").toString());
-
-                        //如果有系统错误,也需要抛出异常
-                        if (existsSystemError) {
-
-                            throw new StatusException("201008", "活体检测失败,请稍候重试");
-                        }
-
-                        //case1.1.有陌生人(即多人脸),不管是否比对成功,直接结束考试
-                        if (isStranger) {
-                            return true;
-                        }
-                        //case1.2.无陌生人且检测失败且不是系统错误(即照片非本人或无人脸),也直接结束考试
-                        else {
-                            if (!isPass && !existsSystemError) {
-                                return true;
-                            }
-                        }
-                    }
-                    break;
-                case HAPPY:
-                case SERIOUS:
-                    //如果有陌生人脸或晃出摄像头或无人脸,直接结束考试
-                    if ((null != stepInfo.getStranger() && stepInfo.getStranger()) ||
-                            (null != stepInfo.getWaggleOutCamera() && stepInfo.getWaggleOutCamera()) ||
-                            (null != stepInfo.getHasFace() && !stepInfo.getHasFace())) {
-                        return true;
-                    }
-                    break;
-            }
-        }
-
-        /**
-         * 根据活检情况结束考试
-         * 当前为第二次活检,且失败,且第一次活检也失败,则直接结束考试
-         * 当前为第二次活检,且失败,且第一次活检成功,则直接结束考试
-         * 当前为第三次活检,且失败,且第一次活检失败,第二次活检成功,则直接结束考试
-         */
-        //如果是第二次活检,且失败,则结束考试(无论第一次是否成功)
-        int verifyTimes = getVerifyTimes(examRecordDataId);
-        if (verifyTimes == 2 && !finalIsSuccess) {
-            return true;
-        }
-
-        if (verifyTimes == 3 && !finalIsSuccess) {
-            return true;
-        }
-
-        //其它情况不结束考试
-        return false;
-    }
-
-    /**
-     * 计算是否需要下次活检
-     *
-     * @param isEndExam
-     * @param finalIsSuccess
-     * @return
-     */
-    private boolean calculateNeedNextVerify(boolean isEndExam, boolean finalIsSuccess, Long examRecordDataId) {
-        //考试已结束,不需要继续下次活检
-        if (isEndExam) {
-            return false;
-        }
-
-        int verifyTimes = getVerifyTimes(examRecordDataId);
-        //如果是第一次活检,且成功,且开启追加活检,则允许继续活检
-        //或者是第一次活检,且失败,则允许继续活检
-        if (verifyTimes == 1) {
-            if ((finalIsSuccess && isAddFaceVerifyOutFreezeTime(examRecordDataId)) ||
-                    !finalIsSuccess) {
-                return true;
-            }
-        }
-
-        //如果是第二次活检,且成功,且第一次活检失败,且开启追加活检,则允许继续活检
-        if (verifyTimes == 2 && finalIsSuccess) {
-            FaceBiopsyItemEntity firstFaceBiopsyItem =
-                    faceBiopsyItemRepo.findFirstByExamRecordDataIdOrderByIdAsc(examRecordDataId);
-            if (!firstFaceBiopsyItem.getResult() && isAddFaceVerifyOutFreezeTime(examRecordDataId)) {
-                return true;
-            }
-        }
-
-        //其它情况均不允许继续活检
-        return false;
-    }
-
-    /**
-     * 获取活体检测次数
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    private int getVerifyTimes(Long examRecordDataId) {
-        FaceBiopsyEntity faceBiopsy = faceBiopsyRepo.findByExamRecordDataId(examRecordDataId);
-        return faceBiopsy.getVerifiedTimes();
-    }
-
-    /**
-     * 根据完整路径获取相对路径
-     *
-     * @param resourceUrl
-     * @return
-     */
-    private String getRelativePath(String resourceUrl) {
-        if (!StringUtils.isNullOrEmpty(resourceUrl)) {
-            String domain = PropertyHolder.getString("$upyun.site.1.domain");
-            String backupDomain = PropertyHolder.getString("$upyun.site.1.domain.backup");
-            if (!StringUtils.isNullOrEmpty(domain)) {
-                resourceUrl = resourceUrl.replace(domain, "");
-            }
-            if (!StringUtils.isNullOrEmpty(backupDomain)) {
-                resourceUrl = resourceUrl.replace(backupDomain, "");
-            }
-        }
-        return resourceUrl;
-    }
-
-    /**
-     * 第一次添加人脸活体检测结果
-     *
-     * @param rootOrgId
-     * @param examRecordDataId
-     * @param faceBiopsyType
-     * @return
-     */
-    public FaceBiopsyInfo addFirstFaceBiopsy(Long rootOrgId, Long examRecordDataId, FaceBiopsyType faceBiopsyType) {
-        //保存人脸活体检测相关信息
-        Long faceBiopsyId = addFaceBiopsyEntity(rootOrgId, examRecordDataId);
-        Long faceBiopsyItemId = addFaceBiopsyItemEntity(examRecordDataId, faceBiopsyType, faceBiopsyId, true);
-        List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList =
-                addFaceBiopsyItemStepList(examRecordDataId, faceBiopsyItemId);
-
-        //构建业务实体
-        return buildFaceBiopsyInfo(examRecordDataId, faceBiopsyItemId, faceBiopsyItemStepEntityList);
-    }
-
-    /**
-     * 追加人脸活体检测结果
-     *
-     * @param faceBiopsyId
-     * @param verifiedTimes
-     * @param examRecordDataId
-     * @param faceBiopsyType
-     * @return
-     */
-    @Transactional
-    public FaceBiopsyInfo appendFaceBiopsy(Long faceBiopsyId, Integer verifiedTimes, Long examRecordDataId,
-                                           FaceBiopsyType faceBiopsyType, boolean isInFreezeTime) {
-        verifiedTimes++;
-        //更新人脸活体检测次数
-        FaceBiopsyEntity faceBiopsyEntity = GlobalHelper.getEntity(faceBiopsyRepo, faceBiopsyId, FaceBiopsyEntity.class);
-        faceBiopsyEntity.setVerifiedTimes(verifiedTimes);
-        faceBiopsyRepo.save(faceBiopsyEntity);
-        //添加人脸活体检测明细
-        Long faceBiopsyItemId = addFaceBiopsyItemEntity(examRecordDataId, faceBiopsyType, faceBiopsyId, isInFreezeTime);
-        //添加人脸活体检测步骤
-        List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList =
-                addFaceBiopsyItemStepList(examRecordDataId, faceBiopsyItemId);
-
-        return buildFaceBiopsyInfo(examRecordDataId, faceBiopsyItemId, faceBiopsyItemStepEntityList);
-
-    }
-
-    /**
-     * 构建人脸检测基本信息的业务实体对象
-     *
-     * @param examRecordDataId
-     * @param faceBiopsyItemId
-     * @param faceBiopsyItemStepEntityList
-     * @return
-     */
-    private FaceBiopsyInfo buildFaceBiopsyInfo(Long examRecordDataId, Long faceBiopsyItemId,
-                                               List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList) {
-        //构建业务实体
-        FaceBiopsyInfo faceBiopsyInfo = new FaceBiopsyInfo();
-        faceBiopsyInfo.setFaceBiopsyItemId(faceBiopsyItemId);
-        faceBiopsyInfo.setFaceVerifyMinute(calculateFaceBiopsyStartMinute(examRecordDataId));
-        faceBiopsyInfo.setVerifySteps(copyFaceBiopsyStepDomainListFrom(faceBiopsyItemStepEntityList));
-        return faceBiopsyInfo;
-    }
-
-    private List<FaceBiopsyStepInfo> copyFaceBiopsyStepDomainListFrom
-            (List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList) {
-        List<FaceBiopsyStepInfo> resultList = new ArrayList<>();
-        for (FaceBiopsyItemStepEntity entity : faceBiopsyItemStepEntityList) {
-            FaceBiopsyStepInfo domain = new FaceBiopsyStepInfo();
-            domain.setAction(entity.getAction());
-            domain.setStay(entity.getActionStay());
-            domain.setStepId(entity.getId());
-            resultList.add(domain);
-        }
-        return resultList;
-    }
-
-    /**
-     * 添加活体检测的具体步骤
-     *
-     * @param examRecordDataId 考试记录id
-     * @param faceBiopsyItemId 人脸活体检测明细id
-     */
-    private List<FaceBiopsyItemStepEntity> addFaceBiopsyItemStepList(Long examRecordDataId, Long faceBiopsyItemId) {
-        List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList = new ArrayList<FaceBiopsyItemStepEntity>();
-
-        //step1.人脸比对
-        FaceBiopsyItemStepEntity firstStep = new FaceBiopsyItemStepEntity();
-        firstStep.setExamRecordDataId(examRecordDataId);
-        firstStep.setFaceBiopsyItemId(faceBiopsyItemId);
-        firstStep.setAction(FaceBiopsyAction.FACE_COMPARE);
-        faceBiopsyItemStepEntityList.add(firstStep);
-
-        //生成乱序表情集合
-        List<FaceBiopsyAction> shuffledExpressionList = generateShuffleExpressions();
-
-        //step2随机表情
-        faceBiopsyItemStepEntityList.add(
-                randomGenerateExpressionStep(examRecordDataId, faceBiopsyItemId, shuffledExpressionList));
-
-        //step3随机表情
-        faceBiopsyItemStepEntityList.add(
-                randomGenerateExpressionStep(examRecordDataId, faceBiopsyItemId, shuffledExpressionList));
-
-        faceBiopsyItemStepRepo.saveAll(faceBiopsyItemStepEntityList);
-        return faceBiopsyItemStepEntityList;
-    }
-
-    /**
-     * 乱序生成人脸表情
-     *
-     * @return
-     */
-    private List<FaceBiopsyAction> generateShuffleExpressions() {
-        List<FaceBiopsyAction> expressionList = Lists.newArrayList();
-        expressionList.add(FaceBiopsyAction.HAPPY);
-        expressionList.add(FaceBiopsyAction.SERIOUS);
-        Collections.shuffle(expressionList);
-        return expressionList;
-    }
-
-    /**
-     * 随机生成表情相关步骤
-     *
-     * @param examRecordDataId
-     * @param faceBiopsyItemId
-     * @return
-     */
-    private FaceBiopsyItemStepEntity randomGenerateExpressionStep(Long examRecordDataId,
-                                                                  Long faceBiopsyItemId,
-                                                                  List<FaceBiopsyAction> shuffledExpressionList) {
-        FaceBiopsyItemStepEntity secondStep = new FaceBiopsyItemStepEntity();
-        secondStep.setExamRecordDataId(examRecordDataId);
-        secondStep.setFaceBiopsyItemId(faceBiopsyItemId);
-        secondStep.setAction(takeShuffledExpression(shuffledExpressionList));//获取一条随机生成表情指令
-        secondStep.setActionStay(randomGenerateActionStay());//随机生成指令时长(3至6秒)
-        return secondStep;
-    }
-
-    /**
-     * 获取一条随机生成的指令
-     *
-     * @param shuffledExpressionList
-     * @return
-     */
-    private FaceBiopsyAction takeShuffledExpression(List<FaceBiopsyAction> shuffledExpressionList) {
-        //取完第一条并删除
-        FaceBiopsyAction expression = shuffledExpressionList.get(0);
-        shuffledExpressionList.remove(0);
-        return expression;
-    }
-
-
-    /**
-     * 随机生成指令持续的时长
-     *
-     * @return
-     */
-    private Integer randomGenerateActionStay() {
-        int minStay = PropertyHolder.getInt("oe.faceBiopsy.minActionStay", 3);
-        int maxStay = PropertyHolder.getInt("oe.faceBiopsy.maxActionStay", 6);
-        return RandomUtils.nextInt(minStay, maxStay);
-    }
-
-    /**
-     * 添加人脸活体检测明细
-     *
-     * @param examRecordDataId 考试记录id
-     * @param faceBiopsyType   人脸活体检测类型
-     * @param faceBiopsyId     人脸活体检测id
-     * @return Long 人脸活体检测明细id
-     */
-    private Long addFaceBiopsyItemEntity(Long examRecordDataId, FaceBiopsyType faceBiopsyType,
-                                         Long faceBiopsyId, boolean isInFreezeTime) {
-        FaceBiopsyItemEntity faceBiopsyItemEntity = new FaceBiopsyItemEntity();
-        faceBiopsyItemEntity.setExamRecordDataId(examRecordDataId);
-        faceBiopsyItemEntity.setFaceBiopsyId(faceBiopsyId);
-        faceBiopsyItemEntity.setFaceBiopsyType(faceBiopsyType);
-        faceBiopsyItemEntity.setCompleted(false);
-        faceBiopsyItemEntity.setInFreezeTime(isInFreezeTime);
-        faceBiopsyItemRepo.save(faceBiopsyItemEntity);
-        return faceBiopsyItemEntity.getId();
-    }
-
-    /**
-     * 添加人脸活体检测结果
-     *
-     * @param rootOrgId        学校id
-     * @param examRecordDataId 考试记录id
-     * @return Long 人脸活体检测结果id
-     */
-    private Long addFaceBiopsyEntity(Long rootOrgId, Long examRecordDataId) {
-        FaceBiopsyEntity faceBiopsyEntity = new FaceBiopsyEntity();
-        faceBiopsyEntity.setRootOrgId(rootOrgId);
-        faceBiopsyEntity.setExamRecordDataId(examRecordDataId);
-        faceBiopsyEntity.setVerifiedTimes(1);
-        faceBiopsyRepo.save(faceBiopsyEntity);
-        return faceBiopsyEntity.getId();
-    }
-
-    /**
-     * 获取心跳时间
-     *
-     * @param studentId
-     * @return
-     */
-    private Integer getHeartbeat(Long studentId) {
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("201002", "考试会话已过期");
-        }
-
-        Integer heartbeat = examSessionInfo.getHeartbeat();
-        //由于会话心跳的默认值为-1,所以这里需要特殊处理一下
-        if (heartbeat < 0) {
-            heartbeat = 0;
-        }
-
-        return heartbeat;
-    }
-
-    /**
-     * 获取冻结时间
-     *
-     * @param studentId
-     * @return
-     */
-    private Integer getFreezeTime(Long studentId) {
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(studentId);
-        if (examSessionInfo == null) {
-            throw new StatusException("201002", "考试会话已过期");
-        }
-
-        Integer freezeTime = examSessionInfo.getFreezeTime();
-        return freezeTime;
-    }
-
-    /**
-     * 冻结时间边界枚举
-     */
-    enum FreezeTimeBorder {
-        /**
-         * 冻结时间内
-         */
-        IN,
-        /**
-         * 冻结时间外
-         */
-        OUT
-    }
-
-    /**
-     * 冻结时间内生成人脸活体检测的开始时间
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    private Integer generateInFreezeTimeFaceBiopsyStartMinute(Long examRecordDataId) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        Long examId = examRecordData.getExamId();
-        Long orgId = examRecordData.getOrgId();
-        Long studentId = examRecordData.getStudentId();
-
-        //如果一次接口都没调用过,则默认活检次数为1,否则从库中取出已活检次数
-        Integer verifyTimes = 1;
-        FaceBiopsyEntity faceBiopsyEntity = faceBiopsyRepo.findByExamRecordDataId(examRecordDataId);
-        if (faceBiopsyEntity != null) {
-            verifyTimes = faceBiopsyEntity.getVerifiedTimes();
-        }
-
-        //默认二次活检的开始与结束时间
-        int minSecondFaceCheckMinute = PropertyHolder.getInt("oe.faceBiopsy.minSecondFaceCheckMinute", 1);
-        int maxSecondFaceCheckMinute = PropertyHolder.getInt("oe.faceBiopsy.maxSecondFaceCheckMinute", 3);
-
-        //如果是第一次活体检测
-        if (verifyTimes == 1) {
-            String faceVerifyStartMinuteStr = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                    studentId, ExamProperties.FACE_VERIFY_START_MINUTE.name()).getValue();
-            Integer faceVerifyStartMinute = Integer.valueOf(faceVerifyStartMinuteStr);
-
-            String faceVerifyEndMinuteStr = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                    studentId, ExamProperties.FACE_VERIFY_END_MINUTE.name()).getValue();
-            Integer faceVerifyEndMinute = Integer.valueOf(faceVerifyEndMinuteStr);
-
-            Integer heartbeat = getHeartbeat(studentId);
-
-            //	case1.如果考生已使用的考试时间(即心跳时间)还未达到系统设置的活体检测开始时间,
-            //	则实际活体检测时间=random(配置结束时间,配置开始时间)-考试已用时间
-            if (heartbeat < faceVerifyStartMinute) {
-                return CommonUtil.calculationRandomNumber(faceVerifyStartMinute, faceVerifyEndMinute) - heartbeat;
-            }
-            //	case2如果配置开始时间<考生已使用的考试时间<配置结束时间,
-            //	则实际活体检测时间=random(配置结束时间,考试已用时间)-考试已用时间,如果结果小于1分钟则默认1分钟
-            else if (heartbeat >= faceVerifyStartMinute && heartbeat < faceVerifyEndMinute) {
-                int startMinute = CommonUtil.calculationRandomNumber(heartbeat, faceVerifyEndMinute) - heartbeat;
-                return startMinute < 1 ? 1 : startMinute;
-            }
-            //case3如果考试已用时间>配置结束时间,则默认random(1,4)分钟后开始人脸检测
-            else {
-                return CommonUtil.calculationRandomNumber(minSecondFaceCheckMinute, maxSecondFaceCheckMinute);
-            }
-        }
-        //如果是第二次人脸
-        else {
-            return CommonUtil.calculationRandomNumber(minSecondFaceCheckMinute, maxSecondFaceCheckMinute);
-        }
-    }
-
-    /**
-     * 冻结时间外生成人脸活体检测的开始时间
-     *
-     * @return
-     */
-    private Integer generateOutFreezeTimeFaceBiopsyStartMinute(Long examRecordDataId) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        Long examId = examRecordData.getExamId();
-        Long orgId = examRecordData.getOrgId();
-        Long studentId = examRecordData.getStudentId();
-
-        //如果冻结时间外不添加活体检测,则直接返回null
-        if (!isAddFaceVerifyOutFreezeTime(examId, orgId, studentId)) {
-            return null;
-        }
-
-        String strOutFreezeTimeFaceVerifyStartMinute = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                studentId, ExamProperties.OUT_FREEZE_TIME_FACE_VERIFY_START_MINUTE.name()).getValue();
-        Integer faceVerifyStartMinute = Integer.valueOf(strOutFreezeTimeFaceVerifyStartMinute);
-
-        String strOutFreezeTimeFaceVerifyEndMinute = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                studentId, ExamProperties.OUT_FREEZE_TIME_FACE_VERIFY_END_MINUTE.name()).getValue();
-        Integer faceVerifyEndMinute = Integer.valueOf(strOutFreezeTimeFaceVerifyEndMinute);
-
-        //活检开始时间 = (冻结时间 + random(配置开始时间,配置结束时间)) -  考试已用时间
-        int result = getFreezeTime(studentId) +
-                CommonUtil.calculationRandomNumber(faceVerifyStartMinute, faceVerifyEndMinute) - getHeartbeat(studentId);
-        return result < 1 ? 1 : result;
-    }
-
-    /**
-     * 是否允许冻结时间外添加人脸活体检测
-     *
-     * @param examId
-     * @param orgId
-     * @return
-     */
-    private boolean isAddFaceVerifyOutFreezeTime(Long examId, Long orgId, Long studentId) {
-        String addFaceVerifyOutFreezeTime = ExamCacheTransferHelper.getCachedExamProperty(examId,
-                studentId, ExamProperties.ADD_FACE_VERIFY_OUT_FREEZE_TIME.name()).getValue();
-        return Constants.isTrue.equals(addFaceVerifyOutFreezeTime);
-    }
-
-    /**
-     * 是否允许冻结时间外添加人脸活体检测
-     *
-     * @param examRecordDataId
-     * @return
-     */
-    private boolean isAddFaceVerifyOutFreezeTime(Long examRecordDataId) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        return isAddFaceVerifyOutFreezeTime(examRecordData.getExamId(),
-                examRecordData.getOrgId(), examRecordData.getStudentId());
-    }
-
-    /**
-     * 当前考试是否在冻结时间内
-     *
-     * @param examRecordDataId 考试记录id
-     * @return
-     */
-    private boolean calculateIsInFreezeTime(Long examRecordDataId) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-
-        ExamSessionInfo examSessionInfo = examSessionInfoService.getExamSessionInfo(examRecordData.getStudentId());
-        if (examSessionInfo == null) {
-            throw new StatusException("201003", "考试会话已过期");
-        }
-        Long usedMilliseconds = examControlService.calculateExamUsedMilliseconds(examSessionInfo);
-
-        return usedMilliseconds < examSessionInfo.getFreezeTime() * 60 * 1000;
-    }
-
-    /**
-     * 获取是否开启人脸活体检测
-     *
-     * @param examRecordDataId 考试记录id
-     * @return
-     */
-    private Boolean getIsFaceVerify(Long examRecordDataId) {
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
-                ExamRecordDataEntity.class);
-        Long orgId = examRecordData.getOrgId();
-
-        //如果未开启人脸活体检测,则返回null
-        return FaceBiopsyHelper.isFaceVerify(examRecordData.getRootOrgId(),
-                examRecordData.getExamId(), examRecordData.getStudentId());
-    }
-}

+ 0 - 345
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/OfflineExamServiceImpl.java

@@ -1,345 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.commons.util.HttpClientUtil;
-import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamProperties;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamRecordForMarkingEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.ExamStudentEntity;
-import cn.com.qmth.examcloud.core.oe.common.entity.OfflineFileEntity;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamType;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordForMarkingRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.OfflineFileRepo;
-import cn.com.qmth.examcloud.core.oe.common.service.GainBaseDataService;
-import cn.com.qmth.examcloud.core.oe.student.bean.OfflineExamCourseInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordDataService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordForMarkingService;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamScoreService;
-import cn.com.qmth.examcloud.core.oe.student.service.OfflineExamService;
-import cn.com.qmth.examcloud.core.questions.api.ExtractConfigCloudService;
-import cn.com.qmth.examcloud.core.questions.api.request.GetPaperReq;
-import cn.com.qmth.examcloud.core.questions.api.response.GetPaperResp;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.*;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import main.java.com.UpYun;
-import org.apache.commons.io.FileUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import javax.transaction.Transactional;
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * @author chenken
- * @date 2018年9月5日 下午3:24:44
- * @company QMTH
- * @description 离线考试服务实现
- */
-@Service("offlineExamService")
-public class OfflineExamServiceImpl implements OfflineExamService {
-
-    @Autowired
-    private ExamStudentRepo examStudentRepo;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private GainBaseDataService gainBaseDataService;
-
-    @Autowired
-    private ExtractConfigCloudService extractConfigCloudService;
-
-    @Autowired
-    private ExamRecordDataService examRecordDataService;
-
-    @Autowired
-    private ExamScoreService examScoreService;
-
-    @Autowired
-    private ExamRecordForMarkingService examRecordForMarkingService;
-
-    @Autowired
-    private ExamRecordForMarkingRepo examRecordForMarkingRepo;
-
-    @Autowired
-    private OfflineFileRepo offlineFileRepo;
-
-    @Value("${$upyun.site.1.bucketName}")
-    private String bucketName;
-
-    @Value("${$upyun.site.1.userName}")
-    private String userName;
-
-    @Value("${$upyun.site.1.password}")
-    private String password;
-
-    @Value("${app.upyun.uploadUrl}")
-    private String upyunUploadUrl;
-
-    @Value("${$upyun.site.1.domain}")
-    private String upyunFileUrl;
-
-    @Override
-    public List<OfflineExamCourseInfo> getOfflineCourse(Long studentId) {
-        List<ExamStudentEntity> examStudents = examStudentRepo.findByStudentId(studentId);
-        List<OfflineExamCourseInfo> offlineExamCourseInfoList = new ArrayList<OfflineExamCourseInfo>();
-        for (ExamStudentEntity examStudent : examStudents) {
-            ExamBean examBean = ExamCacheTransferHelper.getCachedExam(examStudent.getExamId(), studentId);
-            if (!ExamType.OFFLINE.name().equals(examBean.getExamType())) {
-                continue;
-            }
-            if (!examBean.getEnable() || (examBean.getExamLimit() != null && examBean.getExamLimit())) {
-                continue;
-            }
-            if (new Date().before(examBean.getBeginTime()) || examBean.getEndTime().before(new Date())) {
-                continue;
-            }
-            offlineExamCourseInfoList.add(toOfflineExamCourse(examStudent, examBean));
-        }
-        return offlineExamCourseInfoList;
-    }
-
-    private OfflineExamCourseInfo toOfflineExamCourse(ExamStudentEntity examStudent, ExamBean examBean) {
-        OfflineExamCourseInfo offlineExamCourseInfo = new OfflineExamCourseInfo();
-
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudent.getCourseId());
-        offlineExamCourseInfo.setCourseCode(courseBean.getCode());
-        offlineExamCourseInfo.setCourseLevel(courseBean.getLevel());
-        offlineExamCourseInfo.setCourseName(courseBean.getName());
-        offlineExamCourseInfo.setExamId(examBean.getId());
-        offlineExamCourseInfo.setExamName(examBean.getName());
-        offlineExamCourseInfo.setSpecialtyName(examStudent.getSpecialtyName());
-        offlineExamCourseInfo.setExamStudentId(examStudent.getExamStudentId());
-        offlineExamCourseInfo.setStudentCode(examStudent.getStudentCode());
-        offlineExamCourseInfo.setStudentName(examStudent.getStudentName());
-        offlineExamCourseInfo.setStartTime(examBean.getBeginTime());
-        offlineExamCourseInfo.setEndTime(examBean.getEndTime());
-        Date nowDate = new Date();
-        if (nowDate.getTime() > offlineExamCourseInfo.getStartTime().getTime()
-                && nowDate.getTime() < offlineExamCourseInfo.getEndTime().getTime()) {
-            offlineExamCourseInfo.setIsvalid(true);
-        } else {
-            offlineExamCourseInfo.setIsvalid(false);
-        }
-
-        OrgCacheBean orgBean = gainBaseDataService.getOrgBean(examStudent.getOrgId());
-        offlineExamCourseInfo.setOrgName(orgBean.getName());
-
-        List<ExamRecordDataEntity> examRecords = examRecordDataRepo.findByExamStudentId(examStudent.getExamStudentId());
-        if (examRecords.size() > 0) {
-            ExamRecordDataEntity examRecordDataEntity = examRecords.get(0);
-            offlineExamCourseInfo.setExamRecordDataId(examRecordDataEntity.getId());
-            offlineExamCourseInfo.setStatus(examRecordDataEntity.getExamRecordStatus());
-            offlineExamCourseInfo.setPaperId(examRecordDataEntity.getBasePaperId());
-            if (examRecordDataEntity.getExamRecordStatus() == ExamRecordStatus.EXAM_END) {
-                ExamRecordForMarkingEntity examRecordForMarkingEntity = examRecordForMarkingRepo.findByExamRecordDataId(examRecordDataEntity.getId());
-                offlineExamCourseInfo.setOfflineFileUrl(examRecordForMarkingEntity.getOfflineFileUrl());
-                offlineExamCourseInfo.setFileName(examRecordForMarkingEntity.getOfflineFileName());
-            }
-        }
-        return offlineExamCourseInfo;
-    }
-
-    @Override
-    public void startOfflineExam(Long examStudentId) {
-        SysPropertyCacheBean stuClientLoginLimit = CacheHelper.getSysProperty("STU_CLIENT_LOGIN_LIMIT");
-        Boolean stuClientLoginLimitBoolean = false;
-        if (stuClientLoginLimit.getHasValue()) {
-            stuClientLoginLimitBoolean = Boolean.valueOf(stuClientLoginLimit.getValue().toString());
-        }
-        if (stuClientLoginLimitBoolean) {
-            throw new StatusException("OE-001505", "系统维护中... ...");
-        }
-        List<ExamRecordDataEntity> examRecordList = examRecordDataRepo.findByExamStudentId(examStudentId);
-        if (examRecordList != null && examRecordList.size() > 0) {
-            throw new StatusException("OfflineExamServiceImpl-startOfflineExam-exception", "已经存在examStudentId=" + examStudentId + "的离线考试记录");
-        }
-        //获取考生信息
-        ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(examStudentId);
-        //检查并获取课程信息
-        CourseBean courseBean = checkCourse(examStudentEntity);
-        //检查并获取考试信息
-        ExamBean examBean = checkExam(examStudentEntity);
-        //获取题库试卷结构(由于存在随机抽卷,所以不能缓存 )
-        GetPaperReq getPaperReq = new GetPaperReq();
-        getPaperReq.setExamId(examStudentEntity.getExamId());
-        getPaperReq.setCourseCode(courseBean.getCode());
-        getPaperReq.setGroupCode(examStudentEntity.getPaperType());
-        GetPaperResp getPaperResp = extractConfigCloudService.getPaper(getPaperReq);
-
-        //生成考试记录
-        ExamRecordDataEntity examRecordData = examRecordDataService.createOfflineExamRecordData(examStudentEntity,
-                examBean, courseBean, getPaperResp.getPaperId(),
-                null, getPaperResp.getDefaultPaper().getFullyObjective());
-        //生成分数
-        examScoreService.createExamScoreWithOffline(examRecordData.getId());
-        //更新考生
-        examStudentRepo.updateExamStudentFinished(examStudentId);
-    }
-
-    private CourseBean checkCourse(ExamStudentEntity examStudentEntity) {
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudentEntity.getCourseId());
-        if (!courseBean.getEnable()) {
-            throw new StatusException("OfflineExamServiceImpl-checkCourse-exception", "该课程已被禁用");
-        }
-        return courseBean;
-    }
-
-    private ExamBean checkExam(ExamStudentEntity examStudentEntity) {
-        Long examId = examStudentEntity.getExamId();
-        Long studentId = examStudentEntity.getStudentId();
-        ExamBean examBean = ExamCacheTransferHelper.getCachedExam(examId, studentId);
-
-        //如果启用了了特殊设置,并且无特殊设置时结束考试 配置 设置为true..且实际未设置特殊设置则不允许考试
-        ExamPropertyCacheBean limitedIfNoSpecialSettings = ExamCacheTransferHelper.getDefaultCachedExamProperty(examId,
-                ExamProperties.LIMITED_IF_NO_SPECIAL_SETTINGS.toString());
-        if (examBean.getSpecialSettingsEnabled() &&
-                (limitedIfNoSpecialSettings.getHasValue() && Boolean.valueOf(limitedIfNoSpecialSettings.getValue()))) {
-
-            //学生特殊设置开启未配置,不允许考试
-            if (examBean.getSpecialSettingsType() == ExamSpecialSettingsType.STUDENT_BASED) {
-                ExamStudentSettingsCacheBean specialSettings = CacheHelper.getExamStudentSettings(examId, studentId);
-                if (!specialSettings.getHasValue()) {
-                    throw new StatusException("100014", "考试配置未完成,不允许考试");
-                }
-            }
-
-            //机构特殊设置开启未配置,不允许考试
-            if (examBean.getSpecialSettingsType() == ExamSpecialSettingsType.ORG_BASED) {
-                //需求调整,所有的组织机构取学生表所关联的orgId
-                Long orgId = CacheHelper.getStudent(studentId).getOrgId();
-                ExamOrgSettingsCacheBean specialSettings = CacheHelper.getExamOrgSettings(examId, orgId);
-                if (!specialSettings.getHasValue()) {
-                    throw new StatusException("100015", "考试配置未完成,不允许考试");
-                }
-            }
-        }
-
-        if (!examBean.getEnable() || (examBean.getExamLimit() != null && examBean.getExamLimit())) {
-            throw new StatusException("ExamControlServiceImpl-checkExam-exception-01", "暂无考试资格,请与学校老师联系");
-        }
-        if (new Date().before(examBean.getBeginTime())) {
-            throw new StatusException("ExamControlServiceImpl-checkExam-exception-02", "考试未开始");
-        }
-        if (examBean.getEndTime().before(new Date())) {
-            throw new StatusException("ExamControlServiceImpl-checkExam-exception-03", "本次考试已结束");
-        }
-        return examBean;
-    }
-
-    @Override
-    @Transactional
-    public void submitPaper(Long examRecordDataId, File tempFile) throws Exception {
-        SysPropertyCacheBean stuClientLoginLimit = CacheHelper.getSysProperty("STU_CLIENT_LOGIN_LIMIT");
-        Boolean stuClientLoginLimitBoolean = false;
-        if (stuClientLoginLimit.getHasValue()) {
-            stuClientLoginLimitBoolean = Boolean.valueOf(stuClientLoginLimit.getValue().toString());
-        }
-        if (stuClientLoginLimitBoolean) {
-            throw new StatusException("OE-001505", "系统维护中... ...");
-        }
-        ExamRecordDataEntity examRecordDataEntity = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        if (examRecordDataEntity == null) {
-            return;
-        }
-        String fileName = tempFile.getName();
-        String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
-        //上传文件至又拍云
-        String fileNewName = createOfflineFileName(examRecordDataEntity) + "." + fileSuffix;
-
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        String upyunFilePath = upyunUploadUrl + examRecordData.getExamId() + "/" + fileNewName;
-        UpYun upyun = new UpYun(bucketName, userName, password);
-        upyun.writeFile(upyunFilePath, tempFile, true);
-        tempFile.delete();
-        //保存 文件信息
-        String fileUrl = upyunFileUrl + upyunFilePath;
-        examRecordForMarkingService.saveOffLineExamRecordForMarking(examRecordDataEntity, fileNewName, fileUrl);
-        //更新考试记录状态
-        examRecordDataEntity.setExamRecordStatus(ExamRecordStatus.EXAM_END);
-        examRecordDataEntity.setEndTime(new Date());//交卷(上传)时间
-        examRecordDataRepo.save(examRecordDataEntity);
-    }
-
-    @Override
-    public void downOfflineExam() {
-        List<OfflineFileEntity> list = offlineFileRepo.findAll();
-        for (int i = 0; i < list.size(); i++) {
-            OfflineFileEntity fileEntity = list.get(i);
-            String fileUrl = fileEntity.getFileUrl();
-            System.out.println((i + 1) + "开始下载文件:" + fileEntity.getFileUrl());
-
-            //对fileUrl中的中文进行编码
-            fileUrl = encode(fileUrl, "utf-8");
-
-            byte[] bs;
-            try {
-                bs = HttpClientUtil.get(fileUrl);
-            } catch (Exception e) {
-                System.err.println((i + 1) + "文件:" + fileEntity.getFileUrl() + "下载失败,继续下一个文件...");
-                e.printStackTrace();
-                continue;
-            }
-
-            String suffix = fileUrl.substring(fileUrl.lastIndexOf("."));
-            String filePath = "d:/data/" + fileEntity.getStudentCode() + "_" + fileEntity.getCourseCode() + suffix;
-            File file = new File(filePath);
-            try {
-                FileUtils.writeByteArrayToFile(file, bs);
-                System.out.println((i + 1) + "文件:" + fileEntity.getFileUrl() + "下载完毕...");
-                System.out.println("剩余" + (list.size() - i - 1) + "个文件待下载...");
-            } catch (IOException e) {
-                throw new StatusException("100003", "文件读写失败");
-            }
-        }
-    }
-
-    private static String encode(String url, String chartSet) {
-        try {
-            Matcher matcher = Pattern.compile("[^\\x00-\\xff]").matcher(url);//双字节,包括中文和中文符号[^\x00-\xff]  中文[\u4e00-\u9fa5]
-            while (matcher.find()) {
-                String tmp = matcher.group();
-                url = url.replaceAll(tmp, java.net.URLEncoder.encode(tmp, chartSet));
-            }
-        } catch (UnsupportedEncodingException e) {
-            try {
-                throw e;
-            } catch (UnsupportedEncodingException e1) {
-                e1.printStackTrace();
-            }
-        }
-        return url;
-    }
-
-    private String createOfflineFileName(ExamRecordDataEntity examRecordDataEntity) {
-        long currentTime = System.currentTimeMillis();
-
-        long orgId = examRecordDataEntity.getOrgId();
-        OrgCacheBean orgBean = gainBaseDataService.getOrgBean(orgId);
-        long courseId = examRecordDataEntity.getCourseId();
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(courseId);
-        return orgBean.getCode() + "_" +
-                examRecordDataEntity.getStudentCode() + "_" +
-                examRecordDataEntity.getStudentName() + "_" +
-                courseBean.getCode() + "_" + currentTime;
-    }
-
-
-}

+ 0 - 264
examcloud-core-oe-student-service/src/main/java/cn/com/qmth/examcloud/core/oe/student/service/impl/PracticeServiceImpl.java

@@ -1,264 +0,0 @@
-package cn.com.qmth.examcloud.core.oe.student.service.impl;
-
-import cn.com.qmth.examcloud.core.basic.api.bean.CourseBean;
-import cn.com.qmth.examcloud.core.oe.common.helper.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.core.oe.common.base.utils.QuestionTypeUtil;
-import cn.com.qmth.examcloud.core.oe.common.entity.*;
-import cn.com.qmth.examcloud.core.oe.common.enums.ExamRecordStatus;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamRecordQuestionsRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamScoreRepo;
-import cn.com.qmth.examcloud.core.oe.common.repository.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.oe.common.service.GainBaseDataService;
-import cn.com.qmth.examcloud.core.oe.student.bean.PaperStructInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeCourseInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeDetailInfo;
-import cn.com.qmth.examcloud.core.oe.student.bean.PracticeRecordInfo;
-import cn.com.qmth.examcloud.core.oe.student.service.ExamRecordPaperStructService;
-import cn.com.qmth.examcloud.core.oe.student.service.PracticeService;
-import cn.com.qmth.examcloud.examwork.api.bean.ExamBean;
-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.web.helpers.GlobalHelper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-
-/**
- * @author chenken
- * @date 2018年9月7日 上午11:05:18
- * @company QMTH
- * @description PracticeServiceImpl.java
- */
-@Service("practiceService")
-public class PracticeServiceImpl implements PracticeService {
-
-    @Autowired
-    private ExamStudentRepo examStudentRepo;
-
-    @Autowired
-    private ExamRecordDataRepo examRecordDataRepo;
-
-    @Autowired
-    private ExamScoreRepo examScoreRepo;
-
-    @Autowired
-    private ExamRecordQuestionsRepo examRecordQuestionsRepo;
-
-    @Autowired
-    private ExamRecordPaperStructService examRecordPaperStructService;
-
-    @Autowired
-    private GainBaseDataService gainBaseDataService;
-
-    @Override
-    public List<PracticeCourseInfo> queryPracticeCourseList(Long examId, Long studentId) {
-        if (examId == null || studentId == null) {
-            return null;
-        }
-        List<ExamStudentEntity> examStudentList = examStudentRepo.findByExamIdAndStudentId(examId, studentId);
-        if (examStudentList == null || examStudentList.size() == 0) {
-            return null;
-        }
-        List<PracticeCourseInfo> practiceCourseInfos = new ArrayList<PracticeCourseInfo>();
-        ExamBean examBean = ExamCacheTransferHelper.getCachedExam(examId,studentId);
-        for (ExamStudentEntity examStudent : examStudentList) {
-            practiceCourseInfos.add(buildPracticeCourseInfo(examStudent, examBean));
-        }
-        return practiceCourseInfos;
-    }
-
-
-    private PracticeCourseInfo buildPracticeCourseInfo(ExamStudentEntity examStudent, ExamBean examBean) {
-        PracticeCourseInfo practiceCourseInfo = new PracticeCourseInfo();
-        practiceCourseInfo.setExamStudentId(examStudent.getExamStudentId());
-        practiceCourseInfo.setCourseCode(examStudent.getCourseCode());
-
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudent.getCourseId());
-        practiceCourseInfo.setCourseName(courseBean.getName());
-        practiceCourseInfo.setStudentCode(examStudent.getStudentCode());
-        practiceCourseInfo.setStudentName(examStudent.getStudentName());
-
-        practiceCourseInfo.setExamId(examBean.getId());
-        practiceCourseInfo.setExamName(examBean.getName());
-        practiceCourseInfo.setExamType(examBean.getExamType());
-        practiceCourseInfo.setStartTime(examBean.getBeginTime());
-        practiceCourseInfo.setEndTime(examBean.getEndTime());
-
-        List<ExamRecordDataEntity> examRecordEntities = examRecordDataRepo.findByExamStudentId(examStudent.getExamStudentId());
-
-        int allExamRecordNums = 0;
-        List<ExamScoreEntity> examScoreEntities = new ArrayList<ExamScoreEntity>();
-        for (ExamRecordDataEntity examRecordData : examRecordEntities) {
-            if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
-                allExamRecordNums++;
-                ExamScoreEntity examScore = examScoreRepo.findByExamRecordDataId(examRecordData.getId());
-                examScoreEntities.add(examScore);
-            }
-        }
-        double allObjectiveAccuracy = 0;//总正确率
-        double maxObjectiveAccuracy = 0;//最高客观题正确率
-        long recentObjectiveAccuracyId = 0;//最近ID
-        double recentObjectiveAccuracy = 0;//最近客观题正确率
-
-        for (ExamScoreEntity examScore : examScoreEntities) {
-            if (examScore != null) {
-                if (examScore.getObjectiveAccuracy() > maxObjectiveAccuracy) {
-                    maxObjectiveAccuracy = examScore.getObjectiveAccuracy();
-                }
-                if (examScore.getId() > recentObjectiveAccuracyId) {//判断是否为最近的
-                    recentObjectiveAccuracyId = examScore.getId();
-                    recentObjectiveAccuracy = examScore.getObjectiveAccuracy();
-                }
-                allObjectiveAccuracy = allObjectiveAccuracy + examScore.getObjectiveAccuracy();
-            }
-        }
-        //平均正确率
-        double aveObjectiveAccuracy = 0D;
-        if (allExamRecordNums > 0) {
-            aveObjectiveAccuracy = Double.valueOf(new DecimalFormat("#.00").format(allObjectiveAccuracy / allExamRecordNums));
-        }
-        practiceCourseInfo.setAveObjectiveAccuracy(aveObjectiveAccuracy);
-        practiceCourseInfo.setMaxObjectiveAccuracy(maxObjectiveAccuracy);
-        practiceCourseInfo.setRecentObjectiveAccuracy(recentObjectiveAccuracy);
-        practiceCourseInfo.setPracticeCount(allExamRecordNums);//练习总次数
-        return practiceCourseInfo;
-    }
-
-    @Override
-    public List<PracticeRecordInfo> queryPracticeRecordList(Long examStudentId) {
-        if (examStudentId == null) {
-            return null;
-        }
-        List<ExamRecordDataEntity> examRecordDataList = examRecordDataRepo.findByExamStudentId(examStudentId);
-        List<PracticeRecordInfo> practiceRecords = new ArrayList<PracticeRecordInfo>();
-        ExamStudentEntity examStudent = examStudentRepo.findByExamStudentId(examStudentId);
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examStudent.getCourseId());
-        for (ExamRecordDataEntity examRecordData : examRecordDataList) {
-            if (examRecordData.getExamRecordStatus() != ExamRecordStatus.EXAM_ING) {
-                practiceRecords.add(buildPracticeRecord(examRecordData, courseBean));
-            }
-        }
-        return practiceRecords;
-    }
-
-    private PracticeRecordInfo buildPracticeRecord(ExamRecordDataEntity examRecordData, CourseBean courseBean) {
-        PracticeRecordInfo practiceRecordInfo = new PracticeRecordInfo();
-
-        practiceRecordInfo.setId(examRecordData.getId());
-        practiceRecordInfo.setCourseCode(courseBean.getCode());
-        practiceRecordInfo.setCourseName(courseBean.getName());
-        practiceRecordInfo.setStartTime(examRecordData.getStartTime());
-        practiceRecordInfo.setEndTime(examRecordData.getEndTime());
-        practiceRecordInfo.setUsedExamTime(examRecordData.getUsedExamTime());
-
-        ExamScoreEntity examScoreEntity = examScoreRepo.findByExamRecordDataId(examRecordData.getId());
-        practiceRecordInfo.setObjectiveAccuracy(examScoreEntity.getObjectiveAccuracy());//客观题答对的比率
-        ExamRecordQuestionsEntity examRecordQuestions = examRecordQuestionsRepo.findByExamRecordDataId(examRecordData.getId());
-        List<ExamQuestionEntity> examQuestionEntities = examRecordQuestions.getExamQuestionEntities();
-        practiceRecordInfo = calculationExamQuestionSituationInfo(practiceRecordInfo, examQuestionEntities);
-
-        return practiceRecordInfo;
-    }
-
-    /**
-     * 计算答题情况
-     *
-     * @param practiceRecordInfo
-     * @param examQuestionEntities
-     * @return
-     */
-    private PracticeRecordInfo calculationExamQuestionSituationInfo(PracticeRecordInfo practiceRecordInfo, List<ExamQuestionEntity> examQuestionEntities) {
-        if (practiceRecordInfo == null) {
-            practiceRecordInfo = new PracticeRecordInfo();
-        }
-        int succQuestionNum = 0;//正确答题数
-        int failQuestionNum = 0;//错误答题数
-        int notAnsweredCount = 0;//未作答题数
-        for (ExamQuestionEntity examQuestionEntity : examQuestionEntities) {
-            if (examQuestionEntity.getIsAnswer() == null || !examQuestionEntity.getIsAnswer()) {
-                notAnsweredCount++;
-            } else {
-                //客观题判断正确错误
-                if (QuestionTypeUtil.isObjectiveQuestion(examQuestionEntity.getQuestionType())) {
-                    if (examQuestionEntity.getCorrectAnswer() != null
-                            && examQuestionEntity.getStudentAnswer() != null
-                            && examQuestionEntity.getCorrectAnswer().equals(examQuestionEntity.getStudentAnswer())) {
-                        succQuestionNum++;
-                    } else {
-                        failQuestionNum++;
-                    }
-                }
-            }
-        }
-        int objectiveQuestionsNum = 0;//客观题总数
-        for (ExamQuestionEntity examQuestionEntity : examQuestionEntities) {
-            if (QuestionTypeUtil.isObjectiveQuestion(examQuestionEntity.getQuestionType())) {
-                objectiveQuestionsNum++;
-            }
-        }
-        practiceRecordInfo.setObjectiveNum(objectiveQuestionsNum);
-        practiceRecordInfo.setSuccQuestionNum(succQuestionNum);
-        practiceRecordInfo.setFailQuestionNum(failQuestionNum);
-        practiceRecordInfo.setNotAnsweredCount(notAnsweredCount);
-        practiceRecordInfo.setTotalQuestionCount(examQuestionEntities.size());
-        return practiceRecordInfo;
-    }
-
-    @Override
-    public PracticeDetailInfo getPracticeDetailInfo(Long examRecordDataId) {
-        if (examRecordDataId == null) {
-            return null;
-        }
-        PracticeDetailInfo practiceDetailInfo = new PracticeDetailInfo();
-        //取出试卷结构
-        ExamRecordPaperStructEntity examRecordPaperStruct = examRecordPaperStructService.getExamRecordPaperStruct(examRecordDataId);
-        DefaultPaper defaultPaper = examRecordPaperStruct.getDefaultPaper();
-        List<PaperStructInfo> paperStructInfos = new ArrayList<PaperStructInfo>();
-        List<DefaultQuestionGroup> questionGroupList = defaultPaper.getQuestionGroupList();
-        //取出作答记录
-        ExamRecordQuestionsEntity examRecordQuestions = examRecordQuestionsRepo.findByExamRecordDataId(examRecordDataId);
-        List<ExamQuestionEntity> examQuestionEntities = examRecordQuestions.getExamQuestionEntities();
-        //遍历大题
-        int objectiveNum = 0;//各个大题中的客观题总数
-        int objectSuccessNum = 0;//各个大题中的客观题答对的总数量
-        for (int i = 0; i < questionGroupList.size(); i++) {
-            DefaultQuestionGroup defaultQuestionGroup = questionGroupList.get(i);
-            PaperStructInfo paperStructInfo = new PaperStructInfo();
-            paperStructInfo.setTitle(defaultQuestionGroup.getGroupName());//大题名称
-            paperStructInfo.setIndex(i + 1);//大题号
-            //使用大题号过滤
-            List<ExamQuestionEntity> examQuestionEntitiesOfMainQuestion = examQuestionEntities.stream().filter(o1 -> o1.getMainNumber().intValue() == paperStructInfo.getIndex()).collect(Collectors.toList());
-            //计算出作答情况
-            PracticeRecordInfo practiceRecordInfo = calculationExamQuestionSituationInfo(null, examQuestionEntitiesOfMainQuestion);
-
-            objectiveNum += practiceRecordInfo.getObjectiveNum();
-            objectSuccessNum += practiceRecordInfo.getSuccQuestionNum();
-
-            paperStructInfo.setQuestionCount(practiceRecordInfo.getTotalQuestionCount());
-            paperStructInfo.setSuccQuestionNum(practiceRecordInfo.getSuccQuestionNum());
-            paperStructInfo.setFailQuestionNum(practiceRecordInfo.getFailQuestionNum());
-            paperStructInfo.setNotAnsweredCount(practiceRecordInfo.getNotAnsweredCount());
-            paperStructInfos.add(paperStructInfo);
-        }
-        practiceDetailInfo.setPaperStructInfos(paperStructInfos);
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        CourseBean courseBean = ExamCacheTransferHelper.getCachedCourse(examRecordData.getCourseId());
-        practiceDetailInfo.setCourseCode(courseBean.getCode());
-        practiceDetailInfo.setCourseName(courseBean.getName());
-        practiceDetailInfo.setId(examRecordDataId);
-
-        double objectiveAccuracy = 0;//客观题答题正确率
-        if (objectiveNum > 0) {
-            objectiveAccuracy = Double.valueOf(new DecimalFormat("#.00").format(objectSuccessNum * 100D / objectiveNum));
-        }
-        practiceDetailInfo.setObjectiveAccuracy(objectiveAccuracy);
-        return practiceDetailInfo;
-    }
-
-}