You've already forked FrameTour-BE
feat(face): 增加自定义人脸匹配次数限制与记录功能
- 新增常量 FACE_CUSTOM_MATCH_COUNT_PFX 用于记录自定义匹配次数 - 在人脸识别逻辑中增加对自定义匹配次数的读取与限制判断 - 实现 recordCustomMatchCount 方法用于记录自定义匹配调用次数 - 优化原有识别次数获取逻辑,避免重复代码 - 增加 Redis 过期时间设置,确保计数数据自动清理
This commit is contained in:
@@ -5,5 +5,6 @@ public class FaceConstant {
|
|||||||
public static final String USER_FACE_DB_NAME="userFace";
|
public static final String USER_FACE_DB_NAME="userFace";
|
||||||
public static final String FACE_USER_URL_PFX="face:user:url:";
|
public static final String FACE_USER_URL_PFX="face:user:url:";
|
||||||
public static final String FACE_RECOGNITION_COUNT_PFX="face:recognition:count:";
|
public static final String FACE_RECOGNITION_COUNT_PFX="face:recognition:count:";
|
||||||
|
public static final String FACE_CUSTOM_MATCH_COUNT_PFX="face:custom:match:count:";
|
||||||
public static final String FACE_LOW_THRESHOLD_PFX="face:low:threshold:";
|
public static final String FACE_LOW_THRESHOLD_PFX="face:low:threshold:";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static com.ycwl.basic.constant.FaceConstant.FACE_CUSTOM_MATCH_COUNT_PFX;
|
||||||
import static com.ycwl.basic.constant.FaceConstant.FACE_LOW_THRESHOLD_PFX;
|
import static com.ycwl.basic.constant.FaceConstant.FACE_LOW_THRESHOLD_PFX;
|
||||||
import static com.ycwl.basic.constant.FaceConstant.FACE_RECOGNITION_COUNT_PFX;
|
import static com.ycwl.basic.constant.FaceConstant.FACE_RECOGNITION_COUNT_PFX;
|
||||||
import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
|
import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
|
||||||
@@ -987,6 +988,36 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(face.getScenicId());
|
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(face.getScenicId());
|
||||||
|
|
||||||
|
String recognitionKey = FACE_RECOGNITION_COUNT_PFX + faceId;
|
||||||
|
String recognitionCountStr = redisTemplate.opsForValue().get(recognitionKey);
|
||||||
|
long recognitionCount = 0L;
|
||||||
|
if (recognitionCountStr != null) {
|
||||||
|
try {
|
||||||
|
recognitionCount = Long.parseLong(recognitionCountStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("识别次数解析失败,faceId={}, count={}", faceId, recognitionCountStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String customMatchKey = FACE_CUSTOM_MATCH_COUNT_PFX + faceId;
|
||||||
|
String customMatchCountStr = redisTemplate.opsForValue().get(customMatchKey);
|
||||||
|
long customMatchCount = 0L;
|
||||||
|
if (customMatchCountStr != null) {
|
||||||
|
try {
|
||||||
|
customMatchCount = Long.parseLong(customMatchCountStr);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("自定义匹配次数解析失败,faceId={}, count={}", faceId, customMatchCountStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer faceSelectMaxCount = scenicConfig.getInteger("face_select_max_count");
|
||||||
|
if (faceSelectMaxCount != null && faceSelectMaxCount > 0 && customMatchCount > faceSelectMaxCount) {
|
||||||
|
log.debug("自定义人脸匹配次数超过限制:faceId={}, customMatchCount={}, limit={}",
|
||||||
|
faceId, customMatchCount, faceSelectMaxCount);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Integer maxTourTime = scenicConfig.getInteger("tour_time");
|
Integer maxTourTime = scenicConfig.getInteger("tour_time");
|
||||||
Integer minTourTime = scenicConfig.getInteger("tour_min_time");
|
Integer minTourTime = scenicConfig.getInteger("tour_min_time");
|
||||||
boolean tourMatch = false;
|
boolean tourMatch = false;
|
||||||
@@ -1015,16 +1046,6 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String countKey = FACE_RECOGNITION_COUNT_PFX + faceId;
|
|
||||||
String countStr = redisTemplate.opsForValue().get(countKey);
|
|
||||||
long recognitionCount = 0L;
|
|
||||||
if (countStr != null) {
|
|
||||||
try {
|
|
||||||
recognitionCount = Long.parseLong(countStr);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
log.warn("识别次数解析失败,faceId={}, count={}", faceId, countStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int ruleMatched = 0;
|
int ruleMatched = 0;
|
||||||
if (recognitionCount > 1) {
|
if (recognitionCount > 1) {
|
||||||
ruleMatched++;
|
ruleMatched++;
|
||||||
@@ -1086,6 +1107,9 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.debug("开始自定义人脸匹配:faceId={}, faceSampleIds={}", faceId, faceSampleIds);
|
log.debug("开始自定义人脸匹配:faceId={}, faceSampleIds={}", faceId, faceSampleIds);
|
||||||
|
|
||||||
|
// 记录自定义匹配调用次数,便于监控调用频率
|
||||||
|
recordCustomMatchCount(faceId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 获取基础数据
|
// 1. 获取基础数据
|
||||||
@@ -1234,6 +1258,28 @@ public class FaceServiceImpl implements FaceService {
|
|||||||
return mergedResult;
|
return mergedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录自定义人脸匹配次数到Redis
|
||||||
|
*
|
||||||
|
* @param faceId 人脸ID
|
||||||
|
*/
|
||||||
|
private void recordCustomMatchCount(Long faceId) {
|
||||||
|
if (faceId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String redisKey = FACE_CUSTOM_MATCH_COUNT_PFX + faceId;
|
||||||
|
|
||||||
|
Long count = redisTemplate.opsForValue().increment(redisKey);
|
||||||
|
redisTemplate.expire(redisKey, 2, TimeUnit.DAYS);
|
||||||
|
|
||||||
|
log.debug("自定义人脸匹配计数更新:faceId={}, count={}", faceId, count);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("记录自定义人脸匹配次数失败:faceId={}", faceId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录人脸识别次数到Redis
|
* 记录人脸识别次数到Redis
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user