package cn.iocoder.yudao.module.iot.service.rule.scene.matcher; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotSceneRuleConditionMatcher; import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.*; import java.util.function.Function; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * IoT 场景规则匹配器统一管理器:负责管理所有匹配器(触发器匹配器和条件匹配器),并提供统一的匹配入口 * * @author HUIHUI */ @Component @Slf4j public class IotSceneRuleMatcherManager { /** * 触发器匹配器映射表 */ private final Map triggerMatchers; /** * 条件匹配器映射表 */ private final Map conditionMatchers; public IotSceneRuleMatcherManager(List matchers) { if (CollUtil.isEmpty(matchers)) { log.warn("[IotSceneRuleMatcherManager][没有找到任何匹配器]"); this.triggerMatchers = new HashMap<>(); this.conditionMatchers = new HashMap<>(); return; } // 1.1 按优先级排序并过滤启用的匹配器 List allMatchers = matchers.stream() .filter(IotSceneRuleMatcher::isEnabled) .sorted(Comparator.comparing(IotSceneRuleMatcher::getPriority)) .toList(); // 1.2 分离触发器匹配器和条件匹配器 List triggerMatchers = allMatchers.stream() .filter(matcher -> matcher instanceof IotSceneRuleTriggerMatcher) .map(matcher -> (IotSceneRuleTriggerMatcher) matcher) .toList(); List conditionMatchers = allMatchers.stream() .filter(matcher -> matcher instanceof IotSceneRuleConditionMatcher) .map(matcher -> (IotSceneRuleConditionMatcher) matcher) .toList(); // 2.1 构建触发器匹配器映射表 this.triggerMatchers = convertMap(triggerMatchers, IotSceneRuleTriggerMatcher::getSupportedTriggerType, Function.identity(), (existing, replacement) -> { log.warn("[IotSceneRuleMatcherManager][触发器类型({})存在多个匹配器,使用优先级更高的: {}]", existing.getSupportedTriggerType(), existing.getPriority() <= replacement.getPriority() ? existing.getSupportedTriggerType() : replacement.getSupportedTriggerType()); return existing.getPriority() <= replacement.getPriority() ? existing : replacement; }, LinkedHashMap::new); // 2.2 构建条件匹配器映射表 this.conditionMatchers = convertMap(conditionMatchers, IotSceneRuleConditionMatcher::getSupportedConditionType, Function.identity(), (existing, replacement) -> { log.warn("[IotSceneRuleMatcherManager][条件类型({})存在多个匹配器,使用优先级更高的: {}]", existing.getSupportedConditionType(), existing.getPriority() <= replacement.getPriority() ? existing.getSupportedConditionType() : replacement.getSupportedConditionType()); return existing.getPriority() <= replacement.getPriority() ? existing : replacement; }, LinkedHashMap::new); // 3. 日志输出初始化信息 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载({})个匹配器,其中触发器匹配器({})个,条件匹配器({})个]", allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size()); this.triggerMatchers.forEach((type, matcher) -> log.info("[IotSceneRuleMatcherManager][触发器匹配器类型: ({}), 优先级: ({})] ", type, matcher.getPriority())); this.conditionMatchers.forEach((type, matcher) -> log.info("[IotSceneRuleMatcherManager][条件匹配器类型: ({}), 优先级: ({})]", type, matcher.getPriority())); } /** * 检查触发器是否匹配消息(主条件匹配) * * @param message 设备消息 * @param trigger 触发器配置 * @return 是否匹配 */ public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { if (message == null || trigger == null || trigger.getType() == null) { log.debug("[isMatched][message({}) trigger({}) 参数无效]", message, trigger); return false; } IotSceneRuleTriggerTypeEnum triggerType = IotSceneRuleTriggerTypeEnum.typeOf(trigger.getType()); if (triggerType == null) { log.warn("[isMatched][triggerType({}) 未知的触发器类型]", trigger.getType()); return false; } IotSceneRuleTriggerMatcher matcher = triggerMatchers.get(triggerType); if (matcher == null) { log.warn("[isMatched][triggerType({}) 没有对应的匹配器]", triggerType); return false; } try { return matcher.matches(message, trigger); } catch (Exception e) { log.error("[isMatched][触发器匹配异常] message: {}, trigger: {}", message, trigger, e); return false; } } /** * 检查子条件是否匹配消息 * * @param message 设备消息 * @param condition 触发条件 * @return 是否匹配 */ public boolean isConditionMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) { if (message == null || condition == null || condition.getType() == null) { log.debug("[isConditionMatched][message({}) condition({}) 参数无效]", message, condition); return false; } // 1. 根据条件类型查找对应的匹配器 IotSceneRuleConditionTypeEnum conditionType = IotSceneRuleConditionTypeEnum.typeOf(condition.getType()); if (conditionType == null) { log.warn("[isConditionMatched][conditionType({}) 未知的条件类型]", condition.getType()); return false; } IotSceneRuleConditionMatcher matcher = conditionMatchers.get(conditionType); if (matcher == null) { log.warn("[isConditionMatched][conditionType({}) 没有对应的匹配器]", conditionType); return false; } // 2. 执行匹配逻辑 try { return matcher.matches(message, condition); } catch (Exception e) { log.error("[isConditionMatched][message({}) condition({}) 条件匹配异常]", message, condition, e); return false; } } }