feat(ai): 实现AI相机人脸识别日志记录功能

- 引入DeviceRepository以获取景区内所有AI相机设备
- 修改searchAndLog方法逻辑,遍历所有AI相机设备进行人脸搜索
- 新增searchDeviceAndLog私有方法处理单个设备的人脸识别与日志记录
- 更新FaceDetectLogAiCamService接口定义,移除deviceId参数
- 在FaceServiceImpl中调用新的日志记录服务
- 删除不再使用的DeviceConfigManager和FaceRecoveryStrategy依赖
- 调整日志记录中的字段名称及异常处理逻辑
This commit is contained in:
2025-12-05 16:54:47 +08:00
parent 24bbb63bf7
commit 4a82ee6c4d
3 changed files with 29 additions and 12 deletions

View File

@@ -11,11 +11,10 @@ public interface FaceDetectLogAiCamService {
/**
* 搜索人脸库并保存日志
* @param scenicId 景区ID
* @param deviceId 设备ID
* @param faceSampleId 人脸样本ID
* @param faceId 人脸样本ID
* @param faceUrl 人脸URL
* @param adapter 人脸适配器
* @return 搜索结果
*/
SearchFaceResp searchAndLog(Long scenicId, Long deviceId, Long faceSampleId, String faceUrl, IFaceBodyAdapter adapter);
void searchAndLog(Long scenicId, Long faceId, String faceUrl, IFaceBodyAdapter adapter);
}

View File

@@ -2,8 +2,10 @@ 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.integration.device.dto.device.DeviceV2DTO;
import com.ycwl.basic.mapper.FaceDetectLogAiCamMapper;
import com.ycwl.basic.model.pc.faceDetectLog.entity.FaceDetectLogAiCamEntity;
import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.service.pc.FaceDetectLogAiCamService;
import com.ycwl.basic.utils.JacksonUtil;
import lombok.RequiredArgsConstructor;
@@ -11,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
@@ -18,17 +21,28 @@ import java.util.Date;
public class FaceDetectLogAiCamServiceImpl implements FaceDetectLogAiCamService {
private final FaceDetectLogAiCamMapper faceDetectLogAiCamMapper;
private final DeviceRepository deviceRepository;
@Override
public SearchFaceResp searchAndLog(Long scenicId, Long deviceId, Long faceSampleId, String faceUrl, IFaceBodyAdapter adapter) {
public void searchAndLog(Long scenicId, Long faceId, String faceUrl, IFaceBodyAdapter adapter) {
List<DeviceV2DTO> devices = deviceRepository.getAllDeviceByScenicId(scenicId);
for (DeviceV2DTO device : devices) {
if (!device.getType().equals("AI_CAM")) {
continue;
}
searchDeviceAndLog(scenicId, device.getId(), faceId, faceUrl, adapter);
}
}
private SearchFaceResp searchDeviceAndLog(Long scenicId, Long deviceId, Long faceId, String faceUrl, IFaceBodyAdapter adapter) {
String dbName = "AiCam" + deviceId;
SearchFaceResp resp = null;
try {
// 调用适配器搜索人脸
resp = adapter.searchFace(dbName, faceUrl);
} catch (Exception e) {
log.error("AI相机人脸搜索异常: scenicId={}, deviceId={}, faceSampleId={}", scenicId, deviceId, faceSampleId, e);
log.error("AI相机人脸搜索异常: scenicId={}, deviceId={}, faceSampleId={}", scenicId, deviceId, faceId, e);
// 发生异常时记录空结果或错误信息,视业务需求而定。这里暂不中断流程,继续记录日志
}
@@ -37,7 +51,7 @@ public class FaceDetectLogAiCamServiceImpl implements FaceDetectLogAiCamService
FaceDetectLogAiCamEntity logEntity = new FaceDetectLogAiCamEntity();
logEntity.setScenicId(scenicId);
logEntity.setDeviceId(deviceId);
logEntity.setFaceId(faceSampleId);
logEntity.setFaceId(faceId);
logEntity.setDbName(dbName);
logEntity.setFaceUrl(faceUrl);
logEntity.setCreateTime(new Date());
@@ -47,17 +61,17 @@ public class FaceDetectLogAiCamServiceImpl implements FaceDetectLogAiCamService
// SearchFaceResp 的 getOriginalFaceScore 通常是图片质量分,getFirstMatchRate 是最佳匹配分
// 需根据 SearchFaceResp 定义确认。假设 getFirstMatchRate() 是匹配分
// 实际上 searchFace 返回的是匹配列表。
// 记录原始响应
logEntity.setMatchRawResult(JacksonUtil.toJSONString(resp));
} else {
logEntity.setMatchRawResult("{\"error\": \"search failed or exception\"}");
logEntity.setMatchRawResult("{\"error\": \"search failed or exception\"}");
}
faceDetectLogAiCamMapper.add(logEntity);
} catch (Exception e) {
log.error("保存AI相机人脸识别日志失败: faceSampleId={}", faceSampleId, e);
log.error("保存AI相机人脸识别日志失败: faceSampleId={}", faceId, e);
}
return resp;

View File

@@ -9,7 +9,6 @@ import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.exception.BaseException;
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
import com.ycwl.basic.facebody.entity.SearchFaceResultItem;
import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.ProjectMapper;
import com.ycwl.basic.mapper.SourceMapper;
@@ -62,6 +61,7 @@ import com.ycwl.basic.repository.TemplateRepository;
import com.ycwl.basic.repository.VideoRepository;
import com.ycwl.basic.repository.VideoTaskRepository;
import com.ycwl.basic.service.mobile.GoodsService;
import com.ycwl.basic.service.pc.FaceDetectLogAiCamService;
import com.ycwl.basic.service.pc.FaceService;
import com.ycwl.basic.service.pc.ScenicService;
import com.ycwl.basic.constant.SourceType;
@@ -71,7 +71,6 @@ import com.ycwl.basic.service.pc.helper.SearchResultMerger;
import com.ycwl.basic.service.pc.helper.ScenicConfigFacade;
import com.ycwl.basic.service.pc.orchestrator.FaceMatchingOrchestrator;
import com.ycwl.basic.service.pc.processor.BuyStatusProcessor;
import com.ycwl.basic.service.pc.processor.FaceRecoveryStrategy;
import com.ycwl.basic.service.pc.processor.SourceRelationProcessor;
import com.ycwl.basic.service.pc.processor.VideoRecreationHandler;
import com.ycwl.basic.service.pc.strategy.RematchContext;
@@ -193,6 +192,8 @@ public class FaceServiceImpl implements FaceService {
private IPriceCalculationService iPriceCalculationService;
@Autowired
private PuzzleTemplateMapper puzzleTemplateMapper;
@Autowired
private FaceDetectLogAiCamService faceDetectLogAiCamService;
@Override
public ApiResponse<PageInfo<FaceRespVO>> pageQuery(FaceReqQuery faceReqQuery) {
@@ -319,6 +320,9 @@ public class FaceServiceImpl implements FaceService {
}
}
if (org.apache.commons.lang3.Strings.CI.equals("aiCam", scene)) {
faceDetectLogAiCamService.searchAndLog(scenicId, newFaceId, faceUrl, faceBodyAdapter);
}
return resp;
}