|
@@ -88,6 +88,7 @@ public class FaceBiopsyServiceImpl implements FaceBiopsyService {
|
|
|
//不存在未完成的活检的校验逻辑
|
|
|
// 已活检次数
|
|
|
int verifiedTimes = faceBiopsyEntity.getVerifiedTimes();
|
|
|
+
|
|
|
if (verifiedTimes == 1) {
|
|
|
FaceBiopsyItemEntity firstFaceBiopsyItem =
|
|
|
faceBiopsyItemRepo.findFirstByFaceBiopsyIdOrderByIdAsc(faceBiopsyEntity.getId());
|
|
@@ -103,6 +104,7 @@ public class FaceBiopsyServiceImpl implements FaceBiopsyService {
|
|
|
//如果第一次活检失败,再次调用,按冻结时间内生成新的活检步骤
|
|
|
return appendFaceBiopsy(faceBiopsyEntity.getId(), verifiedTimes, examRecordDataId, faceBiopsyType, true);
|
|
|
}
|
|
|
+
|
|
|
if (verifiedTimes == 2) {
|
|
|
FaceBiopsyItemEntity secondFaceBiopsyItem =
|
|
|
faceBiopsyItemRepo.findFirstByFaceBiopsyIdOrderByIdDesc(faceBiopsyEntity.getId());
|
|
@@ -221,48 +223,123 @@ public class FaceBiopsyServiceImpl implements FaceBiopsyService {
|
|
|
* @return
|
|
|
*/
|
|
|
private SaveFaceBiopsyResultResp buildSaveFaceBiopsyResultResp(SaveFaceBiopsyResultReq req) {
|
|
|
- Long examRecordDataId = req.getExamRecordDataId();
|
|
|
List<FaceBiopsyStepInfo> verifySteps = req.getVerifySteps();
|
|
|
- //本次检测的最终结果是否成功(检测步骤中只要有一项检测失败,则认为检测失败)
|
|
|
- boolean finalIsSuccess = true;
|
|
|
- String errorMsg = null;
|
|
|
- /**
|
|
|
- * 是否结束考试
|
|
|
- * case1:人脸比对失败(即活检第1步,action==FACE_COMPARE,照片非本人或检测中多人脸)时,结束考试
|
|
|
- * case2:冻结时间内,第2次人脸活检整体失败,结束考试
|
|
|
- * case3:冻结时间外,人脸活检失败,结束考试
|
|
|
- */
|
|
|
- boolean isEndExam = false;
|
|
|
- //检测次数
|
|
|
- int verifyTimes = getVerifyTimes(examRecordDataId);
|
|
|
-
|
|
|
// 检测结果至少有一条检测结果不允许为空
|
|
|
if (!verifySteps.stream().anyMatch(p -> null != p.getResult())) {
|
|
|
throw new StatusException("201005", "检测结果不允许为空");
|
|
|
}
|
|
|
|
|
|
+ boolean finalIsSuccess = calculateIsSuccess(req.getVerifySteps());
|
|
|
+ Boolean isEndExam = calculateIsEndExam(verifySteps, req.getExamRecordDataId(), finalIsSuccess);
|
|
|
+
|
|
|
+ //构建业务实体
|
|
|
+ SaveFaceBiopsyResultResp resp = new SaveFaceBiopsyResultResp();
|
|
|
+ resp.setEndExam(isEndExam);
|
|
|
+ resp.setVerifyResult(finalIsSuccess);
|
|
|
+ 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) {
|
|
|
- //如果检测结果为空,则直接跳过
|
|
|
- if (stepInfo.getResult() == null) {
|
|
|
- continue;
|
|
|
+ //循环更新新活体检测每步的执行结果
|
|
|
+ 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 (!stepInfo.getResult()) {
|
|
|
- errorMsg = stepInfo.getErrorMsg();
|
|
|
+ if (null != stepInfo.getStranger()) {
|
|
|
+ faceBiopsyItemStepEntity.setExt3(stepInfo.getTimeout().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 ((stepInfo.getTimeout() != null && stepInfo.getTimeout())) {
|
|
|
- errorMsg = "超时未完成";
|
|
|
- finalIsSuccess = false;
|
|
|
- break;
|
|
|
+ return "超时未完成";
|
|
|
}
|
|
|
|
|
|
- //整个检测步骤中只要有一次失败或超时,则认为整个活检失败
|
|
|
+ //整个检测步骤中只要有一次失败,则认为整个活检失败
|
|
|
if (!stepInfo.getResult()) {
|
|
|
- finalIsSuccess = false;
|
|
|
+ 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:
|
|
|
//如果第一步检测部分失败(照片非本人或检测中多人脸),需要结束考试
|
|
@@ -278,129 +355,78 @@ public class FaceBiopsyServiceImpl implements FaceBiopsyService {
|
|
|
Boolean existsSystemError = Boolean.valueOf(faceCompareResult.get("existsSystemError").toString());
|
|
|
//case1.1.有陌生人(即多人脸),不管是否比对成功,直接结束考试
|
|
|
if (isStranger) {
|
|
|
- isEndExam = true;
|
|
|
+ return true;
|
|
|
}
|
|
|
- //case1.2.无陌生人且检测失败且不是系统错误(即照片非本人),也直接结束考试
|
|
|
+ //case1.2.无陌生人且检测失败且不是系统错误(即照片非本人或无人脸),也直接结束考试
|
|
|
else {
|
|
|
if (!isPass && !existsSystemError) {
|
|
|
- isEndExam = true;
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case HAPPY:
|
|
|
case SERIOUS:
|
|
|
//如果此前步骤已判断为需要结束考试则不作任何处理
|
|
|
- if (!isEndExam) {
|
|
|
- //本次检测步骤是否在冻结时间内生成
|
|
|
- FaceBiopsyItemEntity faceBiopsyItem = GlobalHelper.getEntity(faceBiopsyItemRepo,
|
|
|
- req.getFaceBiopsyItemId(), FaceBiopsyItemEntity.class);
|
|
|
- Boolean isCurStepInFreezeTime = faceBiopsyItem.getInFreezeTime();
|
|
|
-
|
|
|
- //如果本次活检步骤是在冻结时间内生成,则按冻结时间内的逻辑来处理
|
|
|
- if (null != isCurStepInFreezeTime && isCurStepInFreezeTime) {
|
|
|
- //如果冻结时间内第2次检测失败,则需要结束考试
|
|
|
- if (verifyTimes > 1 && !stepInfo.getResult()) {
|
|
|
- isEndExam = true;
|
|
|
- }
|
|
|
- } else {
|
|
|
- //冻结时间外检测失败,直接结束考试
|
|
|
- if (!stepInfo.getResult()) {
|
|
|
- isEndExam = true;
|
|
|
- }
|
|
|
- }
|
|
|
+ //如果有陌生人脸或晃出摄像头或无人脸,直接结束考试
|
|
|
+ if ((null != stepInfo.getStranger() && stepInfo.getStranger()) ||
|
|
|
+ (null != stepInfo.getWaggleOutCamera() && stepInfo.getWaggleOutCamera()) ||
|
|
|
+ (null != stepInfo.getHasFace() && !stepInfo.getHasFace())) {
|
|
|
+ return true;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //如果当前为第二次活检,且第一次活检已经失败,本次活检也失败,则直接结束考试
|
|
|
- if (verifyTimes == 2) {
|
|
|
- FaceBiopsyItemEntity firstFaceBiopsyItem =
|
|
|
- faceBiopsyItemRepo.findFirstByExamRecordDataIdOrderByIdAsc(req.getExamRecordDataId());
|
|
|
- if (!firstFaceBiopsyItem.getResult() && !finalIsSuccess) {
|
|
|
- isEndExam = true;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 根据活检情况结束考试
|
|
|
+ * 当前为第二次活检,且失败,且第一次活检也失败,则直接结束考试
|
|
|
+ * 当前为第二次活检,且失败,且第一次活检成功,则直接结束考试
|
|
|
+ * 当前为第三次活检,且失败,且第一次活检失败,第二次活检成功,则直接结束考试
|
|
|
+ */
|
|
|
+ //如果是第二次活检,且失败,则结束考试(无论第一次是否成功)
|
|
|
+ int verifyTimes = getVerifyTimes(examRecordDataId);
|
|
|
+ if (verifyTimes == 2 && !finalIsSuccess) {
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- //构建业务实体
|
|
|
- SaveFaceBiopsyResultResp resp = new SaveFaceBiopsyResultResp();
|
|
|
- resp.setEndExam(isEndExam);
|
|
|
- resp.setNeedNextVerify(calculateNeedNextVerify(
|
|
|
- isEndExam, calculateIsInFreezeTime(examRecordDataId), finalIsSuccess, verifyTimes, examRecordDataId));
|
|
|
- resp.setVerifyResult(finalIsSuccess);
|
|
|
- resp.setErrorMessage(errorMsg);
|
|
|
- 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 (verifyTimes == 3 && !finalIsSuccess) {
|
|
|
+ return true;
|
|
|
}
|
|
|
- //批量更新活检步骤执行结果
|
|
|
- faceBiopsyItemStepRepo.saveAll(faceBiopsyItemStepEntityList);
|
|
|
- //更新人脸活体检测最终结果
|
|
|
- faceBiopsyItemRepo.updateFaceBiopsyItemResult(faceBiopsyItemId, finalIsSuccess, errorMsg, true);
|
|
|
- faceBiopsyRepo.updateFaceBiopsyResult(examRecordDataId, finalIsSuccess, errorMsg);
|
|
|
+
|
|
|
+ //其它情况不结束考试
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 计算是否需要下次活检
|
|
|
*
|
|
|
* @param isEndExam
|
|
|
- * @param isInFreezeTime
|
|
|
* @param finalIsSuccess
|
|
|
- * @param verifyTimes
|
|
|
* @return
|
|
|
*/
|
|
|
- private boolean calculateNeedNextVerify(boolean isEndExam, boolean isInFreezeTime, boolean finalIsSuccess,
|
|
|
- int verifyTimes, Long examRecordDataId) {
|
|
|
+ private boolean calculateNeedNextVerify(boolean isEndExam, boolean finalIsSuccess, Long examRecordDataId) {
|
|
|
//考试已结束,不需要继续下次活检
|
|
|
if (isEndExam) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- //如果考试未结束的情况
|
|
|
- if (isInFreezeTime) {
|
|
|
- if (verifyTimes == 1) {
|
|
|
- //冻结时间内第一次活检失败,则需要下次活检
|
|
|
- if (!finalIsSuccess) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- } else {
|
|
|
- //冻结时间内非第一次活检失败,则不需要下次活检
|
|
|
- if (!finalIsSuccess) {
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
+ int verifyTimes = getVerifyTimes(examRecordDataId);
|
|
|
+ //如果是第一次活检,且成功,且开启追加活检,则允许继续活检
|
|
|
+ if (verifyTimes == 1 && finalIsSuccess && isAddFaceVerifyOutFreezeTime(examRecordDataId)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- //冻结时间内第一次或第二次活检成功,且开启冻结时间外增加一次活检,则需要下次活检,否则不需要
|
|
|
- ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId,
|
|
|
- ExamRecordDataEntity.class);
|
|
|
- return isAddFaceVerifyOutFreezeTime(examRecordData.getExamId(),
|
|
|
- examRecordData.getOrgId(), examRecordData.getStudentId());
|
|
|
- } else {
|
|
|
- //冻结时间外,无论活检成功或失败,均不可进行下次活检
|
|
|
- return false;
|
|
|
+ //如果是第二次活检,且成功,且第一次活检失败,且开启追加活检,则允许继续活检
|
|
|
+ if (verifyTimes == 2 && finalIsSuccess) {
|
|
|
+ FaceBiopsyItemEntity firstFaceBiopsyItem =
|
|
|
+ faceBiopsyItemRepo.findFirstByExamRecordDataIdOrderByIdAsc(examRecordDataId);
|
|
|
+ if (!firstFaceBiopsyItem.getResult() && isAddFaceVerifyOutFreezeTime(examRecordDataId)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ //其它情况均不允许继续活检
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -498,7 +524,8 @@ public class FaceBiopsyServiceImpl implements FaceBiopsyService {
|
|
|
return faceBiopsyInfo;
|
|
|
}
|
|
|
|
|
|
- private List<FaceBiopsyStepInfo> copyFaceBiopsyStepDomainListFrom(List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList) {
|
|
|
+ private List<FaceBiopsyStepInfo> copyFaceBiopsyStepDomainListFrom
|
|
|
+ (List<FaceBiopsyItemStepEntity> faceBiopsyItemStepEntityList) {
|
|
|
List<FaceBiopsyStepInfo> resultList = new ArrayList<>();
|
|
|
for (FaceBiopsyItemStepEntity entity : faceBiopsyItemStepEntityList) {
|
|
|
FaceBiopsyStepInfo domain = new FaceBiopsyStepInfo();
|