Commit 97260b8efeedc2a8e51c534f3517463e92403e1a
1 parent
53c7ce22
feat:【IoT 物联网】新增告警恢复场景规则执行类 IotAlertRecoverSceneRuleAction
Showing
6 changed files
with
88 additions
and
27 deletions
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,6 +18,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 18 | import org.springframework.web.bind.annotation.*; | 18 | import org.springframework.web.bind.annotation.*; |
| 19 | 19 | ||
| 20 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 20 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 21 | +import static java.util.Collections.singleton; | ||
| 21 | 22 | ||
| 22 | @Tag(name = "管理后台 - IoT 告警记录") | 23 | @Tag(name = "管理后台 - IoT 告警记录") |
| 23 | @RestController | 24 | @RestController |
| @@ -49,7 +50,7 @@ public class IotAlertRecordController { | @@ -49,7 +50,7 @@ public class IotAlertRecordController { | ||
| 49 | @Operation(summary = "处理告警记录") | 50 | @Operation(summary = "处理告警记录") |
| 50 | @PreAuthorize("@ss.hasPermission('iot:alert-record:process')") | 51 | @PreAuthorize("@ss.hasPermission('iot:alert-record:process')") |
| 51 | public CommonResult<Boolean> processAlertRecord(@Valid @RequestBody IotAlertRecordProcessReqVO processReqVO) { | 52 | public CommonResult<Boolean> processAlertRecord(@Valid @RequestBody IotAlertRecordProcessReqVO processReqVO) { |
| 52 | - alertRecordService.processAlertRecord(processReqVO); | 53 | + alertRecordService.processAlertRecordList(singleton(processReqVO.getId()), processReqVO.getProcessRemark()); |
| 53 | return success(true); | 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,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 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.device.IotDeviceDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 7 | +import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | ||
| 7 | import com.baomidou.mybatisplus.annotation.KeySequence; | 8 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 8 | import com.baomidou.mybatisplus.annotation.TableField; | 9 | import com.baomidou.mybatisplus.annotation.TableField; |
| 9 | import com.baomidou.mybatisplus.annotation.TableId; | 10 | import com.baomidou.mybatisplus.annotation.TableId; |
| @@ -51,6 +52,12 @@ public class IotAlertRecordDO extends BaseDO { | @@ -51,6 +52,12 @@ public class IotAlertRecordDO extends BaseDO { | ||
| 51 | * 字典 {@link cn.iocoder.yudao.module.iot.enums.DictTypeConstants#ALERT_LEVEL} | 52 | * 字典 {@link cn.iocoder.yudao.module.iot.enums.DictTypeConstants#ALERT_LEVEL} |
| 52 | */ | 53 | */ |
| 53 | private Integer configLevel; | 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,8 +5,12 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO; | 6 | import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO; |
| 8 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 8 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 10 | ||
| 11 | +import java.util.Collection; | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 10 | /** | 14 | /** |
| 11 | * IoT 告警记录 Mapper | 15 | * IoT 告警记录 Mapper |
| 12 | * | 16 | * |
| @@ -26,4 +30,17 @@ public interface IotAlertRecordMapper extends BaseMapperX<IotAlertRecordDO> { | @@ -26,4 +30,17 @@ public interface IotAlertRecordMapper extends BaseMapperX<IotAlertRecordDO> { | ||
| 26 | .orderByDesc(IotAlertRecordDO::getId)); | 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 | \ No newline at end of file | 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,10 +2,13 @@ package cn.iocoder.yudao.module.iot.service.alert; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordPageReqVO; | 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 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 5 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO; | 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 | * IoT 告警记录 Service 接口 | 14 | * IoT 告警记录 Service 接口 |
| @@ -31,19 +34,32 @@ public interface IotAlertRecordService { | @@ -31,19 +34,32 @@ public interface IotAlertRecordService { | ||
| 31 | PageResult<IotAlertRecordDO> getAlertRecordPage(IotAlertRecordPageReqVO pageReqVO); | 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 | * @param config 告警配置 | 58 | * @param config 告警配置 |
| 59 | + * @param sceneRuleId 场景规则编号 | ||
| 44 | * @param deviceMessage 设备消息,可为空 | 60 | * @param deviceMessage 设备消息,可为空 |
| 45 | * @return 告警记录编号 | 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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.iot.service.alert; | 1 | package cn.iocoder.yudao.module.iot.service.alert; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 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.IotAlertRecordPageReqVO; |
| 5 | -import cn.iocoder.yudao.module.iot.controller.admin.alert.vo.recrod.IotAlertRecordProcessReqVO; | ||
| 6 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 6 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO; |
| 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertRecordDO; |
| @@ -13,8 +13,8 @@ import jakarta.annotation.Resource; | @@ -13,8 +13,8 @@ import jakarta.annotation.Resource; | ||
| 13 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| 14 | import org.springframework.validation.annotation.Validated; | 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 | * IoT 告警记录 Service 实现类 | 20 | * IoT 告警记录 Service 实现类 |
| @@ -42,35 +42,35 @@ public class IotAlertRecordServiceImpl implements IotAlertRecordService { | @@ -42,35 +42,35 @@ public class IotAlertRecordServiceImpl implements IotAlertRecordService { | ||
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | @Override | 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 | @Override | 59 | @Override |
| 61 | - public Long createAlertRecord(IotAlertConfigDO config, IotDeviceMessage message) { | 60 | + public Long createAlertRecord(IotAlertConfigDO config, Long sceneRuleId, IotDeviceMessage message) { |
| 62 | // 构建告警记录 | 61 | // 构建告警记录 |
| 63 | IotAlertRecordDO.IotAlertRecordDOBuilder builder = IotAlertRecordDO.builder() | 62 | IotAlertRecordDO.IotAlertRecordDOBuilder builder = IotAlertRecordDO.builder() |
| 64 | .configId(config.getId()).configName(config.getName()).configLevel(config.getLevel()) | 63 | .configId(config.getId()).configName(config.getName()).configLevel(config.getLevel()) |
| 65 | - .processStatus(false); | 64 | + .sceneRuleId(sceneRuleId).processStatus(false); |
| 66 | if (message != null) { | 65 | if (message != null) { |
| 67 | builder.deviceMessage(message); | 66 | builder.deviceMessage(message); |
| 68 | // 填充设备信息 | 67 | // 填充设备信息 |
| 69 | IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId()); | 68 | IotDeviceDO device = deviceService.getDeviceFromCache(message.getDeviceId()); |
| 70 | - if (device!= null) { | 69 | + if (device != null) { |
| 71 | builder.productId(device.getProductId()).deviceId(device.getId()); | 70 | builder.productId(device.getProductId()).deviceId(device.getId()); |
| 72 | } | 71 | } |
| 73 | } | 72 | } |
| 73 | + | ||
| 74 | // 插入记录 | 74 | // 插入记录 |
| 75 | IotAlertRecordDO record = builder.build(); | 75 | IotAlertRecordDO record = builder.build(); |
| 76 | alertRecordMapper.insert(record); | 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,6 +8,9 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | ||
| 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 9 | import cn.iocoder.yudao.module.iot.service.alert.IotAlertConfigService; | 9 | import cn.iocoder.yudao.module.iot.service.alert.IotAlertConfigService; |
| 10 | import cn.iocoder.yudao.module.iot.service.alert.IotAlertRecordService; | 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 | import jakarta.annotation.Resource; | 14 | import jakarta.annotation.Resource; |
| 12 | import org.springframework.stereotype.Component; | 15 | import org.springframework.stereotype.Component; |
| 13 | 16 | ||
| @@ -25,10 +28,16 @@ public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction { | @@ -25,10 +28,16 @@ public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction { | ||
| 25 | 28 | ||
| 26 | @Resource | 29 | @Resource |
| 27 | private IotAlertConfigService alertConfigService; | 30 | private IotAlertConfigService alertConfigService; |
| 28 | - | ||
| 29 | @Resource | 31 | @Resource |
| 30 | private IotAlertRecordService alertRecordService; | 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 | @Override | 41 | @Override |
| 33 | public void execute(@Nullable IotDeviceMessage message, | 42 | public void execute(@Nullable IotDeviceMessage message, |
| 34 | IotRuleSceneDO rule, IotRuleSceneDO.ActionConfig actionConfig) throws Exception { | 43 | IotRuleSceneDO rule, IotRuleSceneDO.ActionConfig actionConfig) throws Exception { |
| @@ -37,8 +46,19 @@ public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction { | @@ -37,8 +46,19 @@ public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction { | ||
| 37 | if (CollUtil.isEmpty(alertConfigs)) { | 46 | if (CollUtil.isEmpty(alertConfigs)) { |
| 38 | return; | 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 | @Override | 64 | @Override |