zengzefeng 4 жил өмнө
parent
commit
b4be8e987a
29 өөрчлөгдсөн 420 нэмэгдсэн , 265 устгасан
  1. 46 1
      src/main/java/cn/iocoder/dashboard/framework/sms/client/AbstractSmsClient.java
  2. 31 24
      src/main/java/cn/iocoder/dashboard/framework/sms/client/AliyunSmsClient.java
  3. 6 5
      src/main/java/cn/iocoder/dashboard/framework/sms/client/SmsClient.java
  4. 49 16
      src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java
  5. 12 3
      src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResult.java
  6. 33 0
      src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java
  7. 3 6
      src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java
  8. 8 9
      src/main/java/cn/iocoder/dashboard/framework/sms/core/property/SmsChannelProperty.java
  9. 14 3
      src/main/java/cn/iocoder/dashboard/framework/sms/core/property/SmsTemplateProperty.java
  10. 7 7
      src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java
  11. 8 6
      src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java
  12. 5 5
      src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsTemplateConvert.java
  13. 0 39
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsTemplateMapper.java
  14. 10 10
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsChannelMapper.java
  15. 2 2
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsLogMapper.java
  16. 39 0
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsTemplateMapper.java
  17. 1 1
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsChannelDO.java
  18. 1 1
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsLogDO.java
  19. 1 1
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsTemplateDO.java
  20. 3 3
      src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java
  21. 15 7
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java
  22. 6 4
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsLogService.java
  23. 6 6
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java
  24. 1 1
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateService.java
  25. 0 52
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsServiceImpl.java
  26. 41 32
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java
  27. 16 19
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsLogServiceImpl.java
  28. 54 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java
  29. 2 2
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java

+ 46 - 1
src/main/java/cn/iocoder/dashboard/framework/sms/client/AbstractSmsClient.java

@@ -1,6 +1,11 @@
 package cn.iocoder.dashboard.framework.sms.client;
 
+import cn.iocoder.dashboard.framework.sms.core.SmsBody;
+import cn.iocoder.dashboard.framework.sms.core.SmsResult;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Collection;
 
 /**
  * 抽象短息客户端
@@ -8,7 +13,8 @@ import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
  * @author zzf
  * @date 2021/2/1 9:28
  */
-public abstract class AbstractSmsClient<R> implements SmsClient<R> {
+@Slf4j
+public abstract class AbstractSmsClient implements SmsClient {
 
     /**
      * 短信渠道参数
@@ -29,4 +35,43 @@ public abstract class AbstractSmsClient<R> implements SmsClient<R> {
         return channelVO;
     }
 
+    @Override
+    public SmsResult send(String templateApiId, SmsBody smsBody, Collection<String> targets) {
+        SmsResult result;
+        try {
+            beforeSend(templateApiId, smsBody, targets);
+            result = doSend(templateApiId, smsBody, targets);
+            afterSend(templateApiId, smsBody, targets, result);
+        } catch (Exception e) {
+            // exception handle
+            log.debug(e.getMessage(), e);
+            return failResult("发送异常: " + e.getMessage());
+        }
+        return result;
+    }
+
+
+    /**
+     * 发送消息
+     *
+     * @param templateApiId 短信模板唯一标识
+     * @param smsBody       消息内容
+     * @param targets       发送对象列表
+     * @return 短信发送结果
+     */
+    public abstract SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception;
+
+    protected void beforeSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception {
+    }
+
+    protected void afterSend(String templateApiId, SmsBody smsBody, Collection<String> targets, SmsResult result) throws Exception {
+    }
+
+
+    SmsResult failResult(String message) {
+        SmsResult resultBody = new SmsResult();
+        resultBody.setSuccess(false);
+        resultBody.setMessage(message);
+        return resultBody;
+    }
 }

+ 31 - 24
src/main/java/cn/iocoder/dashboard/framework/sms/client/AliyunSmsClient.java

@@ -1,10 +1,14 @@
 package cn.iocoder.dashboard.framework.sms.client;
 
+import cn.hutool.core.date.DateUtil;
 import cn.iocoder.dashboard.framework.sms.core.SmsBody;
 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
+import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
 import com.aliyuncs.DefaultAcsClient;
 import com.aliyuncs.IAcsClient;
+import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
+import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
 import com.aliyuncs.http.MethodType;
@@ -13,7 +17,9 @@ import com.aliyuncs.profile.IClientProfile;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 /**
  * 阿里短信实现类
@@ -22,7 +28,7 @@ import java.util.Collection;
  * @date 2021/1/25 14:17
  */
 @Slf4j
-public class AliyunSmsClient extends AbstractSmsClient<SendSmsResponse> {
+public class AliyunSmsClient extends AbstractSmsClient {
 
     private static final String OK = "OK";
 
@@ -53,35 +59,36 @@ public class AliyunSmsClient extends AbstractSmsClient<SendSmsResponse> {
 
 
     @Override
-    public SmsResult<SendSmsResponse> send(SmsBody smsBody, Collection<String> targets) {
+    public SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception {
         SendSmsRequest request = new SendSmsRequest();
         request.setSysMethod(MethodType.POST);
         request.setPhoneNumbers(StringUtils.join(targets, ","));
         request.setSignName(channelVO.getApiSignatureId());
-        request.setTemplateCode(channelVO.getTemplateByTemplateCode(smsBody.getTemplateCode()).getApiTemplateId());
+        request.setTemplateCode(templateApiId);
         request.setTemplateParam(smsBody.getParamsStr());
-        // TODO FROM 芋艿 TO zzf:try catch 咱是不是可以交给 abstract 来做。这样,异常处理,重试,限流等等,都可以酱紫
-        try {
-            SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
-
-            boolean result = OK.equals(sendSmsResponse.getCode());
-            if (!result) {
-                log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage());
-            }
-            SmsResult<SendSmsResponse> resultBody = new SmsResult<>();
-            resultBody.setSuccess(result);
-            resultBody.setResult(sendSmsResponse);
-            return resultBody;
-        } catch (Exception e) {
-            log.debug(e.getMessage(), e);
-            return failResult("发送异常: " + e.getMessage());
-        }
-    }
+        // TODO FROM 芋艿 TO zzf:try catch 咱是不是可以交给 abstract 来做。这样,异常处理,重试,限流等等,都可以酱紫  DONE
+        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
 
-    SmsResult<SendSmsResponse> failResult(String message) {
-        SmsResult<SendSmsResponse> resultBody = new SmsResult<>();
-        resultBody.setSuccess(false);
-        resultBody.setMessage(message);
+        boolean result = OK.equals(sendSmsResponse.getCode());
+        if (!result) {
+            log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage());
+        }
+        SmsResult resultBody = new SmsResult();
+        resultBody.setSuccess(result);
+        QuerySendDetailsRequest querySendDetailsRequest = new QuerySendDetailsRequest();
+        querySendDetailsRequest.setBizId(sendSmsResponse.getBizId());
+
+        QuerySendDetailsResponse acsResponse = acsClient.getAcsResponse(querySendDetailsRequest);
+        List<SmsResultDetail> resultDetailList = new ArrayList<>(Integer.parseInt(acsResponse.getTotalCount()));
+        acsResponse.getSmsSendDetailDTOs().forEach(s -> {
+            SmsResultDetail resultDetail = new SmsResultDetail();
+            resultDetail.setCreateTime(DateUtil.parseDateTime(s.getSendDate()));
+            resultDetail.setMessage(s.getContent());
+            resultDetail.setPhone(s.getPhoneNum());
+            resultDetail.setStatus(Math.toIntExact(s.getSendStatus()));
+            resultDetailList.add(resultDetail);
+        });
+        resultBody.setResult(resultDetailList);
         return resultBody;
     }
 

+ 6 - 5
src/main/java/cn/iocoder/dashboard/framework/sms/client/SmsClient.java

@@ -11,15 +11,16 @@ import java.util.Collection;
  * @author zzf
  * @date 2021/1/25 14:14
  */
-public interface SmsClient<R> {
+public interface SmsClient {
 
     /**
      * 发送消息
      *
-     * @param smsBody 消息内容
-     * @param targets 发送对象列表
-     * @return 是否发送成功
+     * @param templateApiId 短信模板唯一标识
+     * @param smsBody       消息内容
+     * @param targets       发送对象列表
+     * @return 短信发送结果
      */
-    SmsResult<R> send(SmsBody smsBody, Collection<String> targets);
+    SmsResult send(String templateApiId, SmsBody smsBody, Collection<String> targets);
 
 }

+ 49 - 16
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java

@@ -1,15 +1,14 @@
 package cn.iocoder.dashboard.framework.sms.core;
 
-import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
 import cn.iocoder.dashboard.common.exception.ServiceException;
-import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
 import cn.iocoder.dashboard.framework.sms.client.AliyunSmsClient;
+import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
+import cn.iocoder.dashboard.framework.sms.core.property.SmsTemplateProperty;
 import org.springframework.stereotype.Component;
 
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -24,7 +23,17 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
 @Component
 public class SmsClientFactory {
 
-    private final Map<Long, AbstractSmsClient<?>> smsSenderMap = new ConcurrentHashMap<>(8);
+    /**
+     * channelId: client map
+     * 保存 渠道id: 对应短信客户端 的map
+     */
+    private final Map<Long, AbstractSmsClient> smsSenderMap = new ConcurrentHashMap<>(8);
+
+    /**
+     * templateCode: TemplateProperty map
+     * 保存 模板编码:模板信息 的map
+     */
+    private final Map<String, SmsTemplateProperty> templatePropertyMap = new ConcurrentHashMap<>(16);
 
     /**
      * 创建短信客户端
@@ -33,20 +42,13 @@ public class SmsClientFactory {
      * @return 客户端id(默认channelId)
      */
     public Long createClient(SmsChannelProperty propertyVO) {
-        // TODO FROM 芋艿 TO zzf:参数的校验,可以考虑统一使用 validation。
-        if (StrUtil.isBlank(propertyVO.getCode())) {
-            throw ServiceExceptionUtil.exception(PARAM_VALUE_IS_NULL, "短信渠道编码");
-        }
-        if (ObjectUtil.isNull(propertyVO.getId())) {
-            throw ServiceExceptionUtil.exception(PARAM_VALUE_IS_NULL, "短信渠道ID");
-        }
-
-        AbstractSmsClient<?> sender = createClient(SmsChannelEnum.getByCode(propertyVO.getCode()), propertyVO);
+        // TODO FROM 芋艿 TO zzf:参数的校验,可以考虑统一使用 validation。   DONE
+        AbstractSmsClient sender = createClient(SmsChannelEnum.getByCode(propertyVO.getCode()), propertyVO);
         smsSenderMap.put(propertyVO.getId(), sender);
         return propertyVO.getId();
     }
 
-    private AbstractSmsClient<?> createClient(SmsChannelEnum channelEnum, SmsChannelProperty channelVO) {
+    private AbstractSmsClient createClient(SmsChannelEnum channelEnum, SmsChannelProperty channelVO) {
         if (channelEnum == null) {
             throw new ServiceException(INVALID_CHANNEL_CODE);
         }
@@ -66,7 +68,38 @@ public class SmsClientFactory {
      * @param channelId 渠道id
      * @return 短信id
      */
-    public AbstractSmsClient<?> getClient(Long channelId) {
+    public AbstractSmsClient getClient(Long channelId) {
         return smsSenderMap.get(channelId);
     }
+
+
+    /**
+     * 添加或修改短信模板信息缓存
+     */
+    public void addOrUpdateTemplateCache(Collection<SmsTemplateProperty> templateProperties) {
+        templateProperties.forEach(s -> templatePropertyMap.put(s.getCode(), s));
+    }
+
+
+    /**
+     * 添加或修改短信模板信息缓存
+     */
+    public void addOrUpdateTemplateCache(SmsTemplateProperty templateProperty) {
+        templatePropertyMap.put(templateProperty.getCode(), templateProperty);
+    }
+
+
+    /**
+     * 根据短信模板编码获取模板唯一标识
+     *
+     * @param templateCode 短信模板编码
+     * @return 短信id
+     */
+    public String getTemplateApiIdByCode(String templateCode) {
+        SmsTemplateProperty smsTemplateProperty = templatePropertyMap.get(templateCode);
+        if (smsTemplateProperty == null) {
+            throw new ServiceException(SMS_TEMPLATE_NOT_FOUND);
+        }
+        return smsTemplateProperty.getApiTemplateId();
+    }
 }

+ 12 - 3
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResult.java

@@ -3,17 +3,24 @@ package cn.iocoder.dashboard.framework.sms.core;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.List;
 
 /**
  * 消息内容实体类
  */
 @Data
-public class SmsResult<T> implements Serializable {
+public class SmsResult implements Serializable {
 
     /**
      * 是否成功
      */
-    private Boolean success; // TODO FROM 芋艿 to zzf:未来要加一个 code,将不同平台的短信失败的情况,做一次统一的收敛。
+    // TODO FROM 芋艿 to zzf:未来要加一个 code,将不同平台的短信失败的情况,做一次统一的收敛。  DONE
+    private Boolean success;
+
+    /**
+     * 状态码
+     */
+    private String code;
 
     /**
      * 提示
@@ -23,5 +30,7 @@ public class SmsResult<T> implements Serializable {
     /**
      * 返回值
      */
-    private T result; // TODO FROM 芋艿 to zzf:是不是统一各个平台的返回结果,这样对调用方来说统一。因为作为统一的短信客户端,最好让上层不太需要知道太具体。黑河诶
+    // TODO FROM 芋艿 to zzf:是不是统一各个平台的返回结果,这样对调用方来说统一。因为作为统一的短信客户端,最好让上层不太需要知道太具体。黑河诶  DONE
+    private List<SmsResultDetail> result;
+
 }

+ 33 - 0
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java

@@ -0,0 +1,33 @@
+package cn.iocoder.dashboard.framework.sms.core;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 消息内容实体类
+ */
+@Data
+public class SmsResultDetail implements Serializable {
+
+    /**
+     * 状态   1成功 2失败 3等待回执
+     */
+    private Integer status;
+
+    /**
+     * 接收手机号
+     */
+    private String phone;
+
+    /**
+     * 提示
+     */
+    private String message;
+
+    /**
+     * 时间
+     */
+    private Date createTime;
+}

+ 3 - 6
src/main/java/cn/iocoder/dashboard/common/enums/SmsChannelEnum.java → src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java

@@ -1,13 +1,10 @@
-package cn.iocoder.dashboard.common.enums;
+package cn.iocoder.dashboard.framework.sms.core.enums;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
 /**
- * 短信渠道枚举 TODO FROM 芋艿 TO zzf:属于短信的枚举类,可以放到 framework/sms 下
+ * 短信渠道枚举 TODO FROM 芋艿 TO zzf:属于短信的枚举类,可以放到 framework/sms 下   DONE
  *
  * @author zzf
  * @date 2021/1/25 10:56
@@ -19,7 +16,7 @@ public enum SmsChannelEnum {
     ALI("ALI", "阿里"),
     HUA_WEI("HUA_WEI", "华为"),
     QI_NIU("QI_NIU", "七牛"),
-    TEN_XUN("TEN_XUN", "腾讯"); // TODO FROM 芋艿 to zzf:TEN 有后鼻音哈,要被马爸爸打了。。。
+    TENCENT("TENCENT", "腾讯"); // TODO FROM 芋艿 to zzf:TEN 有后鼻音哈,要被马爸爸打了。。。 DONE
 
     private final String code;
 

+ 8 - 9
src/main/java/cn/iocoder/dashboard/framework/sms/core/property/SmsChannelProperty.java

@@ -3,6 +3,8 @@ package cn.iocoder.dashboard.framework.sms.core.property;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.util.List;
 
@@ -19,40 +21,37 @@ public class SmsChannelProperty implements Serializable {
     /**
      * id
      */
+    @NotNull(message = "短信渠道ID不能为空")
     private Long id;
 
     /**
      * 编码(来自枚举类 阿里、华为、七牛等)
      */
+    @NotEmpty(message = "短信渠道编码不能为空")
     private String code;
 
     /**
      * 渠道账号id
      */
+    @NotEmpty(message = "渠道账号id不能为空")
     private String apiKey;
 
     /**
      * 渠道账号秘钥
      */
+    @NotEmpty(message = "渠道账号秘钥不能为空")
     private String apiSecret;
 
     /**
      * 实际渠道签名唯一标识
      */
+    @NotEmpty(message = "实际渠道签名唯一标识不能为空")
     private String apiSignatureId;
 
     /**
      * 签名值
      */
+    @NotEmpty(message = "签名值不能为空")
     private String signature;
 
-    /**
-     * 该渠道名下的短信模板集合
-     */
-    private List<SmsTemplateProperty> templateList;
-
-    public SmsTemplateProperty getTemplateByTemplateCode(String tempCode) {
-        return templateList.stream().filter(s -> s.getCode().equals(tempCode)).findFirst().get();
-    }
-
 }

+ 14 - 3
src/main/java/cn/iocoder/dashboard/framework/sms/core/property/SmsTemplateProperty.java

@@ -3,8 +3,12 @@ package cn.iocoder.dashboard.framework.sms.core.property;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
+import javax.validation.constraints.NotEmpty;
+
 /**
- * 渠道模板VO类 TODO FROM 芋艿 TO zzf:模板是不是不要提供到 client 里面,而是交给 factory 统一维护就好。不然,模板修改时候,刷新 client 会比较麻烦。
+ * 渠道模板VO类
+ * TODO FROM 芋艿 TO zzf:模板是不是不要提供到 client 里面,而是交给 factory 统一维护就好。不然,模板修改时候,刷新 client 会比较麻烦。
+ *
  *
  * @author zzf
  * @date 2021/1/25 17:03
@@ -13,6 +17,12 @@ import lombok.EqualsAndHashCode;
 @EqualsAndHashCode
 public class SmsTemplateProperty {
 
+    /**
+     * 渠道id
+     */
+    @NotEmpty(message = "短信渠道编码不能为空")
+    private Long channelId;
+
     /**
      * 业务编码(来自数据字典, 用户自定义业务场景 一个场景可以有多个模板)
      */
@@ -21,18 +31,19 @@ public class SmsTemplateProperty {
     /**
      * 编码
      */
+    @NotEmpty(message = "短信模板编码不能为空")
     private String code;
 
     /**
      * 实际渠道模板唯一标识
      */
+    @NotEmpty(message = "短信模板唯一标识不能为空")
     private String apiTemplateId;
 
     /**
      * 内容
      */
+    @NotEmpty(message = "短信模板内容不能为空")
     private String content;
 
-
-
 }

+ 7 - 7
src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsChannelController.java

@@ -5,8 +5,8 @@ import cn.iocoder.dashboard.common.pojo.PageResult;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.validation.annotation.Validated;
@@ -23,25 +23,25 @@ import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
 public class SmsChannelController {
 
     @Resource
-    private SmsChannelService service;
+    private SysSmsChannelService service;
 
     @ApiOperation("获取渠道/签名分页")
     @GetMapping("/page")
-    public CommonResult<PageResult<SmsChannelDO>> getPermissionInfo(@Validated SmsChannelPageReqVO reqVO) {
-        return success(service.pageChannels(reqVO));
+    public CommonResult<PageResult<SysSmsChannelDO>> getPermissionInfo(@Validated SmsChannelPageReqVO reqVO) {
+        return success(service.pageSmsChannels(reqVO));
     }
 
     @ApiOperation("获取渠道枚举")
     @GetMapping("/list/channel-enum")
     public CommonResult<List<SmsChannelEnumRespVO>> getChannelEnums() {
-        return success(service.getChannelEnums());
+        return success(service.getSmsChannelEnums());
     }
 
 
     @ApiOperation("添加消息渠道")
     @PostMapping("/create")
     public CommonResult<Long> add(@Validated @RequestBody SmsChannelCreateReqVO reqVO) {
-        return success(service.createChannel(reqVO));
+        return success(service.createSmsChannel(reqVO));
     }
 
 

+ 8 - 6
src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsChannelConvert.java

@@ -1,13 +1,13 @@
 package cn.iocoder.dashboard.modules.system.convert.sms;
 
-import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
+import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
 import cn.iocoder.dashboard.common.pojo.PageResult;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
 import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
@@ -21,17 +21,19 @@ public interface SmsChannelConvert {
     SmsChannelConvert INSTANCE = Mappers.getMapper(SmsChannelConvert.class);
 
     @Mapping(source = "records", target = "list")
-    PageResult<SmsChannelDO> convertPage(IPage<SmsChannelDO> page);
+    PageResult<SysSmsChannelDO> convertPage(IPage<SysSmsChannelDO> page);
 
-    SmsChannelDO convert(SmsChannelCreateReqVO bean);
+    SysSmsChannelDO convert(SmsChannelCreateReqVO bean);
 
-    SmsChannelDO convert(SysUserUpdateReqVO bean);
+    SysSmsChannelDO convert(SysUserUpdateReqVO bean);
 
     List<SmsChannelEnumRespVO> convertEnum(List<SmsChannelEnum> bean);
 
-    List<SmsChannelAllVO> convert(List<SmsChannelDO> bean);
+    List<SmsChannelAllVO> convert(List<SysSmsChannelDO> bean);
 
     List<SmsChannelProperty> convertProperty(List<SmsChannelAllVO> list);
 
+    List<SmsChannelProperty> convertProperties(List<SysSmsChannelDO> list);
+
 
 }

+ 5 - 5
src/main/java/cn/iocoder/dashboard/modules/system/convert/sms/SmsTemplateConvert.java

@@ -2,8 +2,8 @@ package cn.iocoder.dashboard.modules.system.convert.sms;
 
 import cn.iocoder.dashboard.common.pojo.PageResult;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsTemplateVO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsTemplateDO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
@@ -17,10 +17,10 @@ public interface SmsTemplateConvert {
     SmsTemplateConvert INSTANCE = Mappers.getMapper(SmsTemplateConvert.class);
 
     @Mapping(source = "records", target = "list")
-    PageResult<SmsChannelDO> convertPage(IPage<SmsChannelDO> page);
+    PageResult<SysSmsChannelDO> convertPage(IPage<SysSmsChannelDO> page);
 
-    List<SmsTemplateVO> convert(List<SmsTemplateDO> bean);
+    List<SmsTemplateVO> convert(List<SysSmsTemplateDO> bean);
 
-    SmsTemplateVO convert(SmsTemplateDO bean);
+    SmsTemplateVO convert(SysSmsTemplateDO bean);
 
 }

+ 0 - 39
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsTemplateMapper.java

@@ -1,39 +0,0 @@
-package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
-
-import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-@Mapper
-public interface SmsTemplateMapper extends BaseMapper<SmsTemplateDO> {
-
-    /**
-     * 根据短信渠道id查询短信模板集合
-     *
-     * @param channelId 渠道id
-     * @return 模板集合
-     */
-    default List<SmsTemplateDO> selectListByChannelId(Long channelId) {
-        return selectList(new LambdaQueryWrapper<SmsTemplateDO>()
-                .eq(SmsTemplateDO::getChannelId, channelId)
-                .eq(SmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
-                .orderByAsc(SmsTemplateDO::getId)
-        );
-    }
-
-    /**
-     * 查询有效短信模板集合
-     *
-     * @return 有效短信模板集合
-     */
-    default List<SmsTemplateDO> selectEnabledList() {
-        return selectList(new LambdaQueryWrapper<SmsTemplateDO>()
-                .eq(SmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
-                .orderByAsc(SmsTemplateDO::getId)
-        );
-    }
-}

+ 10 - 10
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsChannelMapper.java → src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsChannelMapper.java

@@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
 import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -13,19 +13,19 @@ import org.apache.ibatis.annotations.Mapper;
 import java.util.List;
 
 @Mapper
-public interface SmsChannelMapper extends BaseMapper<SmsChannelDO> {
+public interface SysSmsChannelMapper extends BaseMapper<SysSmsChannelDO> {
 
-    default IPage<SmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) {
-        return selectPage(MyBatisUtils.buildPage(reqVO), new LambdaQueryWrapper<SmsChannelDO>()
-                .like(StrUtil.isNotBlank(reqVO.getName()), SmsChannelDO::getName, reqVO.getName())
-                .like(StrUtil.isNotBlank(reqVO.getSignature()), SmsChannelDO::getName, reqVO.getSignature())
+    default IPage<SysSmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) {
+        return selectPage(MyBatisUtils.buildPage(reqVO), new LambdaQueryWrapper<SysSmsChannelDO>()
+                .like(StrUtil.isNotBlank(reqVO.getName()), SysSmsChannelDO::getName, reqVO.getName())
+                .like(StrUtil.isNotBlank(reqVO.getSignature()), SysSmsChannelDO::getName, reqVO.getSignature())
         );
     }
 
-    default List<SmsChannelDO> selectEnabledList() {
-        return selectList(new LambdaQueryWrapper<SmsChannelDO>()
-                .eq(SmsChannelDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
-                .orderByAsc(SmsChannelDO::getId)
+    default List<SysSmsChannelDO> selectEnabledList() {
+        return selectList(new LambdaQueryWrapper<SysSmsChannelDO>()
+                .eq(SysSmsChannelDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
+                .orderByAsc(SysSmsChannelDO::getId)
         );
     }
 }

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SmsLogMapper.java → src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsLogMapper.java

@@ -1,10 +1,10 @@
 package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
 
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsLogDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsLogDO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
-public interface SmsLogMapper extends BaseMapper<SmsLogDO> {
+public interface SysSmsLogMapper extends BaseMapper<SysSmsLogDO> {
 
 }

+ 39 - 0
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsTemplateMapper.java

@@ -0,0 +1,39 @@
+package cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms;
+
+import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsTemplateDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface SysSmsTemplateMapper extends BaseMapper<SysSmsTemplateDO> {
+
+    /**
+     * 根据短信渠道id查询短信模板集合
+     *
+     * @param channelId 渠道id
+     * @return 模板集合
+     */
+    default List<SysSmsTemplateDO> selectListByChannelId(Long channelId) {
+        return selectList(new LambdaQueryWrapper<SysSmsTemplateDO>()
+                .eq(SysSmsTemplateDO::getChannelId, channelId)
+                .eq(SysSmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
+                .orderByAsc(SysSmsTemplateDO::getId)
+        );
+    }
+
+    /**
+     * 查询有效短信模板集合
+     *
+     * @return 有效短信模板集合
+     */
+    default List<SysSmsTemplateDO> selectEnabledList() {
+        return selectList(new LambdaQueryWrapper<SysSmsTemplateDO>()
+                .eq(SysSmsTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
+                .orderByAsc(SysSmsTemplateDO::getId)
+        );
+    }
+}

+ 1 - 1
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsChannelDO.java → src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsChannelDO.java

@@ -15,7 +15,7 @@ import lombok.EqualsAndHashCode;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName(value = "sms_channel", autoResultMap = true)
-public class SmsChannelDO extends BaseDO {
+public class SysSmsChannelDO extends BaseDO {
 
     /**
      * 自增编号

+ 1 - 1
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsLogDO.java → src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsLogDO.java

@@ -18,7 +18,7 @@ import java.util.Date;
 @EqualsAndHashCode
 @Accessors(chain = true)
 @TableName(value = "sms_log", autoResultMap = true)
-public class SmsLogDO implements Serializable {
+public class SysSmsLogDO implements Serializable {
 
     /**
      * 自增编号

+ 1 - 1
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SmsTemplateDO.java → src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsTemplateDO.java

@@ -16,7 +16,7 @@ import java.util.Date;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName(value = "sms_template", autoResultMap = true)
-public class SmsTemplateDO extends BaseDO {
+public class SysSmsTemplateDO extends BaseDO {
 
     /**
      * 自增编号

+ 3 - 3
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
 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
 import cn.iocoder.dashboard.modules.system.mq.message.dept.SysDeptRefreshMessage;
 import cn.iocoder.dashboard.modules.system.mq.message.sms.SmsSendMessage;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsService;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
@@ -20,12 +20,12 @@ import javax.annotation.Resource;
 public class SmsSendConsumer extends AbstractChannelMessageListener<SmsSendMessage> {
 
     @Resource
-    private SmsService smsService;
+    private SysSmsService sysSmsService;
 
     @Override
     public void onMessage(SmsSendMessage message) {
         log.info("[onMessage][收到 发送短信 消息]");
-        SmsResult<?> send = smsService.send(message.getSmsBody(), message.getTargetPhones());
+        SmsResult send = sysSmsService.send(message.getSmsBody(), message.getTargetPhones());
     }
 
 }

+ 15 - 7
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsChannelService.java → 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;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
 
 import java.util.List;
 
@@ -16,7 +16,7 @@ import java.util.List;
  * @author zzf
  * @date 2021/1/25 9:24
  */
-public interface SmsChannelService {
+public interface SysSmsChannelService {
 
     // TODO FROM 芋艿 to ZZF:SmsChannelService=》SysSmsChannelService,增加 Sys 前缀,算在系统模块里
     // TODO FROM 芋艿 to ZZF:方法名,保持不去掉 Sms 前缀。虽然长点,嘿嘿
@@ -32,7 +32,7 @@ public interface SmsChannelService {
      * @param reqVO 参数对象
      * @return 短信渠道分页对象
      */
-    PageResult<SmsChannelDO> pageChannels(SmsChannelPageReqVO reqVO);
+    PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO);
 
     /**
      * 创建新的渠道信息
@@ -40,14 +40,14 @@ public interface SmsChannelService {
      * @param reqVO 参数对象
      * @return 渠道id
      */
-    Long createChannel(SmsChannelCreateReqVO reqVO);
+    Long createSmsChannel(SmsChannelCreateReqVO reqVO);
 
     /**
      * 获取短信渠道枚举/渠道编码
      *
      * @return 短信渠道枚举/渠道编码
      */
-    List<SmsChannelEnumRespVO> getChannelEnums();
+    List<SmsChannelEnumRespVO> getSmsChannelEnums();
 
     /**
      * 根据短信模板编码获取短信客户端
@@ -55,12 +55,20 @@ public interface SmsChannelService {
      * @param templateCode 短信模板编码
      * @return 短信客户端
      */
-    AbstractSmsClient<?> getClient(String templateCode);
+    AbstractSmsClient getSmsClient(String templateCode);
+
+    /**
+     * 根据短信模板编码获取模板唯一标识
+     *
+     * @param templateCode 短信模板编码
+     * @return 短信客户端
+     */
+    String getSmsTemplateApiIdByCode(String templateCode);
 
     /**
      * 查询渠道(包含名下模块)信息集合
      *
      * @return 渠道(包含名下模块)信息集合
      */
-    List<SmsChannelAllVO> listChannelAllEnabledInfo();
+    List<SmsChannelAllVO> listSmsChannelAllEnabledInfo();
 }

+ 6 - 4
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsLogService.java → src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsLogService.java

@@ -12,7 +12,7 @@ import java.util.List;
  * @author zzf
  * @date 2021/1/25 9:24
  */
-public interface SmsLogService {
+public interface SysSmsLogService {
     /**
      * 发送短信前的日志处理
      *
@@ -22,9 +22,11 @@ public interface SmsLogService {
      * @param isAsync      是否异步发送
      * @return 生成的日志id
      */
-    // TODO FROM 芋艿 to ZZF: async 是针对发送的方式,对于日志不一定需要关心。这样,短信日志,实际就发送前插入,发送后更新结果
+    // TODO FROM 芋艿 to ZZF: async 是针对发送的方式,对于日志不一定需要关心。这样,短信日志,实际就发送前插入,发送后更新结果.
+    //   这里只用于记录状态,毕竟异步可能推送失败,此时日志可记录该状态。
+
     // TODO FROM 芋艿 to ZZF:短信日志,群发的情况,应该是每个手机一条哈。虽然是群发,但是可能部分成功,部分失败;对应到短信平台,实际也是多条。
-    Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient<?> client, Boolean isAsync);
+    Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient client, Boolean isAsync);
 
     /**
      * 发送消息后的日志处理
@@ -32,6 +34,6 @@ public interface SmsLogService {
      * @param logId  日志id
      * @param result 消息结果
      */
-    void afterSendLog(Long logId, SmsResult<?> result);
+    void afterSendLog(Long logId, SmsResult result);
 
 }

+ 6 - 6
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsService.java → src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java

@@ -14,7 +14,7 @@ import java.util.List;
  * @author zzf
  * @date 2021/1/25 9:24
  */
-public interface SmsService {
+public interface SysSmsService {
 
     /**
      * 发送消息
@@ -23,7 +23,7 @@ public interface SmsService {
      * @param targetPhones 发送对象手机号列表
      * @return 是否发送成功
      */
-    SmsResult<?> send(SmsBody smsBody, List<String> targetPhones);
+    SmsResult send(SmsBody smsBody, List<String> targetPhones);
 
     /**
      * 发送消息
@@ -32,7 +32,7 @@ public interface SmsService {
      * @param targetPhone 发送对象手机号
      * @return 是否发送成功
      */
-    default SmsResult<?> send(SmsBody smsBody, String targetPhone) {
+    default SmsResult send(SmsBody smsBody, String targetPhone) {
         if (StringUtils.isBlank(targetPhone)) {
             return failResult("targetPhone must not null.");
         }
@@ -47,7 +47,7 @@ public interface SmsService {
      * @param targetPhones 发送对象手机号数组
      * @return 是否发送成功
      */
-    default SmsResult<?> send(SmsBody smsBody, String... targetPhones) {
+    default SmsResult send(SmsBody smsBody, String... targetPhones) {
         if (targetPhones == null) {
             return failResult("targetPhones must not null.");
         }
@@ -91,8 +91,8 @@ public interface SmsService {
     }
 
 
-    default SmsResult<?> failResult(String message) {
-        SmsResult<?> resultBody = new SmsResult<>();
+    default SmsResult failResult(String message) {
+        SmsResult resultBody = new SmsResult();
         resultBody.setSuccess(false);
         resultBody.setMessage(message);
         return resultBody;

+ 1 - 1
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SmsTemplateService.java → src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateService.java

@@ -6,5 +6,5 @@ package cn.iocoder.dashboard.modules.system.service.sms;
  * @author zzf
  * @date 2021/1/25 9:24
  */
-public interface SmsTemplateService {
+public interface SysSmsTemplateService {
 }

+ 0 - 52
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsServiceImpl.java

@@ -1,52 +0,0 @@
-package cn.iocoder.dashboard.modules.system.service.sms.impl;
-
-import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
-import cn.iocoder.dashboard.framework.sms.core.SmsBody;
-import cn.iocoder.dashboard.framework.sms.core.SmsResult;
-import cn.iocoder.dashboard.modules.system.mq.producer.sms.SmsProducer;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsLogService;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsService;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.util.List;
-
-/**
- * 短信日志Service实现类
- *
- * @author zzf
- * @date 2021/1/25 9:25
- */
-@Service
-public class SmsServiceImpl implements SmsService {
-
-    @Resource
-    private SmsChannelService channelService;
-
-    @Resource
-    private SmsLogService smsLogService;
-
-    @Resource
-    private SmsProducer smsProducer;
-
-    @Override
-    public SmsResult<?> send(SmsBody smsBody, List<String> targetPhones) {
-        AbstractSmsClient<?> client = channelService.getClient(smsBody.getTemplateCode());
-        Long logId = smsLogService.beforeSendLog(smsBody, targetPhones, client, false);
-
-        SmsResult<?> result = client.send(smsBody, targetPhones);
-
-        smsLogService.afterSendLog(logId, result);
-
-        return result;
-    }
-
-    // TODO FROM 芋艿 to ZZF:可能要讨论下,对于短信发送来说,貌似只提供异步发送即可。对于业务来说,一定不能依赖短信的发送结果。
-    @Override
-    public void sendAsync(SmsBody smsBody, List<String> targetPhones) {
-        AbstractSmsClient<?> client = channelService.getClient(smsBody.getTemplateCode());
-        smsLogService.beforeSendLog(smsBody, targetPhones, client, true);
-        smsProducer.sendSmsSendMessage(smsBody, targetPhones);
-    }
-}

+ 41 - 32
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsChannelServiceImpl.java → src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsChannelServiceImpl.java

@@ -1,10 +1,10 @@
 package cn.iocoder.dashboard.modules.system.service.sms.impl;
 
 import cn.hutool.core.util.ObjectUtil;
-import cn.iocoder.dashboard.common.enums.SmsChannelEnum;
 import cn.iocoder.dashboard.common.pojo.PageResult;
 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
 import cn.iocoder.dashboard.framework.sms.core.SmsClientFactory;
+import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
 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
 import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
 import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert;
 import cn.iocoder.dashboard.modules.system.convert.sms.SmsTemplateConvert;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsChannelMapper;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsTemplateMapper;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsChannelDO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsTemplateDO;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsChannelService;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsChannelMapper;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsTemplateMapper;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsTemplateDO;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -35,12 +35,12 @@ import java.util.concurrent.ConcurrentHashMap;
  * @date 2021/1/25 9:25
  */
 @Service
-public class SmsChannelServiceImpl implements SmsChannelService {
+public class SysSmsChannelServiceImpl implements SysSmsChannelService {
 
     private final Map<String, Long> templateCode2ChannelIdMap = new ConcurrentHashMap<>(32);
 
     @Autowired
-    private SmsClientFactory smsClientFactory;
+    private SmsClientFactory clientFactory;
 
     /**
      * 初始化短信客户端
@@ -48,51 +48,60 @@ public class SmsChannelServiceImpl implements SmsChannelService {
     @PostConstruct
     @Override
     public void initSmsClient() {
-        List<SmsChannelAllVO> smsChannelAllVOList = listChannelAllEnabledInfo();
-        if (ObjectUtil.isEmpty(smsChannelAllVOList)) {
-            return;
-        }
-        List<SmsChannelProperty> channelPropertyList = SmsChannelConvert.INSTANCE.convertProperty(smsChannelAllVOList);
-        channelPropertyList.forEach(smsChannelProperty -> {
-            Long clientId = smsClientFactory.createClient(smsChannelProperty);
-            smsChannelProperty.getTemplateList().forEach(smsTemplateVO -> {
-                templateCode2ChannelIdMap.put(smsTemplateVO.getCode(), clientId);
-            });
+        // 查询有效渠道信息
+        List<SysSmsChannelDO> channelDOList = channelMapper.selectEnabledList();
+        List<SmsChannelProperty> propertyList = SmsChannelConvert.INSTANCE.convertProperties(channelDOList);
+
+        // 遍历渠道生成client并获取模板缓存
+        propertyList.forEach(channelProperty -> {
+            Long clientId = clientFactory.createClient(channelProperty);
+            List<SysSmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(channelProperty.getId());
+            if (ObjectUtil.isNotEmpty(templateDOList)) {
+                templateDOList.forEach(template -> {
+                    templateCode2ChannelIdMap.put(template.getCode(), clientId);
+                });
+                SmsTemplateConvert.INSTANCE.convert(templateDOList);
+            }
         });
     }
 
-    // TODO FROM 芋艿 to ZZF:channelMapper 嘿,保持命名统一。
+    // TODO FROM 芋艿 to ZZF:channelMapper 嘿,保持命名统一。 DONE
     @Resource
-    private SmsChannelMapper mapper;
+    private SysSmsChannelMapper channelMapper;
 
     @Resource
-    private SmsTemplateMapper templateMapper;
+    private SysSmsTemplateMapper templateMapper;
 
     @Override
-    public PageResult<SmsChannelDO> pageChannels(SmsChannelPageReqVO reqVO) {
-        return SmsChannelConvert.INSTANCE.convertPage(mapper.selectChannelPage(reqVO));
+    public PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO) {
+        return SmsChannelConvert.INSTANCE.convertPage(channelMapper.selectChannelPage(reqVO));
     }
 
     @Override
-    public Long createChannel(SmsChannelCreateReqVO reqVO) {
-        SmsChannelDO channelDO = SmsChannelConvert.INSTANCE.convert(reqVO);
-        mapper.insert(channelDO);
+    public Long createSmsChannel(SmsChannelCreateReqVO reqVO) {
+        SysSmsChannelDO channelDO = SmsChannelConvert.INSTANCE.convert(reqVO);
+        channelMapper.insert(channelDO);
         return channelDO.getId();
     }
 
     @Override
-    public List<SmsChannelEnumRespVO> getChannelEnums() {
+    public List<SmsChannelEnumRespVO> getSmsChannelEnums() {
         return SmsChannelConvert.INSTANCE.convertEnum(Arrays.asList(SmsChannelEnum.values()));
     }
 
     @Override
-    public AbstractSmsClient<?> getClient(String templateCode) {
-        return smsClientFactory.getClient(templateCode2ChannelIdMap.get(templateCode));
+    public AbstractSmsClient getSmsClient(String templateCode) {
+        return clientFactory.getClient(templateCode2ChannelIdMap.get(templateCode));
+    }
+
+    @Override
+    public String getSmsTemplateApiIdByCode(String templateCode) {
+        return clientFactory.getTemplateApiIdByCode(templateCode);
     }
 
     @Override
-    public List<SmsChannelAllVO> listChannelAllEnabledInfo() {
-        List<SmsChannelDO> channelDOList = mapper.selectEnabledList();
+    public List<SmsChannelAllVO> listSmsChannelAllEnabledInfo() {
+        List<SysSmsChannelDO> channelDOList = channelMapper.selectEnabledList();
         if (ObjectUtil.isNull(channelDOList)) {
             return null;
         }
@@ -100,7 +109,7 @@ public class SmsChannelServiceImpl implements SmsChannelService {
 
         channelAllVOList.forEach(smsChannelDO -> {
 
-            List<SmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(smsChannelDO.getId());
+            List<SysSmsTemplateDO> templateDOList = templateMapper.selectListByChannelId(smsChannelDO.getId());
             if (ObjectUtil.isNull(templateDOList)) {
                 templateDOList = new ArrayList<>();
             }

+ 16 - 19
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsLogServiceImpl.java → 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;
 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
 import cn.iocoder.dashboard.framework.sms.core.SmsBody;
 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
-import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
-import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsTemplateVO;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SmsLogMapper;
-import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SmsLogDO;
+import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsLogMapper;
+import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsLogDO;
 import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
-import cn.iocoder.dashboard.modules.system.service.sms.SmsLogService;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsLogService;
 import cn.iocoder.dashboard.util.json.JsonUtils;
-import cn.iocoder.dashboard.util.string.StrUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -23,42 +21,41 @@ import java.util.List;
  * @date 2021/1/25 9:25
  */
 @Service
-public class SmsLogServiceImpl implements SmsLogService {
+public class SysSmsLogServiceImpl implements SysSmsLogService {
 
     @Resource
-    private SmsLogMapper smsLogMapper;
+    private SysSmsLogMapper logMapper;
 
     @Override
-    public Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient<?> client, Boolean isAsync) {
-        SmsLogDO smsLog = new SmsLogDO();
+    public Long beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient client, Boolean isAsync) {
+        SysSmsLogDO smsLog = new SysSmsLogDO();
         if (smsBody.getSmsLogId() != null) {
             smsLog.setId(smsBody.getSmsLogId());
             smsLog.setSendStatus(SmsSendStatusEnum.SENDING.getStatus());
-            smsLogMapper.updateById(smsLog);
+            logMapper.updateById(smsLog);
             return smsBody.getSmsLogId();
         } else {
-            SmsChannelAllVO property = client.getProperty();
-            SmsTemplateVO smsTemplate = property.getTemplateByTemplateCode(smsBody.getTemplateCode());
+            SmsChannelProperty property = client.getProperty();
 
             smsLog.setChannelCode(property.getCode())
                     .setChannelId(property.getId())
-                    .setTemplateCode(smsTemplate.getCode())
+                    .setTemplateCode(smsBody.getTemplateCode())
                     .setPhones(JsonUtils.toJsonString(targetPhones))
-                    .setContent(StrUtils.replace(smsTemplate.getContent(), smsBody.getParams()));
+                    .setContent(smsBody.getParams().toString());
 
             if (isAsync) {
                 smsLog.setSendStatus(SmsSendStatusEnum.ASYNC.getStatus());
             } else {
                 smsLog.setSendStatus(SmsSendStatusEnum.SENDING.getStatus());
             }
-            smsLogMapper.insert(smsLog);
+            logMapper.insert(smsLog);
             return smsLog.getId();
         }
     }
 
     @Override
-    public void afterSendLog(Long logId, SmsResult<?> result) {
-        SmsLogDO smsLog = new SmsLogDO();
+    public void afterSendLog(Long logId, SmsResult result) {
+        SysSmsLogDO smsLog = new SysSmsLogDO();
         smsLog.setId(logId);
         if (result.getSuccess()) {
             smsLog.setSendStatus(SmsSendStatusEnum.SUCCESS.getStatus());
@@ -66,7 +63,7 @@ public class SmsLogServiceImpl implements SmsLogService {
             smsLog.setSendStatus(SmsSendStatusEnum.FAIL.getStatus());
             smsLog.setRemark(result.getMessage() + JsonUtils.toJsonString(result.getResult()));
         }
-        smsLogMapper.updateById(smsLog);
+        logMapper.updateById(smsLog);
     }
 
 }

+ 54 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java

@@ -0,0 +1,54 @@
+package cn.iocoder.dashboard.modules.system.service.sms.impl;
+
+import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
+import cn.iocoder.dashboard.framework.sms.core.SmsBody;
+import cn.iocoder.dashboard.framework.sms.core.SmsResult;
+import cn.iocoder.dashboard.modules.system.mq.producer.sms.SmsProducer;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsLogService;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 短信日志Service实现类
+ *
+ * @author zzf
+ * @date 2021/1/25 9:25
+ */
+@Service
+public class SysSmsServiceImpl implements SysSmsService {
+
+    @Resource
+    private SysSmsChannelService channelService;
+
+    @Resource
+    private SysSmsLogService logService;
+
+    @Resource
+    private SmsProducer smsProducer;
+
+    @Override
+    public SmsResult send(SmsBody smsBody, List<String> targetPhones) {
+        AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode());
+        String templateApiId = channelService.getSmsTemplateApiIdByCode(smsBody.getTemplateCode());
+        Long logId = logService.beforeSendLog(smsBody, targetPhones, client, false);
+
+        SmsResult result = client.send(templateApiId, smsBody, targetPhones);
+
+        logService.afterSendLog(logId, result);
+
+        return result;
+    }
+
+    // TODO FROM 芋艿 to ZZF:可能要讨论下,对于短信发送来说,貌似只提供异步发送即可。对于业务来说,一定不能依赖短信的发送结果。
+    //  我的想法是1、很多短信,比如验证码,总还是需要知道是否发送成功的。2、别人可以不用,我们不能没有。3、实现挺简单的,个人觉得无需纠结。
+    @Override
+    public void sendAsync(SmsBody smsBody, List<String> targetPhones) {
+        AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode());
+        logService.beforeSendLog(smsBody, targetPhones, client, true);
+        smsProducer.sendSmsSendMessage(smsBody, targetPhones);
+    }
+}

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SmsTemplateServiceImpl.java → src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java

@@ -1,6 +1,6 @@
 package cn.iocoder.dashboard.modules.system.service.sms.impl;
 
-import cn.iocoder.dashboard.modules.system.service.sms.SmsTemplateService;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService;
 import org.springframework.stereotype.Service;
 
 /**
@@ -10,5 +10,5 @@ import org.springframework.stereotype.Service;
  * @date 2021/1/25 9:25
  */
 @Service
-public class SmsTemplateServiceImpl implements SmsTemplateService {
+public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
 }