diff --git a/xservice-message-starter/pom.xml b/xservice-message-starter/pom.xml
index 94ed166..aefc4ae 100644
--- a/xservice-message-starter/pom.xml
+++ b/xservice-message-starter/pom.xml
@@ -44,6 +44,17 @@
commons-codec
1.11
+
+
+ com.aliyun
+ dysmsapi20170525
+ 4.1.2
+
+
+ com.aliyun
+ alibabacloud-dysmsapi20170525
+ 4.0.3
+
\ No newline at end of file
diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/common/ClientUtils.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/common/ClientUtils.java
new file mode 100644
index 0000000..69ded96
--- /dev/null
+++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/common/ClientUtils.java
@@ -0,0 +1,47 @@
+package com.xiang.xservice.basic.xservice.aliyun.common;
+
+import com.aliyun.auth.credentials.Credential;
+import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
+import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
+import com.aliyun.teaopenapi.models.Config;
+import com.xiang.xservice.basic.xservice.aliyun.config.AliyunProperties;
+import darabonba.core.client.ClientOverrideConfiguration;
+import lombok.Setter;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@EnableConfigurationProperties({AliyunProperties.class})
+public class ClientUtils {
+
+ @Setter
+ private static AliyunProperties aliyunProperties;
+ private static final String ENDPOINT = "dysmsapi.aliyuncs.com";
+
+ public static com.aliyun.dysmsapi20170525.Client initClients() throws Exception {
+ AliyunProperties properties = new AliyunProperties();
+ Config config = new Config()
+ // 配置 AccessKey ID,请确保代码运行环境配置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
+ .setAccessKeyId(aliyunProperties.getAccessKeyId())
+ // 配置 AccessKey Secret,请确保代码运行环境配置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+ .setAccessKeySecret(aliyunProperties.getAccessKeySecret());
+ config.endpoint = ENDPOINT;
+
+ return new com.aliyun.dysmsapi20170525.Client(config);
+ }
+
+ public static AsyncClient initAsyncClient() {
+ StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
+ .accessKeyId(System.getenv(aliyunProperties.getAccessKeyId()))
+ .accessKeySecret(System.getenv(aliyunProperties.getAccessKeySecret()))
+ .build());
+ return AsyncClient.builder()
+ .region("cn-hangzhou") // Region ID
+ .credentialsProvider(provider)
+ .overrideConfiguration(
+ ClientOverrideConfiguration.create()
+ .setEndpointOverride(ENDPOINT)
+ )
+ .build();
+ }
+}
diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/config/AliyunConfigHolder.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/config/AliyunConfigHolder.java
new file mode 100644
index 0000000..31a244a
--- /dev/null
+++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/config/AliyunConfigHolder.java
@@ -0,0 +1,20 @@
+package com.xiang.xservice.basic.xservice.aliyun.config;
+
+import org.springframework.stereotype.Component;
+import com.xiang.xservice.basic.xservice.aliyun.common.ClientUtils;
+import javax.annotation.PostConstruct;
+
+@Component
+public class AliyunConfigHolder {
+
+ private final AliyunProperties aliyunProperties;
+
+ public AliyunConfigHolder(AliyunProperties aliyunProperties) {
+ this.aliyunProperties = aliyunProperties;
+ }
+
+ @PostConstruct
+ public void init() {
+ ClientUtils.setAliyunProperties(aliyunProperties);
+ }
+}
\ No newline at end of file
diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/config/AliyunProperties.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/config/AliyunProperties.java
new file mode 100644
index 0000000..b5cdc54
--- /dev/null
+++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/config/AliyunProperties.java
@@ -0,0 +1,16 @@
+package com.xiang.xservice.basic.xservice.aliyun.config;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@RefreshScope
+public class AliyunProperties {
+
+ private String accessKeyId;
+ private String accessKeySecret;
+}
diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/ISmsCodeService.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/ISmsCodeService.java
new file mode 100644
index 0000000..90ad71d
--- /dev/null
+++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/ISmsCodeService.java
@@ -0,0 +1,6 @@
+package com.xiang.xservice.basic.xservice.aliyun.smscode;
+
+public interface ISmsCodeService {
+
+ Boolean asyncSendPhoneValidCode4DaXiangNet(String phoneNumber, String smsCode);
+}
diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/SmsCodeServiceImpl.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/SmsCodeServiceImpl.java
new file mode 100644
index 0000000..3f43490
--- /dev/null
+++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/SmsCodeServiceImpl.java
@@ -0,0 +1,22 @@
+package com.xiang.xservice.basic.xservice.aliyun.smscode;
+
+import com.google.common.collect.Maps;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+@Service
+public class SmsCodeServiceImpl implements ISmsCodeService {
+ @Override
+ public Boolean asyncSendPhoneValidCode4DaXiangNet(String phoneNumber, String smsCode) {
+
+ Map param = Maps.newHashMap();
+ param.put("code", smsCode);
+ try {
+ SmsCodeUtils.asyncSmsCode(phoneNumber, "大象网", "SMS_259435198", param, null);
+ return Boolean.TRUE;
+ } catch (Exception e) {
+ return Boolean.FALSE;
+ }
+ }
+}
diff --git a/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/SmsCodeUtils.java b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/SmsCodeUtils.java
new file mode 100644
index 0000000..e3aa919
--- /dev/null
+++ b/xservice-message-starter/src/main/java/com/xiang/xservice/basic/xservice/aliyun/smscode/SmsCodeUtils.java
@@ -0,0 +1,122 @@
+package com.xiang.xservice.basic.xservice.aliyun.smscode;
+
+import com.alibaba.fastjson.JSON;
+
+import com.xiang.xservice.basic.exception.BusinessException;
+import com.xiang.xservice.basic.xservice.aliyun.common.ClientUtils;
+import lombok.extern.slf4j.Slf4j;
+import com.aliyun.sdk.service.dysmsapi20170525.*;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import java.util.Map;
+
+@Slf4j
+public class SmsCodeUtils {
+
+ /**
+ * 向多个个手机号发送短信
+ * @param phoneNumber 手机号
+ * @param signName 签名
+ * @param templateCode 模板编号
+ * @param templateParam 模板参数
+ */
+ public static void getBasicSmsCode(String phoneNumber, String signName, String templateCode,
+ Map templateParam) {
+ getBasicSmsCode(Collections.singletonList(phoneNumber), signName, templateCode, templateParam);
+ }
+
+ /**
+ * 向单个个手机号发送短信
+ * @param phoneNumber 手机号
+ * @param signName 签名
+ * @param templateCode 模板编号
+ * @param templateParam 模板参数
+ */
+ public static void getBasicSmsCode(List phoneNumber, String signName, String templateCode,
+ Map templateParam) {
+ com.aliyun.dysmsapi20170525.Client client;
+ // 初始化请求客户端
+ try {
+ client = ClientUtils.initClients();
+ } catch (Exception e) {
+ log.error("初始化Aliyun客户端失败", e);
+ throw new BusinessException("初始化Aliyun客户端失败");
+ }
+
+ // 构造API请求对象,请替换请求参数值
+ com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
+ .setPhoneNumbers(getPhoneNumbers(phoneNumber))
+ .setSignName(signName)
+ .setTemplateCode(templateCode)
+ .setTemplateParam(JSON.toJSONString(templateParam));
+
+ // 获取响应对象
+ try {
+ com.aliyun.dysmsapi20170525.models.SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
+ log.info("发送短信验证码,请求:{}, 响应:{}", JSON.toJSONString(sendSmsResponse), JSON.toJSONString(sendSmsResponse));
+ } catch (Exception e) {
+ log.error("发送短信验证码失败,发送请求:{}", JSON.toJSONString(sendSmsRequest), e);
+ throw new BusinessException("发送短信验证码失败");
+ }
+ }
+
+ /**
+ * 单个手机号异步发送短信
+ * @param phoneNumber 手机号
+ * @param signName 签名
+ * @param templateCode 模板编号
+ * @param templateParam 模板参数
+ * @param externParam 外部流水扩展字段
+ */
+ public static void asyncSmsCode(String phoneNumber, String signName, String templateCode,
+ Map templateParam, String externParam) {
+ asyncSmsCode(Collections.singletonList(phoneNumber), signName, templateCode, templateParam, externParam);
+ }
+
+ /**
+ * 多个手机号异步发送短信
+ * @param phoneNumber 手机号集合(多个手机号)
+ * @param signName 签名
+ * @param templateCode 模板编号
+ * @param templateParam 模板参数
+ * @param externParam 外部流水扩展字段
+ */
+ public static void asyncSmsCode(List phoneNumber, String signName, String templateCode,
+ Map templateParam, String externParam) {
+ AsyncClient client = ClientUtils.initAsyncClient();
+
+
+
+ com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest sendSmsRequest =
+ com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest.builder()
+ .templateCode(templateCode)
+ .phoneNumbers(getPhoneNumbers(phoneNumber))
+ .signName(signName)
+ .outId(externParam)
+ .templateParam(JSON.toJSONString(templateParam))
+ .build();
+ log.info("异步发送短信,请求:{}", JSON.toJSONString(sendSmsRequest));
+ try {
+ CompletableFuture future = client.sendSms(sendSmsRequest);
+ com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse response = future.get();
+ log.info("异步发送短信, 响应:{}", JSON.toJSONString(response));
+ } catch (Exception e) {
+ log.error("异步发送短信失败", e);
+ throw new BusinessException("异步发送短信失败");
+ } finally {
+ client.close();
+ }
+ }
+
+ private static String getPhoneNumbers(List phoneNumberList) {
+ StringBuilder phoneNumbers = new StringBuilder();
+ for (String phone : phoneNumberList) {
+ phoneNumbers.append(phone).append(",");
+ }
+ phoneNumbers.deleteCharAt(phoneNumbers.length() - 1);
+ return phoneNumbers.toString();
+ }
+}
diff --git a/xservice-message-starter/src/main/resources/META-INF/spring.factories b/xservice-message-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..4bfae8a
--- /dev/null
+++ b/xservice-message-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+com.xiang.xservice.basic.xservice.aliyun.config.AliyunProperties
\ No newline at end of file