Commit 37c39365ec4e0e7a5f043943d6ea854da6f7d6f6

Authored by zengzefeng
1 parent df8bda53

重构短信功能

Showing 40 changed files with 365 additions and 477 deletions
sql/ruoyi-vue-pro.sql
@@ -892,9 +892,8 @@ DROP TABLE IF EXISTS `sms_channel`; @@ -892,9 +892,8 @@ DROP TABLE IF EXISTS `sms_channel`;
892 CREATE TABLE `sms_channel` ( 892 CREATE TABLE `sms_channel` (
893 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增编号', 893 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
894 `code` varchar(50) not null COMMENT '编码(来自枚举类 阿里、华为、七牛等)', 894 `code` varchar(50) not null COMMENT '编码(来自枚举类 阿里、华为、七牛等)',
895 - `api_key` varchar(100) NOT NULL COMMENT '账号id', -- add  
896 - `api_secret` varchar(100) NOT NULL COMMENT '账号秘钥', -- add  
897 - `priority` tinyint(8) NOT NULL default 1 COMMENT '优先级(存在多个签名时,选择值最小的,渠道不可用时,按优先级从小到大切换)', -- add 895 + `api_key` varchar(100) NOT NULL COMMENT '账号id',
  896 + `api_secret` varchar(100) NOT NULL COMMENT '账号秘钥',
898 `api_signature_id` varchar(100) NOT NULL COMMENT '实际渠道签名唯一标识', 897 `api_signature_id` varchar(100) NOT NULL COMMENT '实际渠道签名唯一标识',
899 `name` varchar(50) not null COMMENT '名称', 898 `name` varchar(50) not null COMMENT '名称',
900 `signature` varchar(50) not null COMMENT '签名值', 899 `signature` varchar(50) not null COMMENT '签名值',
@@ -919,15 +918,14 @@ DROP TABLE IF EXISTS `sms_template`; @@ -919,15 +918,14 @@ DROP TABLE IF EXISTS `sms_template`;
919 CREATE TABLE `sms_template` ( 918 CREATE TABLE `sms_template` (
920 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增编号', 919 `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
921 `channel_code` varchar(50) not null COMMENT '短信渠道编码(来自枚举类)', 920 `channel_code` varchar(50) not null COMMENT '短信渠道编码(来自枚举类)',
922 - `channel_id` bigint(20) not null COMMENT '短信渠道id (对于前端来说就是绑定一个签名)', -- add 921 + `channel_id` bigint(20) not null COMMENT '短信渠道id (对于前端来说就是绑定一个签名)',
923 `type` tinyint(4) NOT NULL default 1 COMMENT '消息类型 [0验证码 1短信通知 2推广短信 3国际/港澳台消息]', 922 `type` tinyint(4) NOT NULL default 1 COMMENT '消息类型 [0验证码 1短信通知 2推广短信 3国际/港澳台消息]',
924 - `biz_code` varchar(50) not null COMMENT '业务编码(来自数据字典, 用户自定义业务场景 一个场景可以有多个模板)', -- add  
925 - `priority` tinyint(8) NOT NULL default 1 COMMENT '优先级(默认直接继承渠道表的,逻辑也与渠道表的一致,可以针对每个biz_code进行修改)',-- add 923 + `biz_code` varchar(50) not null COMMENT '业务编码(来自数据字典, 用户自定义业务场景 一个场景可以有多个模板)',
926 `code` varchar(50) not null COMMENT '编码', 924 `code` varchar(50) not null COMMENT '编码',
927 `name` varchar(50) not null COMMENT '名称', 925 `name` varchar(50) not null COMMENT '名称',
928 `api_template_id` varchar(100) NOT NULL COMMENT '实际渠道模板唯一标识', 926 `api_template_id` varchar(100) NOT NULL COMMENT '实际渠道模板唯一标识',
929 `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容', 927 `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容',
930 - `params` varchar(200) NOT NULL DEFAULT '' COMMENT '参数数组(自动根据内容生成)', -- add 928 + `params` varchar(200) NOT NULL DEFAULT '' COMMENT '参数数组(自动根据内容生成)',
931 `remark` varchar(200) NOT NULL COMMENT '备注', 929 `remark` varchar(200) NOT NULL COMMENT '备注',
932 930
933 `status` tinyint(4) NOT NULL default 0 COMMENT '启用状态(0正常 1停用)', 931 `status` tinyint(4) NOT NULL default 0 COMMENT '启用状态(0正常 1停用)',
src/main/java/cn/iocoder/dashboard/framework/msg/sms/config/SmsConfiguration.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.config;  
2 -  
3 -import cn.iocoder.dashboard.framework.msg.sms.factory.DefaultSmsSenderFactory;  
4 -import cn.iocoder.dashboard.framework.msg.sms.intercepter.AbstractSmsIntercepterChain;  
5 -import cn.iocoder.dashboard.framework.msg.sms.intercepter.DefaultSmsIntercepterChain;  
6 -import cn.iocoder.dashboard.framework.msg.sms.intercepter.SmsLogIntercepter;  
7 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsChannelAllVO;  
8 -import cn.iocoder.dashboard.modules.msg.service.sms.SmsChannelService;  
9 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
10 -import org.springframework.context.annotation.Bean;  
11 -import org.springframework.context.annotation.Configuration;  
12 -  
13 -import javax.annotation.Resource;  
14 -import java.util.List;  
15 -  
16 -/**  
17 - * 短信服务配置  
18 - *  
19 - * @author guer  
20 - */  
21 -@Configuration  
22 -@ConditionalOnProperty("sms.enabled")  
23 -public class SmsConfiguration {  
24 -  
25 - @Resource  
26 - private SmsChannelService channelService;  
27 -  
28 -  
29 - @Bean  
30 - public AbstractSmsIntercepterChain smsIntercepterChain() {  
31 - DefaultSmsIntercepterChain intercepterChain = new DefaultSmsIntercepterChain();  
32 - //添加拦截器  
33 - intercepterChain.addSmsIntercepter(new SmsLogIntercepter());  
34 - return intercepterChain;  
35 - }  
36 -  
37 - @Bean  
38 - public DefaultSmsSenderFactory smsSenderFactory(AbstractSmsIntercepterChain intercepterChain) {  
39 - DefaultSmsSenderFactory defaultSmsSenderFactory = new DefaultSmsSenderFactory();  
40 - List<SmsChannelAllVO> smsChannelAllVOList = channelService.listChannelAllEnabledInfo();  
41 - //初始化渠道、模板信息  
42 - defaultSmsSenderFactory.init(smsChannelAllVOList);  
43 - //注入拦截器链  
44 - defaultSmsSenderFactory.setIntercepterChain(intercepterChain);  
45 - return defaultSmsSenderFactory;  
46 - }  
47 -  
48 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/factory/DefaultSmsSenderFactory.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.factory;  
2 -  
3 -import cn.hutool.core.util.ObjectUtil;  
4 -import cn.iocoder.dashboard.common.enums.SmsChannelEnum;  
5 -import cn.iocoder.dashboard.common.exception.ServiceException;  
6 -import cn.iocoder.dashboard.framework.msg.sms.SmsSender;  
7 -import cn.iocoder.dashboard.framework.msg.sms.impl.ali.AliSmsSender;  
8 -import cn.iocoder.dashboard.framework.msg.sms.intercepter.AbstractSmsIntercepterChain;  
9 -import cn.iocoder.dashboard.framework.msg.sms.proxy.DefaultSmsSenderProxy;  
10 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsChannelAllVO;  
11 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsTemplateVO;  
12 -import lombok.Setter;  
13 -  
14 -import java.util.List;  
15 -import java.util.concurrent.ConcurrentHashMap;  
16 -import java.util.concurrent.locks.Lock;  
17 -import java.util.concurrent.locks.ReadWriteLock;  
18 -import java.util.concurrent.locks.ReentrantReadWriteLock;  
19 -  
20 -import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;  
21 -  
22 -/**  
23 - * 短信发送者工厂  
24 - *  
25 - * @author zzf  
26 - * @date 2021/1/25 16:18  
27 - */  
28 -public class DefaultSmsSenderFactory {  
29 -  
30 - /**  
31 - * sender索引  
32 - * key: {@link SmsTemplateVO#getBizCode()}  
33 - * value: {@link SmsSender}  
34 - */  
35 - private final ConcurrentHashMap<String, SmsSender<?>> bizCode2SenderMap = new ConcurrentHashMap<>(8);  
36 -  
37 - /**  
38 - * sender索引  
39 - * key: {@link SmsTemplateVO#getCode()}  
40 - * value: {@link SmsSender}  
41 - */  
42 - private final ConcurrentHashMap<String, SmsSender<?>> templateCode2SenderMap = new ConcurrentHashMap<>(8);  
43 -  
44 -  
45 - @Setter  
46 - private AbstractSmsIntercepterChain intercepterChain;  
47 -  
48 - /**  
49 - * 读写锁  
50 - */  
51 - private final ReadWriteLock lock = new ReentrantReadWriteLock();  
52 - private final Lock readLock = lock.readLock();  
53 - private final Lock writeLock = lock.writeLock();  
54 -  
55 -  
56 - public void init(List<SmsChannelAllVO> smsChannelAllVOList) {  
57 - if (ObjectUtil.isEmpty(smsChannelAllVOList)) {  
58 - throw new ServiceException(SMS_CHANNEL_NOT_FOUND);  
59 - }  
60 - try {  
61 - writeLock.lock();  
62 - addSender(smsChannelAllVOList);  
63 - } finally {  
64 - writeLock.unlock();  
65 - }  
66 - }  
67 -  
68 - public SmsSender<?> getSenderByBizCode(String bizCode) {  
69 - return getSmsSender(bizCode, bizCode2SenderMap);  
70 - }  
71 -  
72 - public SmsSender<?> getSenderByTemplateCode(String templateCode) {  
73 - return getSmsSender(templateCode, templateCode2SenderMap);  
74 - }  
75 -  
76 - private SmsSender<?> getSmsSender(String templateCode, ConcurrentHashMap<String, SmsSender<?>> cacheMap) {  
77 - try {  
78 - readLock.lock();  
79 - SmsSender<?> smsSender = cacheMap.get(templateCode);  
80 - if (smsSender == null) {  
81 - throw new ServiceException(SMS_SENDER_NOT_FOUND);  
82 - }  
83 - return smsSender;  
84 - } finally {  
85 - readLock.unlock();  
86 - }  
87 - }  
88 -  
89 - public void flush(List<SmsChannelAllVO> smsChannelAllVOList) {  
90 - try {  
91 - writeLock.lock();  
92 - bizCode2SenderMap.clear();  
93 - templateCode2SenderMap.clear();  
94 - addSender(smsChannelAllVOList);  
95 - } finally {  
96 - writeLock.unlock();  
97 - }  
98 - }  
99 -  
100 -  
101 - private void addSender(List<SmsChannelAllVO> smsChannelAllVOList) {  
102 - smsChannelAllVOList.forEach(channelAllVO -> addSender(SmsChannelEnum.getByCode(channelAllVO.getCode()), channelAllVO));  
103 - }  
104 -  
105 - private void addSender(SmsChannelEnum channelEnum, SmsChannelAllVO channelAllVO) {  
106 - if (channelEnum == null) {  
107 - throw new ServiceException(INVALID_CHANNEL_CODE);  
108 - }  
109 - List<SmsTemplateVO> templateList = channelAllVO.getTemplateList();  
110 - if (ObjectUtil.isEmpty(templateList)) {  
111 - throw new ServiceException(SMS_TEMPLATE_NOT_FOUND);  
112 - }  
113 -  
114 - SmsSender<?> aliSmsSender = getSender(channelEnum, channelAllVO);  
115 -  
116 -  
117 - templateList.forEach(smsTemplateVO -> {  
118 - bizCode2SenderMap.put(smsTemplateVO.getBizCode(), aliSmsSender);  
119 - templateCode2SenderMap.put(smsTemplateVO.getCode(), aliSmsSender);  
120 - });  
121 - }  
122 -  
123 - private SmsSender<?> getSender(SmsChannelEnum channelEnum, SmsChannelAllVO channelAllVO) {  
124 - switch (channelEnum) {  
125 - case ALI:  
126 - return new DefaultSmsSenderProxy<>(new AliSmsSender(channelAllVO), intercepterChain);  
127 - // TODO fill more channel  
128 - default:  
129 - break;  
130 - }  
131 - throw new ServiceException(SMS_SENDER_NOT_FOUND);  
132 - }  
133 -  
134 -  
135 -  
136 -  
137 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/intercepter/AbstractSmsIntercepterChain.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.intercepter;  
2 -  
3 -import lombok.Getter;  
4 -  
5 -import java.util.ArrayList;  
6 -import java.util.Collections;  
7 -import java.util.List;  
8 -  
9 -/**  
10 - * 消息父接口  
11 - *  
12 - * @author zzf  
13 - * @date 2021/1/22 15:46  
14 - */  
15 -public abstract class AbstractSmsIntercepterChain {  
16 -  
17 - @Getter  
18 - protected final List<SmsIntercepter> intercepterList = new ArrayList<>(8);  
19 -  
20 -  
21 - /**  
22 - * 添加短信拦截器  
23 - *  
24 - * @param smsIntercepter 短信拦截器  
25 - */  
26 - public void addSmsIntercepter(SmsIntercepter smsIntercepter) {  
27 - addSmsIntercepter(Collections.singletonList(smsIntercepter));  
28 - }  
29 -  
30 - /**  
31 - * 添加短信拦截器  
32 - *  
33 - * @param smsIntercepterList 短信拦截器数组  
34 - */  
35 - abstract void addSmsIntercepter(List<SmsIntercepter> smsIntercepterList);  
36 -  
37 -  
38 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/intercepter/DefaultSmsIntercepterChain.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.intercepter;  
2 -  
3 -import java.util.Comparator;  
4 -import java.util.List;  
5 -  
6 -/**  
7 - * 消息父接口  
8 - *  
9 - * @author zzf  
10 - * @date 2021/1/22 15:46  
11 - */  
12 -public class DefaultSmsIntercepterChain extends AbstractSmsIntercepterChain {  
13 -  
14 - @Override  
15 - public void addSmsIntercepter(List<SmsIntercepter> smsIntercepterList) {  
16 - intercepterList.addAll(smsIntercepterList);  
17 - //排序  
18 - intercepterList.sort(Comparator.comparingInt(SmsIntercepter::getOrder));  
19 - }  
20 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/intercepter/SmsIntercepter.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.intercepter;  
2 -  
3 -import cn.iocoder.dashboard.framework.msg.sms.SmsBody;  
4 -import cn.iocoder.dashboard.framework.msg.sms.SmsResult;  
5 -  
6 -import java.util.Collection;  
7 -  
8 -/**  
9 - * 消息父接口  
10 - *  
11 - * @author zzf  
12 - * @date 2021/1/22 15:46  
13 - */  
14 -public interface SmsIntercepter {  
15 -  
16 - /**  
17 - * 监听发送前  
18 - *  
19 - * @param msgBody 消息体  
20 - * @param targets 发送对象数组  
21 - */  
22 - void beforeSender(SmsBody msgBody, Collection<String> targets);  
23 -  
24 - /**  
25 - * 监听发送后  
26 - *  
27 - * @param msgBody 消息体  
28 - * @param targets 发送对象数组  
29 - * @param resultBody 返回对象  
30 - */  
31 - <T> void afterSender(SmsBody msgBody, Collection<String> targets, SmsResult<T> resultBody);  
32 -  
33 - /**  
34 - * 排序值,拦截器根据order值顺序执行  
35 - * <p>  
36 - * 值越小,越早执行  
37 - *  
38 - * @return 排序值  
39 - */  
40 - int getOrder();  
41 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/proxy/DefaultSmsSenderProxy.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.proxy;  
2 -  
3 -import cn.hutool.core.util.ObjectUtil;  
4 -import cn.iocoder.dashboard.framework.msg.sms.SmsBody;  
5 -import cn.iocoder.dashboard.framework.msg.sms.SmsResult;  
6 -import cn.iocoder.dashboard.framework.msg.sms.SmsSender;  
7 -import cn.iocoder.dashboard.framework.msg.sms.intercepter.AbstractSmsIntercepterChain;  
8 -  
9 -import java.util.Collection;  
10 -  
11 -/**  
12 - * 消息父接口  
13 - *  
14 - * @author zzf  
15 - * @date 2021/1/22 15:46  
16 - */  
17 -public class DefaultSmsSenderProxy<R> implements SmsSender<R> {  
18 -  
19 - private final SmsSender<R> smsSender;  
20 - private final AbstractSmsIntercepterChain chain;  
21 -  
22 - @Override  
23 - public SmsResult<R> send(SmsBody msgBody, Collection<String> targets) {  
24 - if (ObjectUtil.isNotNull(chain) && ObjectUtil.isNotEmpty(chain.getIntercepterList())) {  
25 - chain.getIntercepterList().forEach(s -> s.beforeSender(msgBody, targets));  
26 - }  
27 -  
28 - SmsResult<R> resultBody = smsSender.send(msgBody, targets);  
29 -  
30 - if (ObjectUtil.isNotNull(chain) && ObjectUtil.isNotEmpty(chain.getIntercepterList())) {  
31 - chain.getIntercepterList().forEach(s -> s.afterSender(msgBody, targets, resultBody));  
32 - }  
33 - return resultBody;  
34 - }  
35 -  
36 - public DefaultSmsSenderProxy(SmsSender<R> smsSender,  
37 - AbstractSmsIntercepterChain chain) {  
38 - this.smsSender = smsSender;  
39 - this.chain = chain;  
40 - }  
41 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/proxy/SmsSenderProxy.java deleted
1 -package cn.iocoder.dashboard.framework.msg.sms.proxy;  
2 -  
3 -import cn.iocoder.dashboard.framework.msg.sms.SmsSender;  
4 -import cn.iocoder.dashboard.framework.msg.sms.intercepter.SmsIntercepter;  
5 -  
6 -import java.util.Collections;  
7 -import java.util.List;  
8 -  
9 -/**  
10 - * 消息父接口  
11 - *  
12 - * @author zzf  
13 - * @date 2021/1/22 15:46  
14 - */  
15 -public interface SmsSenderProxy<R> extends SmsSender<R> {  
16 -  
17 - /**  
18 - * 添加短信拦截器  
19 - *  
20 - * @param smsIntercepter 短信拦截器  
21 - */  
22 - default void addSmsIntercepter(SmsIntercepter smsIntercepter) {  
23 - addSmsIntercepter(Collections.singletonList(smsIntercepter));  
24 - }  
25 -  
26 - /**  
27 - * 添加短信拦截器  
28 - *  
29 - * @param smsIntercepterList 短信拦截器数组  
30 - */  
31 - void addSmsIntercepter(List<SmsIntercepter> smsIntercepterList);  
32 -  
33 -  
34 -}  
src/main/java/cn/iocoder/dashboard/framework/msg/sms/SmsBody.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/SmsBody.java
1 -package cn.iocoder.dashboard.framework.msg.sms; 1 +package cn.iocoder.dashboard.framework.sms;
2 2
3 import cn.iocoder.dashboard.util.json.JsonUtils; 3 import cn.iocoder.dashboard.util.json.JsonUtils;
4 import lombok.Data; 4 import lombok.Data;
src/main/java/cn/iocoder/dashboard/framework/msg/sms/SmsSender.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/SmsClient.java
1 -package cn.iocoder.dashboard.framework.msg.sms; 1 +package cn.iocoder.dashboard.framework.sms;
2 2
3 import org.apache.commons.lang3.StringUtils; 3 import org.apache.commons.lang3.StringUtils;
4 4
@@ -12,22 +12,22 @@ import java.util.Collections; @@ -12,22 +12,22 @@ import java.util.Collections;
12 * @author zzf 12 * @author zzf
13 * @date 2021/1/25 14:14 13 * @date 2021/1/25 14:14
14 */ 14 */
15 -public interface SmsSender<R> { 15 +public interface SmsClient<R> {
16 16
17 /** 17 /**
18 - * 发送通知 18 + * 发送消息
19 * 19 *
20 - * @param msgBody 通知内容 20 + * @param msgBody 消息内容
21 * @param targets 发送对象列表 21 * @param targets 发送对象列表
22 * @return 是否发送成功 22 * @return 是否发送成功
23 */ 23 */
24 SmsResult<R> send(SmsBody msgBody, Collection<String> targets); 24 SmsResult<R> send(SmsBody msgBody, Collection<String> targets);
25 25
26 /** 26 /**
27 - * 发送通知 27 + * 发送消息
28 * 28 *
29 - * @param msgBody 通知内容  
30 - * @param target 发送对象列表 29 + * @param msgBody 消息内容
  30 + * @param target 发送对象
31 * @return 是否发送成功 31 * @return 是否发送成功
32 */ 32 */
33 default SmsResult<R> send(SmsBody msgBody, String target) { 33 default SmsResult<R> send(SmsBody msgBody, String target) {
@@ -39,9 +39,9 @@ public interface SmsSender&lt;R&gt; { @@ -39,9 +39,9 @@ public interface SmsSender&lt;R&gt; {
39 } 39 }
40 40
41 /** 41 /**
42 - * 发送通知 42 + * 发送消息
43 * 43 *
44 - * @param msgBody 通知内容 44 + * @param msgBody 消息内容
45 * @param targets 发送对象列表 45 * @param targets 发送对象列表
46 * @return 是否发送成功 46 * @return 是否发送成功
47 */ 47 */
@@ -53,6 +53,46 @@ public interface SmsSender&lt;R&gt; { @@ -53,6 +53,46 @@ public interface SmsSender&lt;R&gt; {
53 return send(msgBody, Arrays.asList(targets)); 53 return send(msgBody, Arrays.asList(targets));
54 } 54 }
55 55
  56 +
  57 + /**
  58 + * 异步发送消息
  59 + *
  60 + * @param msgBody 消息内容
  61 + * @param targets 发送对象列表
  62 + * @return 是否发送成功
  63 + */
  64 + SmsResult<R> sendAsync(SmsBody msgBody, Collection<String> targets);
  65 +
  66 + /**
  67 + * 异步发送消息
  68 + *
  69 + * @param msgBody 消息内容
  70 + * @param target 发送对象
  71 + * @return 是否发送成功
  72 + */
  73 + default SmsResult<R> sendAsync(SmsBody msgBody, String target) {
  74 + if (StringUtils.isBlank(target)) {
  75 + return failResult("target must not null.");
  76 + }
  77 +
  78 + return sendAsync(msgBody, Collections.singletonList(target));
  79 + }
  80 +
  81 + /**
  82 + * 异步发送消息
  83 + *
  84 + * @param msgBody 消息内容
  85 + * @param targets 发送对象列表
  86 + * @return 是否发送成功
  87 + */
  88 + default SmsResult<R> sendAsync(SmsBody msgBody, String... targets) {
  89 + if (targets == null) {
  90 + return failResult("targets must not null.");
  91 + }
  92 +
  93 + return sendAsync(msgBody, Arrays.asList(targets));
  94 + }
  95 +
56 default SmsResult<R> failResult() { 96 default SmsResult<R> failResult() {
57 SmsResult<R> resultBody = new SmsResult<>(); 97 SmsResult<R> resultBody = new SmsResult<>();
58 resultBody.setSuccess(false); 98 resultBody.setSuccess(false);
src/main/java/cn/iocoder/dashboard/framework/sms/SmsClientAdapter.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.sms;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.dashboard.common.exception.ServiceException;
  5 +
  6 +import java.util.Collection;
  7 +import java.util.Collections;
  8 +import java.util.Map;
  9 +
  10 +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.SMS_CHANNEL_NOT_INIT;
  11 +
  12 +/**
  13 + * 抽象短信客户端工厂
  14 + *
  15 + * @author zzf
  16 + * @date 2021/1/28 14:01
  17 + */
  18 +public class SmsClientAdapter {
  19 +
  20 + private final Map<Long, SmsClient<?>> smsSenderMap;
  21 +
  22 + public SmsClientAdapter(Map<Long, SmsClient<?>> smsSenderMap) {
  23 + if (ObjectUtil.isEmpty(smsSenderMap)) {
  24 + throw new ServiceException(SMS_CHANNEL_NOT_INIT);
  25 + }
  26 + this.smsSenderMap = smsSenderMap;
  27 + }
  28 +
  29 + public void flushClient(Map<Long, SmsClient<?>> smsSenderMap) {
  30 + this.smsSenderMap.clear();
  31 + smsSenderMap.putAll(Collections.unmodifiableMap(smsSenderMap));
  32 + }
  33 +
  34 + public SmsResult<?> send(Long channelId, SmsBody smsBody, Collection<String> targetPhone) {
  35 + SmsClient<?> smsClient = getSmsSender(channelId);
  36 + return smsClient.send(smsBody, targetPhone);
  37 + }
  38 +
  39 + private SmsClient<?> getSmsSender(Long channelId) {
  40 + return smsSenderMap.get(channelId);
  41 + }
  42 +}
src/main/java/cn/iocoder/dashboard/framework/msg/sms/SmsResult.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/SmsResult.java
1 -package cn.iocoder.dashboard.framework.msg.sms; 1 +package cn.iocoder.dashboard.framework.sms;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 4
src/main/java/cn/iocoder/dashboard/modules/msg/package-info.java deleted
1 -/**  
2 - * msg 包,专门专门用于发送消息的功能,支撑上层的通用与核心业务。  
3 - * 例如说:短信、邮件、app通知等等  
4 - *  
5 - */  
6 -package cn.iocoder.dashboard.modules.msg;  
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/SmsChannelController.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms; 1 +package cn.iocoder.dashboard.modules.system.controller.sms;
2 2
3 import cn.iocoder.dashboard.common.pojo.CommonResult; 3 import cn.iocoder.dashboard.common.pojo.CommonResult;
4 import cn.iocoder.dashboard.common.pojo.PageResult; 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelCreateReqVO;  
6 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelPageReqVO;  
7 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.resp.SmsChannelEnumRespVO;  
8 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsChannelDO;  
9 -import cn.iocoder.dashboard.modules.msg.service.sms.SmsChannelService; 5 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
  8 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
  9 +import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
10 import io.swagger.annotations.Api; 10 import io.swagger.annotations.Api;
11 import io.swagger.annotations.ApiOperation; 11 import io.swagger.annotations.ApiOperation;
12 import org.springframework.validation.annotation.Validated; 12 import org.springframework.validation.annotation.Validated;
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/SmsTemplateController.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsTemplateController.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms; 1 +package cn.iocoder.dashboard.modules.system.controller.sms;
2 2
3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 import cn.iocoder.dashboard.common.pojo.CommonResult; 4 import cn.iocoder.dashboard.common.pojo.CommonResult;
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/vo/SmsChannelAllVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/SmsChannelAllVO.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms.vo; 1 +package cn.iocoder.dashboard.modules.system.controller.sms.vo;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/vo/SmsTemplateVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/SmsTemplateVO.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms.vo; 1 +package cn.iocoder.dashboard.modules.system.controller.sms.vo;
2 2
3 import lombok.Data; 3 import lombok.Data;
4 import lombok.EqualsAndHashCode; 4 import lombok.EqualsAndHashCode;
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/vo/req/SmsChannelCreateReqVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelCreateReqVO.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms.vo.req; 1 +package cn.iocoder.dashboard.modules.system.controller.sms.vo.req;
2 2
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/vo/req/SmsChannelPageReqVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/req/SmsChannelPageReqVO.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms.vo.req; 1 +package cn.iocoder.dashboard.modules.system.controller.sms.vo.req;
2 2
3 import cn.iocoder.dashboard.common.pojo.PageParam; 3 import cn.iocoder.dashboard.common.pojo.PageParam;
4 import io.swagger.annotations.ApiModel; 4 import io.swagger.annotations.ApiModel;
@@ -7,11 +7,6 @@ import lombok.AllArgsConstructor; @@ -7,11 +7,6 @@ import lombok.AllArgsConstructor;
7 import lombok.Data; 7 import lombok.Data;
8 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
9 import lombok.NoArgsConstructor; 9 import lombok.NoArgsConstructor;
10 -import org.springframework.format.annotation.DateTimeFormat;  
11 -  
12 -import java.util.Date;  
13 -  
14 -import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
15 10
16 @ApiModel("消息渠道分页 Request VO") 11 @ApiModel("消息渠道分页 Request VO")
17 @Data 12 @Data
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/vo/resp/SmsChannelEnumRespVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/resp/SmsChannelEnumRespVO.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms.vo.resp; 1 +package cn.iocoder.dashboard.modules.system.controller.sms.vo.resp;
2 2
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 import lombok.Data; 4 import lombok.Data;
src/main/java/cn/iocoder/dashboard/modules/msg/controller/sms/vo/resp/SmsChannelPageRespVO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/vo/resp/SmsChannelPageRespVO.java
1 -package cn.iocoder.dashboard.modules.msg.controller.sms.vo.resp; 1 +package cn.iocoder.dashboard.modules.system.controller.sms.vo.resp;
2 2
3 import cn.iocoder.dashboard.common.pojo.PageParam; 3 import cn.iocoder.dashboard.common.pojo.PageParam;
4 import io.swagger.annotations.ApiModel; 4 import io.swagger.annotations.ApiModel;
src/main/java/cn/iocoder/dashboard/modules/msg/convert/sms/SmsChannelConvert.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java
1 -package cn.iocoder.dashboard.modules.msg.convert.sms; 1 +package cn.iocoder.dashboard.modules.system.convert.sms;
2 2
3 import cn.iocoder.dashboard.common.enums.SmsChannelEnum; 3 import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
4 import cn.iocoder.dashboard.common.pojo.PageResult; 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsChannelAllVO;  
6 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelCreateReqVO;  
7 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.resp.SmsChannelEnumRespVO;  
8 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsChannelDO; 5 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
  8 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
9 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; 9 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
10 import com.baomidou.mybatisplus.core.metadata.IPage; 10 import com.baomidou.mybatisplus.core.metadata.IPage;
11 import org.mapstruct.Mapper; 11 import org.mapstruct.Mapper;
src/main/java/cn/iocoder/dashboard/modules/msg/convert/sms/SmsTemplateConvert.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsTemplateConvert.java
1 -package cn.iocoder.dashboard.modules.msg.convert.sms; 1 +package cn.iocoder.dashboard.modules.system.convert.sms;
2 2
3 import cn.iocoder.dashboard.common.pojo.PageResult; 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsTemplateVO;  
5 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsChannelDO;  
6 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsTemplateDO; 4 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsTemplateVO;
  5 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
  6 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
7 import com.baomidou.mybatisplus.core.metadata.IPage; 7 import com.baomidou.mybatisplus.core.metadata.IPage;
8 import org.mapstruct.Mapper; 8 import org.mapstruct.Mapper;
9 import org.mapstruct.Mapping; 9 import org.mapstruct.Mapping;
src/main/java/cn/iocoder/dashboard/modules/msg/dal/mysql/dao/sms/SmsChannelMapper.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsChannelMapper.java
1 -package cn.iocoder.dashboard.modules.msg.dal.mysql.dao.sms; 1 +package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 4 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
5 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils; 5 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
6 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelPageReqVO;  
7 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsChannelDO; 6 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
  7 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
8 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 8 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
9 import com.baomidou.mybatisplus.core.mapper.BaseMapper; 9 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
10 import com.baomidou.mybatisplus.core.metadata.IPage; 10 import com.baomidou.mybatisplus.core.metadata.IPage;
src/main/java/cn/iocoder/dashboard/modules/msg/dal/mysql/dao/sms/SmsLogMapper.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsLogMapper.java
1 -package cn.iocoder.dashboard.modules.msg.dal.mysql.dao.sms; 1 +package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
2 2
3 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsLog; 3 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsLog;
4 import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
6 6
src/main/java/cn/iocoder/dashboard/modules/msg/dal/mysql/dao/sms/SmsTemplateMapper.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsTemplateMapper.java
1 -package cn.iocoder.dashboard.modules.msg.dal.mysql.dao.sms; 1 +package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
2 2
3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsTemplateDO; 4 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 import com.baomidou.mybatisplus.core.mapper.BaseMapper; 6 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
7 import org.apache.ibatis.annotations.Mapper; 7 import org.apache.ibatis.annotations.Mapper;
src/main/java/cn/iocoder/dashboard/modules/msg/dal/mysql/daoobject/sms/SmsChannelDO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsChannelDO.java
1 -package cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms; 1 +package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms;
2 2
3 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
4 import com.baomidou.mybatisplus.annotation.TableName; 4 import com.baomidou.mybatisplus.annotation.TableName;
src/main/java/cn/iocoder/dashboard/modules/msg/dal/mysql/daoobject/sms/SmsLog.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsLog.java
1 -package cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms; 1 +package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms;
2 2
3 import com.baomidou.mybatisplus.annotation.TableName; 3 import com.baomidou.mybatisplus.annotation.TableName;
4 import lombok.Data; 4 import lombok.Data;
src/main/java/cn/iocoder/dashboard/modules/msg/dal/mysql/daoobject/sms/SmsTemplateDO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsTemplateDO.java
1 -package cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms; 1 +package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms;
2 2
3 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
4 import com.baomidou.mybatisplus.annotation.TableName; 4 import com.baomidou.mybatisplus.annotation.TableName;
src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java
@@ -77,9 +77,11 @@ public interface SysErrorCodeConstants { @@ -77,9 +77,11 @@ public interface SysErrorCodeConstants {
77 77
78 78
79 // ========== 消息 1003001000 ========== 79 // ========== 消息 1003001000 ==========
80 - ErrorCode SMS_CHANNEL_NOT_FOUND = new ErrorCode(1003001001, "没有短信渠道信息, 请初始化sms_channel表数据。");  
81 - ErrorCode SMS_TEMPLATE_NOT_FOUND = new ErrorCode(1003001002, "没有短信模板信息, 请初始化sms_template表数据。");  
82 - ErrorCode SMS_SENDER_NOT_FOUND = new ErrorCode(1003001003, "没有找到对应的短信发送对象,请检查sms_channel表和sms_template表数据");  
83 - ErrorCode INVALID_CHANNEL_CODE = new ErrorCode(1003001004, "非法的短信渠道code,请检查sms_channel表的code值是否与SmsChannelEnum中的code值一致。"); 80 + ErrorCode SMS_CHANNEL_NOT_INIT = new ErrorCode(1003001001,
  81 + "短信渠道没有初始化, 请调用SmsClientWrapper#initSmsClient()或SmsClientWrapper#addSmsClient");
  82 + ErrorCode SMS_CHANNEL_NOT_FOUND = new ErrorCode(1003001002, "没有短信渠道信息, 请初始化sms_channel表数据。");
  83 + ErrorCode SMS_TEMPLATE_NOT_FOUND = new ErrorCode(1003001003, "没有短信模板信息, 请初始化sms_template表数据。");
  84 + ErrorCode SMS_SENDER_NOT_FOUND = new ErrorCode(1003001004, "没有找到对应的短信发送对象,请检查sms_channel表和sms_template表数据");
  85 + ErrorCode INVALID_CHANNEL_CODE = new ErrorCode(1003001005, "非法的短信渠道code,请检查sms_channel表的code值是否与SmsChannelEnum中的code值一致。");
84 86
85 } 87 }
src/main/java/cn/iocoder/dashboard/modules/msg/service/sms/SmsChannelService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsChannelService.java
1 -package cn.iocoder.dashboard.modules.msg.service.sms; 1 +package cn.iocoder.dashboard.modules.system.service.sms;
2 2
3 import cn.iocoder.dashboard.common.pojo.PageResult; 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsChannelAllVO;  
5 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelCreateReqVO;  
6 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelPageReqVO;  
7 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.resp.SmsChannelEnumRespVO;  
8 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsChannelDO; 4 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
  5 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
  8 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
9 9
10 import java.util.List; 10 import java.util.List;
11 11
src/main/java/cn/iocoder/dashboard/modules/msg/service/sms/SmsLogService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsLogService.java
1 -package cn.iocoder.dashboard.modules.msg.service.sms; 1 +package cn.iocoder.dashboard.modules.system.service.sms;
2 2
3 /** 3 /**
4 * 短信渠道Service接口 4 * 短信渠道Service接口
src/main/java/cn/iocoder/dashboard/modules/msg/service/sms/SmsTemplateService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsTemplateService.java
1 -package cn.iocoder.dashboard.modules.msg.service.sms; 1 +package cn.iocoder.dashboard.modules.system.service.sms;
2 2
3 /** 3 /**
4 * 短信渠道Service接口 4 * 短信渠道Service接口
src/main/java/cn/iocoder/dashboard/modules/msg/service/sms/impl/SmsChannelServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsChannelServiceImpl.java
1 -package cn.iocoder.dashboard.modules.msg.service.sms.impl; 1 +package cn.iocoder.dashboard.modules.system.service.sms.impl;
2 2
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 -import cn.hutool.extra.spring.SpringUtil;  
5 import cn.iocoder.dashboard.common.enums.SmsChannelEnum; 4 import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
6 import cn.iocoder.dashboard.common.pojo.PageResult; 5 import cn.iocoder.dashboard.common.pojo.PageResult;
7 -import cn.iocoder.dashboard.framework.msg.sms.factory.AbstractSmsSenderFactory;  
8 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsChannelAllVO;  
9 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelCreateReqVO;  
10 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.req.SmsChannelPageReqVO;  
11 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.resp.SmsChannelEnumRespVO;  
12 -import cn.iocoder.dashboard.modules.msg.convert.sms.SmsChannelConvert;  
13 -import cn.iocoder.dashboard.modules.msg.convert.sms.SmsTemplateConvert;  
14 -import cn.iocoder.dashboard.modules.msg.dal.mysql.dao.sms.SmsChannelMapper;  
15 -import cn.iocoder.dashboard.modules.msg.dal.mysql.dao.sms.SmsTemplateMapper;  
16 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsChannelDO;  
17 -import cn.iocoder.dashboard.modules.msg.dal.mysql.daoobject.sms.SmsTemplateDO;  
18 -import cn.iocoder.dashboard.modules.msg.service.sms.SmsChannelService; 6 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
  8 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
  9 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
  10 +import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert;
  11 +import cn.iocoder.dashboard.modules.system.convert.sms.SmsTemplateConvert;
  12 +import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsChannelMapper;
  13 +import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsTemplateMapper;
  14 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
  15 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
  16 +import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
19 import org.springframework.stereotype.Service; 17 import org.springframework.stereotype.Service;
20 18
21 import javax.annotation.Resource; 19 import javax.annotation.Resource;
@@ -76,12 +74,6 @@ public class SmsChannelServiceImpl implements SmsChannelService { @@ -76,12 +74,6 @@ public class SmsChannelServiceImpl implements SmsChannelService {
76 74
77 @Override 75 @Override
78 public boolean flushChannel() { 76 public boolean flushChannel() {
79 - AbstractSmsSenderFactory smsSenderFactory = SpringUtil.getBean(AbstractSmsSenderFactory.class);  
80 - if (smsSenderFactory == null) {  
81 - return false;  
82 - }  
83 -  
84 - smsSenderFactory.flush(listChannelAllEnabledInfo());  
85 77
86 return true; 78 return true;
87 } 79 }
src/main/java/cn/iocoder/dashboard/modules/msg/service/sms/impl/SmsLogServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsLogServiceImpl.java
1 -package cn.iocoder.dashboard.modules.msg.service.sms.impl; 1 +package cn.iocoder.dashboard.modules.system.service.sms.impl;
2 2
3 -import cn.iocoder.dashboard.modules.msg.service.sms.SmsLogService; 3 +import cn.iocoder.dashboard.modules.system.service.sms.SmsLogService;
4 import org.springframework.stereotype.Service; 4 import org.springframework.stereotype.Service;
5 5
6 /** 6 /**
src/main/java/cn/iocoder/dashboard/modules/msg/service/sms/impl/SmsTemplateServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsTemplateServiceImpl.java
1 -package cn.iocoder.dashboard.modules.msg.service.sms.impl; 1 +package cn.iocoder.dashboard.modules.system.service.sms.impl;
2 2
3 -import cn.iocoder.dashboard.modules.msg.service.sms.SmsTemplateService; 3 +import cn.iocoder.dashboard.modules.system.service.sms.SmsTemplateService;
4 import org.springframework.stereotype.Service; 4 import org.springframework.stereotype.Service;
5 5
6 /** 6 /**
src/main/java/cn/iocoder/dashboard/modules/system/sms/SmsConfiguration.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.sms;
  2 +
  3 +import cn.iocoder.dashboard.framework.sms.SmsClient;
  4 +import cn.iocoder.dashboard.framework.sms.SmsClientAdapter;
  5 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
  6 +import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
  7 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  8 +import org.springframework.context.annotation.Bean;
  9 +import org.springframework.context.annotation.Configuration;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.util.List;
  13 +import java.util.Map;
  14 +
  15 +/**
  16 + * 短信服务配置
  17 + *
  18 + * @author guer
  19 + */
  20 +@Configuration
  21 +@ConditionalOnProperty("sms.enabled")
  22 +public class SmsConfiguration {
  23 +
  24 + @Resource
  25 + private SmsChannelService channelService;
  26 +
  27 + @Bean
  28 + public SmsClientAdapter smsClientWrapper() {
  29 + List<SmsChannelAllVO> smsChannelAllVOList = channelService.listChannelAllEnabledInfo();
  30 + Map<Long, SmsClient<?>> channelId2SmsClientMap = SmsSenderUtils.init(smsChannelAllVOList);
  31 + return new SmsClientAdapter(channelId2SmsClientMap);
  32 + }
  33 +
  34 +}
src/main/java/cn/iocoder/dashboard/modules/system/sms/SmsSenderUtils.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.sms;
  2 +
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
  5 +import cn.iocoder.dashboard.common.exception.ServiceException;
  6 +import cn.iocoder.dashboard.framework.sms.SmsBody;
  7 +import cn.iocoder.dashboard.framework.sms.SmsClient;
  8 +import cn.iocoder.dashboard.framework.sms.SmsClientAdapter;
  9 +import cn.iocoder.dashboard.framework.sms.SmsResult;
  10 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
  11 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsTemplateVO;
  12 +import cn.iocoder.dashboard.modules.system.sms.client.AliSmsClient;
  13 +import cn.iocoder.dashboard.modules.system.sms.proxy.SmsClientLogProxy;
  14 +
  15 +import java.util.*;
  16 +import java.util.concurrent.ConcurrentHashMap;
  17 +
  18 +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
  19 +
  20 +/**
  21 + * 短信发送者工厂
  22 + *
  23 + * @author zzf
  24 + * @date 2021/1/25 16:18
  25 + */
  26 +public class SmsSenderUtils {
  27 +
  28 + /**
  29 + * 短信渠道id:短信客户端map
  30 + * key: channelId
  31 + * val: SmsClient
  32 + */
  33 + private static final Map<Long, SmsClient<?>> smsSenderMap = new ConcurrentHashMap<>(8);
  34 +
  35 + /**
  36 + * 短信模板code: 短信渠道id map
  37 + * key: templateCode
  38 + * val: channelId
  39 + */
  40 + private static final Map<String, Long> templateCode2ChannelIdMap = new HashMap<>();
  41 +
  42 + /**
  43 + * 将短信渠道信息初始化成短信客户端
  44 + *
  45 + * @param smsChannelAllVOList 短信渠道信息
  46 + * @return 短信渠道id:短信客户端map
  47 + */
  48 + public synchronized static Map<Long, SmsClient<?>> init(List<SmsChannelAllVO> smsChannelAllVOList) {
  49 + if (ObjectUtil.isEmpty(smsChannelAllVOList)) {
  50 + throw new ServiceException(SMS_CHANNEL_NOT_FOUND);
  51 + }
  52 + addSender(smsChannelAllVOList);
  53 + return smsSenderMap;
  54 + }
  55 +
  56 + /**
  57 + * 重置短信客户端信息
  58 + *
  59 + * @param smsClientAdapter 短信客户端适配器
  60 + * @param smsChannelAllVOList 短信渠道信息集合
  61 + */
  62 + public synchronized static void flush(SmsClientAdapter smsClientAdapter, List<SmsChannelAllVO> smsChannelAllVOList) {
  63 + smsSenderMap.clear();
  64 + smsClientAdapter.flushClient(init(smsChannelAllVOList));
  65 + }
  66 +
  67 + /**
  68 + * 发送短信
  69 + *
  70 + * @param smsClientAdapter 短信客户端适配器
  71 + * @param smsBody 短信内容
  72 + * @param targetPhones 对象手机集合
  73 + * @return 短信发送结果
  74 + */
  75 + public static SmsResult<?> send(SmsClientAdapter smsClientAdapter, SmsBody smsBody, Collection<String> targetPhones) {
  76 + Long channelId = templateCode2ChannelIdMap.get(smsBody.getCode());
  77 + if (channelId == null) {
  78 + throw new ServiceException(SMS_SENDER_NOT_FOUND);
  79 + }
  80 + return smsClientAdapter.send(channelId, smsBody, targetPhones);
  81 + }
  82 +
  83 + /**
  84 + * 发送短信
  85 + *
  86 + * @param smsClientAdapter 短信客户端适配器
  87 + * @param smsBody 短信内容
  88 + * @param targetPhone 对象手机
  89 + * @return 短信发送结果
  90 + */
  91 + public static SmsResult<?> send(SmsClientAdapter smsClientAdapter, SmsBody smsBody, String targetPhone) {
  92 + Long channelId = templateCode2ChannelIdMap.get(smsBody.getCode());
  93 + if (channelId == null) {
  94 + throw new ServiceException(SMS_SENDER_NOT_FOUND);
  95 + }
  96 + return smsClientAdapter.send(channelId, smsBody, Collections.singletonList(targetPhone));
  97 + }
  98 +
  99 + /**
  100 + * 发送短信
  101 + *
  102 + * @param smsClientAdapter 短信客户端适配器
  103 + * @param smsBody 短信内容
  104 + * @param targetPhones 对象手机数组
  105 + * @return 短信发送结果
  106 + */
  107 + public static SmsResult<?> send(SmsClientAdapter smsClientAdapter, SmsBody smsBody, String... targetPhones) {
  108 + Long channelId = templateCode2ChannelIdMap.get(smsBody.getCode());
  109 + if (channelId == null) {
  110 + throw new ServiceException(SMS_SENDER_NOT_FOUND);
  111 + }
  112 + return smsClientAdapter.send(channelId, smsBody, Arrays.asList(targetPhones));
  113 + }
  114 +
  115 +
  116 + private static void addSender(List<SmsChannelAllVO> smsChannelAllVOList) {
  117 + smsChannelAllVOList.forEach(channelAllVO -> addSender(SmsChannelEnum.getByCode(channelAllVO.getCode()), channelAllVO));
  118 + }
  119 +
  120 + private static void addSender(SmsChannelEnum channelEnum, SmsChannelAllVO channelAllVO) {
  121 + if (channelEnum == null) {
  122 + throw new ServiceException(INVALID_CHANNEL_CODE);
  123 + }
  124 + List<SmsTemplateVO> templateList = channelAllVO.getTemplateList();
  125 + if (ObjectUtil.isEmpty(templateList)) {
  126 + throw new ServiceException(SMS_TEMPLATE_NOT_FOUND);
  127 + }
  128 + SmsClient<?> aliSmsClient = getSender(channelEnum, channelAllVO);
  129 + templateList.forEach(smsTemplateVO -> templateCode2ChannelIdMap.put(smsTemplateVO.getCode(), channelAllVO.getId()));
  130 + smsSenderMap.put(channelAllVO.getId(), aliSmsClient);
  131 + }
  132 +
  133 + private static SmsClient<?> getSender(SmsChannelEnum channelEnum, SmsChannelAllVO channelAllVO) {
  134 + switch (channelEnum) {
  135 + case ALI:
  136 + return new SmsClientLogProxy<>(new AliSmsClient(channelAllVO));
  137 + // TODO fill more channel
  138 + default:
  139 + break;
  140 + }
  141 + throw new ServiceException(SMS_SENDER_NOT_FOUND);
  142 + }
  143 +}
src/main/java/cn/iocoder/dashboard/framework/msg/sms/impl/ali/AliSmsSender.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/sms/client/AliSmsClient.java
1 -package cn.iocoder.dashboard.framework.msg.sms.impl.ali; 1 +package cn.iocoder.dashboard.modules.system.sms.client;
2 2
3 -import cn.iocoder.dashboard.framework.msg.sms.SmsBody;  
4 -import cn.iocoder.dashboard.framework.msg.sms.SmsResult;  
5 -import cn.iocoder.dashboard.framework.msg.sms.SmsSender;  
6 -import cn.iocoder.dashboard.modules.msg.controller.sms.vo.SmsChannelAllVO; 3 +import cn.iocoder.dashboard.framework.sms.SmsBody;
  4 +import cn.iocoder.dashboard.framework.sms.SmsClient;
  5 +import cn.iocoder.dashboard.framework.sms.SmsResult;
  6 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
7 import com.aliyuncs.DefaultAcsClient; 7 import com.aliyuncs.DefaultAcsClient;
8 import com.aliyuncs.IAcsClient; 8 import com.aliyuncs.IAcsClient;
9 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; 9 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
@@ -23,7 +23,7 @@ import java.util.Collection; @@ -23,7 +23,7 @@ import java.util.Collection;
23 * @date 2021/1/25 14:17 23 * @date 2021/1/25 14:17
24 */ 24 */
25 @Slf4j 25 @Slf4j
26 -public class AliSmsSender implements SmsSender<SendSmsResponse> { 26 +public class AliSmsClient implements SmsClient<SendSmsResponse> {
27 27
28 private static final String OK = "OK"; 28 private static final String OK = "OK";
29 29
@@ -42,7 +42,7 @@ public class AliSmsSender implements SmsSender&lt;SendSmsResponse&gt; { @@ -42,7 +42,7 @@ public class AliSmsSender implements SmsSender&lt;SendSmsResponse&gt; {
42 * 42 *
43 * @param channelVO 阿里云短信配置 43 * @param channelVO 阿里云短信配置
44 */ 44 */
45 - public AliSmsSender(SmsChannelAllVO channelVO) { 45 + public AliSmsClient(SmsChannelAllVO channelVO) {
46 46
47 this.channelVO = channelVO; 47 this.channelVO = channelVO;
48 48
@@ -83,4 +83,9 @@ public class AliSmsSender implements SmsSender&lt;SendSmsResponse&gt; { @@ -83,4 +83,9 @@ public class AliSmsSender implements SmsSender&lt;SendSmsResponse&gt; {
83 return failResult(); 83 return failResult();
84 } 84 }
85 85
  86 + @Override
  87 + public SmsResult<SendSmsResponse> sendAsync(SmsBody msgBody, Collection<String> targets) {
  88 + return null;
  89 + }
  90 +
86 } 91 }
src/main/java/cn/iocoder/dashboard/framework/msg/sms/intercepter/SmsLogIntercepter.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/sms/proxy/SmsClientLogProxy.java
1 -package cn.iocoder.dashboard.framework.msg.sms.intercepter; 1 +package cn.iocoder.dashboard.modules.system.sms.proxy;
2 2
3 -import cn.iocoder.dashboard.framework.msg.sms.SmsBody;  
4 -import cn.iocoder.dashboard.framework.msg.sms.SmsResult;  
5 -import cn.iocoder.dashboard.modules.msg.dal.mysql.dao.sms.SmsLogMapper; 3 +import cn.iocoder.dashboard.framework.sms.SmsBody;
  4 +import cn.iocoder.dashboard.framework.sms.SmsClient;
  5 +import cn.iocoder.dashboard.framework.sms.SmsResult;
6 import cn.iocoder.dashboard.util.json.JsonUtils; 6 import cn.iocoder.dashboard.util.json.JsonUtils;
7 -import lombok.Setter;  
8 import lombok.extern.slf4j.Slf4j; 7 import lombok.extern.slf4j.Slf4j;
9 8
10 import java.util.Collection; 9 import java.util.Collection;
11 10
12 /** 11 /**
13 - * 短信日志拦截器 12 + * 消息父接口
14 * 13 *
15 * @author zzf 14 * @author zzf
16 * @date 2021/1/22 15:46 15 * @date 2021/1/22 15:46
17 */ 16 */
18 @Slf4j 17 @Slf4j
19 -public class SmsLogIntercepter implements SmsIntercepter { 18 +public class SmsClientLogProxy<R> implements SmsClient<R> {
20 19
  20 + private final SmsClient<R> smsClient;
21 21
22 @Override 22 @Override
23 - public void beforeSender(SmsBody msgBody, Collection<String> targets) { 23 + public SmsResult<R> send(SmsBody msgBody, Collection<String> targets) {
24 log.debug("ready send sms, body: {}, target: {}", JsonUtils.toJsonString(msgBody), targets); 24 log.debug("ready send sms, body: {}, target: {}", JsonUtils.toJsonString(msgBody), targets);
25 25
26 - } 26 + SmsResult<R> resultBody = smsClient.send(msgBody, targets);
27 27
28 - @Override  
29 - public <T> void afterSender(SmsBody msgBody, Collection<String> targets, SmsResult<T> resultBody) {  
30 if (resultBody.getSuccess()) { 28 if (resultBody.getSuccess()) {
31 // 29 //
32 } else { 30 } else {
@@ -36,11 +34,15 @@ public class SmsLogIntercepter implements SmsIntercepter { @@ -36,11 +34,15 @@ public class SmsLogIntercepter implements SmsIntercepter {
36 JsonUtils.toJsonString(resultBody) 34 JsonUtils.toJsonString(resultBody)
37 ); 35 );
38 } 36 }
39 - 37 + return resultBody;
40 } 38 }
41 39
42 @Override 40 @Override
43 - public int getOrder() {  
44 - return 0; 41 + public SmsResult<R> sendAsync(SmsBody msgBody, Collection<String> targets) {
  42 + return send(msgBody, targets);
  43 + }
  44 +
  45 + public SmsClientLogProxy(SmsClient<R> smsClient) {
  46 + this.smsClient = smsClient;
45 } 47 }
46 } 48 }