From 6791c628589b66b7419bf46a3e476d29d0d77470 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 16 Aug 2025 20:37:22 +0800 Subject: [PATCH] =?UTF-8?q?review=EF=BC=9A=E3=80=90iot=20=E7=89=A9?= =?UTF-8?q?=E8=81=94=E7=BD=91=E3=80=91=E5=9C=BA=E6=99=AF=E8=81=94=E5=8A=A8?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rule/IotSceneRuleTriggerTypeEnum.java | 2 +- .../rule/data/action/IotRedisRuleAction.java | 1 - .../rule/scene/IotSceneRuleServiceImpl.java | 13 ++--- .../matcher/AbstractIotSceneRuleMatcher.java | 10 ++-- .../matcher/CurrentTimeConditionMatcher.java | 18 +++---- .../DevicePropertyConditionMatcher.java | 3 +- .../DevicePropertyPostTriggerMatcher.java | 3 +- .../matcher/DeviceStateConditionMatcher.java | 2 - .../DeviceStateUpdateTriggerMatcher.java | 3 +- .../scene/matcher/IotSceneRuleMatcher.java | 10 ++++ .../matcher/IotSceneRuleMatcherManager.java | 53 +++++++++---------- .../scene/matcher/TimerTriggerMatcher.java | 1 + .../IotSceneRuleTriggerMatcherTest.java | 8 +-- 13 files changed, 65 insertions(+), 62 deletions(-) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleTriggerTypeEnum.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleTriggerTypeEnum.java index 16b5e79446..216584ec20 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleTriggerTypeEnum.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleTriggerTypeEnum.java @@ -60,7 +60,7 @@ public enum IotSceneRuleTriggerTypeEnum implements ArrayValuable { return ARRAYS; } - + // TODO @puhui999:可以参考下别的枚举哈,方法名,和实现都可以更简洁;of(String type) { firstMatch /** * 根据类型值查找触发器类型枚举 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRedisRuleAction.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRedisRuleAction.java index 51abffee3b..904240da8b 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRedisRuleAction.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/data/action/IotRedisRuleAction.java @@ -45,7 +45,6 @@ public class IotRedisRuleAction extends // 2. 根据数据结构类型执行不同的操作 String messageJson = JsonUtils.toJsonString(message); IotRedisDataStructureEnum dataStructure = getDataStructureByType(config.getDataStructure()); - switch (dataStructure) { case STREAM: executeStream(redisTemplate, config, messageJson); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java index fc3e96798f..ee56310fba 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java @@ -58,12 +58,15 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @Resource private IotSceneRuleMapper sceneRuleMapper; + // TODO @puhui999:定时任务,基于它调度; @Resource(name = "iotSchedulerManager") private IotSchedulerManager schedulerManager; @Resource private IotProductService productService; @Resource private IotDeviceService deviceService; + + // TODO @puhui999:sceneRuleMatcherManager 变量名 @Resource private IotSceneRuleMatcherManager matcherManager; @Resource @@ -135,7 +138,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { return sceneRuleMapper.selectListByStatus(status); } - // TODO 芋艿,缓存待实现 + // TODO 芋艿,缓存待实现 @puhui999 @Override @TenantIgnore // 忽略租户隔离:因为 IotSceneRuleMessageHandler 调用时,一般未传递租户,所以需要忽略 public List getSceneRuleListByProductIdAndDeviceIdFromCache(Long productId, Long deviceId) { @@ -177,7 +180,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { @Override public void executeSceneRuleByDevice(IotDeviceMessage message) { - // TODO @芋艿:这里的 tenantId,通过设备获取; + // TODO @芋艿:这里的 tenantId,通过设备获取;@puhui999: TenantUtils.execute(message.getTenantId(), () -> { // 1. 获得设备匹配的规则场景 List sceneRules = getMatchedSceneRuleListByMessage(message); @@ -223,7 +226,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { */ private List getMatchedSceneRuleListByMessage(IotDeviceMessage message) { // 1. 匹配设备 - // TODO @芋艿:可能需要 getSelf(); 缓存 + // TODO @芋艿:可能需要 getSelf(); 缓存 @puhui999; // 1.1 通过 deviceId 获取设备信息 IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId()); if (device == null) { @@ -342,7 +345,6 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { private boolean isTriggerConditionMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition, IotSceneRuleDO sceneRule, IotSceneRuleDO.Trigger trigger) { try { - // 使用重构后的条件匹配管理器进行匹配 return matcherManager.isConditionMatched(message, condition); } catch (Exception e) { log.error("[isTriggerConditionMatched][规则场景编号({}) 的触发器({}) 条件匹配异常]", @@ -351,8 +353,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService { } } - // TODO @芋艿:【可优化】可以考虑增加下单测,边界太多了。 - + // TODO @puhui999:下面还需要么? /** * 判断触发器的条件参数是否匹配 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java index a77854ef96..5d48bba293 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java @@ -24,6 +24,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @Slf4j public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher { + // TODO @puhui999:这个是不是也是【通用】条件哈? + /** * 评估条件是否匹配 * @@ -32,6 +34,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher * @param paramValue 参数值(来自条件配置) * @return 是否匹配 */ + @SuppressWarnings("DataFlowIssue") protected boolean evaluateCondition(Object sourceValue, String operator, String paramValue) { try { // 1. 校验操作符是否合法 @@ -48,6 +51,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher // 处理参数值 if (StrUtil.isNotBlank(paramValue)) { // 处理多值情况(如 IN、BETWEEN 操作符) + // TODO @puhui999:使用这个,会不会有问题?例如说:string 恰好有 , 分隔? if (paramValue.contains(",")) { List paramValues = StrUtil.split(paramValue, ','); springExpressionVariables.put(IotSceneRuleConditionOperatorEnum.SPRING_EXPRESSION_VALUE_LIST, @@ -68,7 +72,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher } } - // ========== 触发器相关工具方法 ========== + // ========== 【触发器】相关工具方法 ========== /** * 检查基础触发器参数是否有效 @@ -111,7 +115,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", getMatcherName(), message.getRequestId(), trigger.getType(), reason); } - // ========== 条件相关工具方法 ========== + // ========== 【条件】相关工具方法 ========== /** * 检查基础条件参数是否有效 @@ -154,7 +158,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", getMatcherName(), message.getRequestId(), condition.getType(), reason); } - // ========== 通用工具方法 ========== + // ========== 【通用】工具方法 ========== /** * 检查标识符是否匹配 diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/CurrentTimeConditionMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/CurrentTimeConditionMatcher.java index ae6c8f671d..94e7401b63 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/CurrentTimeConditionMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/CurrentTimeConditionMatcher.java @@ -56,15 +56,11 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { return false; } - // 3. 获取当前时间 + // 3. 根据操作符类型进行不同的时间匹配 LocalDateTime now = LocalDateTime.now(); - - // 4. 根据操作符类型进行不同的时间匹配 String operator = condition.getOperator(); String param = condition.getParam(); - - boolean matched = false; - + boolean matched; try { if (operator.startsWith("date_time_")) { // 日期时间匹配(时间戳) @@ -82,13 +78,11 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { } else { logConditionMatchFailure(message, condition, "时间条件不匹配"); } - } catch (Exception e) { log.error("[CurrentTimeConditionMatcher][时间条件匹配异常] operator: {}, param: {}", operator, param, e); logConditionMatchFailure(message, condition, "时间条件匹配异常: " + e.getMessage()); matched = false; } - return matched; } @@ -107,21 +101,20 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { try { String actualOperator = operator.substring("time_".length()); + // TODO @puhui999:if return 简化; if ("between".equals(actualOperator)) { // 时间区间匹配 String[] timeRange = param.split(","); if (timeRange.length != 2) { return false; } - LocalTime startTime = parseTime(timeRange[0].trim()); LocalTime endTime = parseTime(timeRange[1].trim()); - return !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime); } else { // 单个时间比较 LocalTime targetTime = parseTime(param); - + // TODO @puhui999:枚举类; switch (actualOperator) { case ">": return currentTime.isAfter(targetTime); @@ -138,6 +131,7 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { } } } catch (Exception e) { + // TODO @puhui999:1)日志格式 [][];2)方法名不对哈; log.error("[CurrentTimeConditionMatcher][时间解析异常] param: {}", param, e); return false; } @@ -147,10 +141,10 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { * 解析时间字符串 */ private LocalTime parseTime(String timeStr) { + // TODO @puhui999:可以用 hutool Assert 类简化 if (StrUtil.isBlank(timeStr)) { throw new IllegalArgumentException("时间字符串不能为空"); } - // 尝试不同的时间格式 try { if (timeStr.length() == 5) { // HH:mm diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyConditionMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyConditionMatcher.java index ed8e12d6c6..37381500b9 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyConditionMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyConditionMatcher.java @@ -26,6 +26,7 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher return IotSceneRuleConditionTypeEnum.DEVICE_PROPERTY; } + // TODO @puhui999:参数校验的,要不要 1.1 1.2 1.3 1.4 ?这样最终看到 2. 3. 就是核心逻辑列; @Override public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) { // 1. 基础参数校验 @@ -56,13 +57,11 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher // 5. 使用条件评估器进行匹配 boolean matched = evaluateCondition(propertyValue, condition.getOperator(), condition.getParam()); - if (matched) { logConditionMatchSuccess(message, condition); } else { logConditionMatchFailure(message, condition, "设备属性条件不匹配"); } - return matched; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyPostTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyPostTriggerMatcher.java index 0953453ed2..ed228fc72d 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyPostTriggerMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DevicePropertyPostTriggerMatcher.java @@ -20,6 +20,7 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche /** * 设备属性上报消息方法 */ + // TODO @puhui999:是不是不用枚举哈?直接使用 IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod() private static final String DEVICE_PROPERTY_POST_METHOD = IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod(); @Override @@ -68,13 +69,11 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche // 6. 使用条件评估器进行匹配 boolean matched = evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue()); - if (matched) { logTriggerMatchSuccess(message, trigger); } else { logTriggerMatchFailure(message, trigger, "属性值条件不匹配"); } - return matched; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateConditionMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateConditionMatcher.java index f946e499c8..69d3a7dcb7 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateConditionMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateConditionMatcher.java @@ -49,13 +49,11 @@ public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher { // 4. 使用条件评估器进行匹配 boolean matched = evaluateCondition(stateValue, condition.getOperator(), condition.getParam()); - if (matched) { logConditionMatchSuccess(message, condition); } else { logConditionMatchFailure(message, condition, "设备状态条件不匹配"); } - return matched; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateUpdateTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateUpdateTriggerMatcher.java index a505e0d393..3a2a0e712f 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateUpdateTriggerMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/DeviceStateUpdateTriggerMatcher.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Component; @Component public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher { + // TODO @puhui999:是不是不用枚举哈; /** * 设备状态更新消息方法 */ @@ -60,13 +61,11 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher // 5. 使用条件评估器进行匹配 boolean matched = evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue()); - if (matched) { logTriggerMatchSuccess(message, trigger); } else { logTriggerMatchFailure(message, trigger, "状态值条件不匹配"); } - return matched; } diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java index cb12384647..b9b439c786 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java @@ -18,18 +18,23 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; */ public interface IotSceneRuleMatcher { + // TODO @puhui999:MatcherTypeEnum; + // TODO @puhui999:可以考虑根据类型,新建 trigger、condition 包,然后把对应的实现类放进去哈; /** * 匹配器类型枚举 */ enum MatcherType { + /** * 触发器匹配器 - 用于匹配主触发条件 */ TRIGGER, + /** * 条件匹配器 - 用于匹配子条件 */ CONDITION + } /** @@ -39,6 +44,10 @@ public interface IotSceneRuleMatcher { */ MatcherType getMatcherType(); + // TODO @puhui999:【重要】有个思路,IotSceneRuleMatcher 拆分成 2 种 mather 接口;然后 AbstractIotSceneRuleMatcher 是个 Helper 工具类; + + // TODO @puhui999:是不是和 AbstractSceneRuleMatcher 一样,分下块; + /** * 获取支持的触发器类型(仅触发器匹配器需要实现) * @@ -90,6 +99,7 @@ public interface IotSceneRuleMatcher { return 100; } + // TODO @puhui999:如果目前没自定义,体感可以删除哈; /** * 获取匹配器名称,用于日志和调试 * diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java index 7c45a6ca6b..e95e553cab 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java @@ -30,14 +30,14 @@ public class IotSceneRuleMatcherManager { * Key: 触发器类型枚举 * Value: 对应的匹配器实例 */ - private final Map triggerMatcherMap; + private final Map triggerMatchers; /** * 条件匹配器映射表 * Key: 条件类型枚举 * Value: 对应的匹配器实例 */ - private final Map conditionMatcherMap; + private final Map conditionMatchers; /** * 所有匹配器列表(按优先级排序) @@ -47,8 +47,8 @@ public class IotSceneRuleMatcherManager { public IotSceneRuleMatcherManager(List matchers) { if (CollUtil.isEmpty(matchers)) { log.warn("[IotSceneRuleMatcherManager][没有找到任何匹配器]"); - this.triggerMatcherMap = new HashMap<>(); - this.conditionMatcherMap = new HashMap<>(); + this.triggerMatchers = new HashMap<>(); + this.conditionMatchers = new HashMap<>(); this.allMatchers = new ArrayList<>(); return; } @@ -63,13 +63,13 @@ public class IotSceneRuleMatcherManager { List triggerMatchers = this.allMatchers.stream() .filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherType.TRIGGER) .toList(); - List conditionMatchers = this.allMatchers.stream() .filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherType.CONDITION) .toList(); // 构建触发器匹配器映射表 - this.triggerMatcherMap = triggerMatchers.stream() + // TODO @puhui999:convertMap() + this.triggerMatchers = triggerMatchers.stream() .collect(Collectors.toMap( IotSceneRuleMatcher::getSupportedTriggerType, Function.identity(), @@ -81,9 +81,8 @@ public class IotSceneRuleMatcherManager { }, LinkedHashMap::new )); - // 构建条件匹配器映射表 - this.conditionMatcherMap = conditionMatchers.stream() + this.conditionMatchers = conditionMatchers.stream() .collect(Collectors.toMap( IotSceneRuleMatcher::getSupportedConditionType, Function.identity(), @@ -96,16 +95,13 @@ public class IotSceneRuleMatcherManager { LinkedHashMap::new )); + // 日志输出初始化信息 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载 {} 个匹配器,其中触发器匹配器 {} 个,条件匹配器 {} 个]", - this.allMatchers.size(), this.triggerMatcherMap.size(), this.conditionMatcherMap.size()); - - // 记录触发器匹配器详情 - this.triggerMatcherMap.forEach((type, matcher) -> + this.allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size()); + this.triggerMatchers.forEach((type, matcher) -> log.info("[IotSceneRuleMatcherManager][触发器匹配器] 类型: {}, 匹配器: {}, 优先级: {}", type, matcher.getMatcherName(), matcher.getPriority())); - - // 记录条件匹配器详情 - this.conditionMatcherMap.forEach((type, matcher) -> + this.conditionMatchers.forEach((type, matcher) -> log.info("[IotSceneRuleMatcherManager][条件匹配器] 类型: {}, 匹配器: {}, 优先级: {}", type, matcher.getMatcherName(), matcher.getPriority())); } @@ -118,19 +114,17 @@ public class IotSceneRuleMatcherManager { * @return 是否匹配 */ public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { + // TODO @puhui999:日志优化下;claude 打出来的日志风格,和项目有点不一样哈; if (message == null || trigger == null || trigger.getType() == null) { log.debug("[isMatched][参数无效] message: {}, trigger: {}", message, trigger); return false; } - - // 根据触发器类型查找对应的匹配器 IotSceneRuleTriggerTypeEnum triggerType = findTriggerTypeEnum(trigger.getType()); if (triggerType == null) { log.warn("[isMatched][未知的触发器类型: {}]", trigger.getType()); return false; } - - IotSceneRuleMatcher matcher = triggerMatcherMap.get(triggerType); + IotSceneRuleMatcher matcher = triggerMatchers.get(triggerType); if (matcher == null) { log.warn("[isMatched][触发器类型({})没有对应的匹配器]", triggerType); return false; @@ -165,7 +159,7 @@ public class IotSceneRuleMatcherManager { return false; } - IotSceneRuleMatcher matcher = conditionMatcherMap.get(conditionType); + IotSceneRuleMatcher matcher = conditionMatchers.get(conditionType); if (matcher == null) { log.warn("[isConditionMatched][条件类型({})没有对应的匹配器]", conditionType); return false; @@ -199,7 +193,7 @@ public class IotSceneRuleMatcherManager { * @return 支持的触发器类型列表 */ public Set getSupportedTriggerTypes() { - return new HashSet<>(triggerMatcherMap.keySet()); + return new HashSet<>(triggerMatchers.keySet()); } /** @@ -208,9 +202,11 @@ public class IotSceneRuleMatcherManager { * @return 支持的条件类型列表 */ public Set getSupportedConditionTypes() { - return new HashSet<>(conditionMatcherMap.keySet()); + return new HashSet<>(conditionMatchers.keySet()); } + // TODO @puhui999:用不到的方法,可以去掉先哈; + /** * 获取指定触发器类型的匹配器 * @@ -218,7 +214,7 @@ public class IotSceneRuleMatcherManager { * @return 匹配器实例,如果不存在则返回 null */ public IotSceneRuleMatcher getTriggerMatcher(IotSceneRuleTriggerTypeEnum triggerType) { - return triggerMatcherMap.get(triggerType); + return triggerMatchers.get(triggerType); } /** @@ -228,9 +224,10 @@ public class IotSceneRuleMatcherManager { * @return 匹配器实例,如果不存在则返回 null */ public IotSceneRuleMatcher getConditionMatcher(IotSceneRuleConditionTypeEnum conditionType) { - return conditionMatcherMap.get(conditionType); + return conditionMatchers.get(conditionType); } + // TODO @puhui999:是不是不用这个哈;直接 @Getter,单测直接处理; /** * 获取所有匹配器的统计信息 * @@ -239,14 +236,14 @@ public class IotSceneRuleMatcherManager { public Map getMatcherStatistics() { Map statistics = new HashMap<>(); statistics.put("totalMatchers", allMatchers.size()); - statistics.put("triggerMatchers", triggerMatcherMap.size()); - statistics.put("conditionMatchers", conditionMatcherMap.size()); + statistics.put("triggerMatchers", triggerMatchers.size()); + statistics.put("conditionMatchers", conditionMatchers.size()); statistics.put("supportedTriggerTypes", getSupportedTriggerTypes()); statistics.put("supportedConditionTypes", getSupportedConditionTypes()); // 触发器匹配器详情 Map triggerMatcherDetails = new HashMap<>(); - triggerMatcherMap.forEach((type, matcher) -> { + triggerMatchers.forEach((type, matcher) -> { Map detail = new HashMap<>(); detail.put("matcherName", matcher.getMatcherName()); detail.put("priority", matcher.getPriority()); @@ -257,7 +254,7 @@ public class IotSceneRuleMatcherManager { // 条件匹配器详情 Map conditionMatcherDetails = new HashMap<>(); - conditionMatcherMap.forEach((type, matcher) -> { + conditionMatchers.forEach((type, matcher) -> { Map detail = new HashMap<>(); detail.put("matcherName", matcher.getMatcherName()); detail.put("priority", matcher.getPriority()); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/TimerTriggerMatcher.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/TimerTriggerMatcher.java index a5d536cb8f..edc18771a3 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/TimerTriggerMatcher.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/TimerTriggerMatcher.java @@ -61,6 +61,7 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher { * @return 是否有效 */ private boolean isValidCronExpression(String cronExpression) { + // TODO @puhui999:CronExpression.isValidExpression(cronExpression); try { // 简单的 CRON 表达式格式验证 // 标准 CRON 表达式应该有 6 或 7 个字段(秒 分 时 日 月 周 [年]) diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleTriggerMatcherTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleTriggerMatcherTest.java index 7483182566..ff5e28397a 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleTriggerMatcherTest.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleTriggerMatcherTest.java @@ -20,6 +20,8 @@ import static org.junit.jupiter.api.Assertions.*; */ public class IotSceneRuleTriggerMatcherTest extends BaseMockitoUnitTest { + // TODO @puhui999:public 都加下哈; + private IotSceneRuleMatcherManager matcherManager; @BeforeEach @@ -42,13 +44,13 @@ public class IotSceneRuleTriggerMatcherTest extends BaseMockitoUnitTest { // 1. 准备测试数据 IotDeviceMessage message = IotDeviceMessage.builder() .requestId("test-001") - .method("thing.state.update") - .data(1) // 在线状态 + .method("thing.state.update") // TODO @puhui999:这里的枚举; + .data(1) // 在线状态 TODO @puhui999:这里的枚举; .build(); IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger(); trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE.getType()); - trigger.setOperator("="); + trigger.setOperator("="); // TODO @puhui999:这里的枚举;下面也是类似; trigger.setValue("1"); // 2. 执行测试