diff --git a/pom.xml b/pom.xml index b20e7f059..308779449 100644 --- a/pom.xml +++ b/pom.xml @@ -48,8 +48,7 @@ 1.12.400 - 2.0.23 - 3.1.687 + 2.1.0 3.2.2 @@ -236,15 +235,9 @@ - com.aliyun - dysmsapi20170525 - ${aliyun.sms.version} - - - - com.tencentcloudapi - tencentcloud-sdk-java-sms - ${tencent.sms.version} + org.dromara.sms4j + sms4j-autoimmit + ${sms4j.sms.version} diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 92a3640e9..869bbc275 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -160,12 +160,22 @@ mail: --- # sms 短信 sms: + # 是否启用短信 enabled: false - # 阿里云 dysmsapi.aliyuncs.com - # 腾讯云 sms.tencentcloudapi.com - endpoint: "dysmsapi.aliyuncs.com" - accessKeyId: xxxxxxx - accessKeySecret: xxxxxx - signName: 测试 - # 腾讯专用 - sdkAppId: + # SupplierType中枚举 + # ALIBABA 阿里云短信/ HUAWEI 华为云短信/ YUNPIAN 云片短信/ TENCENT 腾讯云短信/ UNI_SMS 合一短信/ JD_CLOUD 京东云短信/ CLOOPEN 容联云短信/ EMAY 亿美软通/ CTYUN 天翼云短信 + supplierType: ALIBABA + # supplierType 对应的配置 + alibaba: + #阿里云的accessKey + accessKeyId: 您的accessKey + #阿里云的accessKeySecret + accessKeySecret: 您的accessKeySecret + #短信签名 + signature: 测试签名 + #模板ID 用于发送固定模板短信使用 + templateId: SMS_215125134 + #模板变量 上述模板的变量 + templateName: code + #请求地址 默认为dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 + requestUrl: dysmsapi.aliyuncs.com diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index e760823ad..1863353c0 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -163,12 +163,22 @@ mail: --- # sms 短信 sms: + # 是否启用短信 enabled: false - # 阿里云 dysmsapi.aliyuncs.com - # 腾讯云 sms.tencentcloudapi.com - endpoint: "dysmsapi.aliyuncs.com" - accessKeyId: xxxxxxx - accessKeySecret: xxxxxx - signName: 测试 - # 腾讯专用 - sdkAppId: + # SupplierType中枚举 + # ALIBABA 阿里云短信/ HUAWEI 华为云短信/ YUNPIAN 云片短信/ TENCENT 腾讯云短信/ UNI_SMS 合一短信/ JD_CLOUD 京东云短信/ CLOOPEN 容联云短信/ EMAY 亿美软通/ CTYUN 天翼云短信 + supplierType: ALIBABA + # supplierType 对应的配置 + alibaba: + #阿里云的accessKey + accessKeyId: 您的accessKey + #阿里云的accessKeySecret + accessKeySecret: 您的accessKeySecret + #短信签名 + signature: 测试签名 + #模板ID 用于发送固定模板短信使用 + templateId: SMS_215125134 + #模板变量 上述模板的变量 + templateName: code + #请求地址 默认为dysmsapi.aliyuncs.com 如无特殊改变可以不用设置 + requestUrl: dysmsapi.aliyuncs.com diff --git a/ruoyi-common/ruoyi-common-sms/pom.xml b/ruoyi-common/ruoyi-common-sms/pom.xml index b06c5caff..53de0a6ef 100644 --- a/ruoyi-common/ruoyi-common-sms/pom.xml +++ b/ruoyi-common/ruoyi-common-sms/pom.xml @@ -22,15 +22,8 @@ - com.aliyun - dysmsapi20170525 - true - - - - com.tencentcloudapi - tencentcloud-sdk-java-sms - true + org.dromara.sms4j + sms4j-autoimmit diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java index 86881f1d8..07c06e87f 100644 --- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java +++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java @@ -1,15 +1,16 @@ package org.dromara.common.sms.config; import org.dromara.common.sms.config.properties.SmsProperties; -import org.dromara.common.sms.core.AliyunSmsTemplate; +import org.dromara.common.sms.core.Sms4jSmsTemplate; import org.dromara.common.sms.core.SmsTemplate; -import org.dromara.common.sms.core.TencentSmsTemplate; +import org.dromara.sms4j.autoimmit.config.SmsAutowiredConfig; +import org.dromara.sms4j.autoimmit.utils.SpringUtil; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; /** * 短信配置类 @@ -19,30 +20,26 @@ import org.springframework.context.annotation.Configuration; */ @AutoConfiguration @EnableConfigurationProperties(SmsProperties.class) +@ConditionalOnProperty(value = "sms.enabled", havingValue = "true") +@ConditionalOnClass(org.dromara.sms4j.autoimmit.config.SmsAutowiredConfig.class) public class SmsConfig { - @Configuration - @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") - @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) - static class AliyunSmsConfig { - - @Bean - public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) { - return new AliyunSmsTemplate(smsProperties); - } - + @Bean + public SpringUtil springUtil(DefaultListableBeanFactory defaultListableBeanFactory) { + return new SpringUtil(defaultListableBeanFactory); } - @Configuration - @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") - @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) - static class TencentSmsConfig { - - @Bean - public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) { - return new TencentSmsTemplate(smsProperties); - } + /** + * 主要配置注入 确保springUtil注入后再注入 + */ + @Bean(initMethod = "init") + public SmsAutowiredConfig smsAutowiredConfig(SpringUtil springUtil) { + return new SmsAutowiredConfig(springUtil); + } + @Bean + public SmsTemplate sms4jSmsTemplate(SmsProperties smsProperties) { + return new Sms4jSmsTemplate(smsProperties); } } diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java index da6d9400e..ec1ee6769 100644 --- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java +++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java @@ -1,6 +1,7 @@ package org.dromara.common.sms.config.properties; import lombok.Data; +import org.dromara.sms4j.provider.enumerate.SupplierType; import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -15,31 +16,6 @@ public class SmsProperties { private Boolean enabled; - /** - * 配置节点 - * 阿里云 dysmsapi.aliyuncs.com - * 腾讯云 sms.tencentcloudapi.com - */ - private String endpoint; - - /** - * key - */ - private String accessKeyId; - - /** - * 密匙 - */ - private String accessKeySecret; - - /* - * 短信签名 - */ - private String signName; - - /** - * 短信应用ID (腾讯专属) - */ - private String sdkAppId; + private SupplierType supplierType; } diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java deleted file mode 100644 index 00d81523a..000000000 --- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/AliyunSmsTemplate.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.dromara.common.sms.core; - -import com.aliyun.dysmsapi20170525.Client; -import com.aliyun.dysmsapi20170525.models.SendSmsRequest; -import com.aliyun.dysmsapi20170525.models.SendSmsResponse; -import com.aliyun.teaopenapi.models.Config; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.json.utils.JsonUtils; -import org.dromara.common.sms.config.properties.SmsProperties; -import org.dromara.common.sms.entity.SmsResult; -import org.dromara.common.sms.exception.SmsException; -import lombok.SneakyThrows; - -import java.util.Map; - -/** - * Aliyun 短信模板 - * - * @author Lion Li - * @version 4.2.0 - */ -public class AliyunSmsTemplate implements SmsTemplate { - - private SmsProperties properties; - - private Client client; - - @SneakyThrows(Exception.class) - public AliyunSmsTemplate(SmsProperties smsProperties) { - this.properties = smsProperties; - Config config = new Config() - // 您的AccessKey ID - .setAccessKeyId(smsProperties.getAccessKeyId()) - // 您的AccessKey Secret - .setAccessKeySecret(smsProperties.getAccessKeySecret()) - // 访问的域名 - .setEndpoint(smsProperties.getEndpoint()); - this.client = new Client(config); - } - - @Override - public SmsResult send(String phones, String templateId, Map param) { - if (StringUtils.isBlank(phones)) { - throw new SmsException("手机号不能为空"); - } - if (StringUtils.isBlank(templateId)) { - throw new SmsException("模板ID不能为空"); - } - SendSmsRequest req = new SendSmsRequest() - .setPhoneNumbers(phones) - .setSignName(properties.getSignName()) - .setTemplateCode(templateId) - .setTemplateParam(JsonUtils.toJsonString(param)); - try { - SendSmsResponse resp = client.sendSms(req); - return SmsResult.builder() - .isSuccess("OK".equals(resp.getBody().getCode())) - .message(resp.getBody().getMessage()) - .response(JsonUtils.toJsonString(resp)) - .build(); - } catch (Exception e) { - throw new SmsException(e.getMessage()); - } - } - -} diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/Sms4jSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/Sms4jSmsTemplate.java new file mode 100644 index 000000000..2fb123a2e --- /dev/null +++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/Sms4jSmsTemplate.java @@ -0,0 +1,58 @@ +package org.dromara.common.sms.core; + +import cn.hutool.json.JSONUtil; +import lombok.SneakyThrows; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.json.utils.JsonUtils; +import org.dromara.common.sms.config.properties.SmsProperties; +import org.dromara.common.sms.entity.SmsResult; +import org.dromara.common.sms.exception.SmsException; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.core.factory.SmsFactory; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Tencent 短信模板 + * + * @author Lion Li + * @version 4.2.0 + */ +public class Sms4jSmsTemplate implements SmsTemplate { + + private SmsProperties properties; + + @SneakyThrows(Exception.class) + public Sms4jSmsTemplate(SmsProperties smsProperties) { + this.properties = smsProperties; + } + + @Override + public SmsResult send(String phones, String templateId, Map param) { + if (StringUtils.isBlank(phones)) { + throw new SmsException("手机号不能为空"); + } + try { + SmsResponse resp; + if (StringUtils.isBlank(templateId)) { + String message = JSONUtil.toJsonStr(param); + resp = SmsFactory.createSmsBlend(properties.getSupplierType()).sendMessage(phones, message); + } else { + LinkedHashMap messages = new LinkedHashMap<>(param); + resp = SmsFactory.createSmsBlend(properties.getSupplierType()).sendMessage(phones, templateId, messages); + } + + SmsResult.SmsResultBuilder builder = SmsResult.builder(); + if ("OK".equals(resp.getCode())) { + builder.isSuccess(true).message(resp.getMessage()).response(JsonUtils.toJsonString(resp)); + } else { + builder.isSuccess(false).message(resp.getErrMessage()).response(JsonUtils.toJsonString(resp)); + } + return builder.build(); + } catch (Exception e) { + throw new SmsException(e.getMessage()); + } + } + +} diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java deleted file mode 100644 index 18d738408..000000000 --- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/core/TencentSmsTemplate.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.dromara.common.sms.core; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ArrayUtil; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.json.utils.JsonUtils; -import org.dromara.common.sms.config.properties.SmsProperties; -import org.dromara.common.sms.entity.SmsResult; -import org.dromara.common.sms.exception.SmsException; -import com.tencentcloudapi.common.Credential; -import com.tencentcloudapi.common.profile.ClientProfile; -import com.tencentcloudapi.common.profile.HttpProfile; -import com.tencentcloudapi.sms.v20190711.SmsClient; -import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest; -import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse; -import com.tencentcloudapi.sms.v20190711.models.SendStatus; -import lombok.SneakyThrows; - -import java.util.Arrays; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Tencent 短信模板 - * - * @author Lion Li - * @version 4.2.0 - */ -public class TencentSmsTemplate implements SmsTemplate { - - private SmsProperties properties; - - private SmsClient client; - - @SneakyThrows(Exception.class) - public TencentSmsTemplate(SmsProperties smsProperties) { - this.properties = smsProperties; - Credential credential = new Credential(smsProperties.getAccessKeyId(), smsProperties.getAccessKeySecret()); - HttpProfile httpProfile = new HttpProfile(); - httpProfile.setEndpoint(smsProperties.getEndpoint()); - ClientProfile clientProfile = new ClientProfile(); - clientProfile.setHttpProfile(httpProfile); - this.client = new SmsClient(credential, "", clientProfile); - } - - @Override - public SmsResult send(String phones, String templateId, Map param) { - if (StringUtils.isBlank(phones)) { - throw new SmsException("手机号不能为空"); - } - if (StringUtils.isBlank(templateId)) { - throw new SmsException("模板ID不能为空"); - } - SendSmsRequest req = new SendSmsRequest(); - Set set = Arrays.stream(phones.split(StringUtils.SEPARATOR)).map(p -> "+86" + p).collect(Collectors.toSet()); - req.setPhoneNumberSet(ArrayUtil.toArray(set, String.class)); - if (CollUtil.isNotEmpty(param)) { - req.setTemplateParamSet(ArrayUtil.toArray(param.values(), String.class)); - } - req.setTemplateID(templateId); - req.setSign(properties.getSignName()); - req.setSmsSdkAppid(properties.getSdkAppId()); - try { - SendSmsResponse resp = client.SendSms(req); - SmsResult.SmsResultBuilder builder = SmsResult.builder() - .isSuccess(true) - .message("send success") - .response(JsonUtils.toJsonString(resp)); - for (SendStatus sendStatus : resp.getSendStatusSet()) { - if (!"Ok".equals(sendStatus.getCode())) { - builder.isSuccess(false).message(sendStatus.getMessage()); - break; - } - } - return builder.build(); - } catch (Exception e) { - throw new SmsException(e.getMessage()); - } - } - -} diff --git a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 6988c7efa..bfa539a42 100644 --- a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,3 @@ org.dromara.common.sms.config.SmsConfig +org.dromara.sms4j.autoimmit.config.SmsAutowiredConfig +org.dromara.sms4j.autoimmit.config.SupplierConfig diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java index e130cae35..0154f3c46 100644 --- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java +++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/SmsController.java @@ -1,10 +1,10 @@ package org.dromara.demo.controller; +import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.sms.config.properties.SmsProperties; import org.dromara.common.sms.core.SmsTemplate; -import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -27,29 +27,6 @@ import java.util.Map; public class SmsController { private final SmsProperties smsProperties; -// private final SmsTemplate smsTemplate; // 可以使用spring注入 -// private final AliyunSmsTemplate smsTemplate; // 也可以注入某个厂家的模板工具 - - /** - * 发送短信Aliyun - * - * @param phones 电话号 - * @param templateId 模板ID - */ - @GetMapping("/sendAliyun") - public R sendAliyun(String phones, String templateId) { - if (!smsProperties.getEnabled()) { - return R.fail("当前系统没有开启短信功能!"); - } - if (!SpringUtils.containsBean("aliyunSmsTemplate")) { - return R.fail("阿里云依赖未引入!"); - } - SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); - Map map = new HashMap<>(1); - map.put("code", "1234"); - Object send = smsTemplate.send(phones, templateId, map); - return R.ok(send); - } /** * 发送短信Tencent @@ -57,18 +34,18 @@ public class SmsController { * @param phones 电话号 * @param templateId 模板ID */ - @GetMapping("/sendTencent") - public R sendTencent(String phones, String templateId) { + @GetMapping("/sendSms4j") + public R sendSms4j(String phones, String templateId) { if (!smsProperties.getEnabled()) { return R.fail("当前系统没有开启短信功能!"); } - if (!SpringUtils.containsBean("tencentSmsTemplate")) { - return R.fail("腾讯云依赖未引入!"); + if (!SpringUtils.containsBean("sms4jSmsTemplate")) { + return R.fail("Sms4j依赖未引入!"); } SmsTemplate smsTemplate = SpringUtils.getBean(SmsTemplate.class); Map map = new HashMap<>(1); // map.put("2", "测试测试"); - map.put("1", "1234"); + map.put("code", "123456"); Object send = smsTemplate.send(phones, templateId, map); return R.ok(send); }