Commit 97260b8efeedc2a8e51c534f3517463e92403e1a

Authored by YunaiV
1 parent 53c7ce22

feat:【IoT 物联网】新增告警恢复场景规则执行类 IotAlertRecoverSceneRuleAction

yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/alert/IotAlertRecordController.java
... ... @@ -18,6 +18,7 @@ import org.springframework.validation.annotation.Validated;
18 18 import org.springframework.web.bind.annotation.*;
19 19  
20 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +import static java.util.Collections.singleton;
21 22  
22 23 @Tag(name = "管理后台 - IoT 告警记录")
23 24 @RestController
... ... @@ -49,7 +50,7 @@ public class IotAlertRecordController {
49 50 @Operation(summary = "处理告警记录")
50 51 @PreAuthorize("@ss.hasPermission('iot:alert-record:process')")
51 52 public CommonResult<Boolean> processAlertRecord(@Valid @RequestBody IotAlertRecordProcessReqVO processReqVO) {
52   - alertRecordService.processAlertRecord(processReqVO);
  53 + alertRecordService.processAlertRecordList(singleton(processReqVO.getId()), processReqVO.getProcessRemark());
53 54 return success(true);
54 55 }
55 56  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/alert/IotAlertRecordDO.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 5 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
6 6 import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
7 8 import com.baomidou.mybatisplus.annotation.KeySequence;
8 9 import com.baomidou.mybatisplus.annotation.TableField;
9 10 import com.baomidou.mybatisplus.annotation.TableId;
... ... @@ -51,6 +52,12 @@ public class IotAlertRecordDO extends BaseDO {
51 52 * 字典 {@link cn.iocoder.yudao.module.iot.enums.DictTypeConstants#ALERT_LEVEL}
52 53 */
53 54 private Integer configLevel;
  55 + /**
  56 + * 场景规则编号
  57 + *
  58 + * 关联 {@link IotRuleSceneDO#getId()}
  59 + */
  60 + private Long sceneRuleId;
54 61  
55 62 /**
56 63 * 产品编号
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/alert/IotAlertRecordMapper.java
... ... @@ -5,8 +5,12 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO;
  8 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
10 14 /**
11 15 * IoT 告警记录 Mapper
12 16 *
... ... @@ -26,4 +30,17 @@ public interface IotAlertRecordMapper extends BaseMapperX&lt;IotAlertRecordDO&gt; {
26 30 .orderByDesc(IotAlertRecordDO::getId));
27 31 }
28 32  
  33 + default List<IotAlertRecordDO> selectListBySceneRuleId(Long sceneRuleId, Long deviceId, Boolean processStatus) {
  34 + return selectList(new LambdaQueryWrapperX<IotAlertRecordDO>()
  35 + .eq(IotAlertRecordDO::getSceneRuleId, sceneRuleId)
  36 + .eqIfPresent(IotAlertRecordDO::getDeviceId, deviceId)
  37 + .eqIfPresent(IotAlertRecordDO::getProcessStatus, processStatus)
  38 + .orderByDesc(IotAlertRecordDO::getId));
  39 + }
  40 +
  41 + default int updateList(Collection<Long> ids, IotAlertRecordDO updateObj) {
  42 + return update(updateObj, new LambdaUpdateWrapper<IotAlertRecordDO>()
  43 + .in(IotAlertRecordDO::getId, ids));
  44 + }
  45 +
29 46 }
30 47 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/alert/IotAlertRecordService.java
... ... @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.iot.service.alert;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordProcessReqVO;
6 5 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 6 import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
8 7 import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO;
  8 +import jakarta.validation.constraints.NotNull;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
9 12  
10 13 /**
11 14 * IoT 告警记录 Service 接口
... ... @@ -31,19 +34,32 @@ public interface IotAlertRecordService {
31 34 PageResult<IotAlertRecordDO> getAlertRecordPage(IotAlertRecordPageReqVO pageReqVO);
32 35  
33 36 /**
  37 + * 获得指定场景规则的告警记录列表
  38 + *
  39 + * @param sceneRuleId 场景规则编号
  40 + * @param deviceId 设备编号
  41 + * @param processStatus 处理状态,允许空
  42 + * @return 告警记录列表
  43 + */
  44 + List<IotAlertRecordDO> getAlertRecordListBySceneRuleId(@NotNull(message = "场景规则编号不能为空") Long sceneRuleId,
  45 + Long deviceId, Boolean processStatus);
  46 +
  47 + /**
34 48 * 处理告警记录
35 49 *
36   - * @param processReqVO 处理请求
  50 + * @param ids 告警记录编号
  51 + * @param remark 处理结果(备注)
37 52 */
38   - void processAlertRecord(IotAlertRecordProcessReqVO processReqVO);
  53 + void processAlertRecordList(Collection<Long> ids, String remark);
39 54  
40 55 /**
41   - * 创建告警记录
  56 + * 创建告警记录(包含场景规则编号)
42 57 *
43 58 * @param config 告警配置
  59 + * @param sceneRuleId 场景规则编号
44 60 * @param deviceMessage 设备消息,可为空
45 61 * @return 告警记录编号
46 62 */
47   - Long createAlertRecord(IotAlertConfigDO config, IotDeviceMessage deviceMessage);
  63 + Long createAlertRecord(IotAlertConfigDO config, Long sceneRuleId, IotDeviceMessage deviceMessage);
48 64  
49 65 }
50 66 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/alert/IotAlertRecordServiceImpl.java
1 1 package cn.iocoder.yudao.module.iot.service.alert;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO;
5   -import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordProcessReqVO;
6 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
8 8 import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO;
... ... @@ -13,8 +13,8 @@ import jakarta.annotation.Resource;
13 13 import org.springframework.stereotype.Service;
14 14 import org.springframework.validation.annotation.Validated;
15 15  
16   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
17   -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.ALERT_RECORD_NOT_EXISTS;
  16 +import java.util.Collection;
  17 +import java.util.List;
18 18  
19 19 /**
20 20 * IoT 告警记录 Service 实现类
... ... @@ -42,35 +42,35 @@ public class IotAlertRecordServiceImpl implements IotAlertRecordService {
42 42 }
43 43  
44 44 @Override
45   - public void processAlertRecord(IotAlertRecordProcessReqVO processReqVO) {
46   - // 校验告警记录是否存在
47   - IotAlertRecordDO alertRecord = alertRecordMapper.selectById(processReqVO.getId());
48   - if (alertRecord == null) {
49   - throw exception(ALERT_RECORD_NOT_EXISTS);
50   - }
  45 + public List<IotAlertRecordDO> getAlertRecordListBySceneRuleId(Long sceneRuleId, Long deviceId, Boolean processStatus) {
  46 + return alertRecordMapper.selectListBySceneRuleId(sceneRuleId, deviceId, processStatus);
  47 + }
51 48  
52   - // 更新处理状态和备注
53   - alertRecordMapper.updateById(IotAlertRecordDO.builder()
54   - .id(processReqVO.getId())
55   - .processStatus(true)
56   - .processRemark(processReqVO.getProcessRemark())
57   - .build());
  49 + @Override
  50 + public void processAlertRecordList(Collection<Long> ids, String processRemark) {
  51 + if (CollUtil.isEmpty(ids)) {
  52 + return;
  53 + }
  54 + // 批量更新告警记录的处理状态
  55 + alertRecordMapper.updateList(ids, IotAlertRecordDO.builder()
  56 + .processStatus(true).processRemark(processRemark).build());
58 57 }
59 58  
60 59 @Override
61   - public Long createAlertRecord(IotAlertConfigDO config, IotDeviceMessage message) {
  60 + public Long createAlertRecord(IotAlertConfigDO config, Long sceneRuleId, IotDeviceMessage message) {
62 61 // 构建告警记录
63 62 IotAlertRecordDO.IotAlertRecordDOBuilder builder = IotAlertRecordDO.builder()
64 63 .configId(config.getId()).configName(config.getName()).configLevel(config.getLevel())
65   - .processStatus(false);
  64 + .sceneRuleId(sceneRuleId).processStatus(false);
66 65 if (message != null) {
67 66 builder.deviceMessage(message);
68 67 // 填充设备信息
69 68 IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId());
70   - if (device!= null) {
  69 + if (device != null) {
71 70 builder.productId(device.getProductId()).deviceId(device.getId());
72 71 }
73 72 }
  73 +
74 74 // 插入记录
75 75 IotAlertRecordDO record = builder.build();
76 76 alertRecordMapper.insert(record);
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/action/IotAlertTriggerSceneRuleAction.java
... ... @@ -8,6 +8,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum;
9 9 import cn.iocoder.yudao.module.iot.service.alert.IotAlertConfigService;
10 10 import cn.iocoder.yudao.module.iot.service.alert.IotAlertRecordService;
  11 +import cn.iocoder.yudao.module.system.api.mail.MailSendApi;
  12 +import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
  13 +import cn.iocoder.yudao.module.system.api.sms.SmsSendApi;
11 14 import jakarta.annotation.Resource;
12 15 import org.springframework.stereotype.Component;
13 16  
... ... @@ -25,10 +28,16 @@ public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction {
25 28  
26 29 @Resource
27 30 private IotAlertConfigService alertConfigService;
28   -
29 31 @Resource
30 32 private IotAlertRecordService alertRecordService;
31 33  
  34 + @Resource
  35 + private SmsSendApi smsSendApi;
  36 + @Resource
  37 + private MailSendApi mailSendApi;
  38 + @Resource
  39 + private NotifyMessageSendApi notifyMessageSendApi;
  40 +
32 41 @Override
33 42 public void execute(@Nullable IotDeviceMessage message,
34 43 IotRuleSceneDO rule, IotRuleSceneDO.ActionConfig actionConfig) throws Exception {
... ... @@ -37,8 +46,19 @@ public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction {
37 46 if (CollUtil.isEmpty(alertConfigs)) {
38 47 return;
39 48 }
40   - alertConfigs.forEach(alertConfig ->
41   - alertRecordService.createAlertRecord(alertConfig, message));
  49 + alertConfigs.forEach(alertConfig -> {
  50 + // 记录告警记录,传递场景规则ID
  51 + alertRecordService.createAlertRecord(alertConfig, rule.getId(), message);
  52 + // 发送告警消息
  53 + sendAlertMessage(alertConfig, message);
  54 + });
  55 + }
  56 +
  57 + private void sendAlertMessage(IotAlertConfigDO config, IotDeviceMessage deviceMessage) {
  58 + // TODO @芋艿:等场景联动开发完,再实现
  59 + // TODO @芋艿:短信
  60 + // TODO @芋艿:邮箱
  61 + // TODO @芋艿:站内信
42 62 }
43 63  
44 64 @Override
... ...