liusheng
2026-10-10 0afac42fb2e9d6e5291304dd0044ce3042b45d2b
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package com.ruoyi.message.sms.provider.aliyun;
 
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.AddSmsTemplateRequest;
import com.aliyun.dysmsapi20170525.models.AddSmsTemplateResponse;
import com.aliyun.dysmsapi20170525.models.AddSmsTemplateResponseBody;
import com.aliyun.dysmsapi20170525.models.ModifySmsTemplateRequest;
import com.aliyun.dysmsapi20170525.models.ModifySmsTemplateResponse;
import com.aliyun.dysmsapi20170525.models.ModifySmsTemplateResponseBody;
import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateListRequest;
import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateListResponse;
import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateListResponseBody;
import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateRequest;
import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateResponse;
import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateResponseBody;
import com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponseBody;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ruoyi.message.config.MessageProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * 阿里云短信 API。
 * <p>
 * 迁移说明:逻辑取自 {@code com.smartor.service.impl.BaseSmsaccountServiceImpl},
 * 但<b>不再依赖 smartor 的 domain 对象</b>({@code BaseSmsRequest} / {@code BatchBaseSmsRequest} /
 * {@code TemplateSmsRequest}),改为直接接收基础参数,从而让本模块可以放在
 * {@code ruoyi-system} 之前、被所有业务模块复用。
 * <p>
 * 原 {@code BaseSmsaccountServiceImpl} 保留为「短信账号管理 + DB 读写」的 Service,
 * 其上的阿里云调用改为委托本类(见改造说明)。
 */
@Slf4j
@Component
public class AliYunSmsApi {
 
    private final MessageProperties properties;
 
    public AliYunSmsApi(MessageProperties properties) {
        this.properties = properties;
    }
 
    /**
     * 发送短信
     *
     * @param phoneNumbers  手机号,多个用逗号分隔
     * @param templateCode  模板编码
     * @param templateParam 模板参数 JSON
     */
    public SendSmsResponseBody sendSms(String phoneNumbers, String templateCode, String templateParam) {
        try {
            Client client = createClient();
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setPhoneNumbers(phoneNumbers)
                    .setSignName(properties.getSms().getAliyun().getSignName())
                    .setTemplateCode(templateCode)
                    .setTemplateParam(templateParam);
            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
            return sendSmsResponse.getBody();
        } catch (Exception e) {
            log.error("阿里云短信发送失败,phoneNumbers:{},templateCode:{}", phoneNumbers, templateCode, e);
        }
        return null;
    }
 
    /**
     * 批量发送短信
     */
    public SendBatchSmsResponseBody batchSendMsg(List<String> phoneNumbers, String templateCode) {
        try {
            Client client = createClient();
            List<String> signNameJson = new ArrayList<>();
            for (int i = 0; i < phoneNumbers.size(); i++) {
                signNameJson.add("\"" + properties.getSms().getAliyun().getSignName() + "\"");
            }
            SendBatchSmsRequest sendBatchSmsRequest = new SendBatchSmsRequest()
                    .setSignNameJson(signNameJson.toString())
                    .setPhoneNumberJson(phoneNumbers.toString())
                    .setTemplateCode(templateCode);
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                SendBatchSmsResponse sendBatchSmsResponse = client.sendBatchSmsWithOptions(sendBatchSmsRequest, runtime);
                return sendBatchSmsResponse.getBody();
            } catch (TeaException error) {
                Common.assertAsString(error.message);
            } catch (Exception innerError) {
                TeaException error = new TeaException(innerError.getMessage(), innerError);
                Common.assertAsString(error.message);
            }
        } catch (Exception e) {
            log.error("阿里云短信批量发送失败,templateCode:{}", templateCode, e);
        }
        return null;
    }
 
    /**
     * 新增短信模板
     */
    public AddSmsTemplateResponseBody addSmsTemplate(Integer templateType, String templateName,
                                                     String templateContent, String remark) {
        try {
            Client client = createClient();
            AddSmsTemplateRequest addSmsTemplateRequest = new AddSmsTemplateRequest()
                    .setTemplateType(templateType)
                    .setTemplateName(templateName)
                    .setTemplateContent(templateContent)
                    .setRemark(remark);
            RuntimeOptions runtime = new RuntimeOptions();
            AddSmsTemplateResponse response = client.addSmsTemplateWithOptions(addSmsTemplateRequest, runtime);
            return response.getBody();
        } catch (TeaException error) {
            Common.assertAsString(error.message);
        } catch (Exception innerError) {
            TeaException error = new TeaException(innerError.getMessage(), innerError);
            Common.assertAsString(error.message);
        }
        return null;
    }
 
    /**
     * 修改短信模板
     */
    public ModifySmsTemplateResponseBody modifySmsTemplate(Integer templateType, String templateName,
                                                          String templateCode, String templateContent, String remark) {
        try {
            Client client = createClient();
            ModifySmsTemplateRequest modifySmsTemplateRequest = new ModifySmsTemplateRequest();
            modifySmsTemplateRequest.setTemplateType(templateType);
            modifySmsTemplateRequest.setTemplateName(templateName);
            modifySmsTemplateRequest.setTemplateCode(templateCode);
            modifySmsTemplateRequest.setTemplateContent(templateContent);
            modifySmsTemplateRequest.setRemark(remark);
            RuntimeOptions runtime = new RuntimeOptions();
            ModifySmsTemplateResponse response = client.modifySmsTemplateWithOptions(modifySmsTemplateRequest, runtime);
            return response.getBody();
        } catch (TeaException error) {
            Common.assertAsString(error.message);
        } catch (Exception innerError) {
            TeaException error = new TeaException(innerError.getMessage(), innerError);
            Common.assertAsString(error.message);
        }
        return null;
    }
 
    /**
     * 查询短信模板列表
     */
    public QuerySmsTemplateListResponseBody querySmsTemplate(Integer pageIndex, Integer pageSize) {
        try {
            Client client = createClient();
            QuerySmsTemplateListRequest request = new QuerySmsTemplateListRequest()
                    .setPageIndex(pageIndex)
                    .setPageSize(pageSize);
            RuntimeOptions runtime = new RuntimeOptions();
            QuerySmsTemplateListResponse response = client.querySmsTemplateListWithOptions(request, runtime);
            return response.getBody();
        } catch (TeaException error) {
            Common.assertAsString(error.message);
        } catch (Exception innerError) {
            TeaException error = new TeaException(innerError.getMessage(), innerError);
            Common.assertAsString(error.message);
        }
        return null;
    }
 
    /**
     * 查询短信模板审核状态
     */
    public QuerySmsTemplateResponseBody querySmsTemplateStatus(String templateCode) {
        try {
            Client client = createClient();
            QuerySmsTemplateRequest request = new QuerySmsTemplateRequest().setTemplateCode(templateCode);
            RuntimeOptions runtime = new RuntimeOptions();
            QuerySmsTemplateResponse response = client.querySmsTemplateWithOptions(request, runtime);
            return response.getBody();
        } catch (TeaException error) {
            Common.assertAsString(error.message);
        } catch (Exception innerError) {
            TeaException error = new TeaException(innerError.getMessage(), innerError);
            Common.assertAsString(error.message);
        }
        return null;
    }
 
    private Client createClient() throws Exception {
        Config config = new Config()
                .setAccessKeyId(properties.getSms().getAliyun().getAccessKeyId())
                .setAccessKeySecret(properties.getSms().getAliyun().getAccessKeySecret());
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new Client(config);
    }
}