|
@@ -0,0 +1,673 @@
|
|
|
+package cn.com.qmth.examcloud.core.oe.admin.api.provider;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.api.commons.enums.ExamType;
|
|
|
+import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
+import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
|
|
|
+import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.SyncExamDataCloudService;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.*;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.request.SyncExamDataReq;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.api.response.SyncExamDataResp;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.*;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.entity.*;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.dao.enums.*;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.*;
|
|
|
+import cn.com.qmth.examcloud.core.oe.admin.service.cache.ExamStudentCache;
|
|
|
+import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
|
|
|
+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.ExamSettingsCacheBean;
|
|
|
+import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
|
|
|
+import cn.com.qmth.examcloud.support.helper.FaceBiopsyHelper;
|
|
|
+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.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.domain.Example;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+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;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Description 同步考试相关数据接口
|
|
|
+ * @Author lideyin
|
|
|
+ * @Date 2019/12/20 10:32
|
|
|
+ * @Version 1.0
|
|
|
+ */
|
|
|
+@Api(tags = "同步考试相关数据接口")
|
|
|
+@RestController
|
|
|
+@RequestMapping("${$rmp.cloud.oe}/exam/sync")
|
|
|
+public class SyncExamDataCloudServiceProvider extends ControllerSupport implements SyncExamDataCloudService {
|
|
|
+
|
|
|
+ private static final long serialVersionUID = -25466948667789119L;
|
|
|
+
|
|
|
+ private static final ExamCloudLog LOG = ExamCloudLogFactory.getLog(SyncExamDataCloudServiceProvider.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExamRecordForMarkingService examRecordForMarkingService;
|
|
|
+ @Autowired
|
|
|
+ private ExamScorePushQueueService examScorePushQueueService;
|
|
|
+ @Autowired
|
|
|
+ private ExamScoreObtainQueueService examScoreObtainQueueService;
|
|
|
+ @Autowired
|
|
|
+ private ExamRecordDataRepo examRecordDataRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamStudentRepo examStudentRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamSyncCaptureRepo examSyncCaptureRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamCaptureRepo examCaptureRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamFaceLivenessVerifyRepo examFaceLivenessVerifyRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamRecordPaperStructRepo examRecordPaperStructRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamRecordQuestionsRepo examRecordQuestionsRepo;
|
|
|
+ @Autowired
|
|
|
+ private FaceBiopsyRepo faceBiopsyRepo;
|
|
|
+ @Autowired
|
|
|
+ private FaceBiopsyItemRepo faceBiopsyItemRepo;
|
|
|
+ @Autowired
|
|
|
+ private FaceBiopsyItemStepRepo faceBiopsyItemStepRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamAuditService examAuditService;
|
|
|
+ @Autowired
|
|
|
+ private ExamRecordDataSyncRepo examRecordDataSyncRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamScoreRepo examScoreRepo;
|
|
|
+ @Autowired
|
|
|
+ private ExamStudentCache examStudentCache;
|
|
|
+ @Autowired
|
|
|
+ private ExamStudentFinalScoreService examStudentFinalScoreService;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步考试记录数据
|
|
|
+ *
|
|
|
+ * @param req
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @ApiOperation(value = "同步考试记录相关数据")
|
|
|
+ @PostMapping("/syncExamData")
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public SyncExamDataResp syncExamData(@RequestBody SyncExamDataReq req) {
|
|
|
+
|
|
|
+ long st = System.currentTimeMillis();
|
|
|
+
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ Long transitionExamRecordDataId = req.getExamRecordData().getId();
|
|
|
+
|
|
|
+ //校验考试记录是否已同步,如果已同步,则直接返回
|
|
|
+ if (hasSynced(transitionExamRecordDataId)) {
|
|
|
+ return new SyncExamDataResp();
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("1 校验考试记录是否已同步", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //临时考试记录
|
|
|
+ ExamRecordDataBean transitionExamRecordData = req.getExamRecordData();
|
|
|
+
|
|
|
+ //必须先更新考生的考试次数,同步考试记录会用
|
|
|
+ Long examStudentId = transitionExamRecordData.getExamStudentId();
|
|
|
+ updateExamStudent(examStudentId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("2 更新考生考试次数", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步考试记录,并返回真实的考试记录id
|
|
|
+ Long realExamRecordDataId = syncExamRecordData(transitionExamRecordData);
|
|
|
+
|
|
|
+ startTime = this.debugCost("3 同步考试记录表", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //添加同步记录
|
|
|
+ addExamRecordDataSync(transitionExamRecordData.getId(), realExamRecordDataId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("4 添加同步关系表", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步考试分数表
|
|
|
+ Long examScoreId = syncExamScore(transitionExamRecordData, realExamRecordDataId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("5 同步考试分数表", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //计算最终分数
|
|
|
+ String examType = ExamCacheTransferHelper.getDefaultCachedExam(transitionExamRecordData.getExamId()).getExamType();
|
|
|
+ if (ExamType.ONLINE.name().equals(examType) || ExamType.OFFLINE.name().equals(examType)) {
|
|
|
+ examStudentFinalScoreService.calcAndSaveFinalScore(examStudentId);
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("6 计算最终考试分数", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步抓拍照片结果(同步抓拍的数据)
|
|
|
+ if (null != req.getExamSyncCapture()) {
|
|
|
+ syncExamSyncCapture(req.getExamSyncCapture(), realExamRecordDataId);
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("7 同步抓拍照片结果(同步抓拍的数据)", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步抓拍照片结果(异步抓拍的数据)
|
|
|
+ if (null != req.getExamCaptures()) {
|
|
|
+
|
|
|
+ syncExamCapture(req.getExamCaptures(), realExamRecordDataId);
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("8 同步抓拍照片结果(异步抓拍的数据)", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步face id活体检测数据
|
|
|
+ if (null != req.getExamFaceLivenessVerifies()) {
|
|
|
+
|
|
|
+ syncExamFaceLivenessVerify(req.getExamFaceLivenessVerifies(), realExamRecordDataId);
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("9 同步face id活体检测数据", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步新活检
|
|
|
+ if (null != req.getFaceBiopsy()) {
|
|
|
+
|
|
|
+ syncFaceBiopsy(req.getFaceBiopsy(), realExamRecordDataId);
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("10 同步face id活体检测数据", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步考试记录对应的试卷结构
|
|
|
+ syncExamRecordPaperStruct(req.getExamRecordPaperStruct(), realExamRecordDataId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("11 同步考试记录对应的试卷结构", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步作答记录
|
|
|
+ syncExamRecordQuestions(req.getExamRecordQuestions(), realExamRecordDataId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("12 同步作答记录", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //如果开启了活检
|
|
|
+ if (FaceBiopsyHelper.isFaceEnable(transitionExamRecordData.getRootOrgId(), transitionExamRecordData.getExamId(), transitionExamRecordData.getStudentId())) {
|
|
|
+ //计算违纪自动审核结果(无人脸或活检失败)
|
|
|
+ boolean isNoPhotoAndIllegality = (null == req.getExamCaptures() || req.getExamCaptures().isEmpty());//是否无照片
|
|
|
+ saveAutoAudit(transitionExamRecordData, isNoPhotoAndIllegality, realExamRecordDataId);
|
|
|
+ }
|
|
|
+
|
|
|
+ startTime = this.debugCost("13 如果开启了活检,计算违纪自动审核结果", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //同步后续处理
|
|
|
+ processAfterSyncExamData(realExamRecordDataId, examScoreId, transitionExamRecordData.getObjectiveScore(),
|
|
|
+ examStudentId, transitionExamRecordDataId);
|
|
|
+
|
|
|
+ this.debugCost("14 同步后续处理 - 共计", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ this.debugCost("100 同步考试记录相关数据 - 共计", transitionExamRecordDataId, st);
|
|
|
+
|
|
|
+ return new SyncExamDataResp();
|
|
|
+ }
|
|
|
+
|
|
|
+ public Long syncExamScore(ExamRecordDataBean transitionExamRecordData, Long realExamRecordDataId) {
|
|
|
+ //如果考试成绩不存在,则新增,否则更新数据
|
|
|
+ ExamScoreEntity examScoreEntity = examScoreRepo.findByExamRecordDataId(realExamRecordDataId);
|
|
|
+
|
|
|
+ if (examScoreEntity == null) {
|
|
|
+ examScoreEntity = new ExamScoreEntity();
|
|
|
+ examScoreEntity.setExamRecordDataId(realExamRecordDataId);
|
|
|
+ }
|
|
|
+ examScoreEntity.setObjectiveScore(transitionExamRecordData.getObjectiveScore());
|
|
|
+ examScoreEntity.setObjectiveAccuracy(transitionExamRecordData.getObjectiveAccuracy());
|
|
|
+ examScoreEntity.setTotalScore(transitionExamRecordData.getTotalScore());//交卷时,总分=客观分得分
|
|
|
+ examScoreEntity.setSubjectiveScore(transitionExamRecordData.getSubjectiveScore());
|
|
|
+ examScoreEntity.setSuccPercent(transitionExamRecordData.getSuccPercent());
|
|
|
+
|
|
|
+ ExamScoreEntity result = examScoreRepo.saveAndFlush(examScoreEntity);
|
|
|
+
|
|
|
+ return result.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新考生相关信息
|
|
|
+ * 增加考试次数,修改考试状态为已完成
|
|
|
+ *
|
|
|
+ * @param examStudentId
|
|
|
+ */
|
|
|
+ private void updateExamStudent(Long examStudentId) {
|
|
|
+ //更新数据库中的已考次数
|
|
|
+ ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(examStudentId);
|
|
|
+ if (null == examStudentEntity) {
|
|
|
+ throw new StatusException("100101", "考生id不正确");
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer usedTimes = examStudentEntity.getUsedNum() == null
|
|
|
+ ? 0
|
|
|
+ : examStudentEntity.getUsedNum();
|
|
|
+
|
|
|
+ examStudentEntity.setUsedNum(usedTimes + 1);
|
|
|
+ examStudentEntity.setFinished(true);
|
|
|
+
|
|
|
+ examStudentRepo.saveAndFlush(examStudentEntity);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加考试记录的同步记录
|
|
|
+ *
|
|
|
+ * @param cacheId
|
|
|
+ * @param dbId
|
|
|
+ */
|
|
|
+ private void addExamRecordDataSync(Long cacheId, Long dbId) {
|
|
|
+ ExamRecordDataSyncEntity entity = new ExamRecordDataSyncEntity();
|
|
|
+ entity.setCacheId(cacheId);
|
|
|
+ entity.setDbId(dbId);
|
|
|
+
|
|
|
+ examRecordDataSyncRepo.saveAndFlush(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 考试记录表是否已同步
|
|
|
+ *
|
|
|
+ * @param cacheExamRecordDataId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean hasSynced(Long cacheExamRecordDataId) {
|
|
|
+ ExamRecordDataSyncEntity query = new ExamRecordDataSyncEntity();
|
|
|
+ query.setCacheId(cacheExamRecordDataId);
|
|
|
+ Example<ExamRecordDataSyncEntity> example = Example.of(query);
|
|
|
+ return examRecordDataSyncRepo.exists(example);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Long syncExamRecordData(ExamRecordDataBean examRecordData) {
|
|
|
+
|
|
|
+
|
|
|
+ ExamRecordDataEntity examRecordDataEntity = copyExamRecordDataEntityFrom(examRecordData);
|
|
|
+
|
|
|
+ ExamRecordDataEntity result = examRecordDataRepo.saveAndFlush(examRecordDataEntity);
|
|
|
+
|
|
|
+ return result.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ private ExamRecordDataEntity copyExamRecordDataEntityFrom(ExamRecordDataBean examRecordData) {
|
|
|
+ ExamRecordDataEntity result = new ExamRecordDataEntity();
|
|
|
+ Long examId = examRecordData.getExamId();
|
|
|
+ result.setExamId(examId);
|
|
|
+ result.setExamType(ExamType.valueOf(examRecordData.getExamType()));
|
|
|
+ result.setExamStudentId(examRecordData.getExamStudentId());
|
|
|
+ Long studentId = examRecordData.getStudentId();
|
|
|
+ result.setStudentId(studentId);
|
|
|
+
|
|
|
+ //部分数据从考生表中获取
|
|
|
+ ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(examRecordData.getExamStudentId());
|
|
|
+ if (null == examStudentEntity) {
|
|
|
+ throw new StatusException("100101", "考生id不正确");
|
|
|
+ }
|
|
|
+ result.setStudentCode(examStudentEntity.getStudentCode());
|
|
|
+ result.setStudentName(examStudentEntity.getStudentName());
|
|
|
+ result.setIdentityNumber(examStudentEntity.getIdentityNumber());
|
|
|
+ result.setInfoCollector(examStudentEntity.getInfoCollector());
|
|
|
+ Integer usedNum = examStudentEntity.getUsedNum();
|
|
|
+ result.setExamOrder(getExamOrder(examId, studentId, usedNum));//考试次数
|
|
|
+ result.setIsReexamine(isReexamine(examId, studentId, usedNum));//是否重考
|
|
|
+
|
|
|
+ result.setCourseId(examRecordData.getCourseId());
|
|
|
+ result.setOrgId(examRecordData.getOrgId());
|
|
|
+ result.setRootOrgId(examRecordData.getRootOrgId());
|
|
|
+ result.setBasePaperId(examRecordData.getBasePaperId());
|
|
|
+
|
|
|
+// result.setPaperStructId(examRecordData.getPaperStructId());
|
|
|
+ result.setPaperType(examRecordData.getPaperType());
|
|
|
+
|
|
|
+ CourseCacheBean course = CacheHelper.getCourse(examRecordData.getCourseId());
|
|
|
+ result.setCourseLevel(course.getLevel());
|
|
|
+
|
|
|
+
|
|
|
+ result.setStartTime(examRecordData.getStartTime());
|
|
|
+ result.setEndTime(examRecordData.getEndTime());
|
|
|
+ result.setCleanTime(examRecordData.getCleanTime());
|
|
|
+ result.setIsWarn(examRecordData.getWarn());
|
|
|
+ result.setIsAudit(examRecordData.getAudit());
|
|
|
+ result.setIsIllegality(examRecordData.getIllegality());
|
|
|
+ result.setExamRecordStatus(ExamRecordStatus.getByName(examRecordData.getExamRecordStatus()));
|
|
|
+ result.setUsedExamTime(examRecordData.getUsedExamTime());
|
|
|
+
|
|
|
+ result.setIsContinued(examRecordData.getContinued());
|
|
|
+ result.setContinuedCount(examRecordData.getContinuedCount());
|
|
|
+ result.setFaceSuccessCount(examRecordData.getFaceSuccessCount());
|
|
|
+ result.setFaceFailedCount(examRecordData.getFaceFailedCount());
|
|
|
+ result.setFaceStrangerCount(examRecordData.getFaceStrangerCount());
|
|
|
+ result.setFaceTotalCount(examRecordData.getFaceTotalCount());
|
|
|
+ result.setFaceSuccessPercent(examRecordData.getFaceSuccessPercent());
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(examRecordData.getFaceVerifyResult())) {
|
|
|
+ result.setFaceVerifyResult(IsSuccess.valueOf(examRecordData.getFaceVerifyResult()));
|
|
|
+ }
|
|
|
+
|
|
|
+ result.setFaceLandmarkVal(examRecordData.getFaceLandmarkVal());
|
|
|
+ result.setIsAllObjectivePaper(examRecordData.getAllObjectivePaper());
|
|
|
+ result.setBaiduFaceLivenessSuccessPercent(examRecordData.getBaiduFaceLivenessSuccessPercent());
|
|
|
+ result.setIsExceed(examRecordData.getExceed());
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算考试次数
|
|
|
+ *
|
|
|
+ * @param examId 考试id
|
|
|
+ * @param studentId 学生id
|
|
|
+ * @param usedExamNum 已考次数
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Integer getExamOrder(Long examId, Long studentId, Integer usedExamNum) {
|
|
|
+ ExamSettingsCacheBean cachedExam = ExamCacheTransferHelper.getCachedExam(examId, studentId);
|
|
|
+ Integer canExamTimes = cachedExam.getExamTimes() == null ? 0 : cachedExam.getExamTimes().intValue();//可考次数
|
|
|
+
|
|
|
+ //超过可考次数,始终为可考次数+1
|
|
|
+ if (usedExamNum > canExamTimes) {
|
|
|
+ return canExamTimes + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return usedExamNum;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算是否为重考
|
|
|
+ *
|
|
|
+ * @param examId 考试id
|
|
|
+ * @param studentId 学生id
|
|
|
+ * @param usedExamNum 已考次数
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private boolean isReexamine(Long examId, Long studentId, Integer usedExamNum) {
|
|
|
+ ExamSettingsCacheBean cachedExam = ExamCacheTransferHelper.getCachedExam(examId, studentId);
|
|
|
+ Integer canExamTimes = cachedExam.getExamTimes() == null ? 0 : cachedExam.getExamTimes().intValue();//可考次数
|
|
|
+
|
|
|
+ //超过可考次数,则认为有重考
|
|
|
+ if (usedExamNum > canExamTimes) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveAutoAudit(ExamRecordDataBean examRecordData, boolean isNoPhotoAndIllegality, Long realExamRecordDataId) {
|
|
|
+ boolean isAutoAudit = false;//是否已自动审核
|
|
|
+ //无照片违纪自动审核
|
|
|
+ if (isNoPhotoAndIllegality) {
|
|
|
+ examAuditService.saveExamAuditByNoPhoto(realExamRecordDataId);
|
|
|
+ isAutoAudit = true;
|
|
|
+ } else {
|
|
|
+ //活体检测失败违纪自动审核
|
|
|
+ if (null != examRecordData.getFaceVerifyResult()
|
|
|
+ && IsSuccess.FAILED.name().equals(examRecordData.getFaceVerifyResult())
|
|
|
+ && examRecordData.getIllegality()) {
|
|
|
+ examAuditService.saveExamAuditByFaceVerifyFailed(realExamRecordDataId, examRecordData.getRootOrgId());
|
|
|
+ isAutoAudit = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //如果进行了自动审核,更新考试记录表中的自动审核状态
|
|
|
+ if (isAutoAudit) {
|
|
|
+ //更新考试记录表中的作答记录id
|
|
|
+ ExamRecordDataEntity examRecordDataEntity =
|
|
|
+ GlobalHelper.getEntity(examRecordDataRepo, realExamRecordDataId, ExamRecordDataEntity.class);
|
|
|
+ examRecordDataEntity.setIsAudit(true);
|
|
|
+ examRecordDataRepo.save(examRecordDataEntity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void syncExamRecordQuestions(ExamRecordQuestionsBean examRecordQuestions, Long realExamRecordDataId) {
|
|
|
+ ExamRecordQuestionsEntity entity = copyExamRecordQuestionsFrom(examRecordQuestions, realExamRecordDataId);
|
|
|
+ examRecordQuestionsRepo.save(entity);
|
|
|
+
|
|
|
+ //更新考试记录表中的作答记录id
|
|
|
+ ExamRecordDataEntity examRecordData =
|
|
|
+ GlobalHelper.getEntity(examRecordDataRepo, realExamRecordDataId, ExamRecordDataEntity.class);
|
|
|
+ examRecordData.setExamRecordQuestionsId(entity.getId());
|
|
|
+ examRecordDataRepo.save(examRecordData);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ExamRecordQuestionsEntity copyExamRecordQuestionsFrom(ExamRecordQuestionsBean bean, Long realExamRecordDataId) {
|
|
|
+ ExamRecordQuestionsEntity entity = new ExamRecordQuestionsEntity();
|
|
|
+ entity.setExamRecordDataId(realExamRecordDataId);
|
|
|
+
|
|
|
+ List<ExamQuestionEntity> examQuestionEntityList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (ExamQuestionBean questionBean : bean.getExamQuestionBeans()) {
|
|
|
+ ExamQuestionEntity questionEntity = new ExamQuestionEntity();
|
|
|
+
|
|
|
+ questionEntity.setExamRecordDataId(realExamRecordDataId);
|
|
|
+ questionEntity.setMainNumber(questionBean.getMainNumber());
|
|
|
+ questionEntity.setQuestionId(questionBean.getQuestionId());
|
|
|
+ questionEntity.setOrder(questionBean.getOrder());
|
|
|
+ questionEntity.setStudentAnswer(questionBean.getStudentAnswer());
|
|
|
+ questionEntity.setStudentScore(questionBean.getStudentScore());
|
|
|
+ questionEntity.setQuestionScore(questionBean.getQuestionScore());
|
|
|
+ questionEntity.setQuestionType(questionBean.getQuestionType());
|
|
|
+ questionEntity.setIsAnswer(questionBean.getAnswer());
|
|
|
+ questionEntity.setIsSign(questionBean.getSign());
|
|
|
+ questionEntity.setCorrectAnswer(questionBean.getCorrectAnswer());
|
|
|
+ questionEntity.setOptionPermutation(questionBean.getOptionPermutation());
|
|
|
+ questionEntity.setAudioPlayTimes(questionBean.getAudioPlayTimes());
|
|
|
+
|
|
|
+ if (null != questionBean.getAnswerType()) {
|
|
|
+
|
|
|
+ questionEntity.setAnswerType(AnswerType.valueOf(questionBean.getAnswerType()));
|
|
|
+ }
|
|
|
+
|
|
|
+ examQuestionEntityList.add(questionEntity);
|
|
|
+ }
|
|
|
+
|
|
|
+ entity.setExamQuestionEntities(examQuestionEntityList);
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void syncExamRecordPaperStruct(ExamRecordPaperStructBean examRecordPaperStruct, Long examRecordDataId) {
|
|
|
+ ExamRecordPaperStructEntity entity = copyExamRecordPaperStructFrom(examRecordPaperStruct, examRecordDataId);
|
|
|
+ examRecordPaperStructRepo.save(entity);
|
|
|
+
|
|
|
+ //更新考试记录表中的试卷结构id
|
|
|
+ ExamRecordDataEntity examRecordData =
|
|
|
+ GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
|
|
|
+ examRecordData.setPaperStructId(entity.getId());
|
|
|
+ examRecordDataRepo.save(examRecordData);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ExamRecordPaperStructEntity copyExamRecordPaperStructFrom(ExamRecordPaperStructBean examRecordPaperStruct, Long examRecordDataId) {
|
|
|
+ ExamRecordPaperStructEntity entity = new ExamRecordPaperStructEntity();
|
|
|
+ entity.setId(examRecordPaperStruct.getId());
|
|
|
+ entity.setDefaultPaper(examRecordPaperStruct.getDefaultPaper());
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional
|
|
|
+ public void syncFaceBiopsy(FaceBiopsyBean faceBiopsy, Long examRecordDataId) {
|
|
|
+ FaceBiopsyEntity faceBiopsyEntity = copyFaceBiopsyFrom(faceBiopsy, examRecordDataId);
|
|
|
+ faceBiopsyRepo.saveAndFlush(faceBiopsyEntity);
|
|
|
+
|
|
|
+ for (FaceBiopsyItemBean itemBean : faceBiopsy.getFaceBiopsyItems()) {
|
|
|
+ FaceBiopsyItemEntity faceBiopsyItemEntity = copyFaceBiopsyItemFrom(
|
|
|
+ itemBean, faceBiopsyEntity.getId(), examRecordDataId);
|
|
|
+ faceBiopsyItemRepo.saveAndFlush(faceBiopsyItemEntity);
|
|
|
+
|
|
|
+ List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList = copyFaceBiopsyItemStepFrom(
|
|
|
+ itemBean.getFaceBiopsyItemSteps(), faceBiopsyItemEntity.getId(), examRecordDataId);
|
|
|
+ for (FaceBiopsyItemStepEntity fbis : faceBiopsyItemStepEntityList) {
|
|
|
+ faceBiopsyItemStepRepo.saveAndFlush(fbis);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private FaceBiopsyEntity copyFaceBiopsyFrom(FaceBiopsyBean bean, Long examRecordDataId) {
|
|
|
+ FaceBiopsyEntity entity = new FaceBiopsyEntity();
|
|
|
+ entity.setRootOrgId(bean.getRootOrgId());
|
|
|
+ entity.setExamRecordDataId(examRecordDataId);
|
|
|
+ entity.setResult(bean.getResult());
|
|
|
+ entity.setErrorMsg(bean.getErrorMsg());
|
|
|
+ entity.setVerifiedTimes(bean.getVerifiedTimes());
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private FaceBiopsyItemEntity copyFaceBiopsyItemFrom(FaceBiopsyItemBean bean, Long faceByiopsyId, Long examRecordDataId) {
|
|
|
+ FaceBiopsyItemEntity entity = new FaceBiopsyItemEntity();
|
|
|
+ entity.setExamRecordDataId(examRecordDataId);
|
|
|
+ entity.setFaceBiopsyId(faceByiopsyId);
|
|
|
+ entity.setFaceBiopsyType(FaceBiopsyType.valueOf(bean.getFaceBiopsyType()));
|
|
|
+ entity.setCompleted(bean.getCompleted());
|
|
|
+ entity.setResult(bean.getResult());
|
|
|
+ entity.setErrorMsg(bean.getErrorMsg());
|
|
|
+ entity.setInFreezeTime(bean.getInFreezeTime());
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<FaceBiopsyItemStepEntity> copyFaceBiopsyItemStepFrom(List<FaceBiopsyItemStepBean> faceBiopsyItemSteps,
|
|
|
+ Long faceBiopsyItemId, Long examRecordDataId) {
|
|
|
+ List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList = new ArrayList<>();
|
|
|
+ for (FaceBiopsyItemStepBean bean : faceBiopsyItemSteps) {
|
|
|
+ FaceBiopsyItemStepEntity entity = new FaceBiopsyItemStepEntity();
|
|
|
+ entity.setExamRecordDataId(examRecordDataId);
|
|
|
+ entity.setFaceBiopsyItemId(faceBiopsyItemId);
|
|
|
+ entity.setAction(FaceBiopsyAction.valueOf(bean.getAction()));
|
|
|
+ entity.setResourceRelativePath(bean.getResourceRelativePath());
|
|
|
+ entity.setResourceType(ResourceType.valueOf(bean.getResourceType()));
|
|
|
+ entity.setActionStay(bean.getActionStay());
|
|
|
+ entity.setResult(bean.getResult());
|
|
|
+ entity.setErrorMsg(bean.getErrorMsg());
|
|
|
+ entity.setExt1(bean.getExt1());
|
|
|
+ entity.setExt2(bean.getExt2());
|
|
|
+ entity.setExt3(bean.getExt3());
|
|
|
+ entity.setExt4(bean.getExt4());
|
|
|
+ entity.setExt5(bean.getExt5());
|
|
|
+
|
|
|
+ faceBiopsyItemStepEntityList.add(entity);
|
|
|
+ }
|
|
|
+
|
|
|
+ return faceBiopsyItemStepEntityList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void syncExamFaceLivenessVerify(List<ExamFaceLivenessVerifyBean> examFaceLivenessVerifies, Long examRecordDataId) {
|
|
|
+ for (ExamFaceLivenessVerifyBean bean : examFaceLivenessVerifies) {
|
|
|
+ ExamFaceLivenessVerifyEntity entity = copyExamFaceLivenessVerifyFrom(bean, examRecordDataId);
|
|
|
+
|
|
|
+ examFaceLivenessVerifyRepo.saveAndFlush(entity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private ExamFaceLivenessVerifyEntity copyExamFaceLivenessVerifyFrom(ExamFaceLivenessVerifyBean bean,
|
|
|
+ Long examRecordDataId) {
|
|
|
+ ExamFaceLivenessVerifyEntity entity = new ExamFaceLivenessVerifyEntity();
|
|
|
+ entity.setExamRecordDataId(examRecordDataId);
|
|
|
+ entity.setStartTime(bean.getStartTime());
|
|
|
+ entity.setUsedTime(bean.getUsedTime());
|
|
|
+ entity.setResultJson(bean.getResultJson());
|
|
|
+
|
|
|
+ if (null != bean.getVerifyResult()) {
|
|
|
+ entity.setVerifyResult(FaceVerifyResult.valueOf(bean.getVerifyResult()));
|
|
|
+ }
|
|
|
+
|
|
|
+ entity.setBizId(bean.getBizId());
|
|
|
+ entity.setIsError(bean.getIsError());
|
|
|
+ entity.setErrorMsg(bean.getErrorMsg());
|
|
|
+ entity.setOperateNum(bean.getOperateNum());
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void syncExamSyncCapture(ExamSyncCaptureBean examSyncCapture, Long examRecordDataId) {
|
|
|
+ ExamSyncCaptureEntity examSyncCaptureEntity = copyExamSyncCaptureFrom(examSyncCapture, examRecordDataId);
|
|
|
+
|
|
|
+ examSyncCaptureRepo.saveAndFlush(examSyncCaptureEntity);
|
|
|
+ }
|
|
|
+
|
|
|
+ private ExamSyncCaptureEntity copyExamSyncCaptureFrom(ExamSyncCaptureBean examSyncCapture, Long examRecordDataId) {
|
|
|
+ ExamSyncCaptureEntity entity = new ExamSyncCaptureEntity();
|
|
|
+ entity.setExamRecordDataId(examRecordDataId);
|
|
|
+ entity.setFileUrl(examSyncCapture.getFileUrl());
|
|
|
+ entity.setFileName(examSyncCapture.getFileName());
|
|
|
+ entity.setFaceCompareResult(examSyncCapture.getFaceCompareResult());
|
|
|
+ entity.setIsPass(examSyncCapture.getPass());
|
|
|
+ entity.setIsStranger(examSyncCapture.getStranger());
|
|
|
+ entity.setLandmark(examSyncCapture.getLandmark());
|
|
|
+ entity.setUsedTime(examSyncCapture.getUsedTime());
|
|
|
+ entity.setFacelivenessResult(examSyncCapture.getFacelivenessResult());
|
|
|
+ entity.setProcessTime(examSyncCapture.getProcessTime());
|
|
|
+ entity.setHasVirtualCamera(examSyncCapture.getHasVirtualCamera());
|
|
|
+ entity.setCameraInfos(examSyncCapture.getCameraInfos());
|
|
|
+ entity.setExtMsg(examSyncCapture.getExtMsg());
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void syncExamCapture(List<ExamCaptureBean> examCaptures, Long examRecordDataId) {
|
|
|
+ for (ExamCaptureBean bean : examCaptures) {
|
|
|
+ ExamCaptureEntity examCaptureEntity = copyExamCaptureFrom(bean, examRecordDataId);
|
|
|
+ examCaptureRepo.saveAndFlush(examCaptureEntity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private ExamCaptureEntity copyExamCaptureFrom(ExamCaptureBean examCapture, Long examRecordDataId) {
|
|
|
+ ExamCaptureEntity entity = new ExamCaptureEntity();
|
|
|
+ entity.setExamRecordDataId(examRecordDataId);
|
|
|
+ entity.setFileUrl(examCapture.getFileUrl());
|
|
|
+ entity.setFileName(examCapture.getFileName());
|
|
|
+ entity.setFaceCompareResult(examCapture.getFaceCompareResult());
|
|
|
+ entity.setIsPass(examCapture.getPass());
|
|
|
+ entity.setIsStranger(examCapture.getStranger());
|
|
|
+ entity.setLandmark(examCapture.getLandmark());
|
|
|
+ entity.setUsedTime(examCapture.getUsedTime());
|
|
|
+ entity.setFacelivenessResult(examCapture.getFacelivenessResult());
|
|
|
+ entity.setProcessTime(examCapture.getProcessTime());
|
|
|
+ entity.setHasVirtualCamera(examCapture.getHasVirtualCamera());
|
|
|
+ entity.setCameraInfos(examCapture.getCameraInfos());
|
|
|
+ entity.setExtMsg(examCapture.getExtMsg());
|
|
|
+
|
|
|
+ return entity;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步后的后续操作
|
|
|
+ *
|
|
|
+ * @param realExamRecordDataId
|
|
|
+ * @param examScoreId
|
|
|
+ */
|
|
|
+ private void processAfterSyncExamData(Long realExamRecordDataId, Long examScoreId, Double objectiveScore,
|
|
|
+ Long examStudentId, Long transitionExamRecordDataId) {
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ // 保存阅卷相关数据
|
|
|
+ examRecordForMarkingService.saveExamRecordForMarking(realExamRecordDataId, objectiveScore);
|
|
|
+
|
|
|
+ startTime = this.debugCost("14.1 同步后续处理 - 保存阅卷相关数据", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ // 保存考试分数数据到推分队列
|
|
|
+ examScorePushQueueService.saveScoreDataInfoToQueue(realExamRecordDataId, examScoreId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("14.2 同步后续处理 - 保存考试分数数据到推分队列", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ // 保存考试分数数据到分数获取队列
|
|
|
+ examScoreObtainQueueService.saveExamScoreObtainQueue(realExamRecordDataId);
|
|
|
+
|
|
|
+ startTime = this.debugCost("14.3 同步后续处理 - 保存考试分数数据到推分队列", transitionExamRecordDataId, startTime);
|
|
|
+
|
|
|
+ //刷新考生的缓存
|
|
|
+ examStudentCache.refresh(examStudentId);
|
|
|
+
|
|
|
+ this.debugCost("14.4 同步后续处理 - 刷新考生的缓存", transitionExamRecordDataId, startTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ //记录耗时
|
|
|
+ private Long debugCost(String msg, Long examRecordDataId, Long startTime) {
|
|
|
+ if (LOG.isDebugEnabled()) {
|
|
|
+ LOG.debug("[SYNC_EXAM_DATA_CLOUD_SERVICE_PROVIDER-" + examRecordDataId + "]:" + msg +
|
|
|
+ " 耗时:" + (System.currentTimeMillis() - startTime) + " ms");
|
|
|
+ }
|
|
|
+
|
|
|
+ return System.currentTimeMillis();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|