wangliang 4 жил өмнө
parent
commit
5bdcc106a8

+ 1 - 0
themis-backend/src/main/java/com/qmth/themis/backend/api/TEExamController.java

@@ -113,6 +113,7 @@ public class TEExamController {
             }
             teExam = new TEExam(teExamDto);
             teExamService.saveOrUpdate(teExam);
+            teExamService.updateExamCacheBean(teExam.getId());
             if (Objects.nonNull(oldTeExam) && !Objects.equals(oldTeExam.getMode().name(), teExamDto.getMode().name())) {//如果模式改变,则删除之前模式的全部quartz
                 QueryWrapper<TEExamActivity> teExamActivityQueryWrapper = new QueryWrapper<>();
                 teExamActivityQueryWrapper.lambda().eq(TEExamActivity::getExamId, oldId);

+ 4 - 2
themis-business/src/main/java/com/qmth/themis/business/dao/TOeFaceVerifyHistoryMapper.java

@@ -5,6 +5,8 @@ import com.qmth.themis.business.entity.TOeFaceVerifyHistory;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.Map;
+
 /**
  * @Description: 人脸验证记录 Mapper 接口
  * @Param:
@@ -24,7 +26,7 @@ public interface TOeFaceVerifyHistoryMapper extends BaseMapper<TOeFaceVerifyHist
      * @param multipleFace
      * @return
      */
-    public Integer faceCountError(@Param("recordId") Long recordId, @Param("exception") String exception, @Param("faceCount") Integer faceCount, @Param("multipleFace") Boolean multipleFace);
+    public Map<String, Object> faceCountError(@Param("recordId") Long recordId, @Param("exception") String exception, @Param("faceCount") Integer faceCount, @Param("multipleFace") Boolean multipleFace);
 
     /**
      * count人脸比对异常
@@ -33,5 +35,5 @@ public interface TOeFaceVerifyHistoryMapper extends BaseMapper<TOeFaceVerifyHist
      * @param exception
      * @return
      */
-    public Integer faceCompareError(@Param("recordId") Long recordId, @Param("exception") String exception);
+    public Map<String, Object> faceCompareError(@Param("recordId") Long recordId, @Param("exception") String exception);
 }

+ 8 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TOeExamBreakHistory.java

@@ -70,6 +70,14 @@ public class TOeExamBreakHistory implements Serializable {
         this.resumeReason = resumeReason;
     }
 
+    public TOeExamBreakHistory(Long id, Long examRecordId, Date breakTime, ExceptionEnum breakReason, String resumeReason) {
+        this.id = id;
+        this.examRecordId = examRecordId;
+        this.breakTime = breakTime;
+        this.breakReason = breakReason;
+        this.resumeReason = resumeReason;
+    }
+
     public static long getSerialVersionUID() {
         return serialVersionUID;
     }

+ 25 - 0
themis-business/src/main/java/com/qmth/themis/business/enums/PhotoTypeEnum.java

@@ -0,0 +1,25 @@
+package com.qmth.themis.business.enums;
+
+/**
+* @Description: 照片来源 enum
+* @Param:
+* @return:
+* @Author: wangliang
+* @Date: 2020/9/15
+*/
+public enum PhotoTypeEnum {
+
+    FACE_VERIFY_PHOTO("人脸识别"),
+
+    LIVENESS_VERIFY_PHOTO("活体检测");
+
+    private String code;
+
+    private PhotoTypeEnum(String code){
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+}

+ 4 - 2
themis-business/src/main/java/com/qmth/themis/business/service/TOeFaceVerifyHistoryService.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.themis.business.bean.exam.FaceVerifyBean;
 import com.qmth.themis.business.entity.TOeFaceVerifyHistory;
 
+import java.util.Map;
+
 /**
  * @Description: 人脸验证记录 服务类
  * @Param:
@@ -28,7 +30,7 @@ public interface TOeFaceVerifyHistoryService extends IService<TOeFaceVerifyHisto
      * @param multipleFace
      * @return
      */
-    public Integer faceCountError(Long recordId, String exception, Integer faceCount, Boolean multipleFace);
+    public Map<String, Object> faceCountError(Long recordId, String exception, Integer faceCount, Boolean multipleFace);
 
     /**
      * count人脸比对异常
@@ -37,5 +39,5 @@ public interface TOeFaceVerifyHistoryService extends IService<TOeFaceVerifyHisto
      * @param exception
      * @return
      */
-    public Integer faceCompareError(Long recordId, String exception);
+    public Map<String, Object> faceCompareError(Long recordId, String exception);
 }

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

@@ -16,6 +16,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.util.Map;
 
 /**
  * @Description: 人脸验证记录 服务实现类
@@ -88,7 +89,7 @@ public class TOeFaceVerifyHistoryServiceImpl extends ServiceImpl<TOeFaceVerifyHi
      * @return
      */
     @Override
-    public Integer faceCountError(Long recordId, String exception, Integer faceCount, Boolean multipleFace) {
+    public Map<String, Object> faceCountError(Long recordId, String exception, Integer faceCount, Boolean multipleFace) {
         return tOeFaceVerifyHistoryMapper.faceCountError(recordId, exception, faceCount, multipleFace);
     }
 
@@ -100,7 +101,7 @@ public class TOeFaceVerifyHistoryServiceImpl extends ServiceImpl<TOeFaceVerifyHi
      * @return
      */
     @Override
-    public Integer faceCompareError(Long recordId, String exception) {
+    public Map<String, Object> faceCompareError(Long recordId, String exception) {
         return tOeFaceVerifyHistoryMapper.faceCompareError(recordId, exception);
     }
 }

+ 56 - 29
themis-business/src/main/java/com/qmth/themis/business/service/impl/WarningServiceImpl.java

@@ -1,18 +1,18 @@
 package com.qmth.themis.business.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.dto.WarningDto;
 import com.qmth.themis.business.entity.TEConfig;
+import com.qmth.themis.business.entity.TEExamStudentLog;
 import com.qmth.themis.business.entity.TIeInvigilateWarnInfo;
 import com.qmth.themis.business.entity.TOeFaceVerifyHistory;
 import com.qmth.themis.business.enums.VerifyExceptionEnum;
 import com.qmth.themis.business.enums.WarningLevelEnum;
-import com.qmth.themis.business.service.TEConfigService;
-import com.qmth.themis.business.service.TIeInvigilateWarnInfoService;
-import com.qmth.themis.business.service.TOeFaceVerifyHistoryService;
-import com.qmth.themis.business.service.WarningService;
+import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.RedisUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -20,8 +20,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * @Description: 预警规则公用
@@ -46,6 +45,12 @@ public class WarningServiceImpl implements WarningService {
     @Resource
     TIeInvigilateWarnInfoService tIeInvigilateWarnInfoService;
 
+    @Resource
+    TEExamStudentLogService teExamStudentLogService;
+
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     /**
      * 人脸数量异常
      *
@@ -62,21 +67,40 @@ public class WarningServiceImpl implements WarningService {
         Long examId = ExamRecordCacheUtil.getExamId(recordId);
         Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
         Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
         if (faceCount > 1) {//多张人脸
-            Integer count = faceVerifyHistoryService.faceCountError(recordId, warningDto.getWarningEnum().name(), faceCount, true);
-            count = Objects.isNull(count) ? 0 : count;
-            if (count >= teConfig.getMultipleFaceCountError()) {
-                TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(1), WarningLevelEnum.valueOf(warningEnum.getLevel().get(1)).getDesc(), warningEnum, photoUrl);
-                tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
-                this.setWarningCount(recordId);
+            Map<String, Object> map = faceVerifyHistoryService.faceCountError(recordId, warningDto.getWarningEnum().name(), faceCount, true);
+            if (Objects.nonNull(map) && map.size() > 0) {
+                Integer count = Integer.parseInt(String.valueOf(map.get("tmpCount")));
+                count = Objects.isNull(count) ? 0 : count;
+                if (count >= teConfig.getMultipleFaceCountError()) {
+                    List photoUrls = null;
+                    if (Objects.nonNull(map.get("photoUrls")) && !Objects.equals(map.get("photoUrls"), "")) {
+                        photoUrls = Arrays.asList(String.valueOf(map.get("photoUrls")).split(","));
+                    }
+                    if (Objects.isNull(photoUrls)) {
+                        photoUrls = new ArrayList();
+                    }
+                    photoUrls.add(photoUrl);
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("PHOTOS", photoUrls);
+                    TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(1), WarningLevelEnum.valueOf(warningEnum.getLevel().get(1)).getDesc(), warningEnum, photoUrl);
+                    tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
+                    TEExamStudentLog teExamStudentLog = new TEExamStudentLog(tIeInvigilateWarnInfo.getType().name(), tIeInvigilateWarnInfo.getType().getCode(), jsonObject.toJSONString(), examStudentCacheBean.getStudentId(), examStudentCacheBean.getId(), recordId);
+                    teExamStudentLogService.saveOrUpdate(teExamStudentLog);
+                    this.setWarningCount(recordId);
+                }
             }
         } else if (faceCount <= 0) {//未检测到人脸
-            Integer count = faceVerifyHistoryService.faceCountError(recordId, warningDto.getWarningEnum().name(), faceCount, false);
-            count = Objects.isNull(count) ? 0 : count;
-            if (count >= teConfig.getNoFaceCountError()) {
-                TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(0), WarningLevelEnum.valueOf(warningEnum.getLevel().get(0)).getDesc(), warningEnum, photoUrl);
-                tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
-                this.setWarningCount(recordId);
+            Map<String, Object> map = faceVerifyHistoryService.faceCountError(recordId, warningDto.getWarningEnum().name(), faceCount, false);
+            if (Objects.nonNull(map) && map.size() > 0) {
+                Integer count = (Integer) map.get("tmpCount");
+                count = Objects.isNull(count) ? 0 : count;
+                if (count >= teConfig.getNoFaceCountError()) {
+                    TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(0), WarningLevelEnum.valueOf(warningEnum.getLevel().get(0)).getDesc(), warningEnum, photoUrl);
+                    tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
+                    this.setWarningCount(recordId);
+                }
             }
         }
     }
@@ -96,17 +120,20 @@ public class WarningServiceImpl implements WarningService {
         Long examId = ExamRecordCacheUtil.getExamId(recordId);
         Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
         Long examActivityId = ExamRecordCacheUtil.getExamActivityId(recordId);
-        Integer count = faceVerifyHistoryService.faceCompareError(recordId, warningDto.getWarningEnum().name());
-        count = Objects.isNull(count) ? 0 : count;
-        if (count >= teConfig.getMatchFaceCompareErrorCount()) {
-            TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(0), WarningLevelEnum.valueOf(warningEnum.getLevel().get(0)).getDesc(), warningEnum, photoUrl);
-            tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
-            this.setWarningCount(recordId);
-        }
-        if (count >= teConfig.getTotalFaceCompareErrorCount()) {
-            TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(1), WarningLevelEnum.valueOf(warningEnum.getLevel().get(1)).getDesc(), warningEnum, photoUrl);
-            tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
-            this.setWarningCount(recordId);
+        Map<String, Object> map = faceVerifyHistoryService.faceCompareError(recordId, warningDto.getWarningEnum().name());
+        if (Objects.nonNull(map) && map.size() > 0) {
+            Integer count = (Integer) map.get("tmpCount");
+            count = Objects.isNull(count) ? 0 : count;
+            if (count >= teConfig.getMatchFaceCompareErrorCount()) {
+                TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(0), WarningLevelEnum.valueOf(warningEnum.getLevel().get(0)).getDesc(), warningEnum, photoUrl);
+                tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
+                this.setWarningCount(recordId);
+            }
+            if (count >= teConfig.getTotalFaceCompareErrorCount()) {
+                TIeInvigilateWarnInfo tIeInvigilateWarnInfo = new TIeInvigilateWarnInfo(examId, examActivityId, recordId, examStudentId, warningEnum.getLevel().get(1), WarningLevelEnum.valueOf(warningEnum.getLevel().get(1)).getDesc(), warningEnum, photoUrl);
+                tIeInvigilateWarnInfoService.saveOrUpdate(tIeInvigilateWarnInfo);
+                this.setWarningCount(recordId);
+            }
         }
     }
 

+ 24 - 11
themis-business/src/main/resources/mapper/TOeFaceVerifyHistoryMapper.xml

@@ -2,13 +2,15 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.qmth.themis.business.dao.TOeFaceVerifyHistoryMapper">
 
-    <select id="faceCountError" resultType="java.lang.Integer">
+    <select id="faceCountError" resultType="java.util.Map">
         select
-            sum(t.tmpCount) as tmpCount
+            sum(t.tmpCount) as tmpCount,
+            group_concat(t.photoUrl) as photoUrls
         from
             (
             select
-                count(1) as tmpCount
+                count(1) as tmpCount,
+                group_concat(tofvh.photo_url) as photoUrl
             from
                 t_oe_face_verify_history tofvh
             <where>
@@ -27,14 +29,18 @@
                     </otherwise>
                 </choose>
             </where>
+            group by tofvh.`exception`
         union all
             select
-                count(1) as tmpCount
+                count(1) as tmpCount,
+                group_concat(t.photoUrl)
             from
                 (
                 select
                     CONVERT((tolvh.actions->>'$.faceCount')
-                        USING utf8) as faceCount, tolvh.`exception`
+                        USING utf8) as faceCount, tolvh.`exception`,
+                    CONVERT((tolvh.actions->>'$.photoUrl')
+                        USING utf8) as photoUrl
                 from
                     t_oe_liveness_verify_history tolvh
                 <where>
@@ -54,16 +60,19 @@
                         and t.faceCount = 0
                     </otherwise>
                 </choose>
-            </where> ) t
+            </where>
+        group by t.`exception` ) t
     </select>
 
-    <select id="faceCompareError" resultType="java.lang.Integer">
+    <select id="faceCompareError" resultType="java.util.Map">
         select
-            sum(t.tmpCount) as tmpCount
+            sum(t.tmpCount) as tmpCount,
+            group_concat(t.photoUrl) as photoUrls
         from
             (
             select
-                count(1) as tmpCount
+                count(1) as tmpCount,
+                group_concat(tofvh.photo_url) as photoUrl
             from
                 t_oe_face_verify_history tofvh
             <where>
@@ -74,9 +83,12 @@
                     and tofvh.`exception` = #{exception}
                 </if>
             </where>
+            group by tofvh.`exception`
         union all
             select
-                count(1) as tmpCount
+                count(1) as tmpCount,
+                CONVERT((tolvh.actions->>'$.photoUrl')
+                USING utf8) as photoUrl
             from
                 t_oe_liveness_verify_history tolvh
             <where>
@@ -86,6 +98,7 @@
                 <if test="exception != null and exception != ''">
                     and tolvh.`exception` = #{exception}
                 </if>
-            </where> ) t
+            </where>
+            group by tolvh.`exception`) t
     </select>
 </mapper>

+ 28 - 8
themis-exam/src/main/java/com/qmth/themis/exam/api/TEExamController.java

@@ -5,6 +5,7 @@ import com.qmth.themis.business.annotation.ApiJsonObject;
 import com.qmth.themis.business.annotation.ApiJsonProperty;
 import com.qmth.themis.business.bean.exam.*;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
+import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.WebsocketDto;
@@ -12,15 +13,14 @@ import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
 import com.qmth.themis.business.dto.response.TEExamDto;
 import com.qmth.themis.business.dto.response.TEExamResultDto;
 import com.qmth.themis.business.entity.TEExam;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.enums.SystemOperationEnum;
-import com.qmth.themis.business.enums.WebsocketTypeEnum;
+import com.qmth.themis.business.enums.*;
 import com.qmth.themis.business.service.MqDtoService;
 import com.qmth.themis.business.service.TEExamService;
+import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.business.util.ServletUtil;
+import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
@@ -44,12 +44,16 @@ public class TEExamController {
 
     @Resource
     TEExamService teExamService;
+
     @Resource
     RedisUtil redisUtil;
 
     @Resource
     MqDtoService mqDtoService;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     @ApiOperation(value = "验证考试口令接口")
     @RequestMapping(value = "/short_code", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "考试信息", response = TEExam.class)})
@@ -121,10 +125,26 @@ public class TEExamController {
             }
             ExamStartBean examStartBean = teExamService.start(teStudent.getId(), param.getRecordId());
             if (Objects.nonNull(param.getReason())) {
-                //考试断点异常原因 发送mq start
-                MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.EXCEPTION_LOG.name(), JacksonUtil.parseJson(param), MqTagEnum.EXCEPTION_LOG, String.valueOf(param.getRecordId()), param.getReason());
-                mqDtoService.assembleSendOneWayMsg(mqDto);
-                //考试断点异常原因 发送mq end
+                Long recordId = param.getRecordId();
+                Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+                ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+                Integer leftBreakResumeCount = Objects.isNull(ExamRecordCacheUtil.getLeftBreakResumeCount(recordId)) ? 0 : ExamRecordCacheUtil.getLeftBreakResumeCount(recordId);
+                leftBreakResumeCount--;
+                leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
+                if (leftBreakResumeCount <= 0) {
+                    Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
+                    teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
+                } else {
+                    ExamRecordCacheUtil.setLastBreakId(param.getRecordId(), Constants.idGen.next());
+                    ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.RESUME_PREPARE);
+                    ExamRecordCacheUtil.setLastBreakTime(recordId);
+                    ExamRecordCacheUtil.setLeftBreakResumeCount(recordId, leftBreakResumeCount);
+                    ExamRecordCacheUtil.setLastStartTime(recordId);
+                    //考试断点异常原因 发送mq start
+                    MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.EXCEPTION_LOG.name(), JacksonUtil.parseJson(param), MqTagEnum.EXCEPTION_LOG, String.valueOf(param.getRecordId()), param.getReason());
+                    mqDtoService.assembleSendOneWayMsg(mqDto);
+                    //考试断点异常原因 发送mq end
+                }
             } else {
                 //mq发送消息start
                 MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.ANSWERING, MqTagEnum.STUDENT, String.valueOf(teStudent.getId()), teStudent.getIdentity());

+ 43 - 47
themis-mq/src/main/java/com/qmth/themis/mq/service/impl/MqLogicServiceImpl.java

@@ -290,13 +290,22 @@ public class MqLogicServiceImpl implements MqLogicService {
         faceVerifyHistoryService.save(id, recordId, type, photoUrl, faceCount, similarity, realness, time, exception);
         VerifyExceptionEnum warningEnum = VerifyExceptionEnum.valueOf(exception);
         WarningDto warningDto = new WarningDto(warningEnum, faceCount, realness, recordId, photoUrl);
-        if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
-            warningService.faceCountError(warningDto);
-        } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
-            warningService.faceCompareError(warningDto);
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+        if (Objects.equals(VerifyExceptionEnum.NONE, warningEnum)) {//无异常,往考生日志表里插一条
+            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);
+            teExamStudentLogService.saveOrUpdate(teExamStudentLog);
         } else {
-            if (realness.intValue() == 0) {//真实性异常
-                warningService.realnessError(warningDto);
+            if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
+                warningService.faceCountError(warningDto);
+            } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
+                warningService.faceCompareError(warningDto);
+            } else {
+                if (realness.intValue() == 0) {//真实性异常
+                    warningService.realnessError(warningDto);
+                }
             }
         }
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
@@ -328,10 +337,19 @@ public class MqLogicServiceImpl implements MqLogicService {
         livenessVerifyHistoryService.save(id, recordId, type, actions, retry, startTime, finishTime, exception);
         VerifyExceptionEnum warningEnum = VerifyExceptionEnum.valueOf(exception);
         JSONObject jsonObject = JSONObject.parseObject(actions);
-        if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
-            warningService.faceCountError(new WarningDto(warningEnum, Integer.parseInt(String.valueOf(jsonObject.get("faceCount"))), null, recordId, String.valueOf(jsonObject.get("photoUrl"))));
-        } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
-            warningService.faceCompareError(new WarningDto(warningEnum, null, null, recordId, String.valueOf(jsonObject.get("photoUrl"))));
+        Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
+        ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
+        if (Objects.equals(VerifyExceptionEnum.NONE, warningEnum)) {//无异常,往考生日志表里插一条
+            JSONObject object = new JSONObject();
+            object.put(PhotoTypeEnum.LIVENESS_VERIFY_PHOTO.name(), String.valueOf(jsonObject.get("photoUrl")));
+            TEExamStudentLog teExamStudentLog = new TEExamStudentLog(type, LivenessTypeEnum.valueOf(type).getTitle(), object.toJSONString(), examStudentCacheBean.getStudentId(), examStudentCacheBean.getId(), recordId);
+            teExamStudentLogService.saveOrUpdate(teExamStudentLog);
+        } else {
+            if (Objects.equals(VerifyExceptionEnum.FACE_COUNT_ERROR, warningEnum)) {//人脸数量异常
+                warningService.faceCountError(new WarningDto(warningEnum, Integer.parseInt(String.valueOf(jsonObject.get("faceCount"))), null, recordId, String.valueOf(jsonObject.get("photoUrl"))));
+            } else if (Objects.equals(VerifyExceptionEnum.FACE_COMPARE_ERROR, warningEnum)) {//人脸比对异常
+                warningService.faceCompareError(new WarningDto(warningEnum, null, null, recordId, String.valueOf(jsonObject.get("photoUrl"))));
+            }
         }
         mqDto.setAck(SystemConstant.STANDARD_ACK_TYPE);
         TMRocketMessage tmRocketMessage = gson.fromJson(gson.toJson(mqDto), TMRocketMessage.class);
@@ -454,46 +472,24 @@ public class MqLogicServiceImpl implements MqLogicService {
                 Long l = ((System.currentTimeMillis() - clientLastSyncTime.getTime()) / 1000);
                 diff = l.intValue();
             }
-
             Long examStudentId = ExamRecordCacheUtil.getExamStudentId(recordId);
             ExamStudentCacheBean examStudentCacheBean = teExamStudentService.getExamStudentCacheBean(examStudentId);
-            Integer leftBreakResumeCount = Objects.isNull(ExamRecordCacheUtil.getLeftBreakResumeCount(recordId)) ? 0 : ExamRecordCacheUtil.getLeftBreakResumeCount(recordId);
-            leftBreakResumeCount--;
-            leftBreakResumeCount = leftBreakResumeCount <= 0 ? 0 : leftBreakResumeCount;
-            if (leftBreakResumeCount <= 0) {
-                Integer durationSeconds = Objects.isNull(ExamRecordCacheUtil.getDurationSeconds(recordId)) ? 0 : ExamRecordCacheUtil.getDurationSeconds(recordId);
-                teExamService.finish(examStudentCacheBean.getStudentId(), recordId, FinishTypeEnum.AUTO.name(), durationSeconds);
-            } else {
-                //先查询之前的断点记录
-                QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();
-                tOeExamBreakHistoryQueryWrapper.lambda().eq(TOeExamBreakHistory::getExamRecordId, recordId);
-                List<TOeExamBreakHistory> tOeExamBreakHistoryList = tOeExamBreakHistoryService.list(tOeExamBreakHistoryQueryWrapper);
-                //删除历史断点缓存
-                if (Objects.nonNull(tOeExamBreakHistoryList) && tOeExamBreakHistoryList.size() > 0) {
-                    tOeExamBreakHistoryList.forEach(s -> {
-                        redisUtil.delete(RedisKeyHelper.examBreakCacheKey(s.getId()));
-                    });
-                }
-                //增加断点记录
-                TOeExamBreakHistory tOeExamBreakHistory = new TOeExamBreakHistory(recordId, new Date(), exceptionEnum, exceptionEnum.name());
-                tOeExamBreakHistoryService.save(tOeExamBreakHistory);
-                redisUtil.setForHash(RedisKeyHelper.examBreakCacheKey(tOeExamBreakHistory.getId()), SimpleBeanUtil.objectToMap(tOeExamBreakHistory));
-
-                ExamRecordCacheUtil.setLastBreakId(recordId, tOeExamBreakHistory.getId());
-                ExamRecordCacheUtil.setStatus(recordId, ExamRecordStatusEnum.RESUME_PREPARE);
-                ExamRecordCacheUtil.setLastBreakTime(recordId);
-                ExamRecordCacheUtil.setLeftBreakResumeCount(recordId, leftBreakResumeCount);
-                ExamRecordCacheUtil.setLastStartTime(recordId);
-                UpdateWrapper<TOeExamRecord> tOeExamRecordUpdateWrapper = new UpdateWrapper<>();
-                tOeExamRecordUpdateWrapper.lambda().set(TOeExamRecord::getLastBreakId, tOeExamBreakHistory.getId())
-                        .set(TOeExamRecord::getStatus, ExamRecordStatusEnum.RESUME_PREPARE)
-                        .set(TOeExamRecord::getLastBreakTime, ExamRecordCacheUtil.getLastBreakTime(recordId))
-                        .set(TOeExamRecord::getLeftBreakResumeCount, leftBreakResumeCount)
-                        .set(TOeExamRecord::getLastStartTime, ExamRecordCacheUtil.getLastStartTime(recordId))
-                        .eq(TOeExamRecord::getId, recordId);
-                examRecordService.update(tOeExamRecordUpdateWrapper);
-                teExamStudentLogService.saveStudentLogInfo(SystemOperationEnum.RESUME_PREPARE.name(), SystemOperationEnum.RESUME_PREPARE.getCode(), SystemOperationEnum.RESUME_PREPARE.getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
+
+            //先查询之前的断点记录
+            QueryWrapper<TOeExamBreakHistory> tOeExamBreakHistoryQueryWrapper = new QueryWrapper<>();
+            tOeExamBreakHistoryQueryWrapper.lambda().eq(TOeExamBreakHistory::getExamRecordId, recordId);
+            List<TOeExamBreakHistory> tOeExamBreakHistoryList = tOeExamBreakHistoryService.list(tOeExamBreakHistoryQueryWrapper);
+            //删除历史断点缓存
+            if (Objects.nonNull(tOeExamBreakHistoryList) && tOeExamBreakHistoryList.size() > 0) {
+                tOeExamBreakHistoryList.forEach(s -> {
+                    redisUtil.delete(RedisKeyHelper.examBreakCacheKey(s.getId()));
+                });
             }
+            //增加断点记录
+            TOeExamBreakHistory tOeExamBreakHistory = new TOeExamBreakHistory(ExamRecordCacheUtil.getLastBreakId(recordId), recordId, new Date(), exceptionEnum, exceptionEnum.name());
+            tOeExamBreakHistoryService.save(tOeExamBreakHistory);
+            redisUtil.setForHash(RedisKeyHelper.examBreakCacheKey(tOeExamBreakHistory.getId()), SimpleBeanUtil.objectToMap(tOeExamBreakHistory));
+            teExamStudentLogService.saveStudentLogInfo(SystemOperationEnum.RESUME_PREPARE.name(), SystemOperationEnum.RESUME_PREPARE.getCode(), SystemOperationEnum.RESUME_PREPARE.getCode(), examStudentCacheBean.getStudentId(), examStudentId, recordId);
 
             //增加异常日志
             Long examId = ExamRecordCacheUtil.getExamId(recordId);