Browse Source

短信提交 2021-03-28,增加发送日志

YunaiV 4 years ago
parent
commit
46ed64ba40

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

@@ -55,7 +55,7 @@ public class SmsClientFactory {
             throw new ServiceException(INVALID_CHANNEL_CODE);
         }
         switch (channelEnum) {
-            case ALI:
+            case ALIYUN:
                 return new AliyunSmsClient(channelVO);
             case YUN_PIAN:
                 return new YunpianSmsClient(channelVO);

+ 11 - 10
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java

@@ -1,5 +1,6 @@
 package cn.iocoder.dashboard.framework.sms.core.enums;
 
+import cn.hutool.core.util.ArrayUtil;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
@@ -13,22 +14,22 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum SmsChannelEnum {
 
-    ALI("ALI", "阿里"),
     YUN_PIAN("YUN_PIAN", "云片"),
-    HUA_WEI("HUA_WEI", "华为"),
-    TENCENT("TENCENT", "腾讯");
+    ALIYUN("ALIYUN", "阿里云"),
+    TENCENT("TENCENT", "腾讯云"),
+    HUA_WEI("HUA_WEI", "华为云"),;
 
+    /**
+     * 编码
+     */
     private final String code;
-
+    /**
+     * 名字
+     */
     private final String name;
 
     public static SmsChannelEnum getByCode(String code) {
-        for (SmsChannelEnum value : SmsChannelEnum.values()) {
-            if (value.getCode().equals(code)) {
-                return value;
-            }
-        }
-        return null;
+        return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values());
     }
 
 }

+ 26 - 0
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsSendFailureTypeEnum.java

@@ -0,0 +1,26 @@
+package cn.iocoder.dashboard.framework.sms.core.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 短信的发送失败类型的枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum SmsSendFailureTypeEnum {
+
+    // ========== 模板相关(100 开头) ==========
+    SMS_TEMPLATE_DISABLE(100), // 短信模板被禁用
+
+    // ========== 其它相关 ==========
+    ;
+
+    /**
+     * 失败类型
+     */
+    private final int type;
+
+}

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsSendLogDO.java

@@ -2,7 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.dataobject.sms;
 
 import cn.iocoder.dashboard.common.enums.UserTypeEnum;
 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendFailureTypeEnum;
+import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
 import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
@@ -108,7 +108,7 @@ public class SysSmsSendLogDO extends BaseDO {
     /**
      * 发送失败的类型
      *
-     * 枚举 {@link SysSmsSendFailureTypeEnum}
+     * 枚举 {@link SmsSendFailureTypeEnum}
      */
     private Integer sendFailureType;
     /**

+ 0 - 19
src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java

@@ -1,19 +0,0 @@
-package cn.iocoder.dashboard.modules.system.enums.sms;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 短信的发送失败类型的枚举
- *
- * @author 芋道源码
- */
-@Getter
-@AllArgsConstructor
-public enum SysSmsSendFailureTypeEnum {
-
-    ;
-
-    private final int type;
-
-}

+ 16 - 6
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendStreamConsumer.java → src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java

@@ -1,10 +1,13 @@
 package cn.iocoder.dashboard.modules.system.mq.consumer.sms;
 
+import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
 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.message.sms.SysSmsSendMessage;
 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService;
+import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
 import cn.iocoder.dashboard.util.json.JsonUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.connection.stream.ObjectRecord;
@@ -14,14 +17,14 @@ import org.springframework.stereotype.Component;
 import javax.annotation.Resource;
 
 /**
- * 短信发送流消息监听器
+ * 针对 {@link SysSmsSendMessage} 的消费者
  *
  * @author zzf
  * @date 2021/3/9 16:35
  */
-@Slf4j
 @Component
-public class SmsSendStreamConsumer implements StreamListener<String, ObjectRecord<String, SmsSendMessage>> {
+@Slf4j
+public class SmsSendConsumer extends AbstractStreamMessageListener<SysSmsSendMessage> {
 
     @Resource
     private SysSmsChannelService smsChannelService;
@@ -29,15 +32,22 @@ public class SmsSendStreamConsumer implements StreamListener<String, ObjectRecor
     @Resource
     private SysSmsQueryLogService smsQueryLogService;
 
+    @Resource
+    private SysSmsService smsService;
+
     @Override
     public void onMessage(ObjectRecord<String, SmsSendMessage> record) {
-        SmsSendMessage message = record.getValue();
-        SmsBody body = message.getSmsBody();
-        log.info("[onMessage][收到 发送短信 消息], content: " + JsonUtils.toJsonString(body));
         AbstractSmsClient smsClient = smsChannelService.getSmsClient(body.getTemplateCode());
         String templateApiId = smsChannelService.getSmsTemplateApiIdByCode(body.getTemplateCode());
 
         SmsResult result = smsClient.send(templateApiId, body, message.getTargetPhone());
         smsQueryLogService.afterSendLog(body.getSmsLogId(), result);
     }
+
+    @Override
+    public void onMessage(SysSmsSendMessage message) {
+        log.info("[onMessage][消息内容({})]", message);
+        smsService.doSendSms(message);
+    }
+
 }

+ 0 - 17
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SysSmsSendConsumer.java

@@ -1,17 +0,0 @@
-package cn.iocoder.dashboard.modules.system.mq.consumer.sms;
-
-import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener;
-import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-@Component
-@Slf4j
-public class SysSmsSendConsumer extends AbstractStreamMessageListener<SysSmsSendMessage> {
-
-    @Override
-    public void onMessage(SysSmsSendMessage message) {
-        log.info("[onMessage][消息内容({})]", message);
-    }
-
-}

+ 13 - 12
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java

@@ -14,29 +14,30 @@ import java.util.Map;
 @Data
 public class SysSmsSendMessage implements StreamMessage {
 
+    /**
+     * 发送日志编号
+     */
+    @NotNull(message = "发送日志编号不能为空")
+    private Long sendLogId;
     /**
      * 手机号
      */
     @NotNull(message = "手机号不能为空")
     private String mobile;
     /**
-     * 短信模板编号
+     * 短信渠道编号
      */
-    @NotNull(message = "短信模板编号不能为空")
-    private String templateCode;
+    @NotNull(message = "短信渠道编号不能为空")
+    private Long channelId;
     /**
-     * 短信模板参数
+     * 短信 API 的模板编号
      */
-    private Map<String, Object> templateParams;
-
+    @NotNull(message = "短信 API 的模板编号不能为空")
+    private String apiTemplateId;
     /**
-     * 用户编号,允许空
-     */
-    private Integer userId;
-    /**
-     * 用户类型,允许空
+     * 短信模板参数
      */
-    private Integer userType;
+    private Map<String, Object> templateParams;
 
     @Override
     public String getStreamKey() {

+ 9 - 9
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SmsSendStreamProducer.java → src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SysSmsProducer.java

@@ -17,7 +17,7 @@ import java.util.Map;
  */
 @Slf4j
 @Component
-public class SmsSendStreamProducer {
+public class SysSmsProducer {
 
     @Resource
     private StringRedisTemplate stringRedisTemplate;
@@ -25,17 +25,17 @@ public class SmsSendStreamProducer {
     /**
      * 发送短信 Message
      *
+     * @param sendLogId 发送日志编号
      * @param mobile 手机号
-     * @param templateCode 短信模板编号
+     * @param channelId 渠道编号
+     * @param apiTemplateId 短信模板编号
      * @param templateParams 短信模板参数
-     * @param userId 用户编号
-     * @param userType 用户类型
+     * @param sendLogId 发送日志编号
      */
-    public void sendSmsSendMessage(String mobile, String templateCode, Map<String, Object> templateParams,
-                                   Integer userId, Integer userType) {
-        SysSmsSendMessage message = new SysSmsSendMessage();
-        message.setMobile(mobile).setTemplateCode(templateCode).setTemplateParams(templateParams);
-        message.setUserId(userId).setUserType(userType);
+    public void sendSmsSendMessage(Long sendLogId, String mobile,
+                                   Long channelId, String apiTemplateId, Map<String, Object> templateParams) {
+        SysSmsSendMessage message = new SysSmsSendMessage().setSendLogId(sendLogId).setMobile(mobile);
+        message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams);
         RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message);
     }
 

+ 8 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsSendLogService.java

@@ -15,6 +15,14 @@ public interface SysSmsSendLogService {
     Long createSmsSendLog(String mobile, Long userId, Integer userType,
                           SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams);
 
+    /**
+     * 更新发送日志为失败
+     *
+     * @param id 发送日志编号
+     * @param sendFailureType 失败类型
+     */
+    void updateSmsSendLogFailure(Long id, Integer sendFailureType);
+
     void getAndSaveSmsSendLog();
 
 }

+ 3 - 1
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java

@@ -1,5 +1,7 @@
 package cn.iocoder.dashboard.modules.system.service.sms;
 
+import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
+
 import javax.servlet.ServletRequest;
 import java.util.List;
 import java.util.Map;
@@ -19,7 +21,7 @@ public interface SysSmsService {
     void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType,
                       String templateCode, Map<String, Object> templateParams);
 
-    void doSendSms();
+    void doSendSms(SysSmsSendMessage message);
 
     /**
      * 处理短信发送回调函数

+ 5 - 1
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java

@@ -42,7 +42,6 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService {
      */
     private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
 
-
     @Override
     public Long createSmsSendLog(String mobile, Long userId, Integer userType,
                                  SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams) {
@@ -61,6 +60,11 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService {
         return logDO.getId();
     }
 
+    @Override
+    public void updateSmsSendLogFailure(Long id, Integer sendFailureType) {
+        smsSendLogMapper.updateById(new SysSmsSendLogDO().setId(id).setSendFailureType(sendFailureType));
+    }
+
     @Override
     public void getAndSaveSmsSendLog() {
 

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

@@ -1,16 +1,16 @@
 package cn.iocoder.dashboard.modules.system.service.sms.impl;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
 import cn.iocoder.dashboard.common.enums.UserTypeEnum;
-import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
-import cn.iocoder.dashboard.framework.sms.core.SmsBody;
 import cn.iocoder.dashboard.framework.sms.core.SmsClientFactory;
 import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
+import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
-import cn.iocoder.dashboard.modules.system.mq.producer.sms.SmsSendStreamProducer;
+import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
+import cn.iocoder.dashboard.modules.system.mq.producer.sms.SysSmsProducer;
 import cn.iocoder.dashboard.modules.system.service.sms.*;
 import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
 import org.springframework.stereotype.Service;
@@ -20,8 +20,6 @@ import javax.servlet.ServletRequest;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.function.Predicate;
 
 import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@@ -51,7 +49,7 @@ public class SysSmsServiceImpl implements SysSmsService {
     private SysSmsQueryLogService logService;
 
     @Resource
-    private SmsSendStreamProducer smsProducer;
+    private SysSmsProducer smsProducer;
 
     @Resource
     private SmsClientFactory smsClientFactory;
@@ -68,8 +66,13 @@ public class SysSmsServiceImpl implements SysSmsService {
         String content = smsTemplateService.formatSmsTemplateContent(template.getContent(), templateParams);
         Long sendLogId = smsSendLogService.createSmsSendLog(mobile, userId, userType, template, content, templateParams);
 
-        // 发送 MQ 消息
-
+        // 如果模板被禁用,则直接标记发送失败。也就说,不发短信,嘿嘿。
+        if (CommonStatusEnum.DISABLE.getStatus().equals(template.getStatus())) {
+            smsSendLogService.updateSmsSendLogFailure(sendLogId, SmsSendFailureTypeEnum.SMS_TEMPLATE_DISABLE.getType());
+            return;
+        }
+        // 如果模板未禁用,发送 MQ 消息。目的是,异步化调用短信平台
+        smsProducer.sendSmsSendMessage(sendLogId, mobile, template.getChannelId(), template.getApiTemplateId(), templateParams);
     }
 
     @Override
@@ -79,11 +82,6 @@ public class SysSmsServiceImpl implements SysSmsService {
         SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode, templateParams);
     }
 
-    @Override
-    public void doSendSms() {
-
-    }
-
     private SysSmsTemplateDO checkSmsTemplateValid(String templateCode, Map<String, Object> templateParams) {
         // 短信模板不存在
         SysSmsTemplateDO template = smsTemplateService.getSmsTemplateByCode(templateCode);
@@ -132,10 +130,8 @@ public class SysSmsServiceImpl implements SysSmsService {
     }
 
     @Override
-    public void send(SmsBody smsBody, String targetPhone) {
-        AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode());
-        logService.beforeSendLog(smsBody, targetPhone, client);
-        smsProducer.sendSmsSendMessage(smsBody, targetPhone);
+    public void doSendSms(SysSmsSendMessage message) {
+
     }
 
     @Override