2026-06-24 f4bd1f3c89d906131495a0aca5aaf82966378510
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package cn.iocoder.yudao.module.iot.service.rule.scene.action;
 
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.alert.IotAlertConfigDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
import cn.iocoder.yudao.module.iot.enums.DictTypeConstants;
import cn.iocoder.yudao.module.iot.enums.alert.IotAlertReceiveTypeEnum;
import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleActionTypeEnum;
import cn.iocoder.yudao.module.iot.service.alert.IotAlertConfigService;
import cn.iocoder.yudao.module.iot.service.alert.IotAlertRecordService;
import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
import cn.iocoder.yudao.module.system.api.mail.MailSendApi;
import cn.iocoder.yudao.module.system.api.mail.dto.MailSendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.sms.SmsSendApi;
import cn.iocoder.yudao.module.system.api.sms.dto.send.SmsSendSingleToUserReqDTO;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * IoT 告警触发的 {@link IotSceneRuleAction} 实现类
 *
 * @author 芋道源码
 */
@Component
@Slf4j
public class IotAlertTriggerSceneRuleAction implements IotSceneRuleAction {
 
    @Resource
    private IotAlertConfigService alertConfigService;
    @Resource
    private IotAlertRecordService alertRecordService;
    @Resource
    private IotDeviceService deviceService;
 
    @Resource
    private SmsSendApi smsSendApi;
    @Resource
    private MailSendApi mailSendApi;
    @Resource
    private NotifyMessageSendApi notifyMessageSendApi;
 
    @Override
    public void execute(@Nullable IotDeviceMessage message,
                        IotSceneRuleDO rule, IotSceneRuleDO.Action actionConfig) throws Exception {
        List<IotAlertConfigDO> alertConfigs = alertConfigService.getAlertConfigListBySceneRuleIdAndStatus(
                rule.getId(), CommonStatusEnum.ENABLE.getStatus());
        if (CollUtil.isEmpty(alertConfigs)) {
            return;
        }
        // 获得设备信息
        IotDeviceDO device = message != null ? deviceService.getDeviceFromCache(message.getDeviceId()) : null;
        alertConfigs.forEach(alertConfig -> {
            // 创建告警记录
            alertRecordService.createAlertRecord(alertConfig, rule.getId(), message, device);
            // 发送告警消息
            sendAlertMessage(alertConfig, message, device);
        });
    }
 
    private void sendAlertMessage(IotAlertConfigDO config,
                                  @Nullable IotDeviceMessage deviceMessage,
                                  @Nullable IotDeviceDO device) {
        if (CollUtil.isEmpty(config.getReceiveUserIds()) || CollUtil.isEmpty(config.getReceiveTypes())) {
            return;
        }
        Map<String, Object> templateParams = buildTemplateParams(config, deviceMessage, device);
        config.getReceiveUserIds().forEach(userId ->
                config.getReceiveTypes().forEach(receiveType -> sendAlertMessageToUser(userId, receiveType, templateParams)));
    }
 
    /**
     * 按指定接收方式,给单个用户发送告警消息
     */
    private void sendAlertMessageToUser(Long userId, Integer receiveType, Map<String, Object> templateParams) {
        IotAlertReceiveTypeEnum typeEnum = IotAlertReceiveTypeEnum.of(receiveType);
        if (typeEnum == null) {
            return;
        }
        try {
            switch (typeEnum) {
                case SMS:
                    smsSendApi.sendSingleSmsToAdmin(new SmsSendSingleToUserReqDTO().setUserId(userId)
                            .setTemplateCode(typeEnum.getTemplateCode()).setTemplateParams(templateParams));
                    break;
                case MAIL:
                    mailSendApi.sendSingleMailToAdmin(new MailSendSingleToUserReqDTO().setUserId(userId)
                            .setTemplateCode(typeEnum.getTemplateCode()).setTemplateParams(templateParams));
                    break;
                case NOTIFY:
                    notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO().setUserId(userId)
                            .setTemplateCode(typeEnum.getTemplateCode()).setTemplateParams(templateParams));
                    break;
            }
        } catch (Exception ex) {
            log.error("[sendAlertMessageToUser][用户({}) 模板参数({}) 发送 {} 告警失败]",
                    userId, templateParams, typeEnum, ex);
        }
    }
 
    private Map<String, Object> buildTemplateParams(IotAlertConfigDO config,
                                                    @Nullable IotDeviceMessage deviceMessage,
                                                    @Nullable IotDeviceDO device) {
        Map<String, Object> params = new HashMap<>();
        params.put("configName", config.getName());
        params.put("configDescription", config.getDescription());
        params.put("configLevel", DictFrameworkUtils.parseDictDataLabel(DictTypeConstants.ALERT_LEVEL, config.getLevel()));
        params.put("deviceName", device != null ? device.getDeviceName() : null);
        params.put("reportTime", deviceMessage != null
                ? LocalDateTimeUtil.format(deviceMessage.getReportTime(), DatePattern.NORM_DATETIME_PATTERN) : null);
        return params;
    }
 
    @Override
    public IotSceneRuleActionTypeEnum getType() {
        return IotSceneRuleActionTypeEnum.ALERT_TRIGGER;
    }
 
}