pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/main/resources/application-dev.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/main/resources/application-prod.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
pom.xml
@@ -50,6 +50,10 @@ <qcloud.cos.version>5.6.72</qcloud.cos.version> <minio.version>8.3.8</minio.version> <!-- SMS é ç½® --> <aliyun.sms.version>2.0.9</aliyun.sms.version> <tencent.sms.version>3.1.500</tencent.sms.version> <!-- docker é ç½® --> <docker.registry.url>localhost</docker.registry.url> <docker.registry.host>http://${docker.registry.url}:2375</docker.registry.host> @@ -193,6 +197,18 @@ </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <version>${aliyun.sms.version}</version> </dependency> <dependency> <groupId>com.tencentcloudapi</groupId> <artifactId>tencentcloud-sdk-java</artifactId> <version>${tencent.sms.version}</version> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> <version>${spring-boot-admin.version}</version> @@ -297,6 +313,13 @@ <version>${ruoyi-vue-plus.version}</version> </dependency> <!-- SMSç信模å --> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-sms</artifactId> <version>${ruoyi-vue-plus.version}</version> </dependency> <!-- demo模å --> <dependency> <groupId>com.ruoyi</groupId> @@ -317,6 +340,7 @@ <module>ruoyi-demo</module> <module>ruoyi-extend</module> <module>ruoyi-oss</module> <module>ruoyi-sms</module> </modules> <packaging>pom</packaging> ruoyi-admin/src/main/resources/application-dev.yml
@@ -178,3 +178,15 @@ timeout: 0 # Socketè¿æ¥è¶ æ¶å¼ï¼å使¯«ç§ï¼ç¼ºçå¼ä¸è¶ æ¶ connectionTimeout: 0 --- # sms çä¿¡ sms: enabled: false # é¿éäº dysmsapi.aliyuncs.com # è ¾è®¯äº sms.tencentcloudapi.com endpoint: "dysmsapi.aliyuncs.com" accessKeyId: xxxxxxx accessKeySecret: xxxxxx signName: æµè¯ # è ¾è®¯ä¸ç¨ sdkAppId: ruoyi-admin/src/main/resources/application-prod.yml
@@ -181,3 +181,15 @@ timeout: 0 # Socketè¿æ¥è¶ æ¶å¼ï¼å使¯«ç§ï¼ç¼ºçå¼ä¸è¶ æ¶ connectionTimeout: 0 --- # sms çä¿¡ sms: enabled: false # é¿éäº dysmsapi.aliyuncs.com # è ¾è®¯äº sms.tencentcloudapi.com endpoint: "dysmsapi.aliyuncs.com" accessKeyId: xxxxxxx accessKeySecret: xxxxxx signName: æµè¯ # è ¾è®¯ä¸ç¨ sdkAppId: ruoyi-sms/pom.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,40 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ruoyi-vue-plus</artifactId> <groupId>com.ruoyi</groupId> <version>4.1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ruoyi-sms</artifactId> <description> SMSç信模å </description> <dependencies> <!-- éç¨å·¥å ·--> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common</artifactId> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.tencentcloudapi</groupId> <artifactId>tencentcloud-sdk-java</artifactId> <optional>true</optional> </dependency> </dependencies> </project> ruoyi-sms/src/main/java/com/ruoyi/sms/config/SmsConfig.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,44 @@ package com.ruoyi.sms.config; import com.ruoyi.sms.config.properties.SmsProperties; import com.ruoyi.sms.core.AliyunSmsTemplate; import com.ruoyi.sms.core.SmsTemplate; import com.ruoyi.sms.core.TencentSmsTemplate; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * çä¿¡é 置类 * * @author Lion Li * @version 4.2.0 */ @Configuration @ConditionalOnProperty(value = "sms.enabled", havingValue = "true") public class SmsConfig { @Configuration @ConditionalOnClass(com.aliyun.dysmsapi20170525.Client.class) static class AliyunSmsConfig { @Bean public SmsTemplate aliyunSmsTemplate(SmsProperties smsProperties) { return new AliyunSmsTemplate(smsProperties); } } @Configuration @ConditionalOnClass(com.tencentcloudapi.sms.v20190711.SmsClient.class) static class TencentSmsConfig { @Bean public SmsTemplate tencentSmsTemplate(SmsProperties smsProperties) { return new TencentSmsTemplate(smsProperties); } } } ruoyi-sms/src/main/java/com/ruoyi/sms/config/properties/SmsProperties.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,47 @@ package com.ruoyi.sms.config.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * SMSçä¿¡ é ç½®å±æ§ * * @author Lion Li * @version 4.2.0 */ @Data @Component @ConfigurationProperties(prefix = "sms") 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; } ruoyi-sms/src/main/java/com/ruoyi/sms/core/AliyunSmsTemplate.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,65 @@ package com.ruoyi.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 com.ruoyi.common.utils.JsonUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.sms.config.properties.SmsProperties; import com.ruoyi.sms.entity.SmsResult; import com.ruoyi.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); } public SmsResult send(String phones, String templateId, Map<String, String> 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(resp) .build(); } catch (Exception e) { throw new SmsException(e.getMessage()); } } } ruoyi-sms/src/main/java/com/ruoyi/sms/core/SmsTemplate.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,26 @@ package com.ruoyi.sms.core; import com.ruoyi.sms.entity.SmsResult; import java.util.Map; /** * çä¿¡æ¨¡æ¿ * * @author Lion Li * @version 4.2.0 */ public interface SmsTemplate { /** * åéçä¿¡ * * @param phones çµè¯å·(å¤ä¸ªéå·åå²) * @param templateId 模æ¿id * @param param 模æ¿å¯¹åºåæ° * é¿é éä½¿ç¨ æ¨¡æ¿åéå称对åºå 容 ä¾å¦: code=1234 * è ¾è®¯ éä½¿ç¨ æ¨¡æ¿åé顺åºå¯¹åºå 容 ä¾å¦: 1=1234, 1为模æ¿å 第ä¸ä¸ªåæ° */ SmsResult send(String phones, String templateId, Map<String, String> param); } ruoyi-sms/src/main/java/com/ruoyi/sms/core/TencentSmsTemplate.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,80 @@ package com.ruoyi.sms.core; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.sms.config.properties.SmsProperties; import com.ruoyi.sms.entity.SmsResult; import com.ruoyi.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); } public SmsResult send(String phones, String templateId, Map<String, String> param) { if (StringUtils.isBlank(phones)) { throw new SmsException("ææºå·ä¸è½ä¸ºç©º"); } if (StringUtils.isBlank(templateId)) { throw new SmsException("模æ¿IDä¸è½ä¸ºç©º"); } SendSmsRequest req = new SendSmsRequest(); Set<String> set = Arrays.stream(phones.split(",")).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(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()); } } } ruoyi-sms/src/main/java/com/ruoyi/sms/entity/SmsResult.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,29 @@ package com.ruoyi.sms.entity; import lombok.Builder; import lombok.Data; /** * ä¸ä¼ è¿åä½ * * @author Lion Li */ @Data @Builder public class SmsResult { /** * æ¯å¦æå */ private boolean isSuccess; /** * ååºæ¶æ¯ */ private String message; /** * å®é ååºä½ */ private Object response; } ruoyi-sms/src/main/java/com/ruoyi/sms/exception/SmsException.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,16 @@ package com.ruoyi.sms.exception; /** * Smså¼å¸¸ç±» * * @author Lion Li */ public class SmsException extends RuntimeException { private static final long serialVersionUID = 1L; public SmsException(String msg) { super(msg); } }