Commit 34f1a2ed71d5d09f48061a56a208eeaa0b5d7edf

Authored by puhui999
1 parent 1e17e357

perf:【IoT 物联网】场景联动规则匹配接口拆分使职责更清晰

Showing 13 changed files with 217 additions and 299 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java
1 package cn.iocoder.yudao.module.iot.service.rule.scene.matcher; 1 package cn.iocoder.yudao.module.iot.service.rule.scene.matcher;
2 2
3 -import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;  
4 -import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;  
5 -import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;  
6 -import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 3 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotSceneRuleConditionMatcher;
  4 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher;
7 5
8 /** 6 /**
9 - * IoT 场景规则匹配器统一接口 7 + * IoT 场景规则匹配器基础接口
10 * <p> 8 * <p>
11 - * 支持触发器匹配和条件匹配两种类型,遵循策略模式设计 9 + * 定义所有匹配器的通用行为,包括优先级、名称和启用状态
12 * <p> 10 * <p>
13 - * 匹配器类型说明:  
14 - * - 触发器匹配器:用于匹配主触发条件(如设备消息类型、定时器等)  
15 - * - 条件匹配器:用于匹配子条件(如设备状态、属性值、时间条件等) 11 + * - {@link IotSceneRuleTriggerMatcher} 触发器匹配器
  12 + * - {@link IotSceneRuleConditionMatcher} 条件匹配器
16 * 13 *
17 * @author HUIHUI 14 * @author HUIHUI
18 */ 15 */
19 public interface IotSceneRuleMatcher { 16 public interface IotSceneRuleMatcher {
20 17
21 /** 18 /**
22 - * 匹配器类型枚举  
23 - */  
24 - enum MatcherTypeEnum {  
25 -  
26 - /**  
27 - * 触发器匹配器 - 用于匹配主触发条件  
28 - */  
29 - TRIGGER,  
30 -  
31 - /**  
32 - * 条件匹配器 - 用于匹配子条件  
33 - */  
34 - CONDITION  
35 -  
36 - }  
37 -  
38 - /**  
39 - * 获取匹配器类型  
40 - *  
41 - * @return 匹配器类型  
42 - */  
43 - MatcherTypeEnum getMatcherType();  
44 -  
45 - // TODO @puhui999:【重要】有个思路,IotSceneRuleMatcher 拆分成 2 种 mather 接口;然后 AbstractIotSceneRuleMatcher 是个 Helper 工具类;  
46 -  
47 - // TODO @puhui999:是不是和 AbstractSceneRuleMatcher 一样,分下块;  
48 -  
49 - /**  
50 - * 获取支持的触发器类型(仅触发器匹配器需要实现)  
51 - *  
52 - * @return 触发器类型枚举,条件匹配器返回 null  
53 - */  
54 - default IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {  
55 - return null;  
56 - }  
57 -  
58 - /**  
59 - * 获取支持的条件类型(仅条件匹配器需要实现)  
60 - *  
61 - * @return 条件类型枚举,触发器匹配器返回 null  
62 - */  
63 - default IotSceneRuleConditionTypeEnum getSupportedConditionType() {  
64 - return null;  
65 - }  
66 -  
67 - /**  
68 - * 检查触发器是否匹配消息(仅触发器匹配器需要实现)  
69 - *  
70 - * @param message 设备消息  
71 - * @param trigger 触发器配置  
72 - * @return 是否匹配  
73 - */  
74 - default boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {  
75 - throw new UnsupportedOperationException("触发器匹配方法仅支持触发器匹配器");  
76 - }  
77 -  
78 - /**  
79 - * 检查条件是否匹配消息(仅条件匹配器需要实现)  
80 - *  
81 - * @param message 设备消息  
82 - * @param condition 触发条件  
83 - * @return 是否匹配  
84 - */  
85 - default boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {  
86 - throw new UnsupportedOperationException("条件匹配方法仅支持条件匹配器");  
87 - }  
88 -  
89 - /**  
90 * 获取匹配优先级(数值越小优先级越高) 19 * 获取匹配优先级(数值越小优先级越高)
91 * <p> 20 * <p>
92 * 用于在多个匹配器支持同一类型时确定优先级 21 * 用于在多个匹配器支持同一类型时确定优先级
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/AbstractIotSceneRuleMatcher.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java
@@ -15,16 +15,22 @@ import java.util.Map; @@ -15,16 +15,22 @@ import java.util.Map;
15 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 15 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
16 16
17 /** 17 /**
18 - * IoT 场景规则匹配器抽象基类 18 + * IoT 场景规则匹配器工具类
19 * <p> 19 * <p>
20 - * 提供通用的条件评估逻辑和工具方法,支持触发器和条件两种匹配类型 20 + * 提供通用的条件评估逻辑和工具方法,供触发器和条件匹配器使用
  21 + * <p>
  22 + * 该类包含了匹配器实现中常用的工具方法,如条件评估、参数校验、日志记录等
21 * 23 *
22 * @author HUIHUI 24 * @author HUIHUI
23 */ 25 */
24 @Slf4j 26 @Slf4j
25 -public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher { 27 +public final class IotSceneRuleMatcherHelper {
26 28
27 - // TODO @puhui999:这个是不是也是【通用】条件哈? 29 + /**
  30 + * 私有构造函数,防止实例化
  31 + */
  32 + private IotSceneRuleMatcherHelper() {
  33 + }
28 34
29 /** 35 /**
30 * 评估条件是否匹配 36 * 评估条件是否匹配
@@ -35,7 +41,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher @@ -35,7 +41,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
35 * @return 是否匹配 41 * @return 是否匹配
36 */ 42 */
37 @SuppressWarnings("DataFlowIssue") 43 @SuppressWarnings("DataFlowIssue")
38 - protected boolean evaluateCondition(Object sourceValue, String operator, String paramValue) { 44 + public static boolean evaluateCondition(Object sourceValue, String operator, String paramValue) {
39 try { 45 try {
40 // 1. 校验操作符是否合法 46 // 1. 校验操作符是否合法
41 IotSceneRuleConditionOperatorEnum operatorEnum = IotSceneRuleConditionOperatorEnum.operatorOf(operator); 47 IotSceneRuleConditionOperatorEnum operatorEnum = IotSceneRuleConditionOperatorEnum.operatorOf(operator);
@@ -80,7 +86,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher @@ -80,7 +86,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
80 * @param trigger 触发器配置 86 * @param trigger 触发器配置
81 * @return 是否有效 87 * @return 是否有效
82 */ 88 */
83 - protected boolean isBasicTriggerValid(IotSceneRuleDO.Trigger trigger) { 89 + public static boolean isBasicTriggerValid(IotSceneRuleDO.Trigger trigger) {
84 return trigger != null && trigger.getType() != null; 90 return trigger != null && trigger.getType() != null;
85 } 91 }
86 92
@@ -90,29 +96,31 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher @@ -90,29 +96,31 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
90 * @param trigger 触发器配置 96 * @param trigger 触发器配置
91 * @return 是否有效 97 * @return 是否有效
92 */ 98 */
93 - protected boolean isTriggerOperatorAndValueValid(IotSceneRuleDO.Trigger trigger) { 99 + public static boolean isTriggerOperatorAndValueValid(IotSceneRuleDO.Trigger trigger) {
94 return StrUtil.isNotBlank(trigger.getOperator()) && StrUtil.isNotBlank(trigger.getValue()); 100 return StrUtil.isNotBlank(trigger.getOperator()) && StrUtil.isNotBlank(trigger.getValue());
95 } 101 }
96 102
97 /** 103 /**
98 * 记录触发器匹配成功日志 104 * 记录触发器匹配成功日志
99 * 105 *
100 - * @param message 设备消息  
101 - * @param trigger 触发器配置 106 + * @param matcherName 匹配器名称
  107 + * @param message 设备消息
  108 + * @param trigger 触发器配置
102 */ 109 */
103 - protected void logTriggerMatchSuccess(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {  
104 - log.debug("[{}][消息({}) 匹配触发器({}) 成功]", getMatcherName(), message.getRequestId(), trigger.getType()); 110 + public static void logTriggerMatchSuccess(String matcherName, IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  111 + log.debug("[{}][消息({}) 匹配触发器({}) 成功]", matcherName, message.getRequestId(), trigger.getType());
105 } 112 }
106 113
107 /** 114 /**
108 * 记录触发器匹配失败日志 115 * 记录触发器匹配失败日志
109 * 116 *
110 - * @param message 设备消息  
111 - * @param trigger 触发器配置  
112 - * @param reason 失败原因 117 + * @param matcherName 匹配器名称
  118 + * @param message 设备消息
  119 + * @param trigger 触发器配置
  120 + * @param reason 失败原因
113 */ 121 */
114 - protected void logTriggerMatchFailure(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, String reason) {  
115 - log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", getMatcherName(), message.getRequestId(), trigger.getType(), reason); 122 + public static void logTriggerMatchFailure(String matcherName, IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, String reason) {
  123 + log.debug("[{}][消息({}) 匹配触发器({}) 失败: {}]", matcherName, message.getRequestId(), trigger.getType(), reason);
116 } 124 }
117 125
118 // ========== 【条件】相关工具方法 ========== 126 // ========== 【条件】相关工具方法 ==========
@@ -123,7 +131,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher @@ -123,7 +131,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
123 * @param condition 触发条件 131 * @param condition 触发条件
124 * @return 是否有效 132 * @return 是否有效
125 */ 133 */
126 - protected boolean isBasicConditionValid(IotSceneRuleDO.TriggerCondition condition) { 134 + public static boolean isBasicConditionValid(IotSceneRuleDO.TriggerCondition condition) {
127 return condition != null && condition.getType() != null; 135 return condition != null && condition.getType() != null;
128 } 136 }
129 137
@@ -133,29 +141,31 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher @@ -133,29 +141,31 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
133 * @param condition 触发条件 141 * @param condition 触发条件
134 * @return 是否有效 142 * @return 是否有效
135 */ 143 */
136 - protected boolean isConditionOperatorAndParamValid(IotSceneRuleDO.TriggerCondition condition) { 144 + public static boolean isConditionOperatorAndParamValid(IotSceneRuleDO.TriggerCondition condition) {
137 return StrUtil.isNotBlank(condition.getOperator()) && StrUtil.isNotBlank(condition.getParam()); 145 return StrUtil.isNotBlank(condition.getOperator()) && StrUtil.isNotBlank(condition.getParam());
138 } 146 }
139 147
140 /** 148 /**
141 * 记录条件匹配成功日志 149 * 记录条件匹配成功日志
142 * 150 *
143 - * @param message 设备消息  
144 - * @param condition 触发条件 151 + * @param matcherName 匹配器名称
  152 + * @param message 设备消息
  153 + * @param condition 触发条件
145 */ 154 */
146 - protected void logConditionMatchSuccess(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {  
147 - log.debug("[{}][消息({}) 匹配条件({}) 成功]", getMatcherName(), message.getRequestId(), condition.getType()); 155 + public static void logConditionMatchSuccess(String matcherName, IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
  156 + log.debug("[{}][消息({}) 匹配条件({}) 成功]", matcherName, message.getRequestId(), condition.getType());
148 } 157 }
149 158
150 /** 159 /**
151 * 记录条件匹配失败日志 160 * 记录条件匹配失败日志
152 * 161 *
153 - * @param message 设备消息  
154 - * @param condition 触发条件  
155 - * @param reason 失败原因 162 + * @param matcherName 匹配器名称
  163 + * @param message 设备消息
  164 + * @param condition 触发条件
  165 + * @param reason 失败原因
156 */ 166 */
157 - protected void logConditionMatchFailure(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition, String reason) {  
158 - log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", getMatcherName(), message.getRequestId(), condition.getType(), reason); 167 + public static void logConditionMatchFailure(String matcherName, IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition, String reason) {
  168 + log.debug("[{}][消息({}) 匹配条件({}) 失败: {}]", matcherName, message.getRequestId(), condition.getType(), reason);
159 } 169 }
160 170
161 // ========== 【通用】工具方法 ========== 171 // ========== 【通用】工具方法 ==========
@@ -167,7 +177,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher @@ -167,7 +177,7 @@ public abstract class AbstractIotSceneRuleMatcher implements IotSceneRuleMatcher
167 * @param actualIdentifier 实际的标识符 177 * @param actualIdentifier 实际的标识符
168 * @return 是否匹配 178 * @return 是否匹配
169 */ 179 */
170 - protected boolean isIdentifierMatched(String expectedIdentifier, String actualIdentifier) { 180 + public static boolean isIdentifierMatched(String expectedIdentifier, String actualIdentifier) {
171 return StrUtil.isNotBlank(expectedIdentifier) && expectedIdentifier.equals(actualIdentifier); 181 return StrUtil.isNotBlank(expectedIdentifier) && expectedIdentifier.equals(actualIdentifier);
172 } 182 }
173 183
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
@@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
  8 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotSceneRuleConditionMatcher;
  9 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher;
8 import lombok.extern.slf4j.Slf4j; 10 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 11 import org.springframework.stereotype.Component;
10 12
@@ -30,14 +32,14 @@ public class IotSceneRuleMatcherManager { @@ -30,14 +32,14 @@ public class IotSceneRuleMatcherManager {
30 * Key: 触发器类型枚举 32 * Key: 触发器类型枚举
31 * Value: 对应的匹配器实例 33 * Value: 对应的匹配器实例
32 */ 34 */
33 - private final Map<IotSceneRuleTriggerTypeEnum, IotSceneRuleMatcher> triggerMatchers; 35 + private final Map<IotSceneRuleTriggerTypeEnum, IotSceneRuleTriggerMatcher> triggerMatchers;
34 36
35 /** 37 /**
36 * 条件匹配器映射表 38 * 条件匹配器映射表
37 * Key: 条件类型枚举 39 * Key: 条件类型枚举
38 * Value: 对应的匹配器实例 40 * Value: 对应的匹配器实例
39 */ 41 */
40 - private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleMatcher> conditionMatchers; 42 + private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleConditionMatcher> conditionMatchers;
41 43
42 /** 44 /**
43 * 所有匹配器列表(按优先级排序) 45 * 所有匹配器列表(按优先级排序)
@@ -60,18 +62,20 @@ public class IotSceneRuleMatcherManager { @@ -60,18 +62,20 @@ public class IotSceneRuleMatcherManager {
60 .collect(Collectors.toList()); 62 .collect(Collectors.toList());
61 63
62 // 分离触发器匹配器和条件匹配器 64 // 分离触发器匹配器和条件匹配器
63 - List<IotSceneRuleMatcher> triggerMatchers = this.allMatchers.stream()  
64 - .filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherTypeEnum.TRIGGER) 65 + List<IotSceneRuleTriggerMatcher> triggerMatchers = this.allMatchers.stream()
  66 + .filter(matcher -> matcher instanceof IotSceneRuleTriggerMatcher)
  67 + .map(matcher -> (IotSceneRuleTriggerMatcher) matcher)
65 .toList(); 68 .toList();
66 - List<IotSceneRuleMatcher> conditionMatchers = this.allMatchers.stream()  
67 - .filter(matcher -> matcher.getMatcherType() == IotSceneRuleMatcher.MatcherTypeEnum.CONDITION) 69 + List<IotSceneRuleConditionMatcher> conditionMatchers = this.allMatchers.stream()
  70 + .filter(matcher -> matcher instanceof IotSceneRuleConditionMatcher)
  71 + .map(matcher -> (IotSceneRuleConditionMatcher) matcher)
68 .toList(); 72 .toList();
69 73
70 // 构建触发器匹配器映射表 74 // 构建触发器匹配器映射表
71 // TODO @puhui999:convertMap() 75 // TODO @puhui999:convertMap()
72 this.triggerMatchers = triggerMatchers.stream() 76 this.triggerMatchers = triggerMatchers.stream()
73 .collect(Collectors.toMap( 77 .collect(Collectors.toMap(
74 - IotSceneRuleMatcher::getSupportedTriggerType, 78 + IotSceneRuleTriggerMatcher::getSupportedTriggerType,
75 Function.identity(), 79 Function.identity(),
76 (existing, replacement) -> { 80 (existing, replacement) -> {
77 log.warn("[IotSceneRuleMatcherManager][触发器类型({})存在多个匹配器,使用优先级更高的: {}]", 81 log.warn("[IotSceneRuleMatcherManager][触发器类型({})存在多个匹配器,使用优先级更高的: {}]",
@@ -84,7 +88,7 @@ public class IotSceneRuleMatcherManager { @@ -84,7 +88,7 @@ public class IotSceneRuleMatcherManager {
84 // 构建条件匹配器映射表 88 // 构建条件匹配器映射表
85 this.conditionMatchers = conditionMatchers.stream() 89 this.conditionMatchers = conditionMatchers.stream()
86 .collect(Collectors.toMap( 90 .collect(Collectors.toMap(
87 - IotSceneRuleMatcher::getSupportedConditionType, 91 + IotSceneRuleConditionMatcher::getSupportedConditionType,
88 Function.identity(), 92 Function.identity(),
89 (existing, replacement) -> { 93 (existing, replacement) -> {
90 log.warn("[IotSceneRuleMatcherManager][条件类型({})存在多个匹配器,使用优先级更高的: {}]", 94 log.warn("[IotSceneRuleMatcherManager][条件类型({})存在多个匹配器,使用优先级更高的: {}]",
@@ -124,7 +128,7 @@ public class IotSceneRuleMatcherManager { @@ -124,7 +128,7 @@ public class IotSceneRuleMatcherManager {
124 log.warn("[isMatched][未知的触发器类型: {}]", trigger.getType()); 128 log.warn("[isMatched][未知的触发器类型: {}]", trigger.getType());
125 return false; 129 return false;
126 } 130 }
127 - IotSceneRuleMatcher matcher = triggerMatchers.get(triggerType); 131 + IotSceneRuleTriggerMatcher matcher = triggerMatchers.get(triggerType);
128 if (matcher == null) { 132 if (matcher == null) {
129 log.warn("[isMatched][触发器类型({})没有对应的匹配器]", triggerType); 133 log.warn("[isMatched][触发器类型({})没有对应的匹配器]", triggerType);
130 return false; 134 return false;
@@ -159,7 +163,7 @@ public class IotSceneRuleMatcherManager { @@ -159,7 +163,7 @@ public class IotSceneRuleMatcherManager {
159 return false; 163 return false;
160 } 164 }
161 165
162 - IotSceneRuleMatcher matcher = conditionMatchers.get(conditionType); 166 + IotSceneRuleConditionMatcher matcher = conditionMatchers.get(conditionType);
163 if (matcher == null) { 167 if (matcher == null) {
164 log.warn("[isConditionMatched][条件类型({})没有对应的匹配器]", conditionType); 168 log.warn("[isConditionMatched][条件类型({})没有对应的匹配器]", conditionType);
165 return false; 169 return false;
@@ -205,65 +209,4 @@ public class IotSceneRuleMatcherManager { @@ -205,65 +209,4 @@ public class IotSceneRuleMatcherManager {
205 return new HashSet<>(conditionMatchers.keySet()); 209 return new HashSet<>(conditionMatchers.keySet());
206 } 210 }
207 211
208 - // TODO @puhui999:用不到的方法,可以去掉先哈;  
209 -  
210 - /**  
211 - * 获取指定触发器类型的匹配器  
212 - *  
213 - * @param triggerType 触发器类型  
214 - * @return 匹配器实例,如果不存在则返回 null  
215 - */  
216 - public IotSceneRuleMatcher getTriggerMatcher(IotSceneRuleTriggerTypeEnum triggerType) {  
217 - return triggerMatchers.get(triggerType);  
218 - }  
219 -  
220 - /**  
221 - * 获取指定条件类型的匹配器  
222 - *  
223 - * @param conditionType 条件类型  
224 - * @return 匹配器实例,如果不存在则返回 null  
225 - */  
226 - public IotSceneRuleMatcher getConditionMatcher(IotSceneRuleConditionTypeEnum conditionType) {  
227 - return conditionMatchers.get(conditionType);  
228 - }  
229 -  
230 - // TODO @puhui999:是不是不用这个哈;直接 @Getter,单测直接处理;  
231 - /**  
232 - * 获取所有匹配器的统计信息  
233 - *  
234 - * @return 统计信息映射表  
235 - */  
236 - public Map<String, Object> getMatcherStatistics() {  
237 - Map<String, Object> statistics = new HashMap<>();  
238 - statistics.put("totalMatchers", allMatchers.size());  
239 - statistics.put("triggerMatchers", triggerMatchers.size());  
240 - statistics.put("conditionMatchers", conditionMatchers.size());  
241 - statistics.put("supportedTriggerTypes", getSupportedTriggerTypes());  
242 - statistics.put("supportedConditionTypes", getSupportedConditionTypes());  
243 -  
244 - // 触发器匹配器详情  
245 - Map<String, Object> triggerMatcherDetails = new HashMap<>();  
246 - triggerMatchers.forEach((type, matcher) -> {  
247 - Map<String, Object> detail = new HashMap<>();  
248 - detail.put("matcherName", matcher.getMatcherName());  
249 - detail.put("priority", matcher.getPriority());  
250 - detail.put("enabled", matcher.isEnabled());  
251 - triggerMatcherDetails.put(type.name(), detail);  
252 - });  
253 - statistics.put("triggerMatcherDetails", triggerMatcherDetails);  
254 -  
255 - // 条件匹配器详情  
256 - Map<String, Object> conditionMatcherDetails = new HashMap<>();  
257 - conditionMatchers.forEach((type, matcher) -> {  
258 - Map<String, Object> detail = new HashMap<>();  
259 - detail.put("matcherName", matcher.getMatcherName());  
260 - detail.put("priority", matcher.getPriority());  
261 - detail.put("enabled", matcher.isEnabled());  
262 - conditionMatcherDetails.put(type.name(), detail);  
263 - });  
264 - statistics.put("conditionMatcherDetails", conditionMatcherDetails);  
265 -  
266 - return statistics;  
267 - }  
268 -  
269 } 212 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/CurrentTimeConditionMatcher.java
@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil; @@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
7 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 7 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
8 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
@@ -21,7 +21,7 @@ import java.time.format.DateTimeFormatter; @@ -21,7 +21,7 @@ import java.time.format.DateTimeFormatter;
21 */ 21 */
22 @Component 22 @Component
23 @Slf4j 23 @Slf4j
24 -public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { 24 +public class CurrentTimeConditionMatcher implements IotSceneRuleConditionMatcher {
25 25
26 /** 26 /**
27 * 时间格式化器 - HH:mm:ss 27 * 时间格式化器 - HH:mm:ss
@@ -34,11 +34,6 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { @@ -34,11 +34,6 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
34 private static final DateTimeFormatter TIME_FORMATTER_SHORT = DateTimeFormatter.ofPattern("HH:mm"); 34 private static final DateTimeFormatter TIME_FORMATTER_SHORT = DateTimeFormatter.ofPattern("HH:mm");
35 35
36 @Override 36 @Override
37 - public MatcherTypeEnum getMatcherType() {  
38 - return MatcherTypeEnum.CONDITION;  
39 - }  
40 -  
41 - @Override  
42 public IotSceneRuleConditionTypeEnum getSupportedConditionType() { 37 public IotSceneRuleConditionTypeEnum getSupportedConditionType() {
43 return IotSceneRuleConditionTypeEnum.CURRENT_TIME; 38 return IotSceneRuleConditionTypeEnum.CURRENT_TIME;
44 } 39 }
@@ -46,14 +41,14 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { @@ -46,14 +41,14 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
46 @Override 41 @Override
47 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) { 42 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
48 // 1. 基础参数校验 43 // 1. 基础参数校验
49 - if (!isBasicConditionValid(condition)) {  
50 - logConditionMatchFailure(message, condition, "条件基础参数无效"); 44 + if (!IotSceneRuleMatcherHelper.isBasicConditionValid(condition)) {
  45 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "条件基础参数无效");
51 return false; 46 return false;
52 } 47 }
53 48
54 // 2. 检查操作符和参数是否有效 49 // 2. 检查操作符和参数是否有效
55 - if (!isConditionOperatorAndParamValid(condition)) {  
56 - logConditionMatchFailure(message, condition, "操作符或参数无效"); 50 + if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) {
  51 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "操作符或参数无效");
57 return false; 52 return false;
58 } 53 }
59 54
@@ -71,17 +66,17 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { @@ -71,17 +66,17 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
71 matched = matchTime(now.toLocalTime(), operator, param); 66 matched = matchTime(now.toLocalTime(), operator, param);
72 } else { 67 } else {
73 // 其他操作符,使用通用条件评估器 68 // 其他操作符,使用通用条件评估器
74 - matched = evaluateCondition(now.toEpochSecond(java.time.ZoneOffset.of("+8")), operator, param); 69 + matched = IotSceneRuleMatcherHelper.evaluateCondition(now.toEpochSecond(java.time.ZoneOffset.of("+8")), operator, param);
75 } 70 }
76 71
77 if (matched) { 72 if (matched) {
78 - logConditionMatchSuccess(message, condition); 73 + IotSceneRuleMatcherHelper.logConditionMatchSuccess(getMatcherName(), message, condition);
79 } else { 74 } else {
80 - logConditionMatchFailure(message, condition, "时间条件不匹配"); 75 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "时间条件不匹配");
81 } 76 }
82 } catch (Exception e) { 77 } catch (Exception e) {
83 log.error("[CurrentTimeConditionMatcher][时间条件匹配异常] operator: {}, param: {}", operator, param, e); 78 log.error("[CurrentTimeConditionMatcher][时间条件匹配异常] operator: {}, param: {}", operator, param, e);
84 - logConditionMatchFailure(message, condition, "时间条件匹配异常: " + e.getMessage()); 79 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "时间条件匹配异常: " + e.getMessage());
85 matched = false; 80 matched = false;
86 } 81 }
87 return matched; 82 return matched;
@@ -92,7 +87,7 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher { @@ -92,7 +87,7 @@ public class CurrentTimeConditionMatcher extends AbstractIotSceneRuleMatcher {
92 */ 87 */
93 private boolean matchDateTime(LocalDateTime now, String operator, String param) { 88 private boolean matchDateTime(LocalDateTime now, String operator, String param) {
94 long currentTimestamp = now.toEpochSecond(java.time.ZoneOffset.of("+8")); 89 long currentTimestamp = now.toEpochSecond(java.time.ZoneOffset.of("+8"));
95 - return evaluateCondition(currentTimestamp, operator.substring("date_time_".length()), param); 90 + return IotSceneRuleMatcherHelper.evaluateCondition(currentTimestamp, operator.substring("date_time_".length()), param);
96 } 91 }
97 92
98 /** 93 /**
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DevicePropertyConditionMatcher.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
4 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 4 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
7 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 7 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
9 9
10 /** 10 /**
@@ -15,12 +15,7 @@ import org.springframework.stereotype.Component; @@ -15,12 +15,7 @@ import org.springframework.stereotype.Component;
15 * @author HUIHUI 15 * @author HUIHUI
16 */ 16 */
17 @Component 17 @Component
18 -public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher {  
19 -  
20 - @Override  
21 - public MatcherTypeEnum getMatcherType() {  
22 - return MatcherTypeEnum.CONDITION;  
23 - } 18 +public class DevicePropertyConditionMatcher implements IotSceneRuleConditionMatcher {
24 19
25 @Override 20 @Override
26 public IotSceneRuleConditionTypeEnum getSupportedConditionType() { 21 public IotSceneRuleConditionTypeEnum getSupportedConditionType() {
@@ -31,37 +26,37 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher @@ -31,37 +26,37 @@ public class DevicePropertyConditionMatcher extends AbstractIotSceneRuleMatcher
31 @Override 26 @Override
32 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) { 27 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
33 // 1. 基础参数校验 28 // 1. 基础参数校验
34 - if (!isBasicConditionValid(condition)) {  
35 - logConditionMatchFailure(message, condition, "条件基础参数无效"); 29 + if (!IotSceneRuleMatcherHelper.isBasicConditionValid(condition)) {
  30 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "条件基础参数无效");
36 return false; 31 return false;
37 } 32 }
38 33
39 // 2. 检查标识符是否匹配 34 // 2. 检查标识符是否匹配
40 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); 35 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
41 - if (!isIdentifierMatched(condition.getIdentifier(), messageIdentifier)) {  
42 - logConditionMatchFailure(message, condition, "标识符不匹配,期望: " + condition.getIdentifier() + ", 实际: " + messageIdentifier); 36 + if (!IotSceneRuleMatcherHelper.isIdentifierMatched(condition.getIdentifier(), messageIdentifier)) {
  37 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "标识符不匹配,期望: " + condition.getIdentifier() + ", 实际: " + messageIdentifier);
43 return false; 38 return false;
44 } 39 }
45 40
46 // 3. 检查操作符和参数是否有效 41 // 3. 检查操作符和参数是否有效
47 - if (!isConditionOperatorAndParamValid(condition)) {  
48 - logConditionMatchFailure(message, condition, "操作符或参数无效"); 42 + if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) {
  43 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "操作符或参数无效");
49 return false; 44 return false;
50 } 45 }
51 46
52 // 4. 获取属性值 47 // 4. 获取属性值
53 Object propertyValue = message.getData(); 48 Object propertyValue = message.getData();
54 if (propertyValue == null) { 49 if (propertyValue == null) {
55 - logConditionMatchFailure(message, condition, "消息中属性值为空"); 50 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "消息中属性值为空");
56 return false; 51 return false;
57 } 52 }
58 53
59 // 5. 使用条件评估器进行匹配 54 // 5. 使用条件评估器进行匹配
60 - boolean matched = evaluateCondition(propertyValue, condition.getOperator(), condition.getParam()); 55 + boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(propertyValue, condition.getOperator(), condition.getParam());
61 if (matched) { 56 if (matched) {
62 - logConditionMatchSuccess(message, condition); 57 + IotSceneRuleMatcherHelper.logConditionMatchSuccess(getMatcherName(), message, condition);
63 } else { 58 } else {
64 - logConditionMatchFailure(message, condition, "设备属性条件不匹配"); 59 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "设备属性条件不匹配");
65 } 60 }
66 return matched; 61 return matched;
67 } 62 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DeviceStateConditionMatcher.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition;
3 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 3 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
4 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 4 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
5 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum; 5 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
6 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 6 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
7 import org.springframework.stereotype.Component; 7 import org.springframework.stereotype.Component;
8 8
9 /** 9 /**
@@ -14,12 +14,7 @@ import org.springframework.stereotype.Component; @@ -14,12 +14,7 @@ import org.springframework.stereotype.Component;
14 * @author HUIHUI 14 * @author HUIHUI
15 */ 15 */
16 @Component 16 @Component
17 -public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher {  
18 -  
19 - @Override  
20 - public MatcherTypeEnum getMatcherType() {  
21 - return MatcherTypeEnum.CONDITION;  
22 - } 17 +public class DeviceStateConditionMatcher implements IotSceneRuleConditionMatcher {
23 18
24 @Override 19 @Override
25 public IotSceneRuleConditionTypeEnum getSupportedConditionType() { 20 public IotSceneRuleConditionTypeEnum getSupportedConditionType() {
@@ -29,14 +24,14 @@ public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher { @@ -29,14 +24,14 @@ public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher {
29 @Override 24 @Override
30 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) { 25 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
31 // 1. 基础参数校验 26 // 1. 基础参数校验
32 - if (!isBasicConditionValid(condition)) {  
33 - logConditionMatchFailure(message, condition, "条件基础参数无效"); 27 + if (!IotSceneRuleMatcherHelper.isBasicConditionValid(condition)) {
  28 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "条件基础参数无效");
34 return false; 29 return false;
35 } 30 }
36 31
37 // 2. 检查操作符和参数是否有效 32 // 2. 检查操作符和参数是否有效
38 - if (!isConditionOperatorAndParamValid(condition)) {  
39 - logConditionMatchFailure(message, condition, "操作符或参数无效"); 33 + if (!IotSceneRuleMatcherHelper.isConditionOperatorAndParamValid(condition)) {
  34 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "操作符或参数无效");
40 return false; 35 return false;
41 } 36 }
42 37
@@ -44,16 +39,16 @@ public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher { @@ -44,16 +39,16 @@ public class DeviceStateConditionMatcher extends AbstractIotSceneRuleMatcher {
44 // 设备状态通常在消息的 data 字段中 39 // 设备状态通常在消息的 data 字段中
45 Object stateValue = message.getData(); 40 Object stateValue = message.getData();
46 if (stateValue == null) { 41 if (stateValue == null) {
47 - logConditionMatchFailure(message, condition, "消息中设备状态值为空"); 42 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "消息中设备状态值为空");
48 return false; 43 return false;
49 } 44 }
50 45
51 // 4. 使用条件评估器进行匹配 46 // 4. 使用条件评估器进行匹配
52 - boolean matched = evaluateCondition(stateValue, condition.getOperator(), condition.getParam()); 47 + boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(stateValue, condition.getOperator(), condition.getParam());
53 if (matched) { 48 if (matched) {
54 - logConditionMatchSuccess(message, condition); 49 + IotSceneRuleMatcherHelper.logConditionMatchSuccess(getMatcherName(), message, condition);
55 } else { 50 } else {
56 - logConditionMatchFailure(message, condition, "设备状态条件不匹配"); 51 + IotSceneRuleMatcherHelper.logConditionMatchFailure(getMatcherName(), message, condition, "设备状态条件不匹配");
57 } 52 }
58 return matched; 53 return matched;
59 } 54 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotSceneRuleConditionMatcher.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition;
  2 +
  3 +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  4 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
  5 +import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
  6 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
  7 +
  8 +/**
  9 + * IoT 场景规则条件匹配器接口
  10 + * <p>
  11 + * 专门处理子条件的匹配逻辑,如设备状态、属性值、时间条件等
  12 + * <p>
  13 + * 条件匹配器负责判断设备消息是否满足场景规则的附加条件,
  14 + * 在触发器匹配成功后进行进一步的条件筛选
  15 + *
  16 + * @author HUIHUI
  17 + */
  18 +public interface IotSceneRuleConditionMatcher extends IotSceneRuleMatcher {
  19 +
  20 + /**
  21 + * 获取支持的条件类型
  22 + *
  23 + * @return 条件类型枚举
  24 + */
  25 + IotSceneRuleConditionTypeEnum getSupportedConditionType();
  26 +
  27 + /**
  28 + * 检查条件是否匹配消息
  29 + * <p>
  30 + * 判断设备消息是否满足指定的触发条件
  31 + *
  32 + * @param message 设备消息
  33 + * @param condition 触发条件
  34 + * @return 是否匹配
  35 + */
  36 + boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition);
  37 +
  38 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
@@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
6 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 6 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
9 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 9 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
10 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
11 11
12 /** 12 /**
@@ -17,7 +17,7 @@ import org.springframework.stereotype.Component; @@ -17,7 +17,7 @@ import org.springframework.stereotype.Component;
17 * @author HUIHUI 17 * @author HUIHUI
18 */ 18 */
19 @Component 19 @Component
20 -public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher { 20 +public class DeviceEventPostTriggerMatcher implements IotSceneRuleTriggerMatcher {
21 21
22 /** 22 /**
23 * 设备事件上报消息方法 23 * 设备事件上报消息方法
@@ -25,11 +25,6 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher { @@ -25,11 +25,6 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
25 private static final String DEVICE_EVENT_POST_METHOD = IotDeviceMessageMethodEnum.EVENT_POST.getMethod(); 25 private static final String DEVICE_EVENT_POST_METHOD = IotDeviceMessageMethodEnum.EVENT_POST.getMethod();
26 26
27 @Override 27 @Override
28 - public MatcherTypeEnum getMatcherType() {  
29 - return MatcherTypeEnum.TRIGGER;  
30 - }  
31 -  
32 - @Override  
33 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { 28 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
34 return IotSceneRuleTriggerTypeEnum.DEVICE_EVENT_POST; 29 return IotSceneRuleTriggerTypeEnum.DEVICE_EVENT_POST;
35 } 30 }
@@ -37,21 +32,21 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher { @@ -37,21 +32,21 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
37 @Override 32 @Override
38 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { 33 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
39 // 1. 基础参数校验 34 // 1. 基础参数校验
40 - if (!isBasicTriggerValid(trigger)) {  
41 - logTriggerMatchFailure(message, trigger, "触发器基础参数无效"); 35 + if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
  36 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
42 return false; 37 return false;
43 } 38 }
44 39
45 // 2. 检查消息方法是否匹配 40 // 2. 检查消息方法是否匹配
46 if (!DEVICE_EVENT_POST_METHOD.equals(message.getMethod())) { 41 if (!DEVICE_EVENT_POST_METHOD.equals(message.getMethod())) {
47 - logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_EVENT_POST_METHOD + ", 实际: " + message.getMethod()); 42 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_EVENT_POST_METHOD + ", 实际: " + message.getMethod());
48 return false; 43 return false;
49 } 44 }
50 45
51 // 3. 检查标识符是否匹配 46 // 3. 检查标识符是否匹配
52 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); 47 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
53 - if (!isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {  
54 - logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier); 48 + if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
  49 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
55 return false; 50 return false;
56 } 51 }
57 52
@@ -60,18 +55,18 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher { @@ -60,18 +55,18 @@ public class DeviceEventPostTriggerMatcher extends AbstractIotSceneRuleMatcher {
60 if (StrUtil.isNotBlank(trigger.getOperator()) && StrUtil.isNotBlank(trigger.getValue())) { 55 if (StrUtil.isNotBlank(trigger.getOperator()) && StrUtil.isNotBlank(trigger.getValue())) {
61 Object eventData = message.getData(); 56 Object eventData = message.getData();
62 if (eventData == null) { 57 if (eventData == null) {
63 - logTriggerMatchFailure(message, trigger, "消息中事件数据为空"); 58 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息中事件数据为空");
64 return false; 59 return false;
65 } 60 }
66 61
67 - boolean matched = evaluateCondition(eventData, trigger.getOperator(), trigger.getValue()); 62 + boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(eventData, trigger.getOperator(), trigger.getValue());
68 if (!matched) { 63 if (!matched) {
69 - logTriggerMatchFailure(message, trigger, "事件数据条件不匹配"); 64 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "事件数据条件不匹配");
70 return false; 65 return false;
71 } 66 }
72 } 67 }
73 68
74 - logTriggerMatchSuccess(message, trigger); 69 + IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
75 return true; 70 return true;
76 } 71 }
77 72
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 5 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
8 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 8 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 /** 11 /**
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Component; @@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
16 * @author HUIHUI 16 * @author HUIHUI
17 */ 17 */
18 @Component 18 @Component
19 -public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatcher { 19 +public class DevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerMatcher {
20 20
21 /** 21 /**
22 * 设备属性上报消息方法 22 * 设备属性上报消息方法
@@ -25,11 +25,6 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche @@ -25,11 +25,6 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
25 private static final String DEVICE_PROPERTY_POST_METHOD = IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod(); 25 private static final String DEVICE_PROPERTY_POST_METHOD = IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod();
26 26
27 @Override 27 @Override
28 - public MatcherTypeEnum getMatcherType() {  
29 - return MatcherTypeEnum.TRIGGER;  
30 - }  
31 -  
32 - @Override  
33 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { 28 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
34 return IotSceneRuleTriggerTypeEnum.DEVICE_PROPERTY_POST; 29 return IotSceneRuleTriggerTypeEnum.DEVICE_PROPERTY_POST;
35 } 30 }
@@ -37,43 +32,43 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche @@ -37,43 +32,43 @@ public class DevicePropertyPostTriggerMatcher extends AbstractIotSceneRuleMatche
37 @Override 32 @Override
38 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { 33 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
39 // 1. 基础参数校验 34 // 1. 基础参数校验
40 - if (!isBasicTriggerValid(trigger)) {  
41 - logTriggerMatchFailure(message, trigger, "触发器基础参数无效"); 35 + if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
  36 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
42 return false; 37 return false;
43 } 38 }
44 39
45 // 2. 检查消息方法是否匹配 40 // 2. 检查消息方法是否匹配
46 if (!DEVICE_PROPERTY_POST_METHOD.equals(message.getMethod())) { 41 if (!DEVICE_PROPERTY_POST_METHOD.equals(message.getMethod())) {
47 - logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_PROPERTY_POST_METHOD + ", 实际: " + message.getMethod()); 42 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_PROPERTY_POST_METHOD + ", 实际: " + message.getMethod());
48 return false; 43 return false;
49 } 44 }
50 45
51 // 3. 检查标识符是否匹配 46 // 3. 检查标识符是否匹配
52 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); 47 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
53 - if (!isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {  
54 - logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier); 48 + if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
  49 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
55 return false; 50 return false;
56 } 51 }
57 52
58 // 4. 检查操作符和值是否有效 53 // 4. 检查操作符和值是否有效
59 - if (!isTriggerOperatorAndValueValid(trigger)) {  
60 - logTriggerMatchFailure(message, trigger, "操作符或值无效"); 54 + if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) {
  55 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "操作符或值无效");
61 return false; 56 return false;
62 } 57 }
63 58
64 // 5. 获取属性值 59 // 5. 获取属性值
65 Object propertyValue = message.getData(); 60 Object propertyValue = message.getData();
66 if (propertyValue == null) { 61 if (propertyValue == null) {
67 - logTriggerMatchFailure(message, trigger, "消息中属性值为空"); 62 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息中属性值为空");
68 return false; 63 return false;
69 } 64 }
70 65
71 // 6. 使用条件评估器进行匹配 66 // 6. 使用条件评估器进行匹配
72 - boolean matched = evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue()); 67 + boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(propertyValue, trigger.getOperator(), trigger.getValue());
73 if (matched) { 68 if (matched) {
74 - logTriggerMatchSuccess(message, trigger); 69 + IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
75 } else { 70 } else {
76 - logTriggerMatchFailure(message, trigger, "属性值条件不匹配"); 71 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "属性值条件不匹配");
77 } 72 }
78 return matched; 73 return matched;
79 } 74 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; 5 import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils;
6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
8 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 8 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
9 import org.springframework.stereotype.Component; 9 import org.springframework.stereotype.Component;
10 10
11 /** 11 /**
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Component; @@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
16 * @author HUIHUI 16 * @author HUIHUI
17 */ 17 */
18 @Component 18 @Component
19 -public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatcher { 19 +public class DeviceServiceInvokeTriggerMatcher implements IotSceneRuleTriggerMatcher {
20 20
21 /** 21 /**
22 * 设备服务调用消息方法 22 * 设备服务调用消息方法
@@ -24,11 +24,6 @@ public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatch @@ -24,11 +24,6 @@ public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatch
24 private static final String DEVICE_SERVICE_INVOKE_METHOD = IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod(); 24 private static final String DEVICE_SERVICE_INVOKE_METHOD = IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod();
25 25
26 @Override 26 @Override
27 - public MatcherTypeEnum getMatcherType() {  
28 - return MatcherTypeEnum.TRIGGER;  
29 - }  
30 -  
31 - @Override  
32 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { 27 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
33 return IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE; 28 return IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE;
34 } 29 }
@@ -36,28 +31,28 @@ public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatch @@ -36,28 +31,28 @@ public class DeviceServiceInvokeTriggerMatcher extends AbstractIotSceneRuleMatch
36 @Override 31 @Override
37 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { 32 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
38 // 1. 基础参数校验 33 // 1. 基础参数校验
39 - if (!isBasicTriggerValid(trigger)) {  
40 - logTriggerMatchFailure(message, trigger, "触发器基础参数无效"); 34 + if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
  35 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
41 return false; 36 return false;
42 } 37 }
43 38
44 // 2. 检查消息方法是否匹配 39 // 2. 检查消息方法是否匹配
45 if (!DEVICE_SERVICE_INVOKE_METHOD.equals(message.getMethod())) { 40 if (!DEVICE_SERVICE_INVOKE_METHOD.equals(message.getMethod())) {
46 - logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_SERVICE_INVOKE_METHOD + ", 实际: " + message.getMethod()); 41 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_SERVICE_INVOKE_METHOD + ", 实际: " + message.getMethod());
47 return false; 42 return false;
48 } 43 }
49 44
50 // 3. 检查标识符是否匹配 45 // 3. 检查标识符是否匹配
51 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message); 46 String messageIdentifier = IotDeviceMessageUtils.getIdentifier(message);
52 - if (!isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {  
53 - logTriggerMatchFailure(message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier); 47 + if (!IotSceneRuleMatcherHelper.isIdentifierMatched(trigger.getIdentifier(), messageIdentifier)) {
  48 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "标识符不匹配,期望: " + trigger.getIdentifier() + ", 实际: " + messageIdentifier);
54 return false; 49 return false;
55 } 50 }
56 51
57 // 4. 对于服务调用触发器,通常只需要匹配服务标识符即可 52 // 4. 对于服务调用触发器,通常只需要匹配服务标识符即可
58 // 不需要检查操作符和值,因为服务调用本身就是触发条件 53 // 不需要检查操作符和值,因为服务调用本身就是触发条件
59 54
60 - logTriggerMatchSuccess(message, trigger); 55 + IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
61 return true; 56 return true;
62 } 57 }
63 58
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
7 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 7 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
9 9
10 /** 10 /**
@@ -15,7 +15,7 @@ import org.springframework.stereotype.Component; @@ -15,7 +15,7 @@ import org.springframework.stereotype.Component;
15 * @author HUIHUI 15 * @author HUIHUI
16 */ 16 */
17 @Component 17 @Component
18 -public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher { 18 +public class DeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMatcher {
19 19
20 // TODO @puhui999:是不是不用枚举哈; 20 // TODO @puhui999:是不是不用枚举哈;
21 /** 21 /**
@@ -24,11 +24,6 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher @@ -24,11 +24,6 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher
24 private static final String DEVICE_STATE_UPDATE_METHOD = IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod(); 24 private static final String DEVICE_STATE_UPDATE_METHOD = IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod();
25 25
26 @Override 26 @Override
27 - public MatcherTypeEnum getMatcherType() {  
28 - return MatcherTypeEnum.TRIGGER;  
29 - }  
30 -  
31 - @Override  
32 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { 27 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
33 return IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE; 28 return IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE;
34 } 29 }
@@ -36,36 +31,36 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher @@ -36,36 +31,36 @@ public class DeviceStateUpdateTriggerMatcher extends AbstractIotSceneRuleMatcher
36 @Override 31 @Override
37 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { 32 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
38 // 1. 基础参数校验 33 // 1. 基础参数校验
39 - if (!isBasicTriggerValid(trigger)) {  
40 - logTriggerMatchFailure(message, trigger, "触发器基础参数无效"); 34 + if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
  35 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
41 return false; 36 return false;
42 } 37 }
43 38
44 // 2. 检查消息方法是否匹配 39 // 2. 检查消息方法是否匹配
45 if (!DEVICE_STATE_UPDATE_METHOD.equals(message.getMethod())) { 40 if (!DEVICE_STATE_UPDATE_METHOD.equals(message.getMethod())) {
46 - logTriggerMatchFailure(message, trigger, "消息方法不匹配,期望: " + DEVICE_STATE_UPDATE_METHOD + ", 实际: " + message.getMethod()); 41 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息方法不匹配,期望: " + DEVICE_STATE_UPDATE_METHOD + ", 实际: " + message.getMethod());
47 return false; 42 return false;
48 } 43 }
49 44
50 // 3. 检查操作符和值是否有效 45 // 3. 检查操作符和值是否有效
51 - if (!isTriggerOperatorAndValueValid(trigger)) {  
52 - logTriggerMatchFailure(message, trigger, "操作符或值无效"); 46 + if (!IotSceneRuleMatcherHelper.isTriggerOperatorAndValueValid(trigger)) {
  47 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "操作符或值无效");
53 return false; 48 return false;
54 } 49 }
55 50
56 // 4. 获取设备状态值 51 // 4. 获取设备状态值
57 Object stateValue = message.getData(); 52 Object stateValue = message.getData();
58 if (stateValue == null) { 53 if (stateValue == null) {
59 - logTriggerMatchFailure(message, trigger, "消息中设备状态值为空"); 54 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "消息中设备状态值为空");
60 return false; 55 return false;
61 } 56 }
62 57
63 // 5. 使用条件评估器进行匹配 58 // 5. 使用条件评估器进行匹配
64 - boolean matched = evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue()); 59 + boolean matched = IotSceneRuleMatcherHelper.evaluateCondition(stateValue, trigger.getOperator(), trigger.getValue());
65 if (matched) { 60 if (matched) {
66 - logTriggerMatchSuccess(message, trigger); 61 + IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
67 } else { 62 } else {
68 - logTriggerMatchFailure(message, trigger, "状态值条件不匹配"); 63 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "状态值条件不匹配");
69 } 64 }
70 return matched; 65 return matched;
71 } 66 }
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger;
  2 +
  3 +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
  4 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
  5 +import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
  6 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
  7 +
  8 +/**
  9 + * IoT 场景规则触发器匹配器接口
  10 + * <p>
  11 + * 专门处理主触发条件的匹配逻辑,如设备消息类型、定时器等
  12 + * <p>
  13 + * 触发器匹配器负责判断设备消息是否满足场景规则的主触发条件,
  14 + * 是场景规则执行的第一道门槛
  15 + *
  16 + * @author HUIHUI
  17 + */
  18 +public interface IotSceneRuleTriggerMatcher extends IotSceneRuleMatcher {
  19 +
  20 + /**
  21 + * 获取支持的触发器类型
  22 + *
  23 + * @return 触发器类型枚举
  24 + */
  25 + IotSceneRuleTriggerTypeEnum getSupportedTriggerType();
  26 +
  27 + /**
  28 + * 检查触发器是否匹配消息
  29 + * <p>
  30 + * 判断设备消息是否满足指定的触发器条件
  31 + *
  32 + * @param message 设备消息
  33 + * @param trigger 触发器配置
  34 + * @return 是否匹配
  35 + */
  36 + boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger);
  37 +
  38 +}
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil; @@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO; 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum; 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
7 -import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.AbstractIotSceneRuleMatcher; 7 +import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcherHelper;
8 import org.springframework.stereotype.Component; 8 import org.springframework.stereotype.Component;
9 9
10 /** 10 /**
@@ -16,12 +16,7 @@ import org.springframework.stereotype.Component; @@ -16,12 +16,7 @@ import org.springframework.stereotype.Component;
16 * @author HUIHUI 16 * @author HUIHUI
17 */ 17 */
18 @Component 18 @Component
19 -public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {  
20 -  
21 - @Override  
22 - public MatcherTypeEnum getMatcherType() {  
23 - return MatcherTypeEnum.TRIGGER;  
24 - } 19 +public class TimerTriggerMatcher implements IotSceneRuleTriggerMatcher {
25 20
26 @Override 21 @Override
27 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() { 22 public IotSceneRuleTriggerTypeEnum getSupportedTriggerType() {
@@ -31,14 +26,14 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher { @@ -31,14 +26,14 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {
31 @Override 26 @Override
32 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) { 27 public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
33 // 1. 基础参数校验 28 // 1. 基础参数校验
34 - if (!isBasicTriggerValid(trigger)) {  
35 - logTriggerMatchFailure(message, trigger, "触发器基础参数无效"); 29 + if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
  30 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "触发器基础参数无效");
36 return false; 31 return false;
37 } 32 }
38 33
39 // 2. 检查 CRON 表达式是否存在 34 // 2. 检查 CRON 表达式是否存在
40 if (StrUtil.isBlank(trigger.getCronExpression())) { 35 if (StrUtil.isBlank(trigger.getCronExpression())) {
41 - logTriggerMatchFailure(message, trigger, "定时触发器缺少 CRON 表达式"); 36 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "定时触发器缺少 CRON 表达式");
42 return false; 37 return false;
43 } 38 }
44 39
@@ -47,11 +42,11 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher { @@ -47,11 +42,11 @@ public class TimerTriggerMatcher extends AbstractIotSceneRuleMatcher {
47 42
48 // 4. 可以添加 CRON 表达式格式验证 43 // 4. 可以添加 CRON 表达式格式验证
49 if (!isValidCronExpression(trigger.getCronExpression())) { 44 if (!isValidCronExpression(trigger.getCronExpression())) {
50 - logTriggerMatchFailure(message, trigger, "CRON 表达式格式无效: " + trigger.getCronExpression()); 45 + IotSceneRuleMatcherHelper.logTriggerMatchFailure(getMatcherName(), message, trigger, "CRON 表达式格式无效: " + trigger.getCronExpression());
51 return false; 46 return false;
52 } 47 }
53 48
54 - logTriggerMatchSuccess(message, trigger); 49 + IotSceneRuleMatcherHelper.logTriggerMatchSuccess(getMatcherName(), message, trigger);
55 return true; 50 return true;
56 } 51 }
57 52