Commit e639dbfeb7bc8963fd34014e40138383ae63a3a6

Authored by YunaiV
1 parent 67a44fd3

review:【iot 物联网】场景联动

Showing 19 changed files with 71 additions and 123 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleTriggerTypeEnum.java
... ... @@ -19,7 +19,6 @@ import java.util.Arrays;
19 19 @Getter
20 20 public enum IotSceneRuleTriggerTypeEnum implements ArrayValuable<Integer> {
21 21  
22   - // TODO @芋艿:后续“对应”部分,要 @下,等包结构梳理完;
23 22 /**
24 23 * 设备上下线变更
25 24 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java
... ... @@ -84,13 +84,14 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
84 84  
85 85 @Override
86 86 public void updateSceneRuleStatus(Long id, Integer status) {
87   - // 校验存在
  87 + // 1. 校验存在
88 88 validateSceneRuleExists(id);
89   - // 更新状态
  89 +
  90 + // 2. 更新状态
90 91 IotSceneRuleDO updateObj = new IotSceneRuleDO().setId(id).setStatus(status);
91 92 sceneRuleMapper.updateById(updateObj);
92 93  
93   - // 根据状态管理定时触发器
  94 + // 3. 根据状态管理定时触发器
94 95 if (CommonStatusEnum.isEnable(status)) {
95 96 // 启用时,获取完整的场景规则信息并注册定时触发器
96 97 IotSceneRuleDO sceneRule = sceneRuleMapper.selectById(id);
... ... @@ -105,12 +106,14 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
105 106  
106 107 @Override
107 108 public void deleteSceneRule(Long id) {
108   - // 校验存在
  109 + // 1. 校验存在
109 110 validateSceneRuleExists(id);
110   - // 删除定时触发器
111   - timerHandler.unregisterTimerTriggers(id);
112   - // 删除
  111 +
  112 + // 2. 删除
113 113 sceneRuleMapper.deleteById(id);
  114 +
  115 + // 3. 删除定时触发器
  116 + timerHandler.unregisterTimerTriggers(id);
114 117 }
115 118  
116 119 private void validateSceneRuleExists(Long id) {
... ... @@ -146,16 +149,17 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
146 149 return sceneRuleMapper.selectListByStatus(status);
147 150 }
148 151  
149   - // TODO 芋艿,缓存待实现 @puhui999
  152 + // TODO @puhui999:缓存待实现
150 153 @Override
151 154 @TenantIgnore // 忽略租户隔离:因为 IotSceneRuleMessageHandler 调用时,一般未传递租户,所以需要忽略
152 155 public List<IotSceneRuleDO> getSceneRuleListByProductIdAndDeviceIdFromCache(Long productId, Long deviceId) {
  156 + // 1. 查询启用状态的规则场景
  157 + // TODO @puhui999:这里查询 enable 的;
153 158 List<IotSceneRuleDO> list = sceneRuleMapper.selectList();
154   - // 只返回启用状态的规则场景
155 159 List<IotSceneRuleDO> enabledList = filterList(list,
156 160 sceneRule -> CommonStatusEnum.isEnable(sceneRule.getStatus()));
157 161  
158   - // 根据 productKey 和 deviceName 进行匹配
  162 + // 2. 根据 productKey 和 deviceName 进行匹配
159 163 return filterList(enabledList, sceneRule -> {
160 164 if (CollUtil.isEmpty(sceneRule.getTriggers())) {
161 165 return false;
... ... @@ -164,21 +168,19 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
164 168 for (IotSceneRuleDO.Trigger trigger : sceneRule.getTriggers()) {
165 169 // 检查触发器是否匹配指定的产品和设备
166 170 try {
167   - // 1. 检查产品是否匹配
168   - if (trigger.getProductId() == null) {
169   - return false;
170   - }
171   - if (trigger.getDeviceId() == null) {
  171 + // 检查产品是否匹配
  172 + if (trigger.getProductId() == null || trigger.getDeviceId() == null) {
172 173 return false;
173 174 }
174 175 // 检查是否是全部设备的特殊标识
175 176 if (IotDeviceDO.DEVICE_ID_ALL.equals(trigger.getDeviceId())) {
176   - return true; // 匹配所有设备
  177 + return true;
177 178 }
178 179 // 检查具体设备 ID 是否匹配
179 180 return ObjUtil.equal(productId, trigger.getProductId()) && ObjUtil.equal(deviceId, trigger.getDeviceId());
180 181 } catch (Exception e) {
181   - log.warn("[isMatchProductAndDevice][产品({}) 设备({}) 匹配触发器异常]", productId, deviceId, e);
  182 + log.warn("[getSceneRuleListByProductIdAndDeviceIdFromCache][产品({}) 设备({}) 匹配触发器异常]",
  183 + productId, deviceId, e);
182 184 return false;
183 185 }
184 186 }
... ... @@ -188,7 +190,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
188 190  
189 191 @Override
190 192 public void executeSceneRuleByDevice(IotDeviceMessage message) {
191   - // TODO @芋艿:这里的 tenantId,通过设备获取;@puhui999:
  193 + // TODO @puhui999:这里的 tenantId,通过设备获取;
192 194 TenantUtils.execute(message.getTenantId(), () -> {
193 195 // 1. 获得设备匹配的规则场景
194 196 List<IotSceneRuleDO> sceneRules = getMatchedSceneRuleListByMessage(message);
... ... @@ -234,7 +236,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
234 236 */
235 237 private List<IotSceneRuleDO> getMatchedSceneRuleListByMessage(IotDeviceMessage message) {
236 238 // 1. 匹配设备
237   - // TODO @芋艿:可能需要 getSelf(); 缓存 @puhui999;
  239 + // TODO 缓存 @puhui999:可能需要 getSelf()
238 240 // 1.1 通过 deviceId 获取设备信息
239 241 IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId());
240 242 if (device == null) {
... ... @@ -293,7 +295,6 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
293 295 */
294 296 private boolean matchSingleTrigger(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, IotSceneRuleDO sceneRule) {
295 297 try {
296   - // 2. 检查触发器的条件分组
297 298 return sceneRuleMatcherManager.isMatched(message, trigger) && isTriggerConditionGroupsMatched(message, trigger, sceneRule);
298 299 } catch (Exception e) {
299 300 log.error("[matchSingleTrigger][触发器匹配异常] sceneRuleId: {}, triggerType: {}, message: {}",
... ... @@ -310,18 +311,19 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
310 311 * @param sceneRule 场景规则(用于日志)
311 312 * @return 是否匹配
312 313 */
313   - private boolean isTriggerConditionGroupsMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, IotSceneRuleDO sceneRule) {
314   - // 如果没有条件分组,则认为匹配成功(只依赖基础触发器匹配)
  314 + private boolean isTriggerConditionGroupsMatched(IotDeviceMessage message,
  315 + IotSceneRuleDO.Trigger trigger,
  316 + IotSceneRuleDO sceneRule) {
  317 + // 1. 如果没有条件分组,则认为匹配成功(只依赖基础触发器匹配)
315 318 if (CollUtil.isEmpty(trigger.getConditionGroups())) {
316 319 return true;
317 320 }
318 321  
319   - // 检查条件分组:分组与分组之间是"或"的关系,条件与条件之间是"且"的关系
  322 + // 2. 检查条件分组:分组与分组之间是"或"的关系,条件与条件之间是"且"的关系
320 323 for (List<IotSceneRuleDO.TriggerCondition> conditionGroup : trigger.getConditionGroups()) {
321 324 if (CollUtil.isEmpty(conditionGroup)) {
322 325 continue;
323 326 }
324   -
325 327 // 检查当前分组中的所有条件是否都匹配(且关系)
326 328 boolean allConditionsMatched = true;
327 329 for (IotSceneRuleDO.TriggerCondition condition : conditionGroup) {
... ... @@ -330,14 +332,13 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
330 332 break;
331 333 }
332 334 }
333   -
334 335 // 如果当前分组的所有条件都匹配,则整个触发器匹配成功
335 336 if (allConditionsMatched) {
336 337 return true;
337 338 }
338 339 }
339 340  
340   - // 所有分组都不匹配
  341 + // 3. 所有分组都不匹配
341 342 return false;
342 343 }
343 344  
... ... @@ -372,13 +373,13 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
372 373 sceneRules.forEach(sceneRule -> {
373 374 // 2. 遍历规则场景的动作
374 375 sceneRule.getActions().forEach(actionConfig -> {
375   - // 3.1 获取对应的动作 Action 数组
  376 + // 2.1 获取对应的动作 Action 数组
376 377 List<IotSceneRuleAction> actions = filterList(sceneRuleActions,
377 378 action -> action.getType().getType().equals(actionConfig.getType()));
378 379 if (CollUtil.isEmpty(actions)) {
379 380 return;
380 381 }
381   - // 3.2 执行动作
  382 + // 2.2 执行动作
382 383 actions.forEach(action -> {
383 384 try {
384 385 action.execute(message, sceneRule, actionConfig);
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotAlertRecoverSceneRuleAction.java
... ... @@ -14,7 +14,6 @@ import java.util.List;
14 14  
15 15 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
16 16  
17   -// TODO @puhui999、@芋艿:未测试;需要场景联动开发完
18 17 /**
19 18 * IoT 告警恢复的 {@link IotSceneRuleAction} 实现类
20 19 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotAlertTriggerSceneRuleAction.java
... ... @@ -17,7 +17,6 @@ import org.springframework.stereotype.Component;
17 17 import javax.annotation.Nullable;
18 18 import java.util.List;
19 19  
20   -// TODO @puhui999、@芋艿:未测试;需要场景联动开发完
21 20 /**
22 21 * IoT 告警触发的 {@link IotSceneRuleAction} 实现类
23 22 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcher.java
... ... @@ -4,10 +4,8 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.condition.IotScene
4 4 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.trigger.IotSceneRuleTriggerMatcher;
5 5  
6 6 /**
7   - * IoT 场景规则匹配器基础接口
8   - * <p>
9   - * 定义所有匹配器的通用行为,包括优先级、名称和启用状态
10   - * <p>
  7 + * IoT 场景规则匹配器基础接口:定义所有匹配器的通用行为,包括优先级、名称和启用状态
  8 + *
11 9 * - {@link IotSceneRuleTriggerMatcher} 触发器匹配器
12 10 * - {@link IotSceneRuleConditionMatcher} 条件匹配器
13 11 *
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherHelper.java
... ... @@ -18,10 +18,8 @@ import java.util.Map;
18 18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
19 19  
20 20 /**
21   - * IoT 场景规则匹配器工具类
22   - * <p>
23   - * 提供通用的条件评估逻辑和工具方法,供触发器和条件匹配器使用
24   - * <p>
  21 + * IoT 场景规则匹配器工具类:提供通用的条件评估逻辑和工具方法,供触发器和条件匹配器使用
  22 + *
25 23 * 该类包含了匹配器实现中常用的工具方法,如条件评估、参数校验、日志记录等
26 24 *
27 25 * @author HUIHUI
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
... ... @@ -16,9 +16,7 @@ import java.util.function.Function;
16 16 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
17 17  
18 18 /**
19   - * IoT 场景规则匹配器统一管理器
20   - * <p>
21   - * 负责管理所有匹配器(触发器匹配器和条件匹配器),并提供统一的匹配入口
  19 + * IoT 场景规则匹配器统一管理器:负责管理所有匹配器(触发器匹配器和条件匹配器),并提供统一的匹配入口
22 20 *
23 21 * @author HUIHUI
24 22 */
... ... @@ -44,13 +42,12 @@ public class IotSceneRuleMatcherManager {
44 42 return;
45 43 }
46 44  
47   - // 按优先级排序并过滤启用的匹配器
  45 + // 1.1 按优先级排序并过滤启用的匹配器
48 46 List<IotSceneRuleMatcher> allMatchers = matchers.stream()
49 47 .filter(IotSceneRuleMatcher::isEnabled)
50 48 .sorted(Comparator.comparing(IotSceneRuleMatcher::getPriority))
51 49 .toList();
52   -
53   - // 分离触发器匹配器和条件匹配器
  50 + // 1.2 分离触发器匹配器和条件匹配器
54 51 List<IotSceneRuleTriggerMatcher> triggerMatchers = allMatchers.stream()
55 52 .filter(matcher -> matcher instanceof IotSceneRuleTriggerMatcher)
56 53 .map(matcher -> (IotSceneRuleTriggerMatcher) matcher)
... ... @@ -60,7 +57,7 @@ public class IotSceneRuleMatcherManager {
60 57 .map(matcher -> (IotSceneRuleConditionMatcher) matcher)
61 58 .toList();
62 59  
63   - // 构建触发器匹配器映射表
  60 + // 2.1 构建触发器匹配器映射表
64 61 this.triggerMatchers = convertMap(triggerMatchers, IotSceneRuleTriggerMatcher::getSupportedTriggerType,
65 62 Function.identity(),
66 63 (existing, replacement) -> {
... ... @@ -70,7 +67,7 @@ public class IotSceneRuleMatcherManager {
70 67 existing.getSupportedTriggerType() : replacement.getSupportedTriggerType());
71 68 return existing.getPriority() <= replacement.getPriority() ? existing : replacement;
72 69 }, LinkedHashMap::new);
73   - // 构建条件匹配器映射表
  70 + // 2.2 构建条件匹配器映射表
74 71 this.conditionMatchers = convertMap(conditionMatchers, IotSceneRuleConditionMatcher::getSupportedConditionType,
75 72 Function.identity(),
76 73 (existing, replacement) -> {
... ... @@ -82,7 +79,7 @@ public class IotSceneRuleMatcherManager {
82 79 },
83 80 LinkedHashMap::new);
84 81  
85   - // 日志输出初始化信息
  82 + // 3. 日志输出初始化信息
86 83 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载({})个匹配器,其中触发器匹配器({})个,条件匹配器({})个]",
87 84 allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size());
88 85 this.triggerMatchers.forEach((type, matcher) ->
... ... @@ -135,7 +132,7 @@ public class IotSceneRuleMatcherManager {
135 132 return false;
136 133 }
137 134  
138   - // 根据条件类型查找对应的匹配器
  135 + // 1. 根据条件类型查找对应的匹配器
139 136 IotSceneRuleConditionTypeEnum conditionType = IotSceneRuleConditionTypeEnum.typeOf(condition.getType());
140 137 if (conditionType == null) {
141 138 log.warn("[isConditionMatched][conditionType({}) 未知的条件类型]", condition.getType());
... ... @@ -147,7 +144,7 @@ public class IotSceneRuleMatcherManager {
147 144 return false;
148 145 }
149 146  
150   - // 执行匹配逻辑
  147 + // 2. 执行匹配逻辑
151 148 try {
152 149 return matcher.matches(message, condition);
153 150 } catch (Exception e) {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/CurrentTimeConditionMatcher.java
... ... @@ -16,10 +16,9 @@ import java.time.LocalTime;
16 16 import java.time.format.DateTimeFormatter;
17 17 import java.util.List;
18 18  
  19 +// TODO @puhui999:是不是 IoT 的前缀,都加下哈;
19 20 /**
20   - * 当前时间条件匹配器
21   - * <p>
22   - * 处理时间相关的子条件匹配逻辑
  21 + * 当前时间条件匹配器:处理时间相关的子条件匹配逻辑
23 22 *
24 23 * @author HUIHUI
25 24 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DevicePropertyConditionMatcher.java
... ... @@ -10,9 +10,7 @@ import org.springframework.stereotype.Component;
10 10  
11 11  
12 12 /**
13   - * 设备属性条件匹配器
14   - * <p>
15   - * 处理设备属性相关的子条件匹配逻辑
  13 + * 设备属性条件匹配器:处理设备属性相关的子条件匹配逻辑
16 14 *
17 15 * @author HUIHUI
18 16 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DeviceStateConditionMatcher.java
... ... @@ -8,9 +8,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
8 8 import org.springframework.stereotype.Component;
9 9  
10 10 /**
11   - * 设备状态条件匹配器
12   - * <p>
13   - * 处理设备状态相关的子条件匹配逻辑
  11 + * 设备状态条件匹配器:处理设备状态相关的子条件匹配逻辑
14 12 *
15 13 * @author HUIHUI
16 14 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotSceneRuleConditionMatcher.java
... ... @@ -6,12 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
6 6 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
7 7  
8 8 /**
9   - * IoT 场景规则条件匹配器接口
10   - * <p>
11   - * 专门处理子条件的匹配逻辑,如设备状态、属性值、时间条件等
12   - * <p>
13   - * 条件匹配器负责判断设备消息是否满足场景规则的附加条件,
14   - * 在触发器匹配成功后进行进一步的条件筛选
  9 + * IoT 场景规则条件匹配器接口:专门处理子条件的匹配逻辑,如设备状态、属性值、时间条件等
  10 + *
  11 + * 条件匹配器负责判断设备消息是否满足场景规则的附加条件,在触发器匹配成功后进行进一步的条件筛选
15 12 *
16 13 * @author HUIHUI
17 14 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
... ... @@ -10,9 +10,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
10 10 import org.springframework.stereotype.Component;
11 11  
12 12 /**
13   - * 设备事件上报触发器匹配器
14   - * <p>
15   - * 处理设备事件上报的触发器匹配逻辑
  13 + * 设备事件上报触发器匹配器:处理设备事件上报的触发器匹配逻辑
16 14 *
17 15 * @author HUIHUI
18 16 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
... ... @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
9 9 import org.springframework.stereotype.Component;
10 10  
11 11 /**
12   - * 设备属性上报触发器匹配器
13   - * <p>
14   - * 处理设备属性数据上报的触发器匹配逻辑
  12 + * 设备属性上报触发器匹配器:处理设备属性数据上报的触发器匹配逻辑
15 13 *
16 14 * @author HUIHUI
17 15 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
... ... @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
9 9 import org.springframework.stereotype.Component;
10 10  
11 11 /**
12   - * 设备服务调用触发器匹配器
13   - * <p>
14   - * 处理设备服务调用的触发器匹配逻辑
  12 + * 设备服务调用触发器匹配器:处理设备服务调用的触发器匹配逻辑
15 13 *
16 14 * @author HUIHUI
17 15 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
... ... @@ -9,9 +9,7 @@ import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatche
9 9 import org.springframework.stereotype.Component;
10 10  
11 11 /**
12   - * 设备状态更新触发器匹配器
13   - * <p>
14   - * 处理设备上下线状态变更的触发器匹配逻辑
  12 + * 设备状态更新触发器匹配器:处理设备上下线状态变更的触发器匹配逻辑
15 13 *
16 14 * @author HUIHUI
17 15 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java
... ... @@ -6,12 +6,9 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
6 6 import cn.iocoder.yudao.module.iot.service.rule.scene.matcher.IotSceneRuleMatcher;
7 7  
8 8 /**
9   - * IoT 场景规则触发器匹配器接口
10   - * <p>
11   - * 专门处理主触发条件的匹配逻辑,如设备消息类型、定时器等
12   - * <p>
13   - * 触发器匹配器负责判断设备消息是否满足场景规则的主触发条件,
14   - * 是场景规则执行的第一道门槛
  9 + * IoT 场景规则触发器匹配器接口:专门处理主触发条件的匹配逻辑,如设备消息类型、定时器等
  10 + *
  11 + * 触发器匹配器负责判断设备消息是否满足场景规则的主触发条件,是场景规则执行的第一道门槛
15 12 *
16 13 * @author HUIHUI
17 14 */
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
... ... @@ -9,9 +9,8 @@ import org.quartz.CronExpression;
9 9 import org.springframework.stereotype.Component;
10 10  
11 11 /**
12   - * 定时触发器匹配器
13   - * <p>
14   - * 处理定时触发的触发器匹配逻辑
  12 + * 定时触发器匹配器:处理定时触发的触发器匹配逻辑
  13 + *
15 14 * 注意:定时触发器不依赖设备消息,主要用于定时任务场景
16 15 *
17 16 * @author HUIHUI
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/timer/IotSceneRuleTimerHandler.java
... ... @@ -18,9 +18,7 @@ import java.util.List;
18 18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
19 19  
20 20 /**
21   - * IoT 场景规则定时触发器处理器
22   - * <p>
23   - * 负责管理定时触发器的注册、更新、删除等操作
  21 + * IoT 场景规则定时触发器处理器:负责管理定时触发器的注册、更新、删除等操作
24 22 *
25 23 * @author HUIHUI
26 24 */
... ... @@ -37,19 +35,17 @@ public class IotSceneRuleTimerHandler {
37 35 * @param sceneRule 场景规则
38 36 */
39 37 public void registerTimerTriggers(IotSceneRuleDO sceneRule) {
  38 + // 1. 过滤出定时触发器
40 39 if (sceneRule == null || CollUtil.isEmpty(sceneRule.getTriggers())) {
41 40 return;
42 41 }
43   -
44   - // 过滤出定时触发器
45 42 List<IotSceneRuleDO.Trigger> timerTriggers = filterList(sceneRule.getTriggers(),
46 43 trigger -> ObjUtil.equals(trigger.getType(), IotSceneRuleTriggerTypeEnum.TIMER.getType()));
47   -
48 44 if (CollUtil.isEmpty(timerTriggers)) {
49 45 return;
50 46 }
51 47  
52   - // 注册每个定时触发器
  48 + // 2. 注册每个定时触发器
53 49 timerTriggers.forEach(trigger -> registerSingleTimerTrigger(sceneRule, trigger));
54 50 }
55 51  
... ... @@ -63,23 +59,23 @@ public class IotSceneRuleTimerHandler {
63 59 return;
64 60 }
65 61  
66   - // 先删除旧的定时任务
  62 + // 1. 先删除旧的定时任务
67 63 unregisterTimerTriggers(sceneRule.getId());
68 64  
69   - // 如果场景规则已禁用,则不重新注册
  65 + // 2.1 如果场景规则已禁用,则不重新注册
70 66 if (CommonStatusEnum.isDisable(sceneRule.getStatus())) {
71 67 log.info("[updateTimerTriggers][场景规则({}) 已禁用,不注册定时触发器]", sceneRule.getId());
72 68 return;
73 69 }
74 70  
75   - // 重新注册定时触发器
  71 + // 2.2 重新注册定时触发器
76 72 registerTimerTriggers(sceneRule);
77 73 }
78 74  
79 75 /**
80 76 * 注销场景规则的定时触发器
81 77 *
82   - * @param sceneRuleId 场景规则ID
  78 + * @param sceneRuleId 场景规则 ID
83 79 */
84 80 public void unregisterTimerTriggers(Long sceneRuleId) {
85 81 if (sceneRuleId == null) {
... ... @@ -98,7 +94,7 @@ public class IotSceneRuleTimerHandler {
98 94 /**
99 95 * 暂停场景规则的定时触发器
100 96 *
101   - * @param sceneRuleId 场景规则ID
  97 + * @param sceneRuleId 场景规则 ID
102 98 */
103 99 public void pauseTimerTriggers(Long sceneRuleId) {
104 100 if (sceneRuleId == null) {
... ... @@ -115,25 +111,6 @@ public class IotSceneRuleTimerHandler {
115 111 }
116 112  
117 113 /**
118   - * 恢复场景规则的定时触发器
119   - *
120   - * @param sceneRuleId 场景规则ID
121   - */
122   - public void resumeTimerTriggers(Long sceneRuleId) {
123   - if (sceneRuleId == null) {
124   - return;
125   - }
126   -
127   - String jobName = buildJobName(sceneRuleId);
128   - try {
129   - schedulerManager.resumeJob(jobName);
130   - log.info("[resumeTimerTriggers][场景规则({}) 定时触发器恢复成功]", sceneRuleId);
131   - } catch (SchedulerException e) {
132   - log.error("[resumeTimerTriggers][场景规则({}) 定时触发器恢复失败]", sceneRuleId, e);
133   - }
134   - }
135   -
136   - /**
137 114 * 注册单个定时触发器
138 115 *
139 116 * @param sceneRule 场景规则
... ... @@ -146,18 +123,16 @@ public class IotSceneRuleTimerHandler {
146 123 return;
147 124 }
148 125  
149   - // 2. 构建任务名称和数据
150   - String jobName = buildJobName(sceneRule.getId());
151   -
152 126 try {
153   - // 3. 注册定时任务
  127 + // 2.1 构建任务名称和数据
  128 + String jobName = buildJobName(sceneRule.getId());
  129 + // 2.2 注册定时任务
154 130 schedulerManager.addOrUpdateJob(
155 131 IotSceneRuleJob.class,
156 132 jobName,
157 133 trigger.getCronExpression(),
158 134 IotSceneRuleJob.buildJobDataMap(sceneRule.getId())
159 135 );
160   -
161 136 log.info("[registerSingleTimerTrigger][场景规则({}) 定时触发器注册成功,CRON: {}]",
162 137 sceneRule.getId(), trigger.getCronExpression());
163 138 } catch (SchedulerException e) {
... ... @@ -169,10 +144,11 @@ public class IotSceneRuleTimerHandler {
169 144 /**
170 145 * 构建任务名称
171 146 *
172   - * @param sceneRuleId 场景规则ID
  147 + * @param sceneRuleId 场景规则 ID
173 148 * @return 任务名称
174 149 */
175 150 private String buildJobName(Long sceneRuleId) {
176 151 return "iot_scene_rule_timer_" + sceneRuleId;
177 152 }
  153 +
178 154 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/BaseMatcherTest.java
... ... @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Bean;
6 6 import org.springframework.context.annotation.Configuration;
7 7 import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
8 8  
  9 +// TODO @puhui999:建议改成 IotBaseConditionMatcherTest
9 10 /**
10 11 * Matcher 测试基类
11 12 * 提供通用的 Spring 测试配置
... ...