Commit b4be8e987a3dfbee6a830ff90733de7cf6d29f6c

Authored by zengzefeng
1 parent a50db6bf

临时提交

Showing 27 changed files with 353 additions and 198 deletions
src/main/java/cn/iocoder/dashboard/framework/sms/client/AbstractSmsClient.java
1 1 package cn.iocoder.dashboard.framework.sms.client;
2 2  
  3 +import cn.iocoder.dashboard.framework.sms.core.SmsBody;
  4 +import cn.iocoder.dashboard.framework.sms.core.SmsResult;
3 5 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +
  8 +import java.util.Collection;
4 9  
5 10 /**
6 11 * 抽象短息客户端
... ... @@ -8,7 +13,8 @@ import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
8 13 * @author zzf
9 14 * @date 2021/2/1 9:28
10 15 */
11   -public abstract class AbstractSmsClient<R> implements SmsClient<R> {
  16 +@Slf4j
  17 +public abstract class AbstractSmsClient implements SmsClient {
12 18  
13 19 /**
14 20 * 短信渠道参数
... ... @@ -29,4 +35,43 @@ public abstract class AbstractSmsClient&lt;R&gt; implements SmsClient&lt;R&gt; {
29 35 return channelVO;
30 36 }
31 37  
  38 + @Override
  39 + public SmsResult send(String templateApiId, SmsBody smsBody, Collection<String> targets) {
  40 + SmsResult result;
  41 + try {
  42 + beforeSend(templateApiId, smsBody, targets);
  43 + result = doSend(templateApiId, smsBody, targets);
  44 + afterSend(templateApiId, smsBody, targets, result);
  45 + } catch (Exception e) {
  46 + // exception handle
  47 + log.debug(e.getMessage(), e);
  48 + return failResult("发送异常: " + e.getMessage());
  49 + }
  50 + return result;
  51 + }
  52 +
  53 +
  54 + /**
  55 + * 发送消息
  56 + *
  57 + * @param templateApiId 短信模板唯一标识
  58 + * @param smsBody 消息内容
  59 + * @param targets 发送对象列表
  60 + * @return 短信发送结果
  61 + */
  62 + public abstract SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception;
  63 +
  64 + protected void beforeSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception {
  65 + }
  66 +
  67 + protected void afterSend(String templateApiId, SmsBody smsBody, Collection<String> targets, SmsResult result) throws Exception {
  68 + }
  69 +
  70 +
  71 + SmsResult failResult(String message) {
  72 + SmsResult resultBody = new SmsResult();
  73 + resultBody.setSuccess(false);
  74 + resultBody.setMessage(message);
  75 + return resultBody;
  76 + }
32 77 }
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/client/AliyunSmsClient.java
1 1 package cn.iocoder.dashboard.framework.sms.client;
2 2  
  3 +import cn.hutool.core.date.DateUtil;
3 4 import cn.iocoder.dashboard.framework.sms.core.SmsBody;
4 5 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
  6 +import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
5 7 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
6 8 import com.aliyuncs.DefaultAcsClient;
7 9 import com.aliyuncs.IAcsClient;
  10 +import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
  11 +import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
8 12 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
9 13 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
10 14 import com.aliyuncs.http.MethodType;
... ... @@ -13,7 +17,9 @@ import com.aliyuncs.profile.IClientProfile;
13 17 import lombok.extern.slf4j.Slf4j;
14 18 import org.apache.commons.lang3.StringUtils;
15 19  
  20 +import java.util.ArrayList;
16 21 import java.util.Collection;
  22 +import java.util.List;
17 23  
18 24 /**
19 25 * 阿里短信实现类
... ... @@ -22,7 +28,7 @@ import java.util.Collection;
22 28 * @date 2021/1/25 14:17
23 29 */
24 30 @Slf4j
25   -public class AliyunSmsClient extends AbstractSmsClient<SendSmsResponse> {
  31 +public class AliyunSmsClient extends AbstractSmsClient {
26 32  
27 33 private static final String OK = "OK";
28 34  
... ... @@ -53,35 +59,36 @@ public class AliyunSmsClient extends AbstractSmsClient&lt;SendSmsResponse&gt; {
53 59  
54 60  
55 61 @Override
56   - public SmsResult<SendSmsResponse> send(SmsBody smsBody, Collection<String> targets) {
  62 + public SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception {
57 63 SendSmsRequest request = new SendSmsRequest();
58 64 request.setSysMethod(MethodType.POST);
59 65 request.setPhoneNumbers(StringUtils.join(targets, ","));
60 66 request.setSignName(channelVO.getApiSignatureId());
61   - request.setTemplateCode(channelVO.getTemplateByTemplateCode(smsBody.getTemplateCode()).getApiTemplateId());
  67 + request.setTemplateCode(templateApiId);
62 68 request.setTemplateParam(smsBody.getParamsStr());
63   - // TODO FROM 芋艿 TO zzf:try catch 咱是不是可以交给 abstract 来做。这样,异常处理,重试,限流等等,都可以酱紫
64   - try {
65   - SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
66   -
67   - boolean result = OK.equals(sendSmsResponse.getCode());
68   - if (!result) {
69   - log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage());
70   - }
71   - SmsResult<SendSmsResponse> resultBody = new SmsResult<>();
72   - resultBody.setSuccess(result);
73   - resultBody.setResult(sendSmsResponse);
74   - return resultBody;
75   - } catch (Exception e) {
76   - log.debug(e.getMessage(), e);
77   - return failResult("发送异常: " + e.getMessage());
78   - }
79   - }
  69 + // TODO FROM 芋艿 TO zzf:try catch 咱是不是可以交给 abstract 来做。这样,异常处理,重试,限流等等,都可以酱紫 DONE
  70 + SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
80 71  
81   - SmsResult<SendSmsResponse> failResult(String message) {
82   - SmsResult<SendSmsResponse> resultBody = new SmsResult<>();
83   - resultBody.setSuccess(false);
84   - resultBody.setMessage(message);
  72 + boolean result = OK.equals(sendSmsResponse.getCode());
  73 + if (!result) {
  74 + log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage());
  75 + }
  76 + SmsResult resultBody = new SmsResult();
  77 + resultBody.setSuccess(result);
  78 + QuerySendDetailsRequest querySendDetailsRequest = new QuerySendDetailsRequest();
  79 + querySendDetailsRequest.setBizId(sendSmsResponse.getBizId());
  80 +
  81 + QuerySendDetailsResponse acsResponse = acsClient.getAcsResponse(querySendDetailsRequest);
  82 + List<SmsResultDetail> resultDetailList = new ArrayList<>(Integer.parseInt(acsResponse.getTotalCount()));
  83 + acsResponse.getSmsSendDetailDTOs().forEach(s -> {
  84 + SmsResultDetail resultDetail = new SmsResultDetail();
  85 + resultDetail.setCreateTime(DateUtil.parseDateTime(s.getSendDate()));
  86 + resultDetail.setMessage(s.getContent());
  87 + resultDetail.setPhone(s.getPhoneNum());
  88 + resultDetail.setStatus(Math.toIntExact(s.getSendStatus()));
  89 + resultDetailList.add(resultDetail);
  90 + });
  91 + resultBody.setResult(resultDetailList);
85 92 return resultBody;
86 93 }
87 94  
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/client/SmsClient.java
... ... @@ -11,15 +11,16 @@ import java.util.Collection;
11 11 * @author zzf
12 12 * @date 2021/1/25 14:14
13 13 */
14   -public interface SmsClient<R> {
  14 +public interface SmsClient {
15 15  
16 16 /**
17 17 * 发送消息
18 18 *
19   - * @param smsBody 消息内容
20   - * @param targets 发送对象列表
21   - * @return 是否发送成功
  19 + * @param templateApiId 短信模板唯一标识
  20 + * @param smsBody 消息内容
  21 + * @param targets 发送对象列表
  22 + * @return 短信发送结果
22 23 */
23   - SmsResult<R> send(SmsBody smsBody, Collection<String> targets);
  24 + SmsResult send(String templateApiId, SmsBody smsBody, Collection<String> targets);
24 25  
25 26 }
26 27 \ No newline at end of file
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java
1 1 package cn.iocoder.dashboard.framework.sms.core;
2 2  
3   -import cn.hutool.core.util.ObjectUtil;
4   -import cn.hutool.core.util.StrUtil;
5   -import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
6 3 import cn.iocoder.dashboard.common.exception.ServiceException;
7   -import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
8 4 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
9 5 import cn.iocoder.dashboard.framework.sms.client.AliyunSmsClient;
  6 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
10 7 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
  8 +import cn.iocoder.dashboard.framework.sms.core.property.SmsTemplateProperty;
11 9 import org.springframework.stereotype.Component;
12 10  
  11 +import java.util.Collection;
13 12 import java.util.Map;
14 13 import java.util.concurrent.ConcurrentHashMap;
15 14  
... ... @@ -24,7 +23,17 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
24 23 @Component
25 24 public class SmsClientFactory {
26 25  
27   - private final Map<Long, AbstractSmsClient<?>> smsSenderMap = new ConcurrentHashMap<>(8);
  26 + /**
  27 + * channelId: client map
  28 + * 保存 渠道id: 对应短信客户端 的map
  29 + */
  30 + private final Map<Long, AbstractSmsClient> smsSenderMap = new ConcurrentHashMap<>(8);
  31 +
  32 + /**
  33 + * templateCode: TemplateProperty map
  34 + * 保存 模板编码:模板信息 的map
  35 + */
  36 + private final Map<String, SmsTemplateProperty> templatePropertyMap = new ConcurrentHashMap<>(16);
28 37  
29 38 /**
30 39 * 创建短信客户端
... ... @@ -33,20 +42,13 @@ public class SmsClientFactory {
33 42 * @return 客户端id(默认channelId)
34 43 */
35 44 public Long createClient(SmsChannelProperty propertyVO) {
36   - // TODO FROM 芋艿 TO zzf:参数的校验,可以考虑统一使用 validation。
37   - if (StrUtil.isBlank(propertyVO.getCode())) {
38   - throw ServiceExceptionUtil.exception(PARAM_VALUE_IS_NULL, "短信渠道编码");
39   - }
40   - if (ObjectUtil.isNull(propertyVO.getId())) {
41   - throw ServiceExceptionUtil.exception(PARAM_VALUE_IS_NULL, "短信渠道ID");
42   - }
43   -
44   - AbstractSmsClient<?> sender = createClient(SmsChannelEnum.getByCode(propertyVO.getCode()), propertyVO);
  45 + // TODO FROM 芋艿 TO zzf:参数的校验,可以考虑统一使用 validation。 DONE
  46 + AbstractSmsClient sender = createClient(SmsChannelEnum.getByCode(propertyVO.getCode()), propertyVO);
45 47 smsSenderMap.put(propertyVO.getId(), sender);
46 48 return propertyVO.getId();
47 49 }
48 50  
49   - private AbstractSmsClient<?> createClient(SmsChannelEnum channelEnum, SmsChannelProperty channelVO) {
  51 + private AbstractSmsClient createClient(SmsChannelEnum channelEnum, SmsChannelProperty channelVO) {
50 52 if (channelEnum == null) {
51 53 throw new ServiceException(INVALID_CHANNEL_CODE);
52 54 }
... ... @@ -66,7 +68,38 @@ public class SmsClientFactory {
66 68 * @param channelId 渠道id
67 69 * @return 短信id
68 70 */
69   - public AbstractSmsClient<?> getClient(Long channelId) {
  71 + public AbstractSmsClient getClient(Long channelId) {
70 72 return smsSenderMap.get(channelId);
71 73 }
  74 +
  75 +
  76 + /**
  77 + * 添加或修改短信模板信息缓存
  78 + */
  79 + public void addOrUpdateTemplateCache(Collection<SmsTemplateProperty> templateProperties) {
  80 + templateProperties.forEach(s -> templatePropertyMap.put(s.getCode(), s));
  81 + }
  82 +
  83 +
  84 + /**
  85 + * 添加或修改短信模板信息缓存
  86 + */
  87 + public void addOrUpdateTemplateCache(SmsTemplateProperty templateProperty) {
  88 + templatePropertyMap.put(templateProperty.getCode(), templateProperty);
  89 + }
  90 +
  91 +
  92 + /**
  93 + * 根据短信模板编码获取模板唯一标识
  94 + *
  95 + * @param templateCode 短信模板编码
  96 + * @return 短信id
  97 + */
  98 + public String getTemplateApiIdByCode(String templateCode) {
  99 + SmsTemplateProperty smsTemplateProperty = templatePropertyMap.get(templateCode);
  100 + if (smsTemplateProperty == null) {
  101 + throw new ServiceException(SMS_TEMPLATE_NOT_FOUND);
  102 + }
  103 + return smsTemplateProperty.getApiTemplateId();
  104 + }
72 105 }
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResult.java
... ... @@ -3,17 +3,24 @@ package cn.iocoder.dashboard.framework.sms.core;
3 3 import lombok.Data;
4 4  
5 5 import java.io.Serializable;
  6 +import java.util.List;
6 7  
7 8 /**
8 9 * 消息内容实体类
9 10 */
10 11 @Data
11   -public class SmsResult<T> implements Serializable {
  12 +public class SmsResult implements Serializable {
12 13  
13 14 /**
14 15 * 是否成功
15 16 */
16   - private Boolean success; // TODO FROM 芋艿 to zzf:未来要加一个 code,将不同平台的短信失败的情况,做一次统一的收敛。
  17 + // TODO FROM 芋艿 to zzf:未来要加一个 code,将不同平台的短信失败的情况,做一次统一的收敛。 DONE
  18 + private Boolean success;
  19 +
  20 + /**
  21 + * 状态码
  22 + */
  23 + private String code;
17 24  
18 25 /**
19 26 * 提示
... ... @@ -23,5 +30,7 @@ public class SmsResult&lt;T&gt; implements Serializable {
23 30 /**
24 31 * 返回值
25 32 */
26   - private T result; // TODO FROM 芋艿 to zzf:是不是统一各个平台的返回结果,这样对调用方来说统一。因为作为统一的短信客户端,最好让上层不太需要知道太具体。黑河诶
  33 + // TODO FROM 芋艿 to zzf:是不是统一各个平台的返回结果,这样对调用方来说统一。因为作为统一的短信客户端,最好让上层不太需要知道太具体。黑河诶 DONE
  34 + private List<SmsResultDetail> result;
  35 +
27 36 }
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java 0 → 100644
  1 +package cn.iocoder.dashboard.framework.sms.core;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.io.Serializable;
  6 +import java.util.Date;
  7 +
  8 +/**
  9 + * 消息内容实体类
  10 + */
  11 +@Data
  12 +public class SmsResultDetail implements Serializable {
  13 +
  14 + /**
  15 + * 状态 1成功 2失败 3等待回执
  16 + */
  17 + private Integer status;
  18 +
  19 + /**
  20 + * 接收手机号
  21 + */
  22 + private String phone;
  23 +
  24 + /**
  25 + * 提示
  26 + */
  27 + private String message;
  28 +
  29 + /**
  30 + * 时间
  31 + */
  32 + private Date createTime;
  33 +}
... ...
src/main/java/cn/iocoder/dashboard/common/enums/SmsChannelEnum.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java
1   -package cn.iocoder.dashboard.common.enums;
  1 +package cn.iocoder.dashboard.framework.sms.core.enums;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
5 5  
6   -import java.util.function.Predicate;
7   -import java.util.stream.Stream;
8   -
9 6 /**
10   - * 短信渠道枚举 TODO FROM 芋艿 TO zzf:属于短信的枚举类,可以放到 framework/sms 下
  7 + * 短信渠道枚举 TODO FROM 芋艿 TO zzf:属于短信的枚举类,可以放到 framework/sms 下 DONE
11 8 *
12 9 * @author zzf
13 10 * @date 2021/1/25 10:56
... ... @@ -19,7 +16,7 @@ public enum SmsChannelEnum {
19 16 ALI("ALI", "阿里"),
20 17 HUA_WEI("HUA_WEI", "华为"),
21 18 QI_NIU("QI_NIU", "七牛"),
22   - TEN_XUN("TEN_XUN", "腾讯"); // TODO FROM 芋艿 to zzf:TEN 有后鼻音哈,要被马爸爸打了。。。
  19 + TENCENT("TENCENT", "腾讯"); // TODO FROM 芋艿 to zzf:TEN 有后鼻音哈,要被马爸爸打了。。。 DONE
23 20  
24 21 private final String code;
25 22  
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/core/property/SmsChannelProperty.java
... ... @@ -3,6 +3,8 @@ package cn.iocoder.dashboard.framework.sms.core.property;
3 3 import lombok.Data;
4 4 import lombok.EqualsAndHashCode;
5 5  
  6 +import javax.validation.constraints.NotEmpty;
  7 +import javax.validation.constraints.NotNull;
6 8 import java.io.Serializable;
7 9 import java.util.List;
8 10  
... ... @@ -19,40 +21,37 @@ public class SmsChannelProperty implements Serializable {
19 21 /**
20 22 * id
21 23 */
  24 + @NotNull(message = "短信渠道ID不能为空")
22 25 private Long id;
23 26  
24 27 /**
25 28 * 编码(来自枚举类 阿里、华为、七牛等)
26 29 */
  30 + @NotEmpty(message = "短信渠道编码不能为空")
27 31 private String code;
28 32  
29 33 /**
30 34 * 渠道账号id
31 35 */
  36 + @NotEmpty(message = "渠道账号id不能为空")
32 37 private String apiKey;
33 38  
34 39 /**
35 40 * 渠道账号秘钥
36 41 */
  42 + @NotEmpty(message = "渠道账号秘钥不能为空")
37 43 private String apiSecret;
38 44  
39 45 /**
40 46 * 实际渠道签名唯一标识
41 47 */
  48 + @NotEmpty(message = "实际渠道签名唯一标识不能为空")
42 49 private String apiSignatureId;
43 50  
44 51 /**
45 52 * 签名值
46 53 */
  54 + @NotEmpty(message = "签名值不能为空")
47 55 private String signature;
48 56  
49   - /**
50   - * 该渠道名下的短信模板集合
51   - */
52   - private List<SmsTemplateProperty> templateList;
53   -
54   - public SmsTemplateProperty getTemplateByTemplateCode(String tempCode) {
55   - return templateList.stream().filter(s -> s.getCode().equals(tempCode)).findFirst().get();
56   - }
57   -
58 57 }
... ...
src/main/java/cn/iocoder/dashboard/framework/sms/core/property/SmsTemplateProperty.java
... ... @@ -3,8 +3,12 @@ package cn.iocoder.dashboard.framework.sms.core.property;
3 3 import lombok.Data;
4 4 import lombok.EqualsAndHashCode;
5 5  
  6 +import javax.validation.constraints.NotEmpty;
  7 +
6 8 /**
7   - * 渠道模板VO类 TODO FROM 芋艿 TO zzf:模板是不是不要提供到 client 里面,而是交给 factory 统一维护就好。不然,模板修改时候,刷新 client 会比较麻烦。
  9 + * 渠道模板VO类
  10 + * TODO FROM 芋艿 TO zzf:模板是不是不要提供到 client 里面,而是交给 factory 统一维护就好。不然,模板修改时候,刷新 client 会比较麻烦。
  11 + *
8 12 *
9 13 * @author zzf
10 14 * @date 2021/1/25 17:03
... ... @@ -14,6 +18,12 @@ import lombok.EqualsAndHashCode;
14 18 public class SmsTemplateProperty {
15 19  
16 20 /**
  21 + * 渠道id
  22 + */
  23 + @NotEmpty(message = "短信渠道编码不能为空")
  24 + private Long channelId;
  25 +
  26 + /**
17 27 * 业务编码(来自数据字典, 用户自定义业务场景 一个场景可以有多个模板)
18 28 */
19 29 private String bizCode;
... ... @@ -21,18 +31,19 @@ public class SmsTemplateProperty {
21 31 /**
22 32 * 编码
23 33 */
  34 + @NotEmpty(message = "短信模板编码不能为空")
24 35 private String code;
25 36  
26 37 /**
27 38 * 实际渠道模板唯一标识
28 39 */
  40 + @NotEmpty(message = "短信模板唯一标识不能为空")
29 41 private String apiTemplateId;
30 42  
31 43 /**
32 44 * 内容
33 45 */
  46 + @NotEmpty(message = "短信模板内容不能为空")
34 47 private String content;
35 48  
36   -
37   -
38 49 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java
... ... @@ -5,8 +5,8 @@ import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
6 6 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
7 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;
  8 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
  9 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
10 10 import io.swagger.annotations.Api;
11 11 import io.swagger.annotations.ApiOperation;
12 12 import org.springframework.validation.annotation.Validated;
... ... @@ -23,25 +23,25 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
23 23 public class SmsChannelController {
24 24  
25 25 @Resource
26   - private SmsChannelService service;
  26 + private SysSmsChannelService service;
27 27  
28 28 @ApiOperation("获取渠道/签名分页")
29 29 @GetMapping("/page")
30   - public CommonResult<PageResult<SmsChannelDO>> getPermissionInfo(@Validated SmsChannelPageReqVO reqVO) {
31   - return success(service.pageChannels(reqVO));
  30 + public CommonResult<PageResult<SysSmsChannelDO>> getPermissionInfo(@Validated SmsChannelPageReqVO reqVO) {
  31 + return success(service.pageSmsChannels(reqVO));
32 32 }
33 33  
34 34 @ApiOperation("获取渠道枚举")
35 35 @GetMapping("/list/channel-enum")
36 36 public CommonResult<List<SmsChannelEnumRespVO>> getChannelEnums() {
37   - return success(service.getChannelEnums());
  37 + return success(service.getSmsChannelEnums());
38 38 }
39 39  
40 40  
41 41 @ApiOperation("添加消息渠道")
42 42 @PostMapping("/create")
43 43 public CommonResult<Long> add(@Validated @RequestBody SmsChannelCreateReqVO reqVO) {
44   - return success(service.createChannel(reqVO));
  44 + return success(service.createSmsChannel(reqVO));
45 45 }
46 46  
47 47  
... ...
src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java
1 1 package cn.iocoder.dashboard.modules.system.convert.sms;
2 2  
3   -import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
  3 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5 5 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
6 6 import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
7 7 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
8 8 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
9 9 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
10   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
  10 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
11 11 import com.baomidou.mybatisplus.core.metadata.IPage;
12 12 import org.mapstruct.Mapper;
13 13 import org.mapstruct.Mapping;
... ... @@ -21,17 +21,19 @@ public interface SmsChannelConvert {
21 21 SmsChannelConvert INSTANCE = Mappers.getMapper(SmsChannelConvert.class);
22 22  
23 23 @Mapping(source = "records", target = "list")
24   - PageResult<SmsChannelDO> convertPage(IPage<SmsChannelDO> page);
  24 + PageResult<SysSmsChannelDO> convertPage(IPage<SysSmsChannelDO> page);
25 25  
26   - SmsChannelDO convert(SmsChannelCreateReqVO bean);
  26 + SysSmsChannelDO convert(SmsChannelCreateReqVO bean);
27 27  
28   - SmsChannelDO convert(SysUserUpdateReqVO bean);
  28 + SysSmsChannelDO convert(SysUserUpdateReqVO bean);
29 29  
30 30 List<SmsChannelEnumRespVO> convertEnum(List<SmsChannelEnum> bean);
31 31  
32   - List<SmsChannelAllVO> convert(List<SmsChannelDO> bean);
  32 + List<SmsChannelAllVO> convert(List<SysSmsChannelDO> bean);
33 33  
34 34 List<SmsChannelProperty> convertProperty(List<SmsChannelAllVO> list);
35 35  
  36 + List<SmsChannelProperty> convertProperties(List<SysSmsChannelDO> list);
  37 +
36 38  
37 39 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsTemplateConvert.java
... ... @@ -2,8 +2,8 @@ package cn.iocoder.dashboard.modules.system.convert.sms;
2 2  
3 3 import cn.iocoder.dashboard.common.pojo.PageResult;
4 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;
  5 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
  6 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsTemplateDO;
7 7 import com.baomidou.mybatisplus.core.metadata.IPage;
8 8 import org.mapstruct.Mapper;
9 9 import org.mapstruct.Mapping;
... ... @@ -17,10 +17,10 @@ public interface SmsTemplateConvert {
17 17 SmsTemplateConvert INSTANCE = Mappers.getMapper(SmsTemplateConvert.class);
18 18  
19 19 @Mapping(source = "records", target = "list")
20   - PageResult<SmsChannelDO> convertPage(IPage<SmsChannelDO> page);
  20 + PageResult<SysSmsChannelDO> convertPage(IPage<SysSmsChannelDO> page);
21 21  
22   - List<SmsTemplateVO> convert(List<SmsTemplateDO> bean);
  22 + List<SmsTemplateVO> convert(List<SysSmsTemplateDO> bean);
23 23  
24   - SmsTemplateVO convert(SmsTemplateDO bean);
  24 + SmsTemplateVO convert(SysSmsTemplateDO bean);
25 25  
26 26 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsChannelMapper.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsChannelMapper.java
... ... @@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
5 5 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
6 6 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
7   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
  7 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
8 8 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
9 9 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
10 10 import com.baomidou.mybatisplus.core.metadata.IPage;
... ... @@ -13,19 +13,19 @@ import org.apache.ibatis.annotations.Mapper;
13 13 import java.util.List;
14 14  
15 15 @Mapper
16   -public interface SmsChannelMapper extends BaseMapper<SmsChannelDO> {
  16 +public interface SysSmsChannelMapper extends BaseMapper<SysSmsChannelDO> {
17 17  
18   - default IPage<SmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) {
19   - return selectPage(MyBatisUtils.buildPage(reqVO), new LambdaQueryWrapper<SmsChannelDO>()
20   - .like(StrUtil.isNotBlank(reqVO.getName()), SmsChannelDO::getName, reqVO.getName())
21   - .like(StrUtil.isNotBlank(reqVO.getSignature()), SmsChannelDO::getName, reqVO.getSignature())
  18 + default IPage<SysSmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) {
  19 + return selectPage(MyBatisUtils.buildPage(reqVO), new LambdaQueryWrapper<SysSmsChannelDO>()
  20 + .like(StrUtil.isNotBlank(reqVO.getName()), SysSmsChannelDO::getName, reqVO.getName())
  21 + .like(StrUtil.isNotBlank(reqVO.getSignature()), SysSmsChannelDO::getName, reqVO.getSignature())
22 22 );
23 23 }
24 24  
25   - default List<SmsChannelDO> selectEnabledList() {
26   - return selectList(new LambdaQueryWrapper<SmsChannelDO>()
27   - .eq(SmsChannelDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
28   - .orderByAsc(SmsChannelDO::getId)
  25 + default List<SysSmsChannelDO> selectEnabledList() {
  26 + return selectList(new LambdaQueryWrapper<SysSmsChannelDO>()
  27 + .eq(SysSmsChannelDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
  28 + .orderByAsc(SysSmsChannelDO::getId)
29 29 );
30 30 }
31 31 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsLogMapper.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsLogMapper.java
1 1 package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
2 2  
3   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsLogDO;
  3 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsLogDO;
4 4 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5 5 import org.apache.ibatis.annotations.Mapper;
6 6  
7 7 @Mapper
8   -public interface SmsLogMapper extends BaseMapper<SmsLogDO> {
  8 +public interface SysSmsLogMapper extends BaseMapper<SysSmsLogDO> {
9 9  
10 10 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsTemplateMapper.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsTemplateMapper.java
1 1 package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
2 2  
3 3 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
4   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
  4 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsTemplateDO;
5 5 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 6 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
7 7 import org.apache.ibatis.annotations.Mapper;
... ... @@ -9,7 +9,7 @@ import org.apache.ibatis.annotations.Mapper;
9 9 import java.util.List;
10 10  
11 11 @Mapper
12   -public interface SmsTemplateMapper extends BaseMapper<SmsTemplateDO> {
  12 +public interface SysSmsTemplateMapper extends BaseMapper<SysSmsTemplateDO> {
13 13  
14 14 /**
15 15 * 根据短信渠道id查询短信模板集合
... ... @@ -17,11 +17,11 @@ public interface SmsTemplateMapper extends BaseMapper&lt;SmsTemplateDO&gt; {
17 17 * @param channelId 渠道id
18 18 * @return 模板集合
19 19 */
20   - default List<SmsTemplateDO> selectListByChannelId(Long channelId) {
21   - return selectList(new LambdaQueryWrapper<SmsTemplateDO>()
22   - .eq(SmsTemplateDO::getChannelId, channelId)
23   - .eq(SmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
24   - .orderByAsc(SmsTemplateDO::getId)
  20 + default List<SysSmsTemplateDO> selectListByChannelId(Long channelId) {
  21 + return selectList(new LambdaQueryWrapper<SysSmsTemplateDO>()
  22 + .eq(SysSmsTemplateDO::getChannelId, channelId)
  23 + .eq(SysSmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
  24 + .orderByAsc(SysSmsTemplateDO::getId)
25 25 );
26 26 }
27 27  
... ... @@ -30,10 +30,10 @@ public interface SmsTemplateMapper extends BaseMapper&lt;SmsTemplateDO&gt; {
30 30 *
31 31 * @return 有效短信模板集合
32 32 */
33   - default List<SmsTemplateDO> selectEnabledList() {
34   - return selectList(new LambdaQueryWrapper<SmsTemplateDO>()
35   - .eq(SmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
36   - .orderByAsc(SmsTemplateDO::getId)
  33 + default List<SysSmsTemplateDO> selectEnabledList() {
  34 + return selectList(new LambdaQueryWrapper<SysSmsTemplateDO>()
  35 + .eq(SysSmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
  36 + .orderByAsc(SysSmsTemplateDO::getId)
37 37 );
38 38 }
39 39 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsChannelDO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsChannelDO.java
... ... @@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode;
15 15 @Data
16 16 @EqualsAndHashCode(callSuper = true)
17 17 @TableName(value = "sms_channel", autoResultMap = true)
18   -public class SmsChannelDO extends BaseDO {
  18 +public class SysSmsChannelDO extends BaseDO {
19 19  
20 20 /**
21 21 * 自增编号
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsLogDO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsLogDO.java
... ... @@ -18,7 +18,7 @@ import java.util.Date;
18 18 @EqualsAndHashCode
19 19 @Accessors(chain = true)
20 20 @TableName(value = "sms_log", autoResultMap = true)
21   -public class SmsLogDO implements Serializable {
  21 +public class SysSmsLogDO implements Serializable {
22 22  
23 23 /**
24 24 * 自增编号
... ...
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsTemplateDO.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsTemplateDO.java
... ... @@ -16,7 +16,7 @@ import java.util.Date;
16 16 @Data
17 17 @EqualsAndHashCode(callSuper = true)
18 18 @TableName(value = "sms_template", autoResultMap = true)
19   -public class SmsTemplateDO extends BaseDO {
  19 +public class SysSmsTemplateDO extends BaseDO {
20 20  
21 21 /**
22 22 * 自增编号
... ...
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java
... ... @@ -4,7 +4,7 @@ import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageLi
4 4 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
5 5 import cn.iocoder.dashboard.modules.system.mq.message.dept.SysDeptRefreshMessage;
6 6 import cn.iocoder.dashboard.modules.system.mq.message.sms.SmsSendMessage;
7   -import cn.iocoder.dashboard.modules.system.service.sms.SmsService;
  7 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
8 8 import lombok.extern.slf4j.Slf4j;
9 9 import org.springframework.stereotype.Component;
10 10  
... ... @@ -20,12 +20,12 @@ import javax.annotation.Resource;
20 20 public class SmsSendConsumer extends AbstractChannelMessageListener<SmsSendMessage> {
21 21  
22 22 @Resource
23   - private SmsService smsService;
  23 + private SysSmsService sysSmsService;
24 24  
25 25 @Override
26 26 public void onMessage(SmsSendMessage message) {
27 27 log.info("[onMessage][收到 发送短信 消息]");
28   - SmsResult<?> send = smsService.send(message.getSmsBody(), message.getTargetPhones());
  28 + SmsResult send = sysSmsService.send(message.getSmsBody(), message.getTargetPhones());
29 29 }
30 30  
31 31 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsChannelService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java
... ... @@ -6,7 +6,7 @@ import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
6 6 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
7 7 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
8 8 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
9   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
  9 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
10 10  
11 11 import java.util.List;
12 12  
... ... @@ -16,7 +16,7 @@ import java.util.List;
16 16 * @author zzf
17 17 * @date 2021/1/25 9:24
18 18 */
19   -public interface SmsChannelService {
  19 +public interface SysSmsChannelService {
20 20  
21 21 // TODO FROM 芋艿 to ZZF:SmsChannelService=》SysSmsChannelService,增加 Sys 前缀,算在系统模块里
22 22 // TODO FROM 芋艿 to ZZF:方法名,保持不去掉 Sms 前缀。虽然长点,嘿嘿
... ... @@ -32,7 +32,7 @@ public interface SmsChannelService {
32 32 * @param reqVO 参数对象
33 33 * @return 短信渠道分页对象
34 34 */
35   - PageResult<SmsChannelDO> pageChannels(SmsChannelPageReqVO reqVO);
  35 + PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO);
36 36  
37 37 /**
38 38 * 创建新的渠道信息
... ... @@ -40,14 +40,14 @@ public interface SmsChannelService {
40 40 * @param reqVO 参数对象
41 41 * @return 渠道id
42 42 */
43   - Long createChannel(SmsChannelCreateReqVO reqVO);
  43 + Long createSmsChannel(SmsChannelCreateReqVO reqVO);
44 44  
45 45 /**
46 46 * 获取短信渠道枚举/渠道编码
47 47 *
48 48 * @return 短信渠道枚举/渠道编码
49 49 */
50   - List<SmsChannelEnumRespVO> getChannelEnums();
  50 + List<SmsChannelEnumRespVO> getSmsChannelEnums();
51 51  
52 52 /**
53 53 * 根据短信模板编码获取短信客户端
... ... @@ -55,12 +55,20 @@ public interface SmsChannelService {
55 55 * @param templateCode 短信模板编码
56 56 * @return 短信客户端
57 57 */
58   - AbstractSmsClient<?> getClient(String templateCode);
  58 + AbstractSmsClient getSmsClient(String templateCode);
  59 +
  60 + /**
  61 + * 根据短信模板编码获取模板唯一标识
  62 + *
  63 + * @param templateCode 短信模板编码
  64 + * @return 短信客户端
  65 + */
  66 + String getSmsTemplateApiIdByCode(String templateCode);
59 67  
60 68 /**
61 69 * 查询渠道(包含名下模块)信息集合
62 70 *
63 71 * @return 渠道(包含名下模块)信息集合
64 72 */
65   - List<SmsChannelAllVO> listChannelAllEnabledInfo();
  73 + List<SmsChannelAllVO> listSmsChannelAllEnabledInfo();
66 74 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsLogService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsLogService.java
... ... @@ -12,7 +12,7 @@ import java.util.List;
12 12 * @author zzf
13 13 * @date 2021/1/25 9:24
14 14 */
15   -public interface SmsLogService {
  15 +public interface SysSmsLogService {
16 16 /**
17 17 * 发送短信前的日志处理
18 18 *
... ... @@ -22,9 +22,11 @@ public interface SmsLogService {
22 22 * @param isAsync 是否异步发送
23 23 * @return 生成的日志id
24 24 */
25   - // TODO FROM 芋艿 to ZZF: async 是针对发送的方式,对于日志不一定需要关心。这样,短信日志,实际就发送前插入,发送后更新结果
  25 + // TODO FROM 芋艿 to ZZF: async 是针对发送的方式,对于日志不一定需要关心。这样,短信日志,实际就发送前插入,发送后更新结果.
  26 + // 这里只用于记录状态,毕竟异步可能推送失败,此时日志可记录该状态。
  27 +
26 28 // TODO FROM 芋艿 to ZZF:短信日志,群发的情况,应该是每个手机一条哈。虽然是群发,但是可能部分成功,部分失败;对应到短信平台,实际也是多条。
27   - Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient<?> client, Boolean isAsync);
  29 + Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient client, Boolean isAsync);
28 30  
29 31 /**
30 32 * 发送消息后的日志处理
... ... @@ -32,6 +34,6 @@ public interface SmsLogService {
32 34 * @param logId 日志id
33 35 * @param result 消息结果
34 36 */
35   - void afterSendLog(Long logId, SmsResult<?> result);
  37 + void afterSendLog(Long logId, SmsResult result);
36 38  
37 39 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java
... ... @@ -14,7 +14,7 @@ import java.util.List;
14 14 * @author zzf
15 15 * @date 2021/1/25 9:24
16 16 */
17   -public interface SmsService {
  17 +public interface SysSmsService {
18 18  
19 19 /**
20 20 * 发送消息
... ... @@ -23,7 +23,7 @@ public interface SmsService {
23 23 * @param targetPhones 发送对象手机号列表
24 24 * @return 是否发送成功
25 25 */
26   - SmsResult<?> send(SmsBody smsBody, List<String> targetPhones);
  26 + SmsResult send(SmsBody smsBody, List<String> targetPhones);
27 27  
28 28 /**
29 29 * 发送消息
... ... @@ -32,7 +32,7 @@ public interface SmsService {
32 32 * @param targetPhone 发送对象手机号
33 33 * @return 是否发送成功
34 34 */
35   - default SmsResult<?> send(SmsBody smsBody, String targetPhone) {
  35 + default SmsResult send(SmsBody smsBody, String targetPhone) {
36 36 if (StringUtils.isBlank(targetPhone)) {
37 37 return failResult("targetPhone must not null.");
38 38 }
... ... @@ -47,7 +47,7 @@ public interface SmsService {
47 47 * @param targetPhones 发送对象手机号数组
48 48 * @return 是否发送成功
49 49 */
50   - default SmsResult<?> send(SmsBody smsBody, String... targetPhones) {
  50 + default SmsResult send(SmsBody smsBody, String... targetPhones) {
51 51 if (targetPhones == null) {
52 52 return failResult("targetPhones must not null.");
53 53 }
... ... @@ -91,8 +91,8 @@ public interface SmsService {
91 91 }
92 92  
93 93  
94   - default SmsResult<?> failResult(String message) {
95   - SmsResult<?> resultBody = new SmsResult<>();
  94 + default SmsResult failResult(String message) {
  95 + SmsResult resultBody = new SmsResult();
96 96 resultBody.setSuccess(false);
97 97 resultBody.setMessage(message);
98 98 return resultBody;
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsTemplateService.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateService.java
... ... @@ -6,5 +6,5 @@ package cn.iocoder.dashboard.modules.system.service.sms;
6 6 * @author zzf
7 7 * @date 2021/1/25 9:24
8 8 */
9   -public interface SmsTemplateService {
  9 +public interface SysSmsTemplateService {
10 10 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsChannelServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java
1 1 package cn.iocoder.dashboard.modules.system.service.sms.impl;
2 2  
3 3 import cn.hutool.core.util.ObjectUtil;
4   -import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
5 4 import cn.iocoder.dashboard.common.pojo.PageResult;
6 5 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
7 6 import cn.iocoder.dashboard.framework.sms.core.SmsClientFactory;
  7 +import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
8 8 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
9 9 import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
10 10 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
... ... @@ -12,11 +12,11 @@ import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageR
12 12 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
13 13 import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert;
14 14 import cn.iocoder.dashboard.modules.system.convert.sms.SmsTemplateConvert;
15   -import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsChannelMapper;
16   -import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsTemplateMapper;
17   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
18   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
19   -import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
  15 +import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsChannelMapper;
  16 +import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsTemplateMapper;
  17 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
  18 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsTemplateDO;
  19 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
20 20 import org.springframework.beans.factory.annotation.Autowired;
21 21 import org.springframework.stereotype.Service;
22 22  
... ... @@ -35,12 +35,12 @@ import java.util.concurrent.ConcurrentHashMap;
35 35 * @date 2021/1/25 9:25
36 36 */
37 37 @Service
38   -public class SmsChannelServiceImpl implements SmsChannelService {
  38 +public class SysSmsChannelServiceImpl implements SysSmsChannelService {
39 39  
40 40 private final Map<String, Long> templateCode2ChannelIdMap = new ConcurrentHashMap<>(32);
41 41  
42 42 @Autowired
43   - private SmsClientFactory smsClientFactory;
  43 + private SmsClientFactory clientFactory;
44 44  
45 45 /**
46 46 * 初始化短信客户端
... ... @@ -48,51 +48,60 @@ public class SmsChannelServiceImpl implements SmsChannelService {
48 48 @PostConstruct
49 49 @Override
50 50 public void initSmsClient() {
51   - List<SmsChannelAllVO> smsChannelAllVOList = listChannelAllEnabledInfo();
52   - if (ObjectUtil.isEmpty(smsChannelAllVOList)) {
53   - return;
54   - }
55   - List<SmsChannelProperty> channelPropertyList = SmsChannelConvert.INSTANCE.convertProperty(smsChannelAllVOList);
56   - channelPropertyList.forEach(smsChannelProperty -> {
57   - Long clientId = smsClientFactory.createClient(smsChannelProperty);
58   - smsChannelProperty.getTemplateList().forEach(smsTemplateVO -> {
59   - templateCode2ChannelIdMap.put(smsTemplateVO.getCode(), clientId);
60   - });
  51 + // 查询有效渠道信息
  52 + List<SysSmsChannelDO> channelDOList = channelMapper.selectEnabledList();
  53 + List<SmsChannelProperty> propertyList = SmsChannelConvert.INSTANCE.convertProperties(channelDOList);
  54 +
  55 + // 遍历渠道生成client并获取模板缓存
  56 + propertyList.forEach(channelProperty -> {
  57 + Long clientId = clientFactory.createClient(channelProperty);
  58 + List<SysSmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(channelProperty.getId());
  59 + if (ObjectUtil.isNotEmpty(templateDOList)) {
  60 + templateDOList.forEach(template -> {
  61 + templateCode2ChannelIdMap.put(template.getCode(), clientId);
  62 + });
  63 + SmsTemplateConvert.INSTANCE.convert(templateDOList);
  64 + }
61 65 });
62 66 }
63 67  
64   - // TODO FROM 芋艿 to ZZF:channelMapper 嘿,保持命名统一。
  68 + // TODO FROM 芋艿 to ZZF:channelMapper 嘿,保持命名统一。 DONE
65 69 @Resource
66   - private SmsChannelMapper mapper;
  70 + private SysSmsChannelMapper channelMapper;
67 71  
68 72 @Resource
69   - private SmsTemplateMapper templateMapper;
  73 + private SysSmsTemplateMapper templateMapper;
70 74  
71 75 @Override
72   - public PageResult<SmsChannelDO> pageChannels(SmsChannelPageReqVO reqVO) {
73   - return SmsChannelConvert.INSTANCE.convertPage(mapper.selectChannelPage(reqVO));
  76 + public PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO) {
  77 + return SmsChannelConvert.INSTANCE.convertPage(channelMapper.selectChannelPage(reqVO));
74 78 }
75 79  
76 80 @Override
77   - public Long createChannel(SmsChannelCreateReqVO reqVO) {
78   - SmsChannelDO channelDO = SmsChannelConvert.INSTANCE.convert(reqVO);
79   - mapper.insert(channelDO);
  81 + public Long createSmsChannel(SmsChannelCreateReqVO reqVO) {
  82 + SysSmsChannelDO channelDO = SmsChannelConvert.INSTANCE.convert(reqVO);
  83 + channelMapper.insert(channelDO);
80 84 return channelDO.getId();
81 85 }
82 86  
83 87 @Override
84   - public List<SmsChannelEnumRespVO> getChannelEnums() {
  88 + public List<SmsChannelEnumRespVO> getSmsChannelEnums() {
85 89 return SmsChannelConvert.INSTANCE.convertEnum(Arrays.asList(SmsChannelEnum.values()));
86 90 }
87 91  
88 92 @Override
89   - public AbstractSmsClient<?> getClient(String templateCode) {
90   - return smsClientFactory.getClient(templateCode2ChannelIdMap.get(templateCode));
  93 + public AbstractSmsClient getSmsClient(String templateCode) {
  94 + return clientFactory.getClient(templateCode2ChannelIdMap.get(templateCode));
  95 + }
  96 +
  97 + @Override
  98 + public String getSmsTemplateApiIdByCode(String templateCode) {
  99 + return clientFactory.getTemplateApiIdByCode(templateCode);
91 100 }
92 101  
93 102 @Override
94   - public List<SmsChannelAllVO> listChannelAllEnabledInfo() {
95   - List<SmsChannelDO> channelDOList = mapper.selectEnabledList();
  103 + public List<SmsChannelAllVO> listSmsChannelAllEnabledInfo() {
  104 + List<SysSmsChannelDO> channelDOList = channelMapper.selectEnabledList();
96 105 if (ObjectUtil.isNull(channelDOList)) {
97 106 return null;
98 107 }
... ... @@ -100,7 +109,7 @@ public class SmsChannelServiceImpl implements SmsChannelService {
100 109  
101 110 channelAllVOList.forEach(smsChannelDO -> {
102 111  
103   - List<SmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(smsChannelDO.getId());
  112 + List<SysSmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(smsChannelDO.getId());
104 113 if (ObjectUtil.isNull(templateDOList)) {
105 114 templateDOList = new ArrayList<>();
106 115 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsLogServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsLogServiceImpl.java
... ... @@ -3,14 +3,12 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl;
3 3 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
4 4 import cn.iocoder.dashboard.framework.sms.core.SmsBody;
5 5 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
6   -import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
7   -import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsTemplateVO;
8   -import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsLogMapper;
9   -import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsLogDO;
  6 +import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
  7 +import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsLogMapper;
  8 +import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsLogDO;
10 9 import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
11   -import cn.iocoder.dashboard.modules.system.service.sms.SmsLogService;
  10 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsLogService;
12 11 import cn.iocoder.dashboard.util.json.JsonUtils;
13   -import cn.iocoder.dashboard.util.string.StrUtils;
14 12 import org.springframework.stereotype.Service;
15 13  
16 14 import javax.annotation.Resource;
... ... @@ -23,42 +21,41 @@ import java.util.List;
23 21 * @date 2021/1/25 9:25
24 22 */
25 23 @Service
26   -public class SmsLogServiceImpl implements SmsLogService {
  24 +public class SysSmsLogServiceImpl implements SysSmsLogService {
27 25  
28 26 @Resource
29   - private SmsLogMapper smsLogMapper;
  27 + private SysSmsLogMapper logMapper;
30 28  
31 29 @Override
32   - public Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient<?> client, Boolean isAsync) {
33   - SmsLogDO smsLog = new SmsLogDO();
  30 + public Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient client, Boolean isAsync) {
  31 + SysSmsLogDO smsLog = new SysSmsLogDO();
34 32 if (smsBody.getSmsLogId() != null) {
35 33 smsLog.setId(smsBody.getSmsLogId());
36 34 smsLog.setSendStatus(SmsSendStatusEnum.SENDING.getStatus());
37   - smsLogMapper.updateById(smsLog);
  35 + logMapper.updateById(smsLog);
38 36 return smsBody.getSmsLogId();
39 37 } else {
40   - SmsChannelAllVO property = client.getProperty();
41   - SmsTemplateVO smsTemplate = property.getTemplateByTemplateCode(smsBody.getTemplateCode());
  38 + SmsChannelProperty property = client.getProperty();
42 39  
43 40 smsLog.setChannelCode(property.getCode())
44 41 .setChannelId(property.getId())
45   - .setTemplateCode(smsTemplate.getCode())
  42 + .setTemplateCode(smsBody.getTemplateCode())
46 43 .setPhones(JsonUtils.toJsonString(targetPhones))
47   - .setContent(StrUtils.replace(smsTemplate.getContent(), smsBody.getParams()));
  44 + .setContent(smsBody.getParams().toString());
48 45  
49 46 if (isAsync) {
50 47 smsLog.setSendStatus(SmsSendStatusEnum.ASYNC.getStatus());
51 48 } else {
52 49 smsLog.setSendStatus(SmsSendStatusEnum.SENDING.getStatus());
53 50 }
54   - smsLogMapper.insert(smsLog);
  51 + logMapper.insert(smsLog);
55 52 return smsLog.getId();
56 53 }
57 54 }
58 55  
59 56 @Override
60   - public void afterSendLog(Long logId, SmsResult<?> result) {
61   - SmsLogDO smsLog = new SmsLogDO();
  57 + public void afterSendLog(Long logId, SmsResult result) {
  58 + SysSmsLogDO smsLog = new SysSmsLogDO();
62 59 smsLog.setId(logId);
63 60 if (result.getSuccess()) {
64 61 smsLog.setSendStatus(SmsSendStatusEnum.SUCCESS.getStatus());
... ... @@ -66,7 +63,7 @@ public class SmsLogServiceImpl implements SmsLogService {
66 63 smsLog.setSendStatus(SmsSendStatusEnum.FAIL.getStatus());
67 64 smsLog.setRemark(result.getMessage() + JsonUtils.toJsonString(result.getResult()));
68 65 }
69   - smsLogMapper.updateById(smsLog);
  66 + logMapper.updateById(smsLog);
70 67 }
71 68  
72 69 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java
... ... @@ -4,9 +4,9 @@ import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
4 4 import cn.iocoder.dashboard.framework.sms.core.SmsBody;
5 5 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
6 6 import cn.iocoder.dashboard.modules.system.mq.producer.sms.SmsProducer;
7   -import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
8   -import cn.iocoder.dashboard.modules.system.service.sms.SmsLogService;
9   -import cn.iocoder.dashboard.modules.system.service.sms.SmsService;
  7 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
  8 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsLogService;
  9 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
10 10 import org.springframework.stereotype.Service;
11 11  
12 12 import javax.annotation.Resource;
... ... @@ -19,34 +19,36 @@ import java.util.List;
19 19 * @date 2021/1/25 9:25
20 20 */
21 21 @Service
22   -public class SmsServiceImpl implements SmsService {
  22 +public class SysSmsServiceImpl implements SysSmsService {
23 23  
24 24 @Resource
25   - private SmsChannelService channelService;
  25 + private SysSmsChannelService channelService;
26 26  
27 27 @Resource
28   - private SmsLogService smsLogService;
  28 + private SysSmsLogService logService;
29 29  
30 30 @Resource
31 31 private SmsProducer smsProducer;
32 32  
33 33 @Override
34   - public SmsResult<?> send(SmsBody smsBody, List<String> targetPhones) {
35   - AbstractSmsClient<?> client = channelService.getClient(smsBody.getTemplateCode());
36   - Long logId = smsLogService.beforeSendLog(smsBody, targetPhones, client, false);
  34 + public SmsResult send(SmsBody smsBody, List<String> targetPhones) {
  35 + AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode());
  36 + String templateApiId = channelService.getSmsTemplateApiIdByCode(smsBody.getTemplateCode());
  37 + Long logId = logService.beforeSendLog(smsBody, targetPhones, client, false);
37 38  
38   - SmsResult<?> result = client.send(smsBody, targetPhones);
  39 + SmsResult result = client.send(templateApiId, smsBody, targetPhones);
39 40  
40   - smsLogService.afterSendLog(logId, result);
  41 + logService.afterSendLog(logId, result);
41 42  
42 43 return result;
43 44 }
44 45  
45 46 // TODO FROM 芋艿 to ZZF:可能要讨论下,对于短信发送来说,貌似只提供异步发送即可。对于业务来说,一定不能依赖短信的发送结果。
  47 + // 我的想法是1、很多短信,比如验证码,总还是需要知道是否发送成功的。2、别人可以不用,我们不能没有。3、实现挺简单的,个人觉得无需纠结。
46 48 @Override
47 49 public void sendAsync(SmsBody smsBody, List<String> targetPhones) {
48   - AbstractSmsClient<?> client = channelService.getClient(smsBody.getTemplateCode());
49   - smsLogService.beforeSendLog(smsBody, targetPhones, client, true);
  50 + AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode());
  51 + logService.beforeSendLog(smsBody, targetPhones, client, true);
50 52 smsProducer.sendSmsSendMessage(smsBody, targetPhones);
51 53 }
52 54 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsTemplateServiceImpl.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java
1 1 package cn.iocoder.dashboard.modules.system.service.sms.impl;
2 2  
3   -import cn.iocoder.dashboard.modules.system.service.sms.SmsTemplateService;
  3 +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService;
4 4 import org.springframework.stereotype.Service;
5 5  
6 6 /**
... ... @@ -10,5 +10,5 @@ import org.springframework.stereotype.Service;
10 10 * @date 2021/1/25 9:25
11 11 */
12 12 @Service
13   -public class SmsTemplateServiceImpl implements SmsTemplateService {
  13 +public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
14 14 }
... ...