|
@@ -123,12 +123,11 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
@Autowired
|
|
|
private ExamProcessRecordRepo examProcessRecordRepo;
|
|
|
|
|
|
- @Autowired
|
|
|
- private RedisClient redisClient;
|
|
|
-
|
|
|
@Autowired
|
|
|
private ExamCaptureCameraInfoRepo examCaptureCameraInfoRepo;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private RedisClient redisClient;
|
|
|
|
|
|
/**
|
|
|
* 同步考试记录数据
|
|
@@ -153,6 +152,10 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
Long studentId = tempExamRecordData.getStudentId();
|
|
|
Long examId = tempExamRecordData.getExamId();
|
|
|
Long rootOrgId = tempExamRecordData.getRootOrgId();
|
|
|
+ String examType = tempExamRecordData.getExamType();
|
|
|
+
|
|
|
+ // 是否开启人脸验证
|
|
|
+ boolean isFaceEnable = FaceBiopsyHelper.isFaceEnable(rootOrgId, examId, studentId);
|
|
|
|
|
|
//先更新考生的考试次数
|
|
|
updateExamStudent(examStudentId);
|
|
@@ -163,6 +166,36 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
//添加同步记录
|
|
|
addExamRecordDataSync(tempExamRecordDataId, realExamRecordDataId);
|
|
|
|
|
|
+ //同步考试记录对应的试卷结构
|
|
|
+ syncExamRecordPaperStruct(req.getExamRecordPaperStruct(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步作答记录
|
|
|
+ syncExamRecordQuestions(req.getExamRecordQuestions(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步考试分数表
|
|
|
+ Long examScoreId = syncExamScore(tempExamRecordData, realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步断点续考记录表
|
|
|
+ syncExamContinuedRecords(req.getExamContinuedRecords(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步考试过程记录表
|
|
|
+ syncExamProcessRecords(req.getExamProcessRecords(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步“开考人脸识别验证”结果
|
|
|
+ syncExamSyncCapture(req.getExamSyncCapture(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步“人脸抓拍比对”结果
|
|
|
+ syncExamCapture(req.getExamCaptures(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步活检结果:FACE_ID("S1", "FaceID活体检测方案")
|
|
|
+ syncExamFaceLivenessVerify(req.getExamFaceLivenessVerifies(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步活检结果: FACE_MOTION("S2", "自研活体检测方案")【已废弃】
|
|
|
+ syncFaceBiopsy(req.getFaceBiopsy(), realExamRecordDataId);
|
|
|
+
|
|
|
+ //同步活检结果: FACE_CLIENT("S3", "C端活体检测方案")
|
|
|
+ syncFaceLiveVerifyRecords(req.getFaceLiveVerifyRecords(), realExamRecordDataId);
|
|
|
+
|
|
|
// 违纪-非法考生端应用
|
|
|
String reason = redisClient.get(CacheConstants.CACHE_OE_DISCIPLINE_ILLEGAL_CLIENT + tempExamRecordDataId, String.class);
|
|
|
if (StringUtils.isNotEmpty(reason)) {
|
|
@@ -180,55 +213,15 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
examAuditService.saveExceedMaxSwitchScreenCount(realExamRecordDataId);
|
|
|
}
|
|
|
|
|
|
- //同步考试分数表
|
|
|
- Long examScoreId = syncExamScore(tempExamRecordData, realExamRecordDataId);
|
|
|
-
|
|
|
- //同步断点续考记录表
|
|
|
- if (null != req.getExamContinuedRecords() && !req.getExamContinuedRecords().isEmpty()) {
|
|
|
- syncExamContinuedRecords(req.getExamContinuedRecords(), realExamRecordDataId);
|
|
|
- }
|
|
|
-
|
|
|
- //同步考试过程记录表
|
|
|
- if (null != req.getExamProcessRecords() && !req.getExamProcessRecords().isEmpty()) {
|
|
|
- syncExamProcessRecords(req.getExamProcessRecords(), realExamRecordDataId);
|
|
|
- }
|
|
|
-
|
|
|
- //同步抓拍照片结果(同步抓拍的数据)
|
|
|
- if (null != req.getExamSyncCapture()) {
|
|
|
- syncExamSyncCapture(req.getExamSyncCapture(), realExamRecordDataId);
|
|
|
- } else {
|
|
|
- //且开启摄像头
|
|
|
- if (FaceBiopsyHelper.isFaceEnable(rootOrgId, examId, studentId)) {
|
|
|
+ if (null == req.getExamSyncCapture()) {
|
|
|
+ //开启摄像头
|
|
|
+ if (isFaceEnable) {
|
|
|
examAuditService.saveHeaderWarnAudit(realExamRecordDataId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //同步抓拍照片结果(异步抓拍的数据)
|
|
|
- if (null != req.getExamCaptures()) {
|
|
|
- syncExamCapture(req.getExamCaptures(), realExamRecordDataId);
|
|
|
- }
|
|
|
-
|
|
|
- //同步face id活体检测数据
|
|
|
- if (null != req.getExamFaceLivenessVerifies()) {
|
|
|
- syncExamFaceLivenessVerify(req.getExamFaceLivenessVerifies(), realExamRecordDataId);
|
|
|
- }
|
|
|
-
|
|
|
- //同步新活检
|
|
|
- if (null != req.getFaceBiopsy()) {
|
|
|
- syncFaceBiopsy(req.getFaceBiopsy(), realExamRecordDataId);
|
|
|
- }
|
|
|
-
|
|
|
- //同步C端活体检测记录
|
|
|
- syncFaceLiveVerifyRecords(req.getFaceLiveVerifyRecords(), realExamRecordDataId);
|
|
|
-
|
|
|
- //同步考试记录对应的试卷结构
|
|
|
- syncExamRecordPaperStruct(req.getExamRecordPaperStruct(), realExamRecordDataId);
|
|
|
-
|
|
|
- //同步作答记录
|
|
|
- syncExamRecordQuestions(req.getExamRecordQuestions(), realExamRecordDataId);
|
|
|
-
|
|
|
//如果开启了活检
|
|
|
- if (FaceBiopsyHelper.isFaceEnable(rootOrgId, examId, studentId)) {
|
|
|
+ if (isFaceEnable) {
|
|
|
//计算违纪自动审核结果(无人脸或活检失败)
|
|
|
boolean isNoPhotoAndIllegality = (null == req.getExamCaptures() || req.getExamCaptures().isEmpty());//是否无照片
|
|
|
saveAutoAudit(tempExamRecordData, isNoPhotoAndIllegality, realExamRecordDataId);
|
|
@@ -237,33 +230,14 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
//若开启审核全通过
|
|
|
auditPassExamRecordData(examId, realExamRecordDataId);
|
|
|
|
|
|
- //***************这个步骤必须放在最后,所有改变违纪、警告、审核状态的操作之后********************************
|
|
|
- //计算最终分数
|
|
|
- String examType = ExamCacheTransferHelper.getDefaultCachedExam(examId).getExamType();
|
|
|
+ //计算最终分数(这个步骤必须放在所有改变“违纪、警告、审核状态”的操作之后)
|
|
|
if (ExamType.ONLINE.name().equals(examType) || ExamType.ONLINE_HOMEWORK.name().equals(examType)
|
|
|
|| ExamType.OFFLINE.name().equals(examType)) {
|
|
|
examStudentFinalScoreService.calcAndSaveFinalScore(examStudentId);
|
|
|
}
|
|
|
|
|
|
- LOG.warn("tempExamRecordDataId:{} realExamRecordDataId:{} cost:{}ms syncExamData ok...",
|
|
|
- tempExamRecordDataId, realExamRecordDataId, System.currentTimeMillis() - startTime);
|
|
|
-
|
|
|
- //同步后续处理
|
|
|
- processAfterSyncExamData(realExamRecordDataId, examScoreId, tempExamRecordData.getObjectiveScore(),
|
|
|
- examStudentId, tempExamRecordDataId);
|
|
|
-
|
|
|
- return new SyncExamDataResp();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 同步后的后续操作
|
|
|
- */
|
|
|
- private void processAfterSyncExamData(Long realExamRecordDataId, Long examScoreId, Double objectiveScore,
|
|
|
- Long examStudentId, Long tempExamRecordDataId) {
|
|
|
- long startTime = System.currentTimeMillis();
|
|
|
-
|
|
|
// 保存阅卷相关数据
|
|
|
- examRecordForMarkingService.saveExamRecordForMarking(realExamRecordDataId, objectiveScore);
|
|
|
+ examRecordForMarkingService.saveExamRecordForMarking(realExamRecordDataId, tempExamRecordData.getObjectiveScore());
|
|
|
|
|
|
// 保存考试分数数据到推分队列
|
|
|
examScorePushQueueService.saveScoreDataInfoToQueue(realExamRecordDataId, examScoreId);
|
|
@@ -274,8 +248,10 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
//刷新考生的缓存
|
|
|
examStudentCache.refresh(examStudentId);
|
|
|
|
|
|
- LOG.warn("tempExamRecordDataId:{} realExamRecordDataId:{} cost:{}ms processAfterSyncExamData ok...",
|
|
|
- tempExamRecordDataId, realExamRecordDataId, System.currentTimeMillis() - startTime);
|
|
|
+ LOG.warn("syncExamData ok, tempExamRecordDataId:{} finalExamRecordDataId:{} studentId:{} cost:{}ms",
|
|
|
+ tempExamRecordDataId, realExamRecordDataId, studentId, System.currentTimeMillis() - startTime);
|
|
|
+
|
|
|
+ return new SyncExamDataResp();
|
|
|
}
|
|
|
|
|
|
private void auditPassExamRecordData(Long examId, Long realExamRecordDataId) {
|
|
@@ -299,6 +275,9 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
}
|
|
|
|
|
|
private void syncExamContinuedRecords(List<ExamContinuedRecordBean> examContinuedRecords, Long realExamRecordDataId) {
|
|
|
+ if (CollectionUtils.isEmpty(examContinuedRecords)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
for (ExamContinuedRecordBean bean : examContinuedRecords) {
|
|
|
ExamContinuedRecordEntity entity = copyExamContinuedRecordFrom(bean, realExamRecordDataId);
|
|
|
examContinuedRecordRepo.saveAndFlush(entity);
|
|
@@ -306,25 +285,27 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
}
|
|
|
|
|
|
private void syncExamProcessRecords(List<ExamProcessRecordBean> examProcessRecords, Long realExamRecordDataId) {
|
|
|
+ if (CollectionUtils.isEmpty(examProcessRecords)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
for (ExamProcessRecordBean bean : examProcessRecords) {
|
|
|
ExamProcessRecordEntity entity = copyExamProcessRecordFrom(bean, realExamRecordDataId);
|
|
|
examProcessRecordRepo.saveAndFlush(entity);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public Long syncExamScore(ExamRecordDataBean transitionExamRecordData, Long realExamRecordDataId) {
|
|
|
+ public Long syncExamScore(ExamRecordDataBean tempExamRecordData, 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.setObjectiveScore(tempExamRecordData.getObjectiveScore());
|
|
|
+ examScoreEntity.setObjectiveAccuracy(tempExamRecordData.getObjectiveAccuracy());
|
|
|
+ examScoreEntity.setTotalScore(tempExamRecordData.getTotalScore());//交卷时,总分=客观分得分
|
|
|
+ examScoreEntity.setSubjectiveScore(tempExamRecordData.getSubjectiveScore());
|
|
|
+ examScoreEntity.setSuccPercent(tempExamRecordData.getSuccPercent());
|
|
|
|
|
|
ExamScoreEntity result = examScoreRepo.saveAndFlush(examScoreEntity);
|
|
|
return result.getId();
|
|
@@ -338,7 +319,7 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
//更新数据库中的已考次数
|
|
|
ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(examStudentId);
|
|
|
if (null == examStudentEntity) {
|
|
|
- throw new StatusException("100101", "考生id不正确");
|
|
|
+ throw new StatusException("100101", "考生ID不正确!" + examStudentId);
|
|
|
}
|
|
|
|
|
|
Integer usedTimes = examStudentEntity.getUsedNum() == null ? 0 : examStudentEntity.getUsedNum();
|
|
@@ -388,7 +369,7 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
//部分数据从考生表中获取
|
|
|
ExamStudentEntity examStudentEntity = examStudentRepo.findByExamStudentId(examRecordData.getExamStudentId());
|
|
|
if (null == examStudentEntity) {
|
|
|
- throw new StatusException("100101", "考生id不正确");
|
|
|
+ throw new StatusException("100101", "考生ID不正确!" + examRecordData.getExamStudentId());
|
|
|
}
|
|
|
result.setStudentCode(examStudentEntity.getStudentCode());
|
|
|
result.setStudentName(examStudentEntity.getStudentName());
|
|
@@ -569,7 +550,7 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
}
|
|
|
|
|
|
private void syncExamRecordPaperStruct(ExamRecordPaperStructBean examRecordPaperStruct, Long examRecordDataId) {
|
|
|
- ExamRecordPaperStructEntity entity = copyExamRecordPaperStructFrom(examRecordPaperStruct, examRecordDataId);
|
|
|
+ ExamRecordPaperStructEntity entity = copyExamRecordPaperStructFrom(examRecordPaperStruct);
|
|
|
examRecordPaperStructRepo.save(entity);
|
|
|
|
|
|
//更新考试记录表中的试卷结构id
|
|
@@ -579,16 +560,18 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
examRecordDataRepo.save(examRecordData);
|
|
|
}
|
|
|
|
|
|
- private ExamRecordPaperStructEntity copyExamRecordPaperStructFrom(ExamRecordPaperStructBean examRecordPaperStruct, Long examRecordDataId) {
|
|
|
+ private ExamRecordPaperStructEntity copyExamRecordPaperStructFrom(ExamRecordPaperStructBean examRecordPaperStruct) {
|
|
|
ExamRecordPaperStructEntity entity = new ExamRecordPaperStructEntity();
|
|
|
entity.setId(examRecordPaperStruct.getId());
|
|
|
entity.setDefaultPaper(examRecordPaperStruct.getDefaultPaper());
|
|
|
-
|
|
|
return entity;
|
|
|
}
|
|
|
|
|
|
@Transactional
|
|
|
public void syncFaceBiopsy(FaceBiopsyBean faceBiopsy, Long examRecordDataId) {
|
|
|
+ if (faceBiopsy == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
FaceBiopsyEntity faceBiopsyEntity = copyFaceBiopsyFrom(faceBiopsy, examRecordDataId);
|
|
|
faceBiopsyRepo.saveAndFlush(faceBiopsyEntity);
|
|
|
|
|
@@ -602,7 +585,6 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
for (FaceBiopsyItemStepEntity fbis : faceBiopsyItemStepEntityList) {
|
|
|
faceBiopsyItemStepRepo.saveAndFlush(fbis);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -679,16 +661,17 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
return faceBiopsyItemStepEntityList;
|
|
|
}
|
|
|
|
|
|
- private void syncExamFaceLivenessVerify(List<ExamFaceLivenessVerifyBean> examFaceLivenessVerifies, Long examRecordDataId) {
|
|
|
- for (ExamFaceLivenessVerifyBean bean : examFaceLivenessVerifies) {
|
|
|
+ private void syncExamFaceLivenessVerify(List<ExamFaceLivenessVerifyBean> verifyBeans, Long examRecordDataId) {
|
|
|
+ if (CollectionUtils.isEmpty(verifyBeans)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (ExamFaceLivenessVerifyBean bean : verifyBeans) {
|
|
|
ExamFaceLivenessVerifyEntity entity = copyExamFaceLivenessVerifyFrom(bean, examRecordDataId);
|
|
|
-
|
|
|
examFaceLivenessVerifyRepo.saveAndFlush(entity);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private ExamFaceLivenessVerifyEntity copyExamFaceLivenessVerifyFrom(ExamFaceLivenessVerifyBean bean,
|
|
|
- Long examRecordDataId) {
|
|
|
+ private ExamFaceLivenessVerifyEntity copyExamFaceLivenessVerifyFrom(ExamFaceLivenessVerifyBean bean, Long examRecordDataId) {
|
|
|
ExamFaceLivenessVerifyEntity entity = new ExamFaceLivenessVerifyEntity();
|
|
|
entity.setExamRecordDataId(examRecordDataId);
|
|
|
entity.setStartTime(bean.getStartTime());
|
|
@@ -708,8 +691,10 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
}
|
|
|
|
|
|
private void syncExamSyncCapture(ExamSyncCaptureBean examSyncCapture, Long examRecordDataId) {
|
|
|
+ if (examSyncCapture == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
ExamSyncCaptureEntity examSyncCaptureEntity = copyExamSyncCaptureFrom(examSyncCapture, examRecordDataId);
|
|
|
-
|
|
|
examSyncCaptureRepo.saveAndFlush(examSyncCaptureEntity);
|
|
|
}
|
|
|
|
|
@@ -733,6 +718,9 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
}
|
|
|
|
|
|
private void syncExamCapture(List<ExamCaptureBean> examCaptures, Long examRecordDataId) {
|
|
|
+ if (CollectionUtils.isEmpty(examCaptures)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
for (ExamCaptureBean bean : examCaptures) {
|
|
|
ExamCaptureEntity examCaptureEntity = copyExamCaptureFrom(bean, examRecordDataId);
|
|
|
saveExamCaptureCameraInfo(examCaptureEntity);
|