You've already forked FrameTour-BE
feat(face): 引入人脸识别指标记录与搜索结果合并功能
- 新增 FaceMetricsRecorder 类用于记录人脸识别、自定义匹配及低阈值检测次数 - 新增 SearchResultMerger 类用于合并多个人脸搜索结果,支持并集与交集模式- 在 FaceServiceImpl 中引入 metricsRecorder 和 resultMerger 辅助类 - 替换原有的 Redis 操作代码为 FaceMetricsRecorder 的方法调用- 将搜索结果合并逻辑从 FaceServiceImpl 提取至 SearchResultMerger- 新增策略模式相关类:RematchContext、RematchModeStrategy 接口及四种实现 - 使用策略工厂 Rematch
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package com.ycwl.basic.service.pc.strategy;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 重匹配上下文
|
||||
* 包含判断是否需要重匹配的所有必要信息
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class RematchContext {
|
||||
/**
|
||||
* 人脸识别次数
|
||||
*/
|
||||
private long recognitionCount;
|
||||
|
||||
/**
|
||||
* 是否触发低阈值检测
|
||||
*/
|
||||
private boolean hasLowThreshold;
|
||||
|
||||
/**
|
||||
* 是否符合游览时间匹配
|
||||
*/
|
||||
private boolean tourMatch;
|
||||
|
||||
/**
|
||||
* 是否符合项目时间匹配
|
||||
*/
|
||||
private boolean projectMatch;
|
||||
|
||||
/**
|
||||
* 规则匹配数量
|
||||
*/
|
||||
private int ruleMatched;
|
||||
|
||||
/**
|
||||
* 人脸创建时间
|
||||
*/
|
||||
private Date faceCreateAt;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ycwl.basic.service.pc.strategy;
|
||||
|
||||
/**
|
||||
* 重匹配模式策略接口
|
||||
* 用于判断是否需要进行人脸重新匹配
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
public interface RematchModeStrategy {
|
||||
|
||||
/**
|
||||
* 判断是否应该重新匹配
|
||||
*
|
||||
* @param context 重匹配上下文
|
||||
* @return true-需要重匹配, false-不需要重匹配
|
||||
*/
|
||||
boolean shouldRematch(RematchContext context);
|
||||
|
||||
/**
|
||||
* 获取策略对应的模式值
|
||||
*
|
||||
* @return 模式值
|
||||
*/
|
||||
int getMode();
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.ycwl.basic.service.pc.strategy;
|
||||
|
||||
import com.ycwl.basic.service.pc.strategy.impl.DefaultRematchStrategy;
|
||||
import com.ycwl.basic.service.pc.strategy.impl.RematchMode1Strategy;
|
||||
import com.ycwl.basic.service.pc.strategy.impl.RematchMode5Strategy;
|
||||
import com.ycwl.basic.service.pc.strategy.impl.RematchMode9Strategy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 重匹配策略工厂
|
||||
* 根据模式值获取对应的策略实例
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RematchStrategyFactory {
|
||||
|
||||
@Autowired
|
||||
private List<RematchModeStrategy> strategies;
|
||||
|
||||
private final Map<Integer, RematchModeStrategy> strategyMap = new HashMap<>();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
for (RematchModeStrategy strategy : strategies) {
|
||||
strategyMap.put(strategy.getMode(), strategy);
|
||||
log.debug("注册重匹配策略: mode={}, class={}",
|
||||
strategy.getMode(), strategy.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据模式值获取对应的策略
|
||||
*
|
||||
* @param mode 模式值(0-默认, 1-模式1, 5-模式5, 9-模式9)
|
||||
* @return 对应的策略实例,如果没有找到则返回默认策略
|
||||
*/
|
||||
public RematchModeStrategy getStrategy(Integer mode) {
|
||||
if (mode == null) {
|
||||
return strategyMap.getOrDefault(0, new DefaultRematchStrategy());
|
||||
}
|
||||
|
||||
RematchModeStrategy strategy = strategyMap.get(mode);
|
||||
if (strategy == null) {
|
||||
log.warn("未找到重匹配模式{}对应的策略,使用默认策略", mode);
|
||||
return strategyMap.getOrDefault(0, new DefaultRematchStrategy());
|
||||
}
|
||||
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.ycwl.basic.service.pc.strategy.impl;
|
||||
|
||||
import com.ycwl.basic.service.pc.strategy.RematchContext;
|
||||
import com.ycwl.basic.service.pc.strategy.RematchModeStrategy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 默认重匹配策略(模式0或其他未定义模式)
|
||||
* 条件: 不触发重匹配
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class DefaultRematchStrategy implements RematchModeStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldRematch(RematchContext context) {
|
||||
log.debug("DefaultRematchStrategy判断: 默认不重匹配");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMode() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ycwl.basic.service.pc.strategy.impl;
|
||||
|
||||
import com.ycwl.basic.service.pc.strategy.RematchContext;
|
||||
import com.ycwl.basic.service.pc.strategy.RematchModeStrategy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 重匹配模式1策略
|
||||
* 条件: tourMatch || recognitionCount > 1 || hasLowThreshold
|
||||
* 满足任一条件即可重匹配
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RematchMode1Strategy implements RematchModeStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldRematch(RematchContext context) {
|
||||
boolean result = context.isTourMatch()
|
||||
|| context.getRecognitionCount() > 1
|
||||
|| context.isHasLowThreshold();
|
||||
|
||||
log.debug("RematchMode1Strategy判断: tourMatch={}, recognitionCount={}, hasLowThreshold={}, result={}",
|
||||
context.isTourMatch(), context.getRecognitionCount(),
|
||||
context.isHasLowThreshold(), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMode() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ycwl.basic.service.pc.strategy.impl;
|
||||
|
||||
import com.ycwl.basic.service.pc.strategy.RematchContext;
|
||||
import com.ycwl.basic.service.pc.strategy.RematchModeStrategy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 重匹配模式5策略
|
||||
* 条件: hasLowThreshold || (ruleMatched >= 2)
|
||||
* 触发低阈值或匹配2个及以上规则即可重匹配
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RematchMode5Strategy implements RematchModeStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldRematch(RematchContext context) {
|
||||
boolean result = context.isHasLowThreshold()
|
||||
|| context.getRuleMatched() >= 2;
|
||||
|
||||
log.debug("RematchMode5Strategy判断: hasLowThreshold={}, ruleMatched={}, result={}",
|
||||
context.isHasLowThreshold(), context.getRuleMatched(), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMode() {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ycwl.basic.service.pc.strategy.impl;
|
||||
|
||||
import com.ycwl.basic.service.pc.strategy.RematchContext;
|
||||
import com.ycwl.basic.service.pc.strategy.RematchModeStrategy;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 重匹配模式9策略
|
||||
* 条件: hasLowThreshold && (ruleMatched >= 2)
|
||||
* 必须同时触发低阈值且匹配2个及以上规则才可重匹配
|
||||
*
|
||||
* @author longbinbin
|
||||
* @date 2025-01-31
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RematchMode9Strategy implements RematchModeStrategy {
|
||||
|
||||
@Override
|
||||
public boolean shouldRematch(RematchContext context) {
|
||||
boolean result = context.isHasLowThreshold()
|
||||
&& context.getRuleMatched() >= 2;
|
||||
|
||||
log.debug("RematchMode9Strategy判断: hasLowThreshold={}, ruleMatched={}, result={}",
|
||||
context.isHasLowThreshold(), context.getRuleMatched(), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMode() {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user