|  | @@ -1,6 +1,14 @@
 | 
	
		
			
				|  |  |  package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import cn.hutool.core.lang.Assert;
 | 
	
		
			
				|  |  | +import cn.hutool.core.util.HexUtil;
 | 
	
		
			
				|  |  | +import cn.hutool.core.util.URLUtil;
 | 
	
		
			
				|  |  | +import cn.hutool.crypto.SecureUtil;
 | 
	
		
			
				|  |  | +import cn.hutool.crypto.digest.DigestUtil;
 | 
	
		
			
				|  |  | +import cn.hutool.http.HttpRequest;
 | 
	
		
			
				|  |  | +import cn.hutool.http.HttpResponse;
 | 
	
		
			
				|  |  | +import cn.hutool.json.JSONObject;
 | 
	
		
			
				|  |  | +import cn.hutool.json.JSONUtil;
 | 
	
		
			
				|  |  |  import cn.iocoder.yudao.framework.common.core.KeyValue;
 | 
	
		
			
				|  |  |  import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 | 
	
		
			
				|  |  |  import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 | 
	
	
		
			
				|  | @@ -9,27 +17,23 @@ import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespD
 | 
	
		
			
				|  |  |  import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO;
 | 
	
		
			
				|  |  |  import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
 | 
	
		
			
				|  |  |  import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
 | 
	
		
			
				|  |  | -import com.aliyuncs.DefaultAcsClient;
 | 
	
		
			
				|  |  | -import com.aliyuncs.IAcsClient;
 | 
	
		
			
				|  |  | -import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateRequest;
 | 
	
		
			
				|  |  | -import com.aliyuncs.dysmsapi.model.v20170525.QuerySmsTemplateResponse;
 | 
	
		
			
				|  |  | -import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
 | 
	
		
			
				|  |  | -import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
 | 
	
		
			
				|  |  | -import com.aliyuncs.profile.DefaultProfile;
 | 
	
		
			
				|  |  | -import com.aliyuncs.profile.IClientProfile;
 | 
	
		
			
				|  |  |  import com.fasterxml.jackson.annotation.JsonFormat;
 | 
	
		
			
				|  |  |  import com.fasterxml.jackson.annotation.JsonProperty;
 | 
	
		
			
				|  |  |  import com.google.common.annotations.VisibleForTesting;
 | 
	
		
			
				|  |  |  import lombok.Data;
 | 
	
		
			
				|  |  |  import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.io.IOException;
 | 
	
		
			
				|  |  | +import java.io.UnsupportedEncodingException;
 | 
	
		
			
				|  |  | +import java.net.URISyntaxException;
 | 
	
		
			
				|  |  | +import java.net.URLEncoder;
 | 
	
		
			
				|  |  |  import java.time.LocalDateTime;
 | 
	
		
			
				|  |  | -import java.util.List;
 | 
	
		
			
				|  |  | -import java.util.Objects;
 | 
	
		
			
				|  |  | +import java.util.*;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 | 
	
		
			
				|  |  |  import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 | 
	
		
			
				|  |  |  import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
 | 
	
		
			
				|  |  | +import java.text.SimpleDateFormat;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * 阿里短信客户端的实现类
 | 
	
	
		
			
				|  | @@ -40,21 +44,6 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE
 | 
	
		
			
				|  |  |  @Slf4j
 | 
	
		
			
				|  |  |  public class AliyunSmsClient extends AbstractSmsClient {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 调用成功 code
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    public static final String API_CODE_SUCCESS = "OK";
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * REGION, 使用杭州
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    private static final String ENDPOINT = "cn-hangzhou";
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 阿里云客户端
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    private volatile IAcsClient client;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      public AliyunSmsClient(SmsChannelProperties properties) {
 | 
	
		
			
				|  |  |          super(properties);
 | 
	
		
			
				|  |  |          Assert.notEmpty(properties.getApiKey(), "apiKey 不能为空");
 | 
	
	
		
			
				|  | @@ -63,24 +52,116 @@ public class AliyunSmsClient extends AbstractSmsClient {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      protected void doInit() {
 | 
	
		
			
				|  |  | -        IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, properties.getApiKey(), properties.getApiSecret());
 | 
	
		
			
				|  |  | -        client = new DefaultAcsClient(profile);
 | 
	
		
			
				|  |  | +//        IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, properties.getApiKey(), properties.getApiSecret());
 | 
	
		
			
				|  |  | +//        client = new DefaultAcsClient(profile);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public SmsSendRespDTO sendSms(Long sendLogId, String mobile, String apiTemplateId,
 | 
	
		
			
				|  |  |                                    List<KeyValue<String, Object>> templateParams) throws Throwable {
 | 
	
		
			
				|  |  | -        // 构建请求
 | 
	
		
			
				|  |  | -        SendSmsRequest request = new SendSmsRequest();
 | 
	
		
			
				|  |  | -        request.setPhoneNumbers(mobile);
 | 
	
		
			
				|  |  | -        request.setSignName(properties.getSignature());
 | 
	
		
			
				|  |  | -        request.setTemplateCode(apiTemplateId);
 | 
	
		
			
				|  |  | -        request.setTemplateParam(JsonUtils.toJsonString(MapUtils.convertMap(templateParams)));
 | 
	
		
			
				|  |  | -        request.setOutId(String.valueOf(sendLogId));
 | 
	
		
			
				|  |  | -        // 执行请求
 | 
	
		
			
				|  |  | -        SendSmsResponse response = client.getAcsResponse(request);
 | 
	
		
			
				|  |  | -        return new SmsSendRespDTO().setSuccess(Objects.equals(response.getCode(), API_CODE_SUCCESS)).setSerialNo(response.getBizId())
 | 
	
		
			
				|  |  | -                .setApiRequestId(response.getRequestId()).setApiCode(response.getCode()).setApiMsg(response.getMessage());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        TreeMap<String, Object> queryParam = new TreeMap<>();
 | 
	
		
			
				|  |  | +        queryParam.put("PhoneNumbers",mobile);
 | 
	
		
			
				|  |  | +        queryParam.put("SignName",properties.getSignature());
 | 
	
		
			
				|  |  | +        queryParam.put("TemplateCode",apiTemplateId);
 | 
	
		
			
				|  |  | +        queryParam.put("TemplateParam",JsonUtils.toJsonString(MapUtils.convertMap(templateParams)));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        JSONObject response = sendSmsRequest(queryParam,"sendSms");
 | 
	
		
			
				|  |  | +        SmsResponse smsResponse = getSmsSendResponse(response);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return new SmsSendRespDTO().setSuccess(smsResponse.success).setApiMsg(smsResponse.data.toString());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    JSONObject sendSmsRequest(TreeMap<String, Object> queryParam,String apiName) throws IOException, URISyntaxException {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // ************* 步骤 1:拼接规范请求串 *************
 | 
	
		
			
				|  |  | +        String url = "https://dysmsapi.aliyuncs.com"; //APP接入地址+接口访问URI
 | 
	
		
			
				|  |  | +        String httpMethod = "POST"; // 请求方式
 | 
	
		
			
				|  |  | +        String canonicalUri = "/";
 | 
	
		
			
				|  |  | +        // 请求参数,当请求的查询字符串为空时,使用空字符串作为规范化查询字符串
 | 
	
		
			
				|  |  | +        StringBuilder canonicalQueryString = new StringBuilder();
 | 
	
		
			
				|  |  | +        queryParam.entrySet().stream().map(entry -> percentCode(entry.getKey()) + "=" + percentCode(String.valueOf(entry.getValue()))).forEachOrdered(queryPart -> {
 | 
	
		
			
				|  |  | +            // 如果canonicalQueryString已经不是空的,则在查询参数前添加"&"
 | 
	
		
			
				|  |  | +            if (!canonicalQueryString.isEmpty()) {
 | 
	
		
			
				|  |  | +                canonicalQueryString.append("&");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            canonicalQueryString.append(queryPart);
 | 
	
		
			
				|  |  | +            System.out.println("canonicalQueryString=========>\n" + canonicalQueryString);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
 | 
	
		
			
				|  |  | +        SDF.setTimeZone(new SimpleTimeZone(0, "GMT"));
 | 
	
		
			
				|  |  | +        String SdfTime = SDF.format(new Date());
 | 
	
		
			
				|  |  | +        String randomUUID = UUID.randomUUID().toString();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        TreeMap<String, String> headers = new TreeMap<>();
 | 
	
		
			
				|  |  | +        headers.put("host", "dysmsapi.aliyuncs.com");
 | 
	
		
			
				|  |  | +        headers.put("x-acs-action", apiName);
 | 
	
		
			
				|  |  | +        headers.put("x-acs-version", "2017-05-25");
 | 
	
		
			
				|  |  | +        headers.put("x-acs-date", SdfTime);
 | 
	
		
			
				|  |  | +        headers.put("x-acs-signature-nonce", randomUUID);
 | 
	
		
			
				|  |  | +//        headers.put("content-type", "application/json;charset=utf-8");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 构造请求头,多个规范化消息头,按照消息头名称(小写)的字符代码顺序以升序排列后拼接在一起
 | 
	
		
			
				|  |  | +        StringBuilder canonicalHeaders = new StringBuilder();
 | 
	
		
			
				|  |  | +        // 已签名消息头列表,多个请求头名称(小写)按首字母升序排列并以英文分号(;)分隔
 | 
	
		
			
				|  |  | +        StringBuilder signedHeadersSb = new StringBuilder();
 | 
	
		
			
				|  |  | +        headers.entrySet().stream().filter(entry -> entry.getKey().toLowerCase().startsWith("x-acs-") || entry.getKey().equalsIgnoreCase("host") || entry.getKey().equalsIgnoreCase("content-type")).sorted(Map.Entry.comparingByKey()).forEach(entry -> {
 | 
	
		
			
				|  |  | +            String lowerKey = entry.getKey().toLowerCase();
 | 
	
		
			
				|  |  | +            String value = String.valueOf(entry.getValue()).trim();
 | 
	
		
			
				|  |  | +            canonicalHeaders.append(lowerKey).append(":").append(value).append("\n");
 | 
	
		
			
				|  |  | +            signedHeadersSb.append(lowerKey).append(";");
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        String signedHeaders = signedHeadersSb.substring(0, signedHeadersSb.length() - 1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        String body = "";//短信API为RPC接口,query parameters在uri中拼接,因此request body如果没有特殊要求,设置为空。
 | 
	
		
			
				|  |  | +        String hashedRequestBody = HexUtil.encodeHexStr(DigestUtil.sha256(body));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        String canonicalRequest = httpMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestBody;
 | 
	
		
			
				|  |  | +        System.out.println("canonicalRequest=========>\n" + canonicalRequest);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // ************* 步骤 2:拼接待签名字符串 *************
 | 
	
		
			
				|  |  | +        String hashedCanonicalRequest = HexUtil.encodeHexStr(DigestUtil.sha256(canonicalRequest));
 | 
	
		
			
				|  |  | +        String stringToSign = "ACS3-HMAC-SHA256" + "\n" + hashedCanonicalRequest;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // ************* 步骤 3:计算签名 *************
 | 
	
		
			
				|  |  | +        String signature = SecureUtil.hmacSha256(properties.getApiSecret()).digestHex(stringToSign);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // ************* 步骤 4:拼接 Authorization *************
 | 
	
		
			
				|  |  | +        String authorization = "ACS3-HMAC-SHA256" + " " + "Credential=" + properties.getApiKey() + ", "
 | 
	
		
			
				|  |  | +                + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
 | 
	
		
			
				|  |  | +        headers.put("Authorization", authorization);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // ************* 步骤 5:构造HttpRequest 并执行request请求,获得response *************
 | 
	
		
			
				|  |  | +//        url = url + canonicalUri;
 | 
	
		
			
				|  |  | +        String urlWithParams = url + "?" + URLUtil.buildQuery(queryParam, null);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        HttpResponse response = HttpRequest.post(urlWithParams)
 | 
	
		
			
				|  |  | +                .addHeaders(headers)
 | 
	
		
			
				|  |  | +                .body(body)
 | 
	
		
			
				|  |  | +                .execute();
 | 
	
		
			
				|  |  | +//        URIBuilder uriBuilder = new URIBuilder(url);
 | 
	
		
			
				|  |  | +//        // 添加请求参数
 | 
	
		
			
				|  |  | +//        for (Map.Entry<String, Object> entry : queryParam.entrySet()) {
 | 
	
		
			
				|  |  | +//            uriBuilder.addParameter(entry.getKey(), String.valueOf(entry.getValue()));
 | 
	
		
			
				|  |  | +//        }
 | 
	
		
			
				|  |  | +//        HttpUriRequest httpRequest = new HttpPost(uriBuilder.build());
 | 
	
		
			
				|  |  | +////        HttpPost httpPost = new HttpPost(uriBuilder.build());
 | 
	
		
			
				|  |  | +////        httpRequest = httpPost;
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        // 添加http请求头
 | 
	
		
			
				|  |  | +//        for (Map.Entry<String, Object> entry : headers.entrySet()) {
 | 
	
		
			
				|  |  | +//            httpRequest.addHeader(entry.getKey(), String.valueOf(entry.getValue()));
 | 
	
		
			
				|  |  | +//        }
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//        // 发送请求
 | 
	
		
			
				|  |  | +//        CloseableHttpClient httpClient = HttpClients.createDefault();
 | 
	
		
			
				|  |  | +//        CloseableHttpResponse response = httpClient.execute(httpRequest);
 | 
	
		
			
				|  |  | +        System.out.println("getEntity====="+response.body());
 | 
	
		
			
				|  |  | +        System.out.println("response====="+response);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return JSONUtil.parseObj(response.body());
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -94,16 +175,15 @@ public class AliyunSmsClient extends AbstractSmsClient {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public SmsTemplateRespDTO getSmsTemplate(String apiTemplateId) throws Throwable {
 | 
	
		
			
				|  |  | -        // 构建请求
 | 
	
		
			
				|  |  | -        QuerySmsTemplateRequest request = new QuerySmsTemplateRequest();
 | 
	
		
			
				|  |  | -        request.setTemplateCode(apiTemplateId);
 | 
	
		
			
				|  |  | -        // 执行请求
 | 
	
		
			
				|  |  | -        QuerySmsTemplateResponse response = client.getAcsResponse(request);
 | 
	
		
			
				|  |  | -        if (response.getTemplateStatus() == null) {
 | 
	
		
			
				|  |  | -            return null;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        return new SmsTemplateRespDTO().setId(response.getTemplateCode()).setContent(response.getTemplateContent())
 | 
	
		
			
				|  |  | -                .setAuditStatus(convertSmsTemplateAuditStatus(response.getTemplateStatus())).setAuditReason(response.getReason());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        TreeMap<String, Object> queryParam = new TreeMap<>();
 | 
	
		
			
				|  |  | +        queryParam.put("TemplateCode",apiTemplateId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        JSONObject response = sendSmsRequest(queryParam,"QuerySmsTemplate");
 | 
	
		
			
				|  |  | +        QuerySmsTemplateResponse smsTemplateResponse = getSmsTemplateResponse(response);
 | 
	
		
			
				|  |  | +        return new SmsTemplateRespDTO().setId(smsTemplateResponse.getTemplateCode()).setContent(smsTemplateResponse.getTemplateContent())
 | 
	
		
			
				|  |  | +                .setAuditStatus(convertSmsTemplateAuditStatus(smsTemplateResponse.getTemplateStatus())).setAuditReason(smsTemplateResponse.getReason());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @VisibleForTesting
 | 
	
	
		
			
				|  | @@ -116,12 +196,99 @@ public class AliyunSmsClient extends AbstractSmsClient {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 对指定的字符串进行URL编码。
 | 
	
		
			
				|  |  | +     * 使用UTF-8编码字符集对字符串进行编码,并对特定的字符进行替换,以符合URL编码规范。
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param str 需要进行URL编码的字符串。
 | 
	
		
			
				|  |  | +     * @return 编码后的字符串。其中,加号"+"被替换为"%20",星号"*"被替换为"%2A",波浪号"%7E"被替换为"~"。
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public static String percentCode(String str) {
 | 
	
		
			
				|  |  | +        if (str == null) {
 | 
	
		
			
				|  |  | +            throw new IllegalArgumentException("输入字符串不可为null");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            return URLEncoder.encode(str, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
 | 
	
		
			
				|  |  | +        } catch (UnsupportedEncodingException e) {
 | 
	
		
			
				|  |  | +            throw new RuntimeException("UTF-8编码不被支持", e);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private SmsResponse getSmsSendResponse(JSONObject resJson) {
 | 
	
		
			
				|  |  | +        SmsResponse smsResponse = new SmsResponse();
 | 
	
		
			
				|  |  | +        smsResponse.setSuccess("OK".equals(resJson.getStr("Code")));
 | 
	
		
			
				|  |  | +        smsResponse.setData(resJson);
 | 
	
		
			
				|  |  | +//        smsResponse.setConfigId(getConfigId());
 | 
	
		
			
				|  |  | +        return smsResponse;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private QuerySmsTemplateResponse getSmsTemplateResponse(JSONObject resJson) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        QuerySmsTemplateResponse smsTemplateResponse = new QuerySmsTemplateResponse();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        smsTemplateResponse.setRequestId(resJson.getStr("RequestId"));
 | 
	
		
			
				|  |  | +        smsTemplateResponse.setTemplateContent(resJson.getStr("TemplateContent"));
 | 
	
		
			
				|  |  | +        smsTemplateResponse.setReason(resJson.getStr("Reason"));
 | 
	
		
			
				|  |  | +        smsTemplateResponse.setTemplateStatus(resJson.getInt("TemplateStatus"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return smsTemplateResponse;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * <p>类名: SmsResponse
 | 
	
		
			
				|  |  | +     * <p>说明:  发送短信返回信息
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @author :scholar
 | 
	
		
			
				|  |  | +     * 2024/07/17  0:25
 | 
	
		
			
				|  |  | +     **/
 | 
	
		
			
				|  |  | +    @Data
 | 
	
		
			
				|  |  | +    public static class SmsResponse {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        /**
 | 
	
		
			
				|  |  | +         * 是否成功
 | 
	
		
			
				|  |  | +         */
 | 
	
		
			
				|  |  | +        private boolean success;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        /**
 | 
	
		
			
				|  |  | +         * 厂商原返回体
 | 
	
		
			
				|  |  | +         */
 | 
	
		
			
				|  |  | +        private Object data;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        /**
 | 
	
		
			
				|  |  | +         * 配置标识名 如未配置取对应渠道名例如 Alibaba
 | 
	
		
			
				|  |  | +         */
 | 
	
		
			
				|  |  | +        private String configId;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * <p>类名: QuerySmsTemplateResponse
 | 
	
		
			
				|  |  | +     * <p>说明:  sms模板查询返回信息
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @author :scholar
 | 
	
		
			
				|  |  | +     * 2024/07/17  0:25
 | 
	
		
			
				|  |  | +     **/
 | 
	
		
			
				|  |  | +    @Data
 | 
	
		
			
				|  |  | +    public static class QuerySmsTemplateResponse {
 | 
	
		
			
				|  |  | +        private String requestId;
 | 
	
		
			
				|  |  | +        private String code;
 | 
	
		
			
				|  |  | +        private String message;
 | 
	
		
			
				|  |  | +        private Integer templateStatus;
 | 
	
		
			
				|  |  | +        private String reason;
 | 
	
		
			
				|  |  | +        private String templateCode;
 | 
	
		
			
				|  |  | +        private Integer templateType;
 | 
	
		
			
				|  |  | +        private String templateName;
 | 
	
		
			
				|  |  | +        private String templateContent;
 | 
	
		
			
				|  |  | +        private String createDate;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 短信接收状态
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * 参见 <a href="https://help.aliyun.com/document_detail/101867.html">文档</a>
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * @author 芋道源码
 | 
	
		
			
				|  |  | +     * @author 润普源码
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @Data
 | 
	
		
			
				|  |  |      public static class SmsReceiveStatus {
 |