Commit 6791c628589b66b7419bf46a3e476d29d0d77470

Authored by YunaiV
1 parent f88d30f1

review:【iot 物联网】场景联动相关实现

Showing 13 changed files with 65 additions and 62 deletions
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<Integer> {
60 60 return ARRAYS;
61 61 }
62 62  
63   -
  63 + // TODO @puhui999:可以参考下别的枚举哈,方法名,和实现都可以更简洁;of(String type) { firstMatch
64 64 /**
65 65 * 根据类型值查找触发器类型枚举
66 66 *
... ...
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
45 45 // 2. 根据数据结构类型执行不同的操作
46 46 String messageJson = JsonUtils.toJsonString(message);
47 47 IotRedisDataStructureEnum dataStructure = getDataStructureByType(config.getDataStructure());
48   -
49 48 switch (dataStructure) {
50 49 case STREAM:
51 50 executeStream(redisTemplate, config, messageJson);
... ...
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 {
58 58 @Resource
59 59 private IotSceneRuleMapper sceneRuleMapper;
60 60  
  61 + // TODO @puhui999:定时任务,基于它调度;
61 62 @Resource(name = "iotSchedulerManager")
62 63 private IotSchedulerManager schedulerManager;
63 64 @Resource
64 65 private IotProductService productService;
65 66 @Resource
66 67 private IotDeviceService deviceService;
  68 +
  69 + // TODO @puhui999:sceneRuleMatcherManager 变量名
67 70 @Resource
68 71 private IotSceneRuleMatcherManager matcherManager;
69 72 @Resource
... ... @@ -135,7 +138,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
135 138 return sceneRuleMapper.selectListByStatus(status);
136 139 }
137 140  
138   - // TODO 芋艿,缓存待实现
  141 + // TODO 芋艿,缓存待实现 @puhui999
139 142 @Override
140 143 @TenantIgnore // 忽略租户隔离:因为 IotSceneRuleMessageHandler 调用时,一般未传递租户,所以需要忽略
141 144 public List<IotSceneRuleDO> getSceneRuleListByProductIdAndDeviceIdFromCache(Long productId, Long deviceId) {
... ... @@ -177,7 +180,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
177 180  
178 181 @Override
179 182 public void executeSceneRuleByDevice(IotDeviceMessage message) {
180   - // TODO @芋艿:这里的 tenantId,通过设备获取;
  183 + // TODO @芋艿:这里的 tenantId,通过设备获取;@puhui999:
181 184 TenantUtils.execute(message.getTenantId(), () -> {
182 185 // 1. 获得设备匹配的规则场景
183 186 List<IotSceneRuleDO> sceneRules = getMatchedSceneRuleListByMessage(message);
... ... @@ -223,7 +226,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
223 226 */
224 227 private List<IotSceneRuleDO> getMatchedSceneRuleListByMessage(IotDeviceMessage message) {
225 228 // 1. 匹配设备
226   - // TODO @芋艿:可能需要 getSelf(); 缓存
  229 + // TODO @芋艿:可能需要 getSelf(); 缓存 @puhui999;
227 230 // 1.1 通过 deviceId 获取设备信息
228 231 IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId());
229 232 if (device == null) {
... ... @@ -342,7 +345,6 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
342 345 private boolean isTriggerConditionMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition,
343 346 IotSceneRuleDO sceneRule, IotSceneRuleDO.Trigger trigger) {
344 347 try {
345   - // 使用重构后的条件匹配管理器进行匹配
346 348 return matcherManager.isConditionMatched(message, condition);
347 349 } catch (Exception e) {
348 350 log.error("[isTriggerConditionMatched][规则场景编号({}) 的触发器({}) 条件匹配异常]",
... ... @@ -351,8 +353,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
351 353 }
352 354 }
353 355  
354   - // TODO @芋艿:【可优化】可以考虑增加下单测,边界太多了。
355   -
  356 + // TODO @puhui999:下面还需要么?
356 357 /**
357 358 * 判断触发器的条件参数是否匹配
358 359 *
... ...
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.
24 24 @Slf4j
25 25 public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher {
26 26  
  27 + // TODO @puhui999:这个是不是也是【通用】条件哈?
  28 +
27 29 /**
28 30 * 评估条件是否匹配
29 31 *
... ... @@ -32,6 +34,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
32 34 * @param paramValue 参数值(来自条件配置)
33 35 * @return 是否匹配
34 36 */
  37 + @SuppressWarnings("DataFlowIssue")
35 38 protected boolean evaluateCondition(Object sourceValue, String operator, String paramValue) {
36 39 try {
37 40 // 1. 校验操作符是否合法
... ... @@ -48,6 +51,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
48 51 // 处理参数值
49 52 if (StrUtil.isNotBlank(paramValue)) {
50 53 // 处理多值情况(如 IN、BETWEEN 操作符)
  54 + // TODO @puhui999:使用这个,会不会有问题?例如说:string 恰好有 , 分隔?
51 55 if (paramValue.contains(",")) {
52 56 List<String> paramValues = StrUtil.split(paramValue, ',');
53 57 springExpressionVariables.put(IotSceneRuleConditionOperatorEnum.SPRING_EXPRESSION_VALUE_LIST,
... ... @@ -68,7 +72,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
68 72 }
69 73 }
70 74  
71   - // ========== 触发器相关工具方法 ==========
  75 + // ========== 【触发器】相关工具方法 ==========
72 76  
73 77 /**
74 78 * 检查基础触发器参数是否有效
... ... @@ -111,7 +115,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
111 115 log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", getMatcherName(), message.getRequestId(), trigger.getType(), reason);
112 116 }
113 117  
114   - // ========== 条件相关工具方法 ==========
  118 + // ========== 【条件】相关工具方法 ==========
115 119  
116 120 /**
117 121 * 检查基础条件参数是否有效
... ... @@ -154,7 +158,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
154 158 log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", getMatcherName(), message.getRequestId(), condition.getType(), reason);
155 159 }
156 160  
157   - // ========== 通用工具方法 ==========
  161 + // ========== 【通用】工具方法 ==========
158 162  
159 163 /**
160 164 * 检查标识符是否匹配
... ...
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 {
56 56 return false;
57 57 }
58 58  
59   - // 3. 获取当前时间
  59 + // 3. 根据操作符类型进行不同的时间匹配
60 60 LocalDateTime now = LocalDateTime.now();
61   -
62   - // 4. 根据操作符类型进行不同的时间匹配
63 61 String operator = condition.getOperator();
64 62 String param = condition.getParam();
65   -
66   - boolean matched = false;
67   -
  63 + boolean matched;
68 64 try {
69 65 if (operator.startsWith("date_time_")) {
70 66 // 日期时间匹配(时间戳)
... ... @@ -82,13 +78,11 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
82 78 } else {
83 79 logConditionMatchFailure(message, condition, "时间条件不匹配");
84 80 }
85   -
86 81 } catch (Exception e) {
87 82 log.error("[CurrentTimeConditionMatcher][时间条件匹配异常] operator: {}, param: {}", operator, param, e);
88 83 logConditionMatchFailure(message, condition, "时间条件匹配异常: " + e.getMessage());
89 84 matched = false;
90 85 }
91   -
92 86 return matched;
93 87 }
94 88  
... ... @@ -107,21 +101,20 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
107 101 try {
108 102 String actualOperator = operator.substring("time_".length());
109 103  
  104 + // TODO @puhui999:if return 简化;
110 105 if ("between".equals(actualOperator)) {
111 106 // 时间区间匹配
112 107 String[] timeRange = param.split(",");
113 108 if (timeRange.length != 2) {
114 109 return false;
115 110 }
116   -
117 111 LocalTime startTime = parseTime(timeRange[0].trim());
118 112 LocalTime endTime = parseTime(timeRange[1].trim());
119   -
120 113 return !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime);
121 114 } else {
122 115 // 单个时间比较
123 116 LocalTime targetTime = parseTime(param);
124   -
  117 + // TODO @puhui999:枚举类;
125 118 switch (actualOperator) {
126 119 case ">":
127 120 return currentTime.isAfter(targetTime);
... ... @@ -138,6 +131,7 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
138 131 }
139 132 }
140 133 } catch (Exception e) {
  134 + // TODO @puhui999:1)日志格式 [][];2)方法名不对哈;
141 135 log.error("[CurrentTimeConditionMatcher][时间解析异常] param: {}", param, e);
142 136 return false;
143 137 }
... ... @@ -147,10 +141,10 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
147 141 * 解析时间字符串
148 142 */
149 143 private LocalTime parseTime(String timeStr) {
  144 + // TODO @puhui999:可以用 hutool Assert 类简化
150 145 if (StrUtil.isBlank(timeStr)) {
151 146 throw new IllegalArgumentException("时间字符串不能为空");
152 147 }
153   -
154 148 // 尝试不同的时间格式
155 149 try {
156 150 if (timeStr.length() == 5) { // HH:mm
... ...
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
26 26 return IotSceneRuleConditionTypeEnum.DEVICE_PROPERTY;
27 27 }
28 28  
  29 + // TODO @puhui999:参数校验的,要不要 1.1 1.2 1.3 1.4 ?这样最终看到 2. 3. 就是核心逻辑列;
29 30 @Override
30 31 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
31 32 // 1. 基础参数校验
... ... @@ -56,13 +57,11 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher
56 57  
57 58 // 5. 使用条件评估器进行匹配
58 59 boolean matched = evaluateCondition(propertyValue, condition.getOperator(), condition.getParam());
59   -
60 60 if (matched) {
61 61 logConditionMatchSuccess(message, condition);
62 62 } else {
63 63 logConditionMatchFailure(message, condition, "设备属性条件不匹配");
64 64 }
65   -
66 65 return matched;
67 66 }
68 67  
... ...
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
20 20 /**
21 21 * 设备属性上报消息方法
22 22 */
  23 + // TODO @puhui999:是不是不用枚举哈?直接使用 IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()
23 24 private static final String DEVICE_PROPERTY_POST_METHOD = IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod();
24 25  
25 26 @Override
... ... @@ -68,13 +69,11 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
68 69  
69 70 // 6. 使用条件评估器进行匹配
70 71 boolean matched = evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue());
71   -
72 72 if (matched) {
73 73 logTriggerMatchSuccess(message, trigger);
74 74 } else {
75 75 logTriggerMatchFailure(message, trigger, "属性值条件不匹配");
76 76 }
77   -
78 77 return matched;
79 78 }
80 79  
... ...
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 {
49 49  
50 50 // 4. 使用条件评估器进行匹配
51 51 boolean matched = evaluateCondition(stateValue, condition.getOperator(), condition.getParam());
52   -
53 52 if (matched) {
54 53 logConditionMatchSuccess(message, condition);
55 54 } else {
56 55 logConditionMatchFailure(message, condition, "设备状态条件不匹配");
57 56 }
58   -
59 57 return matched;
60 58 }
61 59  
... ...
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;
16 16 @Component
17 17 public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher {
18 18  
  19 + // TODO @puhui999:是不是不用枚举哈;
19 20 /**
20 21 * 设备状态更新消息方法
21 22 */
... ... @@ -60,13 +61,11 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher
60 61  
61 62 // 5. 使用条件评估器进行匹配
62 63 boolean matched = evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue());
63   -
64 64 if (matched) {
65 65 logTriggerMatchSuccess(message, trigger);
66 66 } else {
67 67 logTriggerMatchFailure(message, trigger, "状态值条件不匹配");
68 68 }
69   -
70 69 return matched;
71 70 }
72 71  
... ...
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;
18 18 */
19 19 public interface IotSceneRuleMatcher {
20 20  
  21 + // TODO @puhui999:MatcherTypeEnum;
  22 + // TODO @puhui999:可以考虑根据类型,新建 trigger、condition 包,然后把对应的实现类放进去哈;
21 23 /**
22 24 * 匹配器类型枚举
23 25 */
24 26 enum MatcherType {
  27 +
25 28 /**
26 29 * 触发器匹配器 - 用于匹配主触发条件
27 30 */
28 31 TRIGGER,
  32 +
29 33 /**
30 34 * 条件匹配器 - 用于匹配子条件
31 35 */
32 36 CONDITION
  37 +
33 38 }
34 39  
35 40 /**
... ... @@ -39,6 +44,10 @@ public interface IotSceneRuleMatcher {
39 44 */
40 45 MatcherType getMatcherType();
41 46  
  47 + // TODO @puhui999:【重要】有个思路,IotSceneRuleMatcher 拆分成 2 种 mather 接口;然后 AbstractIotSceneRuleMatcher 是个 Helper 工具类;
  48 +
  49 + // TODO @puhui999:是不是和 AbstractSceneRuleMatcher 一样,分下块;
  50 +
42 51 /**
43 52 * 获取支持的触发器类型(仅触发器匹配器需要实现)
44 53 *
... ... @@ -90,6 +99,7 @@ public interface IotSceneRuleMatcher {
90 99 return 100;
91 100 }
92 101  
  102 + // TODO @puhui999:如果目前没自定义,体感可以删除哈;
93 103 /**
94 104 * 获取匹配器名称,用于日志和调试
95 105 *
... ...
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 {
30 30 * Key: 触发器类型枚举
31 31 * Value: 对应的匹配器实例
32 32 */
33   - private final Map<IotSceneRuleTriggerTypeEnum, IotSceneRuleMatcher> triggerMatcherMap;
  33 + private final Map<IotSceneRuleTriggerTypeEnum, IotSceneRuleMatcher> triggerMatchers;
34 34  
35 35 /**
36 36 * 条件匹配器映射表
37 37 * Key: 条件类型枚举
38 38 * Value: 对应的匹配器实例
39 39 */
40   - private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleMatcher> conditionMatcherMap;
  40 + private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleMatcher> conditionMatchers;
41 41  
42 42 /**
43 43 * 所有匹配器列表(按优先级排序)
... ... @@ -47,8 +47,8 @@ public class IotSceneRuleMatcherManager {
47 47 public IotSceneRuleMatcherManager(List<IotSceneRuleMatcher> matchers) {
48 48 if (CollUtil.isEmpty(matchers)) {
49 49 log.warn("[IotSceneRuleMatcherManager][没有找到任何匹配器]");
50   - this.triggerMatcherMap = new HashMap<>();
51   - this.conditionMatcherMap = new HashMap<>();
  50 + this.triggerMatchers = new HashMap<>();
  51 + this.conditionMatchers = new HashMap<>();
52 52 this.allMatchers = new ArrayList<>();
53 53 return;
54 54 }
... ... @@ -63,13 +63,13 @@ public class IotSceneRuleMatcherManager {
63 63 List<IotSceneRuleMatcher> triggerMatchers = this.allMatchers.stream()
64 64 .filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherType.TRIGGER)
65 65 .toList();
66   -
67 66 List<IotSceneRuleMatcher> conditionMatchers = this.allMatchers.stream()
68 67 .filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherType.CONDITION)
69 68 .toList();
70 69  
71 70 // 构建触发器匹配器映射表
72   - this.triggerMatcherMap = triggerMatchers.stream()
  71 + // TODO @puhui999:convertMap()
  72 + this.triggerMatchers = triggerMatchers.stream()
73 73 .collect(Collectors.toMap(
74 74 IotSceneRuleMatcher::getSupportedTriggerType,
75 75 Function.identity(),
... ... @@ -81,9 +81,8 @@ public class IotSceneRuleMatcherManager {
81 81 },
82 82 LinkedHashMap::new
83 83 ));
84   -
85 84 // 构建条件匹配器映射表
86   - this.conditionMatcherMap = conditionMatchers.stream()
  85 + this.conditionMatchers = conditionMatchers.stream()
87 86 .collect(Collectors.toMap(
88 87 IotSceneRuleMatcher::getSupportedConditionType,
89 88 Function.identity(),
... ... @@ -96,16 +95,13 @@ public class IotSceneRuleMatcherManager {
96 95 LinkedHashMap::new
97 96 ));
98 97  
  98 + // 日志输出初始化信息
99 99 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载 {} 个匹配器,其中触发器匹配器 {} 个,条件匹配器 {} 个]",
100   - this.allMatchers.size(), this.triggerMatcherMap.size(), this.conditionMatcherMap.size());
101   -
102   - // 记录触发器匹配器详情
103   - this.triggerMatcherMap.forEach((type, matcher) ->
  100 + this.allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size());
  101 + this.triggerMatchers.forEach((type, matcher) ->
104 102 log.info("[IotSceneRuleMatcherManager][触发器匹配器] 类型: {}, 匹配器: {}, 优先级: {}",
105 103 type, matcher.getMatcherName(), matcher.getPriority()));
106   -
107   - // 记录条件匹配器详情
108   - this.conditionMatcherMap.forEach((type, matcher) ->
  104 + this.conditionMatchers.forEach((type, matcher) ->
109 105 log.info("[IotSceneRuleMatcherManager][条件匹配器] 类型: {}, 匹配器: {}, 优先级: {}",
110 106 type, matcher.getMatcherName(), matcher.getPriority()));
111 107 }
... ... @@ -118,19 +114,17 @@ public class IotSceneRuleMatcherManager {
118 114 * @return 是否匹配
119 115 */
120 116 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  117 + // TODO @puhui999:日志优化下;claude 打出来的日志风格,和项目有点不一样哈;
121 118 if (message == null || trigger == null || trigger.getType() == null) {
122 119 log.debug("[isMatched][参数无效] message: {}, trigger: {}", message, trigger);
123 120 return false;
124 121 }
125   -
126   - // 根据触发器类型查找对应的匹配器
127 122 IotSceneRuleTriggerTypeEnum triggerType = findTriggerTypeEnum(trigger.getType());
128 123 if (triggerType == null) {
129 124 log.warn("[isMatched][未知的触发器类型: {}]", trigger.getType());
130 125 return false;
131 126 }
132   -
133   - IotSceneRuleMatcher matcher = triggerMatcherMap.get(triggerType);
  127 + IotSceneRuleMatcher matcher = triggerMatchers.get(triggerType);
134 128 if (matcher == null) {
135 129 log.warn("[isMatched][触发器类型({})没有对应的匹配器]", triggerType);
136 130 return false;
... ... @@ -165,7 +159,7 @@ public class IotSceneRuleMatcherManager {
165 159 return false;
166 160 }
167 161  
168   - IotSceneRuleMatcher matcher = conditionMatcherMap.get(conditionType);
  162 + IotSceneRuleMatcher matcher = conditionMatchers.get(conditionType);
169 163 if (matcher == null) {
170 164 log.warn("[isConditionMatched][条件类型({})没有对应的匹配器]", conditionType);
171 165 return false;
... ... @@ -199,7 +193,7 @@ public class IotSceneRuleMatcherManager {
199 193 * @return 支持的触发器类型列表
200 194 */
201 195 public Set<IotSceneRuleTriggerTypeEnum> getSupportedTriggerTypes() {
202   - return new HashSet<>(triggerMatcherMap.keySet());
  196 + return new HashSet<>(triggerMatchers.keySet());
203 197 }
204 198  
205 199 /**
... ... @@ -208,9 +202,11 @@ public class IotSceneRuleMatcherManager {
208 202 * @return 支持的条件类型列表
209 203 */
210 204 public Set<IotSceneRuleConditionTypeEnum> getSupportedConditionTypes() {
211   - return new HashSet<>(conditionMatcherMap.keySet());
  205 + return new HashSet<>(conditionMatchers.keySet());
212 206 }
213 207  
  208 + // TODO @puhui999:用不到的方法,可以去掉先哈;
  209 +
214 210 /**
215 211 * 获取指定触发器类型的匹配器
216 212 *
... ... @@ -218,7 +214,7 @@ public class IotSceneRuleMatcherManager {
218 214 * @return 匹配器实例,如果不存在则返回 null
219 215 */
220 216 public IotSceneRuleMatcher getTriggerMatcher(IotSceneRuleTriggerTypeEnum triggerType) {
221   - return triggerMatcherMap.get(triggerType);
  217 + return triggerMatchers.get(triggerType);
222 218 }
223 219  
224 220 /**
... ... @@ -228,9 +224,10 @@ public class IotSceneRuleMatcherManager {
228 224 * @return 匹配器实例,如果不存在则返回 null
229 225 */
230 226 public IotSceneRuleMatcher getConditionMatcher(IotSceneRuleConditionTypeEnum conditionType) {
231   - return conditionMatcherMap.get(conditionType);
  227 + return conditionMatchers.get(conditionType);
232 228 }
233 229  
  230 + // TODO @puhui999:是不是不用这个哈;直接 @Getter,单测直接处理;
234 231 /**
235 232 * 获取所有匹配器的统计信息
236 233 *
... ... @@ -239,14 +236,14 @@ public class IotSceneRuleMatcherManager {
239 236 public Map<String, Object> getMatcherStatistics() {
240 237 Map<String, Object> statistics = new HashMap<>();
241 238 statistics.put("totalMatchers", allMatchers.size());
242   - statistics.put("triggerMatchers", triggerMatcherMap.size());
243   - statistics.put("conditionMatchers", conditionMatcherMap.size());
  239 + statistics.put("triggerMatchers", triggerMatchers.size());
  240 + statistics.put("conditionMatchers", conditionMatchers.size());
244 241 statistics.put("supportedTriggerTypes", getSupportedTriggerTypes());
245 242 statistics.put("supportedConditionTypes", getSupportedConditionTypes());
246 243  
247 244 // 触发器匹配器详情
248 245 Map<String, Object> triggerMatcherDetails = new HashMap<>();
249   - triggerMatcherMap.forEach((type, matcher) -> {
  246 + triggerMatchers.forEach((type, matcher) -> {
250 247 Map<String, Object> detail = new HashMap<>();
251 248 detail.put("matcherName", matcher.getMatcherName());
252 249 detail.put("priority", matcher.getPriority());
... ... @@ -257,7 +254,7 @@ public class IotSceneRuleMatcherManager {
257 254  
258 255 // 条件匹配器详情
259 256 Map<String, Object> conditionMatcherDetails = new HashMap<>();
260   - conditionMatcherMap.forEach((type, matcher) -> {
  257 + conditionMatchers.forEach((type, matcher) -> {
261 258 Map<String, Object> detail = new HashMap<>();
262 259 detail.put("matcherName", matcher.getMatcherName());
263 260 detail.put("priority", matcher.getPriority());
... ...
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 {
61 61 * @return 是否有效
62 62 */
63 63 private boolean isValidCronExpression(String cronExpression) {
  64 + // TODO @puhui999:CronExpression.isValidExpression(cronExpression);
64 65 try {
65 66 // 简单的 CRON 表达式格式验证
66 67 // 标准 CRON 表达式应该有 6 或 7 个字段(秒 分 时 日 月 周 [年])
... ...
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.*;
20 20 */
21 21 public class IotSceneRuleTriggerMatcherTest extends BaseMockitoUnitTest {
22 22  
  23 + // TODO @puhui999:public 都加下哈;
  24 +
23 25 private IotSceneRuleMatcherManager matcherManager;
24 26  
25 27 @BeforeEach
... ... @@ -42,13 +44,13 @@ public class IotSceneRuleTriggerMatcherTest extends BaseMockitoUnitTest {
42 44 // 1. 准备测试数据
43 45 IotDeviceMessage message = IotDeviceMessage.builder()
44 46 .requestId("test-001")
45   - .method("thing.state.update")
46   - .data(1) // 在线状态
  47 + .method("thing.state.update") // TODO @puhui999:这里的枚举;
  48 + .data(1) // 在线状态 TODO @puhui999:这里的枚举;
47 49 .build();
48 50  
49 51 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
50 52 trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE.getType());
51   - trigger.setOperator("=");
  53 + trigger.setOperator("="); // TODO @puhui999:这里的枚举;下面也是类似;
52 54 trigger.setValue("1");
53 55  
54 56 // 2. 执行测试
... ...