You've already forked FrameTour-BE
feat(ai-cam): 新增AI相机人脸识别日志功能
- 创建人脸检测日志实体类FaceDetectLogAiCamEntity - 实现对应的MyBatis Mapper接口FaceDetectLogAiCamMapper - 添加服务接口及实现类FaceDetectLogAiCamService - 支持调用适配器进行人脸搜索并记录日志 - 记录搜索结果、匹配分数及原始响应数据 - 处理异常情况并记录错误信息到日志表中
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ycwl.basic.mapper;
|
||||||
|
|
||||||
|
import com.ycwl.basic.model.pc.faceDetectLog.entity.FaceDetectLogAiCamEntity;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI相机人脸识别日志Mapper
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface FaceDetectLogAiCamMapper {
|
||||||
|
int add(FaceDetectLogAiCamEntity entity);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.ycwl.basic.model.pc.faceDetectLog.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("face_detect_log_ai_cam")
|
||||||
|
public class FaceDetectLogAiCamEntity {
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
private Long deviceId;
|
||||||
|
|
||||||
|
private Long faceSampleId;
|
||||||
|
|
||||||
|
private String dbName;
|
||||||
|
|
||||||
|
private String faceUrl;
|
||||||
|
|
||||||
|
private Float score;
|
||||||
|
|
||||||
|
private String matchRawResult;
|
||||||
|
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ycwl.basic.service.pc;
|
||||||
|
|
||||||
|
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||||
|
import com.ycwl.basic.facebody.entity.SearchFaceResp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AI相机人脸识别日志服务
|
||||||
|
*/
|
||||||
|
public interface FaceDetectLogAiCamService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索人脸库并保存日志
|
||||||
|
* @param scenicId 景区ID
|
||||||
|
* @param deviceId 设备ID
|
||||||
|
* @param faceSampleId 人脸样本ID
|
||||||
|
* @param faceUrl 人脸URL
|
||||||
|
* @param adapter 人脸适配器
|
||||||
|
* @return 搜索结果
|
||||||
|
*/
|
||||||
|
SearchFaceResp searchAndLog(Long scenicId, Long deviceId, Long faceSampleId, String faceUrl, IFaceBodyAdapter adapter);
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.ycwl.basic.service.pc.impl;
|
||||||
|
|
||||||
|
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||||
|
import com.ycwl.basic.facebody.entity.SearchFaceResp;
|
||||||
|
import com.ycwl.basic.mapper.FaceDetectLogAiCamMapper;
|
||||||
|
import com.ycwl.basic.model.pc.faceDetectLog.entity.FaceDetectLogAiCamEntity;
|
||||||
|
import com.ycwl.basic.service.pc.FaceDetectLogAiCamService;
|
||||||
|
import com.ycwl.basic.utils.JacksonUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class FaceDetectLogAiCamServiceImpl implements FaceDetectLogAiCamService {
|
||||||
|
|
||||||
|
private final FaceDetectLogAiCamMapper faceDetectLogAiCamMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchFaceResp searchAndLog(Long scenicId, Long deviceId, Long faceSampleId, String faceUrl, IFaceBodyAdapter adapter) {
|
||||||
|
String dbName = "ai-cam-" + deviceId;
|
||||||
|
|
||||||
|
SearchFaceResp resp = null;
|
||||||
|
try {
|
||||||
|
// 调用适配器搜索人脸
|
||||||
|
resp = adapter.searchFace(dbName, faceUrl);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("AI相机人脸搜索异常: scenicId={}, deviceId={}, faceSampleId={}", scenicId, deviceId, faceSampleId, e);
|
||||||
|
// 发生异常时记录空结果或错误信息,视业务需求而定。这里暂不中断流程,继续记录日志
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 记录日志
|
||||||
|
FaceDetectLogAiCamEntity logEntity = new FaceDetectLogAiCamEntity();
|
||||||
|
logEntity.setScenicId(scenicId);
|
||||||
|
logEntity.setDeviceId(deviceId);
|
||||||
|
logEntity.setFaceSampleId(faceSampleId);
|
||||||
|
logEntity.setDbName(dbName);
|
||||||
|
logEntity.setFaceUrl(faceUrl);
|
||||||
|
logEntity.setCreateTime(new Date());
|
||||||
|
|
||||||
|
if (resp != null) {
|
||||||
|
logEntity.setScore(resp.getOriginalFaceScore()); // 记录图片中检测到的人脸质量分或首位匹配分?
|
||||||
|
// SearchFaceResp 的 getOriginalFaceScore 通常是图片质量分,getFirstMatchRate 是最佳匹配分
|
||||||
|
// 需根据 SearchFaceResp 定义确认。假设 getFirstMatchRate() 是匹配分
|
||||||
|
// 实际上 searchFace 返回的是匹配列表。
|
||||||
|
|
||||||
|
// 记录原始响应
|
||||||
|
logEntity.setMatchRawResult(JacksonUtil.toJSONString(resp));
|
||||||
|
} else {
|
||||||
|
logEntity.setMatchRawResult("{\"error\": \"search failed or exception\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
faceDetectLogAiCamMapper.add(logEntity);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("保存AI相机人脸识别日志失败: faceSampleId={}", faceSampleId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/main/resources/mapper/FaceDetectLogAiCamMapper.xml
Normal file
8
src/main/resources/mapper/FaceDetectLogAiCamMapper.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ycwl.basic.mapper.FaceDetectLogAiCamMapper">
|
||||||
|
<insert id="add" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into face_detect_log_ai_cam(scenic_id, device_id, face_sample_id, db_name, face_url, score, match_raw_result, create_time)
|
||||||
|
values (#{scenicId}, #{deviceId}, #{faceSampleId}, #{dbName}, #{faceUrl}, #{score}, #{matchRawResult}, #{createTime})
|
||||||
|
</insert>
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user