diff --git a/src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java b/src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java index bd41cc2ee..2350bda88 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java +++ b/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); diff --git a/src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java b/src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java index 0265f455e..213034882 100644 --- a/src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java +++ b/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()); } } diff --git a/src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsSendFailureTypeEnum.java b/src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsSendFailureTypeEnum.java new file mode 100644 index 000000000..572ee3908 --- /dev/null +++ b/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; + +} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsSendLogDO.java b/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsSendLogDO.java index 28c9f510f..7147b8d7a 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsSendLogDO.java +++ b/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; /** diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java deleted file mode 100644 index 8548e92ae..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java +++ /dev/null @@ -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; - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendStreamConsumer.java b/src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java similarity index 69% rename from src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendStreamConsumer.java rename to src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java index bbd5de462..63c4bc59e 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendStreamConsumer.java +++ b/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> { +@Slf4j +public class SmsSendConsumer extends AbstractStreamMessageListener { @Resource private SysSmsChannelService smsChannelService; @@ -29,15 +32,22 @@ public class SmsSendStreamConsumer implements StreamListener 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); + } + } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SysSmsSendConsumer.java b/src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SysSmsSendConsumer.java deleted file mode 100644 index e3b18ca75..000000000 --- a/src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SysSmsSendConsumer.java +++ /dev/null @@ -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 { - - @Override - public void onMessage(SysSmsSendMessage message) { - log.info("[onMessage][消息内容({})]", message); - } - -} diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java b/src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java index f47b52466..40cc80ba5 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java @@ -14,30 +14,31 @@ 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 的模板编号 + */ + @NotNull(message = "短信 API 的模板编号不能为空") + private String apiTemplateId; /** * 短信模板参数 */ private Map templateParams; - /** - * 用户编号,允许空 - */ - private Integer userId; - /** - * 用户类型,允许空 - */ - private Integer userType; - @Override public String getStreamKey() { return "system.sms.send"; diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SmsSendStreamProducer.java b/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SysSmsProducer.java similarity index 57% rename from src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SmsSendStreamProducer.java rename to src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SysSmsProducer.java index 891a844cc..257de549c 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SmsSendStreamProducer.java +++ b/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 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 templateParams) { + SysSmsSendMessage message = new SysSmsSendMessage().setSendLogId(sendLogId).setMobile(mobile); + message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams); RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsSendLogService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsSendLogService.java index e36dd1f5c..baf76b7a0 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsSendLogService.java +++ b/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 templateParams); + /** + * 更新发送日志为失败 + * + * @param id 发送日志编号 + * @param sendFailureType 失败类型 + */ + void updateSmsSendLogFailure(Long id, Integer sendFailureType); + void getAndSaveSmsSendLog(); } diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java index d4958f79b..34fcf4e9c 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java +++ b/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 mobiles, List userIds, Integer userType, String templateCode, Map templateParams); - void doSendSms(); + void doSendSms(SysSmsSendMessage message); /** * 处理短信发送回调函数 diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java index e8295a5cf..cfceda947 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java +++ b/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 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() { diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java index dde2580a4..b06e99cec 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java +++ b/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 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