|
@@ -12,6 +12,9 @@ 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.examwork.api.ExamSkipFaceCloudService;
|
|
|
+import cn.com.qmth.examcloud.examwork.api.request.CheckExamSkipFaceReq;
|
|
|
+import cn.com.qmth.examcloud.examwork.api.response.CheckExamSkipFaceResp;
|
|
|
import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
|
|
|
import cn.com.qmth.examcloud.support.CacheConstants;
|
|
|
import cn.com.qmth.examcloud.support.cache.CacheHelper;
|
|
@@ -126,6 +129,12 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
@Autowired
|
|
|
private ExamCaptureCameraInfoRepo examCaptureCameraInfoRepo;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ExamWarnService examWarnService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ExamSkipFaceCloudService examSkipFaceCloudService;
|
|
|
+
|
|
|
@Autowired
|
|
|
private RedisClient redisClient;
|
|
|
|
|
@@ -161,6 +170,12 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
ExamPropertyCacheBean examProperty = CacheHelper.getExamProperty(examId, ExamProperties.AUDIT_ALL_PASS.name());
|
|
|
boolean isAuditAllPass = examProperty != null && StringUtil.isTrue(examProperty.getValue());
|
|
|
|
|
|
+ // 检查当前考生是否跳过人脸识别
|
|
|
+ boolean skipFace = false;
|
|
|
+ if (isFaceEnable) {
|
|
|
+ skipFace = this.checkExamSkipFace(examId, examStudentId);
|
|
|
+ }
|
|
|
+
|
|
|
//先更新考生的考试次数
|
|
|
updateExamStudent(examStudentId);
|
|
|
|
|
@@ -200,35 +215,56 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
//同步活检结果: 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)) {
|
|
|
- examAuditService.saveExamAuditForIllegalClient(realExamRecordDataId, reason);
|
|
|
+ //【违纪】非法考生端应用
|
|
|
+ String illegalReason = redisClient.get(CacheConstants.CACHE_OE_DISCIPLINE_ILLEGAL_CLIENT + tempExamRecordDataId, String.class);
|
|
|
+ if (StringUtils.isNotEmpty(illegalReason)) {
|
|
|
+ examAuditService.saveExamAuditForIllegalClient(realExamRecordDataId, illegalReason);
|
|
|
}
|
|
|
|
|
|
- //header校验错误
|
|
|
- Boolean hasWarn = redisClient.get(CacheConstants.CACHE_OE_DISCIPLINE_ILLEGAL_DATA + tempExamRecordDataId, Boolean.class);
|
|
|
- if (hasWarn != null && hasWarn) {
|
|
|
+ //【违纪】非法数据(已废弃)
|
|
|
+ Boolean hasIllegal = redisClient.get(CacheConstants.CACHE_OE_DISCIPLINE_ILLEGAL_DATA + tempExamRecordDataId, Boolean.class);
|
|
|
+ if (hasIllegal != null && hasIllegal) {
|
|
|
examAuditService.saveHeaderWarnAudit(realExamRecordDataId);
|
|
|
}
|
|
|
|
|
|
- //切屏次数超限
|
|
|
+ //【违纪】超过切屏次数限制
|
|
|
if (tempExamRecordData.getExceedMaxSwitchScreenCount() != null && tempExamRecordData.getExceedMaxSwitchScreenCount()) {
|
|
|
examAuditService.saveExceedMaxSwitchScreenCount(realExamRecordDataId);
|
|
|
}
|
|
|
|
|
|
//若开启人脸验证
|
|
|
if (isFaceEnable) {
|
|
|
- if (req.getExamSyncCapture() == null) {
|
|
|
- //无“开考人脸识别验证”结果
|
|
|
- examAuditService.saveHeaderWarnAudit(realExamRecordDataId);
|
|
|
+ if (skipFace) {
|
|
|
+ //【异常】人工跳过人脸验证
|
|
|
+ examWarnService.saveExamWarn(realExamRecordDataId, WarnType.SKIP_FACE);
|
|
|
+ //修改为异常状态
|
|
|
+ examRecordDataRepo.updateExamRecordIsWarnById(realExamRecordDataId, true);
|
|
|
+ } else {
|
|
|
+ //无“开考人脸识别”结果
|
|
|
+ if (req.getExamSyncCapture() == null) {
|
|
|
+ //【异常】开考照片缺失
|
|
|
+ examWarnService.saveExamWarn(realExamRecordDataId, WarnType.MISS_FACE);
|
|
|
+ //修改为异常状态
|
|
|
+ examRecordDataRepo.updateExamRecordIsWarnById(realExamRecordDataId, true);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//无“人脸抓拍比对”结果
|
|
|
- boolean isNoPhotoAndIllegality = CollectionUtils.isEmpty(req.getExamCaptures());
|
|
|
-
|
|
|
- //计算违纪自动审核结果(无人脸抓拍比对 或 活检失败)
|
|
|
- saveAutoAudit(tempExamRecordData, isNoPhotoAndIllegality, realExamRecordDataId);
|
|
|
+ if (CollectionUtils.isEmpty(req.getExamCaptures())) {
|
|
|
+ //【违纪】抓拍照片数量为0
|
|
|
+ examAuditService.saveExamAuditByNoPhoto(realExamRecordDataId);
|
|
|
+ //修改为已审状态
|
|
|
+ examRecordDataRepo.updateExamRecordIsAuditById(realExamRecordDataId, true);
|
|
|
+ } else {
|
|
|
+ //活检失败
|
|
|
+ if (tempExamRecordData.getIllegality() && tempExamRecordData.getFaceVerifyResult() != null
|
|
|
+ && IsSuccess.FAILED.name().equals(tempExamRecordData.getFaceVerifyResult())) {
|
|
|
+ //【违纪】指定动作失败
|
|
|
+ examAuditService.saveExamAuditByFaceVerifyFailed(realExamRecordDataId, rootOrgId);
|
|
|
+ //修改为已审状态
|
|
|
+ examRecordDataRepo.updateExamRecordIsAuditById(realExamRecordDataId, true);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//若开启审核全通过
|
|
@@ -277,6 +313,15 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private boolean checkExamSkipFace(Long examId, Long examStudentId) {
|
|
|
+ // 检查当前考生是否跳过人脸识别
|
|
|
+ CheckExamSkipFaceReq req = new CheckExamSkipFaceReq();
|
|
|
+ req.setExamId(examId);
|
|
|
+ req.setExamStudentId(examStudentId);
|
|
|
+ CheckExamSkipFaceResp resp = examSkipFaceCloudService.checkExamSkipFace(req);
|
|
|
+ return resp.isSkip();
|
|
|
+ }
|
|
|
+
|
|
|
private void syncExamContinuedRecords(List<ExamContinuedRecordBean> examContinuedRecords, Long realExamRecordDataId) {
|
|
|
if (CollectionUtils.isEmpty(examContinuedRecords)) {
|
|
|
return;
|
|
@@ -482,32 +527,6 @@ public class SyncExamDataCloudServiceProvider extends ControllerSupport implemen
|
|
|
|
|
|
}
|
|
|
|
|
|
- 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);
|