feat(FaceServiceImpl): 实现人脸重复匹配逻辑

- 新增旅游时间和项目匹配逻辑
-增加识别次数、旅游匹配和项目匹配的规则判断
-根据不同匹配模式返回相应的结果
This commit is contained in:
2025-09-17 15:13:39 +08:00
parent 2a8bdaec28
commit 8975ce404c

View File

@@ -12,6 +12,7 @@ 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;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.mapper.FaceMapper;
@@ -32,6 +33,7 @@ import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.model.pc.faceSample.resp.FaceSampleRespVO;
import com.ycwl.basic.model.pc.mp.MpConfigEntity;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.model.pc.project.resp.ProjectRespVO;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
@@ -129,6 +131,8 @@ public class FaceServiceImpl implements FaceService {
private FaceSampleMapper faceSampleMapper;
@Autowired
private GoodsService goodsService;
@Autowired
private ProjectMapper projectMapper;
@Override
public ApiResponse<PageInfo<FaceRespVO>> pageQuery(FaceReqQuery faceReqQuery) {
@@ -904,6 +908,35 @@ public class FaceServiceImpl implements FaceService {
if (face == null) {
return false;
}
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(face.getScenicId());
Integer maxTourTime = scenicConfig.getInteger("tour_time");
Integer minTourTime = scenicConfig.getInteger("tour_min_time");
boolean tourMatch = false;
if (maxTourTime != null && minTourTime != null) {
if ((new Date().getTime()) - face.getCreateAt().getTime() < maxTourTime * 60 * 1000
&& (new Date().getTime()) - face.getCreateAt().getTime() > minTourTime * 60 * 1000) {
tourMatch = true;
}
}
// 判断是否项目匹配
boolean projectMatch = false;
if (maxTourTime != null) {
List<Long> projectIdListForUser = statisticsMapper.getProjectIdListForUser(face.getMemberId(), new Date((new Date().getTime()) - maxTourTime * 60 * 1000), new Date());
if (projectIdListForUser != null && !projectIdListForUser.isEmpty()) {
Long projectId = projectIdListForUser.getFirst();
ProjectRespVO projectRespVO = projectMapper.getById(projectId);
if (projectRespVO != null) {
Integer maxPlayTime = projectRespVO.getMaxPlayTime();
Integer minPlayTime = projectRespVO.getMinPlayTime();
if (maxPlayTime != null && minPlayTime != null) {
if ((new Date().getTime()) - face.getCreateAt().getTime() < maxPlayTime * 60 * 1000
&& (new Date().getTime()) - face.getCreateAt().getTime() > minPlayTime * 60 * 1000) {
projectMatch = true;
}
}
}
}
}
String countKey = FACE_RECOGNITION_COUNT_PFX + faceId;
String countStr = redisTemplate.opsForValue().get(countKey);
long recognitionCount = 0L;
@@ -914,10 +947,26 @@ public class FaceServiceImpl implements FaceService {
log.warn("识别次数解析失败,faceId={}, count={}", faceId, countStr);
}
}
int ruleMatched = 0;
if (recognitionCount > 1) {
ruleMatched++;
}
if (tourMatch) {
ruleMatched++;
}
if (projectMatch) {
ruleMatched++;
}
// 查询是否触发过低阈值检测
String lowThresholdKey = FACE_LOW_THRESHOLD_PFX + faceId;
Boolean hasLowThreshold = redisTemplate.hasKey(lowThresholdKey);
return true;
boolean hasLowThreshold = redisTemplate.hasKey(lowThresholdKey);
Integer mode = scenicConfig.getInteger("re_match_mode");
return switch (mode) {
case 1 -> tourMatch || recognitionCount > 1 || hasLowThreshold;
case 5 -> hasLowThreshold || (ruleMatched >= 2);
case 9 -> hasLowThreshold && ruleMatched >= 2;
default -> false;
};
}
@Override