Przeglądaj źródła

新增活体验证动作错误预警和轨迹

wangliang 2 lat temu
rodzic
commit
bd137e1dce

+ 11 - 0
themis-business/src/main/java/com/qmth/themis/business/dao/TOeFaceVerifyHistoryMapper.java

@@ -66,4 +66,15 @@ public interface TOeFaceVerifyHistoryMapper extends BaseMapper<TOeFaceVerifyHist
      */
     @SuppressWarnings("MybatisXMapperMethodInspection")
     public Map<String, Object> realnessError(@Param("recordId") Long recordId, @Param("exception") String exception, @Param("type") String type, @Param("batchNo") String batchNo);
+
+    /**
+     * 活检动作错误异常
+     *
+     * @param recordId
+     * @param exception
+     * @param type
+     * @return
+     */
+    @SuppressWarnings("MybatisXMapperMethodInspection")
+    public Map<String, Object> livenessActionError(@Param("recordId") Long recordId, @Param("exception") String exception, @Param("type") String type);
 }

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/enums/VerifyExceptionEnum.java

@@ -18,7 +18,7 @@ public enum VerifyExceptionEnum {
 
     EYE_CLOSE_ERROR("闭眼检测异常", Arrays.asList("D14"), "违纪预警"),
 
-    LIVENESS_ACTION_ERROR("活检动作错误", Arrays.asList("-1"), "违纪预警"),
+    LIVENESS_ACTION_ERROR("活检动作错误", Arrays.asList("D16"), "违纪预警"),
 
     NONE("无异常", Arrays.asList("-1"), "违纪预警"),
 

+ 3 - 1
themis-business/src/main/java/com/qmth/themis/business/enums/WarningLevelEnum.java

@@ -19,7 +19,9 @@ public enum WarningLevelEnum {
 
     D15("真实性检测失败1次以上", "【疑似采用照片或虚拟摄像头】系统随机真实性检测失败", "违纪预警"),
 
-    D13("1分钟内进行连续人脸抓拍检测不到闭眼动作", "【疑似采用照片】系统检测到考生疑似在镜头前采用照片", "违纪预警");
+    D13("1分钟内进行连续人脸抓拍检测不到闭眼动作", "【疑似采用照片】系统检测到考生疑似在镜头前采用照片", "违纪预警"),
+
+    D16("1.取检测失败时的3张抓拍照片(开始1张,结束1张,过程1张);2.时间轴上的事件按产生人工干预预警时间显示。", "【疑似替考】过程中随机活体检测不通过", "违纪预警");
 
     private String desc;
 

+ 10 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TOeFaceVerifyHistoryService.java

@@ -66,4 +66,14 @@ public interface TOeFaceVerifyHistoryService extends IService<TOeFaceVerifyHisto
      * @return
      */
     public Map<String, Object> realnessError(Long recordId, String exception, String type, String batchNo);
+
+    /**
+     * 活检动作错误异常
+     *
+     * @param recordId
+     * @param exception
+     * @param type
+     * @return
+     */
+    public Map<String, Object> livenessActionError(Long recordId, String exception, String type);
 }

+ 7 - 0
themis-business/src/main/java/com/qmth/themis/business/service/WarningService.java

@@ -38,4 +38,11 @@ public interface WarningService {
      * @param warningDto
      */
     public void realnessError(WarningDto warningDto);
+
+    /**
+     * 活检动作错误异常
+     *
+     * @param warningDto
+     */
+    public void livenessActionError(WarningDto warningDto);
 }

+ 16 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeFaceVerifyHistoryServiceImpl.java

@@ -43,7 +43,7 @@ public class TOeFaceVerifyHistoryServiceImpl extends ServiceImpl<TOeFaceVerifyHi
 
     @Override
     public FaceVerifyBean verify(Long recordId, String type, String photoUrl, Integer faceCount, Double similarity,
-            Double realness, Long time, String exception) {
+                                 Double realness, Long time, String exception) {
         FaceVerifyCacheBean cache = new FaceVerifyCacheBean();
         cache.setId(uidUtil.getId());
         cache.setExamRecordId(recordId);
@@ -69,7 +69,7 @@ public class TOeFaceVerifyHistoryServiceImpl extends ServiceImpl<TOeFaceVerifyHi
     @Transactional
     @Override
     public void save(Long id, Long recordId, String type, String photoUrl, Integer faceCount, Double similarity,
-            Double realness, Long time, String exception, String batchNo) {
+                     Double realness, Long time, String exception, String batchNo) {
         TOeFaceVerifyHistory entity = new TOeFaceVerifyHistory();
         entity.setId(id);
         entity.setExamRecordId(recordId);
@@ -97,7 +97,7 @@ public class TOeFaceVerifyHistoryServiceImpl extends ServiceImpl<TOeFaceVerifyHi
      */
     @Override
     public Map<String, Object> faceCountError(Long recordId, String exception, Integer faceCount, Boolean multipleFace,
-            String type, String batchNo) {
+                                              String type, String batchNo) {
         return tOeFaceVerifyHistoryMapper.faceCountError(recordId, exception, faceCount, multipleFace, type, batchNo);
     }
 
@@ -142,4 +142,17 @@ public class TOeFaceVerifyHistoryServiceImpl extends ServiceImpl<TOeFaceVerifyHi
     public Map<String, Object> realnessError(Long recordId, String exception, String type, String batchNo) {
         return tOeFaceVerifyHistoryMapper.realnessError(recordId, exception, type, batchNo);
     }
+
+    /**
+     * 活检动作错误异常
+     *
+     * @param recordId
+     * @param exception
+     * @param type
+     * @return
+     */
+    @Override
+    public Map<String, Object> livenessActionError(Long recordId, String exception, String type) {
+        return tOeFaceVerifyHistoryMapper.livenessActionError(recordId, exception, type);
+    }
 }

+ 30 - 1
themis-business/src/main/java/com/qmth/themis/business/service/impl/WarningServiceImpl.java

@@ -22,7 +22,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * @Description: 预警规则公用
@@ -208,6 +207,36 @@ public class WarningServiceImpl implements WarningService {
         }
     }
 
+    /**
+     * 活检动作错误异常
+     *
+     * @param warningDto
+     */
+    @Override
+    @Transactional
+    public void livenessActionError(WarningDto warningDto) {
+        Long recordId = warningDto.getRecordId();
+        VerifyExceptionEnum warningEnum = warningDto.getWarningEnum();
+        String photoUrl = warningDto.getPhotoUrl();
+        Long examId = ExamRecordCacheUtil.getExamId(recordId);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
+        if (Objects.isNull(examStudentId)) {
+            TOeExamRecord tOeExamRecord = tOeExamRecordService.getById(recordId);
+            Optional.ofNullable(tOeExamRecord).orElseThrow(() -> new BusinessException(ExceptionResultEnum.NOT_FOUND_EXAM_RECORD));
+            examStudentId = tOeExamRecord.getExamStudentId();
+            examActivityId = tOeExamRecord.getExamActivityId();
+        }
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+        Map<String, Object> map = faceVerifyHistoryService.livenessActionError(recordId, warningDto.getWarningEnum().name(), ExamTypeEnum.IN_PROCESS.name());
+        if (Objects.nonNull(map) && map.size() > 0) {
+            TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(0), WarningLevelEnum.valueOf(warningEnum.getLevel().get(0)).getTitle(), warningEnum, photoUrl, Objects.nonNull(ExamRecordCacheUtil.getBreachStatus(recordId)) ? ExamRecordCacheUtil.getBreachStatus(recordId) : 1);
+            tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
+            this.setWarningCount(recordId);
+            this.setPhotoUrls(map, tIeInvigilateWarnInfo, examStudentCacheBean, recordId, 0);
+        }
+    }
+
     /**
      * 设置预警数
      *

+ 27 - 0
themis-business/src/main/resources/mapper/TOeFaceVerifyHistoryMapper.xml

@@ -214,4 +214,31 @@
         </where>
         group by tofvh.`exception`) t
     </select>
+
+    <select id="livenessActionError" resultType="java.util.Map">
+        select
+        sum(t.tmpCount) as tmpCount,
+        group_concat(t.photoUrl) as photoUrls,
+        min(t.createTime) as createTime
+        from
+        (
+        select
+        count(1) as tmpCount,
+        group_concat(tofvh.photo_url) as photoUrl,
+        min(tofvh.create_time) as createTime
+        from
+        t_oe_face_verify_history tofvh
+        <where>
+            <if test="recordId != null and recordId != ''">
+                and tofvh.exam_record_id = #{recordId}
+            </if>
+            <if test="exception != null and exception != ''">
+                and tofvh.`exception` = #{exception}
+            </if>
+            <if test="type != null and type != ''">
+                and tofvh.`type` = #{type}
+            </if>
+        </where>
+        group by tofvh.`exception`) t
+    </select>
 </mapper>

+ 41 - 84
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -423,15 +423,13 @@ public class MqLogicServiceImpl implements MqLogicService {
             examStudentId = tOeExamRecord.getExamStudentId();
         }
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        if (Objects.nonNull(photoUrl) && (Objects.equals(type.toUpperCase(), ExamTypeEnum.FIRST_START.name()) || Objects
-                .equals(type.toUpperCase(), ExamTypeEnum.RESUME_START.name()))) {
+        if (Objects.nonNull(photoUrl) && (Objects.equals(type.toUpperCase(), ExamTypeEnum.FIRST_START.name()) || Objects.equals(type.toUpperCase(), ExamTypeEnum.RESUME_START.name()))) {
             JSONObject jsonObject = new JSONObject();
             jsonObject.put(PhotoTypeEnum.FACE_VERIFY_PHOTO.name(), photoUrl);
             TEExamStudentLog teExamStudentLog = new TEExamStudentLog(type, ExamTypeEnum.valueOf(type).getCode(),
                     jsonObject.toJSONString(), examStudentCacheBean.getStudentId(), examStudentCacheBean.getId(),
                     recordId, ExamTypeEnum.valueOf(type).getTitle());
-            faceVerifyHistoryService
-                    .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, null);
+            faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, null);
             teExamStudentLogService.saveOrUpdate(teExamStudentLog);
         } else if (Objects.equals(type.toUpperCase(), ExamTypeEnum.IN_PROCESS.name())) {
             VerifyExceptionEnum warningEnum = VerifyExceptionEnum.valueOf(exception);
@@ -443,22 +441,17 @@ public class MqLogicServiceImpl implements MqLogicService {
                         realnessErrorRandom = SystemConstant.getNanoId();
                         ExamRecordCacheUtil.setRealnessErrorRandom(recordId, realnessErrorRandom);
                     }
-                    ExamRecordCacheUtil
-                            .setRealnessErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getRealnessErrorNum(recordId).incrementAndGet()));
+                    ExamRecordCacheUtil.setRealnessErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getRealnessErrorNum(recordId).incrementAndGet()));
                     warningDto.setRandom(realnessErrorRandom);
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                    realnessErrorRandom);
+                    faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, realnessErrorRandom);
                     Integer count = ExamRecordCacheUtil.getRealnessErrorNum(recordId).get();
                     if (count > teConfig.getRealnessCount()) {
-                        ExamRecordCacheUtil.setRealnessErrorRandom(recordId,
-                                SystemConstant.getNanoId());
+                        ExamRecordCacheUtil.setRealnessErrorRandom(recordId, SystemConstant.getNanoId());
                         ExamRecordCacheUtil.setRealnessErrorNum(recordId, new AtomicInteger(0));
                         warningService.realnessError(warningDto);
                     }
                 } else {
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, null);
+                    faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, null);
                 }
             } else {
                 if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
@@ -468,16 +461,12 @@ public class MqLogicServiceImpl implements MqLogicService {
                             multipleFaceRandom = SystemConstant.getNanoId();
                             ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, multipleFaceRandom);
                         }
-                        ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId,
-                                new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
+                        ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
                         warningDto.setRandom(multipleFaceRandom);
-                        faceVerifyHistoryService
-                                .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                        multipleFaceRandom);
+                        faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, multipleFaceRandom);
                         Integer count = ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).get();
                         if (count > teConfig.getMultipleFaceCountError()) {
-                            ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId,
-                                    SystemConstant.getNanoId());
+                            ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, SystemConstant.getNanoId());
                             ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(0));
                             warningService.faceCountError(warningDto);
                         }
@@ -487,16 +476,12 @@ public class MqLogicServiceImpl implements MqLogicService {
                             noFaceRandom = SystemConstant.getNanoId();
                             ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, noFaceRandom);
                         }
-                        ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId,
-                                new AtomicInteger(ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).incrementAndGet()));
+                        ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).incrementAndGet()));
                         warningDto.setRandom(noFaceRandom);
-                        faceVerifyHistoryService
-                                .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                        noFaceRandom);
+                        faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, noFaceRandom);
                         Integer count = ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).get();
                         if (count > teConfig.getNoFaceCountError()) {
-                            ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId,
-                                    SystemConstant.getNanoId());
+                            ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, SystemConstant.getNanoId());
                             ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(0));
                             warningService.faceCountError(warningDto);
                         }
@@ -507,16 +492,12 @@ public class MqLogicServiceImpl implements MqLogicService {
                         faceCompareErrorRandom = SystemConstant.getNanoId();
                         ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, faceCompareErrorRandom);
                     }
-                    ExamRecordCacheUtil
-                            .setFaceCompareErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
+                    ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
                     warningDto.setRandom(faceCompareErrorRandom);
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                    faceCompareErrorRandom);
+                    faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, faceCompareErrorRandom);
                     Integer count = ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).get();
                     if (count > teConfig.getTotalFaceCompareErrorCount()) {
-                        ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId,
-                                SystemConstant.getNanoId());
+                        ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, SystemConstant.getNanoId());
                         ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(0));
                         warningService.faceCompareError(warningDto);
                     }
@@ -526,24 +507,19 @@ public class MqLogicServiceImpl implements MqLogicService {
                         eyeCloseErrorRandom = SystemConstant.getNanoId();
                         ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId, eyeCloseErrorRandom);
                     }
-                    ExamRecordCacheUtil
-                            .setEyeCloseErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).incrementAndGet()));
+                    ExamRecordCacheUtil.setEyeCloseErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).incrementAndGet()));
                     warningDto.setRandom(eyeCloseErrorRandom);
-                    faceVerifyHistoryService
-                            .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception,
-                                    eyeCloseErrorRandom);
+                    faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, eyeCloseErrorRandom);
                     Integer count = ExamRecordCacheUtil.getEyeCloseErrorNum(recordId).get();
                     if (count > teConfig.getTotalEyeCloseErrorCount()) {
-                        ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId,
-                                SystemConstant.getNanoId());
+                        ExamRecordCacheUtil.setEyeCloseErrorRandom(recordId, SystemConstant.getNanoId());
                         ExamRecordCacheUtil.setEyeCloseErrorNum(recordId, new AtomicInteger(0));
                         warningService.eyeCloseError(warningDto);
                     }
                 }
             }
         } else {
-            faceVerifyHistoryService
-                    .save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, null);
+            faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception, null);
         }
         tmRocketMessageService.saveMqMessageSuccess(mqDto, key);
     }
@@ -573,27 +549,20 @@ public class MqLogicServiceImpl implements MqLogicService {
             examStudentId = tOeExamRecord.getExamStudentId();
         }
         ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-        if (Objects.equals(type.toUpperCase(), ExamTypeEnum.FIRST_START.name()) || Objects
-                .equals(type.toUpperCase(), ExamTypeEnum.RESUME_START.name())) {
+        if (Objects.equals(type.toUpperCase(), ExamTypeEnum.FIRST_START.name()) || Objects.equals(type.toUpperCase(), ExamTypeEnum.RESUME_START.name())) {
             JSONArray jsonArray = JSONArray.parseArray(actions);
             for (int i = 0; i < jsonArray.size(); i++) {
                 JSONObject jsonObject = jsonArray.getJSONObject(i);
-                String photoType = Objects.nonNull(jsonObject.get(SystemConstant.TYPE)) ?
-                        String.valueOf(jsonObject.get(SystemConstant.TYPE)) :
-                        null;
-                String photoUrl = Objects.nonNull(jsonObject.get("photoUrl")) ?
-                        String.valueOf(jsonObject.get("photoUrl")) :
-                        null;
-                if (Objects.nonNull(photoType) && Objects.nonNull(photoUrl) && Objects
-                        .equals(photoType.toLowerCase(), "startup")) {
+                String photoType = Objects.nonNull(jsonObject.get(SystemConstant.TYPE)) ? String.valueOf(jsonObject.get(SystemConstant.TYPE)) : null;
+                String photoUrl = Objects.nonNull(jsonObject.get("photoUrl")) ? String.valueOf(jsonObject.get("photoUrl")) : null;
+                if (Objects.nonNull(photoType) && Objects.nonNull(photoUrl) && Objects.equals(photoType.toLowerCase(), "startup")) {
                     JSONObject object = new JSONObject();
                     object.put(PhotoTypeEnum.LIVENESS_VERIFY_PHOTO.name(), photoUrl);
                     TEExamStudentLog teExamStudentLog = new TEExamStudentLog(type,
                             LivenessTypeEnum.valueOf(type).getCode(), object.toJSONString(),
                             examStudentCacheBean.getStudentId(), examStudentCacheBean.getId(), recordId,
                             LivenessTypeEnum.valueOf(type).getTitle());
-                    livenessVerifyHistoryService
-                            .save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
+                    livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
                     teExamStudentLogService.saveOrUpdate(teExamStudentLog);
                     break;
                 }
@@ -604,29 +573,23 @@ public class MqLogicServiceImpl implements MqLogicService {
             for (int i = 0; i < jsonArray.size(); i++) {
                 JSONObject jsonObject = jsonArray.getJSONObject(i);
                 if (Objects.equals(VerifyExceptionEnum.NONE, warningEnum)) {//无异常,往考生日志表里插一条
-                    livenessVerifyHistoryService
-                            .save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
+                    livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
                 } else {
                     if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
                         Integer faceCount = Integer.parseInt(String.valueOf(jsonObject.get("faceCount")));
-                        WarningDto warningDto = new WarningDto(warningEnum, faceCount, null, recordId,
-                                String.valueOf(jsonObject.get("photoUrl")));
+                        WarningDto warningDto = new WarningDto(warningEnum, faceCount, null, recordId, String.valueOf(jsonObject.get("photoUrl")));
                         if (faceCount > 1) {//多张人脸
                             String multipleFaceRandom = ExamRecordCacheUtil.getMultipleFaceCountErrorRandom(recordId);
                             if (Objects.isNull(multipleFaceRandom)) {
                                 multipleFaceRandom = SystemConstant.getNanoId();
                                 ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, multipleFaceRandom);
                             }
-                            ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId,
-                                    new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
+                            ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
                             warningDto.setRandom(multipleFaceRandom);
-                            livenessVerifyHistoryService
-                                    .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
-                                            multipleFaceRandom);
+                            livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, multipleFaceRandom);
                             Integer count = ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).get();
                             if (count > teConfig.getMultipleFaceCountError()) {
-                                ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId,
-                                        SystemConstant.getNanoId());
+                                ExamRecordCacheUtil.setMultipleFaceCountErrorRandom(recordId, SystemConstant.getNanoId());
                                 ExamRecordCacheUtil.setMultipleFaceCountErrorNum(recordId, new AtomicInteger(0));
                                 warningService.faceCountError(warningDto);
                             }
@@ -636,47 +599,41 @@ public class MqLogicServiceImpl implements MqLogicService {
                                 noFaceRandom = SystemConstant.getNanoId();
                                 ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, noFaceRandom);
                             }
-                            ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId,
-                                    new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
+                            ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getMultipleFaceCountErrorNum(recordId).incrementAndGet()));
                             warningDto.setRandom(noFaceRandom);
-                            livenessVerifyHistoryService
-                                    .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
-                                            noFaceRandom);
+                            livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, noFaceRandom);
                             Integer count = ExamRecordCacheUtil.getNoFaceCountErrorNum(recordId).get();
                             if (count > teConfig.getNoFaceCountError()) {
-                                ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId,
-                                        SystemConstant.getNanoId());
+                                ExamRecordCacheUtil.setNoFaceCountErrorRandom(recordId, SystemConstant.getNanoId());
                                 ExamRecordCacheUtil.setNoFaceCountErrorNum(recordId, new AtomicInteger(0));
                                 warningService.faceCountError(warningDto);
                             }
                         }
                     } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
-                        WarningDto warningDto = new WarningDto(warningEnum, null, null, recordId,
-                                String.valueOf(jsonObject.get("photoUrl")));
+                        WarningDto warningDto = new WarningDto(warningEnum, null, null, recordId, String.valueOf(jsonObject.get("photoUrl")));
                         String faceCompareErrorRandom = ExamRecordCacheUtil.getFaceCompareErrorRandom(recordId);
                         if (Objects.isNull(faceCompareErrorRandom)) {
                             faceCompareErrorRandom = SystemConstant.getNanoId();
                             ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, faceCompareErrorRandom);
                         }
-                        ExamRecordCacheUtil.setFaceCompareErrorNum(recordId,
-                                new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
+                        ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).incrementAndGet()));
                         warningDto.setRandom(faceCompareErrorRandom);
-                        livenessVerifyHistoryService
-                                .save(id, recordId, type, actions, retry, startTime, finishTime, exception,
-                                        faceCompareErrorRandom);
+                        livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, faceCompareErrorRandom);
                         Integer count = ExamRecordCacheUtil.getFaceCompareErrorNum(recordId).get();
                         if (count > teConfig.getTotalFaceCompareErrorCount()) {
-                            ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId,
-                                    SystemConstant.getNanoId());
+                            ExamRecordCacheUtil.setFaceCompareErrorRandom(recordId, SystemConstant.getNanoId());
                             ExamRecordCacheUtil.setFaceCompareErrorNum(recordId, new AtomicInteger(0));
                             warningService.faceCompareError(warningDto);
                         }
+                    } else if (Objects.equals(VerifyExceptionEnum.LIVENESS_ACTION_ERROR, warningEnum)) {//活检动作错误
+                        WarningDto warningDto = new WarningDto(warningEnum, null, null, recordId, String.valueOf(jsonObject.get("photoUrl")));
+                        livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
+                        warningService.livenessActionError(warningDto);
                     }
                 }
             }
         } else {
-            livenessVerifyHistoryService
-                    .save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
+            livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception, null);
         }
         tmRocketMessageService.saveMqMessageSuccess(mqDto, key);
     }