13404089107
2026-04-20 f4b6843a1b3990453d2aef6d87b5ac30723c5870
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
package com.tcm.training.admin.utils;
 
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tcm.training.admin.app.auth.config.AppAliyunSmsProperties;
import org.springframework.beans.factory.annotation.Autowired;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
 
import java.util.Map;
 
@Component
@Slf4j
public class MsgUtils {
 
    private final AppAliyunSmsProperties properties;
    private final ObjectMapper objectMapper;
 
    /**
     * 注入阿里云短信配置与 JSON 序列化工具。
     */
    @Autowired
    public MsgUtils(AppAliyunSmsProperties properties, ObjectMapper objectMapper) {
        this.properties = properties;
        this.objectMapper = objectMapper;
    }
 
    /**
     * 使用AK&SK初始化账号Client
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
                // 您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }
 
    /**
     * 发送阿里云短信验证码。
     */
    public void sendMsg(String phone, Map<String,String> params, String templateCode, String signName) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = MsgUtils.createClient(
                properties.getAccessKeyId(),
                properties.getAccessKeySecret()
        );
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setSignName(signName)
                .setTemplateCode(templateCode)
                .setPhoneNumbers(phone);
        if (params != null && !params.isEmpty()) {
            sendSmsRequest.setTemplateParam(toTemplateParam(params));
        }
        RuntimeOptions runtime = new RuntimeOptions();
        try {
            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
            String responseCode = sendSmsResponse.getBody() == null ? null : sendSmsResponse.getBody().getCode();
            if (!"OK".equalsIgnoreCase(responseCode)) {
                String message = sendSmsResponse.getBody() == null ? "短信发送失败" : sendSmsResponse.getBody().getMessage();
                throw new IllegalStateException(message == null || message.trim().isEmpty() ? "短信发送失败,请稍后重试" : message);
            }
            log.info("阿里云短信发送成功,templateCode={}, statusCode={}", templateCode, sendSmsResponse.getStatusCode());
        } catch (TeaException error) {
            com.aliyun.teautil.Common.assertAsString(error.message);
            log.error("阿里云短信发送失败,templateCode={}, message={}", templateCode, error.message);
            throw new IllegalStateException("短信发送失败,请稍后重试");
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            com.aliyun.teautil.Common.assertAsString(error.message);
            log.error("阿里云短信发送异常,templateCode={}, message={}", templateCode, error.message);
            throw new IllegalStateException("短信发送失败,请稍后重试");
        }
    }
 
    /**
     * 将模板变量转换为阿里云要求的 JSON 字符串。
     */
    private String toTemplateParam(Map<String, String> params) throws JsonProcessingException {
        return objectMapper.writeValueAsString(params);
    }
}