Commit 46ed64ba4048e5e6bf24b791b6af5addf10b996a
1 parent
f3b6783c
短信提交 2021-03-28,增加发送日志
Showing
12 changed files
with
91 additions
and
79 deletions
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java
| ... | ... | @@ -55,7 +55,7 @@ public class SmsClientFactory { |
| 55 | 55 | throw new ServiceException(INVALID_CHANNEL_CODE); |
| 56 | 56 | } |
| 57 | 57 | switch (channelEnum) { |
| 58 | - case ALI: | |
| 58 | + case ALIYUN: | |
| 59 | 59 | return new AliyunSmsClient(channelVO); |
| 60 | 60 | case YUN_PIAN: |
| 61 | 61 | return new YunpianSmsClient(channelVO); | ... | ... |
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java
| 1 | 1 | package cn.iocoder.dashboard.framework.sms.core.enums; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.ArrayUtil; | |
| 3 | 4 | import lombok.AllArgsConstructor; |
| 4 | 5 | import lombok.Getter; |
| 5 | 6 | |
| ... | ... | @@ -13,22 +14,22 @@ import lombok.Getter; |
| 13 | 14 | @AllArgsConstructor |
| 14 | 15 | public enum SmsChannelEnum { |
| 15 | 16 | |
| 16 | - ALI("ALI", "阿里"), | |
| 17 | 17 | YUN_PIAN("YUN_PIAN", "云片"), |
| 18 | - HUA_WEI("HUA_WEI", "华为"), | |
| 19 | - TENCENT("TENCENT", "腾讯"); | |
| 18 | + ALIYUN("ALIYUN", "阿里云"), | |
| 19 | + TENCENT("TENCENT", "腾讯云"), | |
| 20 | + HUA_WEI("HUA_WEI", "华为云"),; | |
| 20 | 21 | |
| 22 | + /** | |
| 23 | + * 编码 | |
| 24 | + */ | |
| 21 | 25 | private final String code; |
| 22 | - | |
| 26 | + /** | |
| 27 | + * 名字 | |
| 28 | + */ | |
| 23 | 29 | private final String name; |
| 24 | 30 | |
| 25 | 31 | public static SmsChannelEnum getByCode(String code) { |
| 26 | - for (SmsChannelEnum value : SmsChannelEnum.values()) { | |
| 27 | - if (value.getCode().equals(code)) { | |
| 28 | - return value; | |
| 29 | - } | |
| 30 | - } | |
| 31 | - return null; | |
| 32 | + return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values()); | |
| 32 | 33 | } |
| 33 | 34 | |
| 34 | 35 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsSendFailureTypeEnum.java
| 1 | -package cn.iocoder.dashboard.modules.system.enums.sms; | |
| 1 | +package cn.iocoder.dashboard.framework.sms.core.enums; | |
| 2 | 2 | |
| 3 | 3 | import lombok.AllArgsConstructor; |
| 4 | 4 | import lombok.Getter; |
| ... | ... | @@ -10,10 +10,17 @@ import lombok.Getter; |
| 10 | 10 | */ |
| 11 | 11 | @Getter |
| 12 | 12 | @AllArgsConstructor |
| 13 | -public enum SysSmsSendFailureTypeEnum { | |
| 13 | +public enum SmsSendFailureTypeEnum { | |
| 14 | 14 | |
| 15 | + // ========== 模板相关(100 开头) ========== | |
| 16 | + SMS_TEMPLATE_DISABLE(100), // 短信模板被禁用 | |
| 17 | + | |
| 18 | + // ========== 其它相关 ========== | |
| 15 | 19 | ; |
| 16 | 20 | |
| 21 | + /** | |
| 22 | + * 失败类型 | |
| 23 | + */ | |
| 17 | 24 | private final int type; |
| 18 | 25 | |
| 19 | 26 | } | ... | ... |
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; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.dashboard.common.enums.UserTypeEnum; |
| 4 | 4 | import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; |
| 5 | -import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendFailureTypeEnum; | |
| 5 | +import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; | |
| 6 | 6 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; |
| 7 | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | 8 | import lombok.*; |
| ... | ... | @@ -108,7 +108,7 @@ public class SysSmsSendLogDO extends BaseDO { |
| 108 | 108 | /** |
| 109 | 109 | * 发送失败的类型 |
| 110 | 110 | * |
| 111 | - * 枚举 {@link SysSmsSendFailureTypeEnum} | |
| 111 | + * 枚举 {@link SmsSendFailureTypeEnum} | |
| 112 | 112 | */ |
| 113 | 113 | private Integer sendFailureType; |
| 114 | 114 | /** | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendStreamConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java
| 1 | 1 | package cn.iocoder.dashboard.modules.system.mq.consumer.sms; |
| 2 | 2 | |
| 3 | +import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener; | |
| 3 | 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 4 | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 5 | 6 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; |
| 7 | +import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage; | |
| 6 | 8 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; |
| 7 | 9 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; |
| 10 | +import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; | |
| 8 | 11 | import cn.iocoder.dashboard.util.json.JsonUtils; |
| 9 | 12 | import lombok.extern.slf4j.Slf4j; |
| 10 | 13 | import org.springframework.data.redis.connection.stream.ObjectRecord; |
| ... | ... | @@ -14,14 +17,14 @@ import org.springframework.stereotype.Component; |
| 14 | 17 | import javax.annotation.Resource; |
| 15 | 18 | |
| 16 | 19 | /** |
| 17 | - * 短信发送流消息监听器 | |
| 20 | + * 针对 {@link SysSmsSendMessage} 的消费者 | |
| 18 | 21 | * |
| 19 | 22 | * @author zzf |
| 20 | 23 | * @date 2021/3/9 16:35 |
| 21 | 24 | */ |
| 22 | -@Slf4j | |
| 23 | 25 | @Component |
| 24 | -public class SmsSendStreamConsumer implements StreamListener<String, ObjectRecord<String, SmsSendMessage>> { | |
| 26 | +@Slf4j | |
| 27 | +public class SmsSendConsumer extends AbstractStreamMessageListener<SysSmsSendMessage> { | |
| 25 | 28 | |
| 26 | 29 | @Resource |
| 27 | 30 | private SysSmsChannelService smsChannelService; |
| ... | ... | @@ -29,15 +32,22 @@ public class SmsSendStreamConsumer implements StreamListener<String, ObjectRecor |
| 29 | 32 | @Resource |
| 30 | 33 | private SysSmsQueryLogService smsQueryLogService; |
| 31 | 34 | |
| 35 | + @Resource | |
| 36 | + private SysSmsService smsService; | |
| 37 | + | |
| 32 | 38 | @Override |
| 33 | 39 | public void onMessage(ObjectRecord<String, SmsSendMessage> record) { |
| 34 | - SmsSendMessage message = record.getValue(); | |
| 35 | - SmsBody body = message.getSmsBody(); | |
| 36 | - log.info("[onMessage][收到 发送短信 消息], content: " + JsonUtils.toJsonString(body)); | |
| 37 | 40 | AbstractSmsClient smsClient = smsChannelService.getSmsClient(body.getTemplateCode()); |
| 38 | 41 | String templateApiId = smsChannelService.getSmsTemplateApiIdByCode(body.getTemplateCode()); |
| 39 | 42 | |
| 40 | 43 | SmsResult result = smsClient.send(templateApiId, body, message.getTargetPhone()); |
| 41 | 44 | smsQueryLogService.afterSendLog(body.getSmsLogId(), result); |
| 42 | 45 | } |
| 46 | + | |
| 47 | + @Override | |
| 48 | + public void onMessage(SysSmsSendMessage message) { | |
| 49 | + log.info("[onMessage][消息内容({})]", message); | |
| 50 | + smsService.doSendSms(message); | |
| 51 | + } | |
| 52 | + | |
| 43 | 53 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SysSmsSendConsumer.java deleted
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.sms; | |
| 2 | - | |
| 3 | -import cn.iocoder.dashboard.framework.redis.core.stream.AbstractStreamMessageListener; | |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage; | |
| 5 | -import lombok.extern.slf4j.Slf4j; | |
| 6 | -import org.springframework.stereotype.Component; | |
| 7 | - | |
| 8 | -@Component | |
| 9 | -@Slf4j | |
| 10 | -public class SysSmsSendConsumer extends AbstractStreamMessageListener<SysSmsSendMessage> { | |
| 11 | - | |
| 12 | - @Override | |
| 13 | - public void onMessage(SysSmsSendMessage message) { | |
| 14 | - log.info("[onMessage][消息内容({})]", message); | |
| 15 | - } | |
| 16 | - | |
| 17 | -} |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SysSmsSendMessage.java
| ... | ... | @@ -15,28 +15,29 @@ import java.util.Map; |
| 15 | 15 | public class SysSmsSendMessage implements StreamMessage { |
| 16 | 16 | |
| 17 | 17 | /** |
| 18 | + * 发送日志编号 | |
| 19 | + */ | |
| 20 | + @NotNull(message = "发送日志编号不能为空") | |
| 21 | + private Long sendLogId; | |
| 22 | + /** | |
| 18 | 23 | * 手机号 |
| 19 | 24 | */ |
| 20 | 25 | @NotNull(message = "手机号不能为空") |
| 21 | 26 | private String mobile; |
| 22 | 27 | /** |
| 23 | - * 短信模板编号 | |
| 28 | + * 短信渠道编号 | |
| 24 | 29 | */ |
| 25 | - @NotNull(message = "短信模板编号不能为空") | |
| 26 | - private String templateCode; | |
| 30 | + @NotNull(message = "短信渠道编号不能为空") | |
| 31 | + private Long channelId; | |
| 27 | 32 | /** |
| 28 | - * 短信模板参数 | |
| 33 | + * 短信 API 的模板编号 | |
| 29 | 34 | */ |
| 30 | - private Map<String, Object> templateParams; | |
| 31 | - | |
| 35 | + @NotNull(message = "短信 API 的模板编号不能为空") | |
| 36 | + private String apiTemplateId; | |
| 32 | 37 | /** |
| 33 | - * 用户编号,允许空 | |
| 34 | - */ | |
| 35 | - private Integer userId; | |
| 36 | - /** | |
| 37 | - * 用户类型,允许空 | |
| 38 | + * 短信模板参数 | |
| 38 | 39 | */ |
| 39 | - private Integer userType; | |
| 40 | + private Map<String, Object> templateParams; | |
| 40 | 41 | |
| 41 | 42 | @Override |
| 42 | 43 | public String getStreamKey() { | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SmsSendStreamProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SysSmsProducer.java
| ... | ... | @@ -17,7 +17,7 @@ import java.util.Map; |
| 17 | 17 | */ |
| 18 | 18 | @Slf4j |
| 19 | 19 | @Component |
| 20 | -public class SmsSendStreamProducer { | |
| 20 | +public class SysSmsProducer { | |
| 21 | 21 | |
| 22 | 22 | @Resource |
| 23 | 23 | private StringRedisTemplate stringRedisTemplate; |
| ... | ... | @@ -25,17 +25,17 @@ public class SmsSendStreamProducer { |
| 25 | 25 | /** |
| 26 | 26 | * 发送短信 Message |
| 27 | 27 | * |
| 28 | + * @param sendLogId 发送日志编号 | |
| 28 | 29 | * @param mobile 手机号 |
| 29 | - * @param templateCode 短信模板编号 | |
| 30 | + * @param channelId 渠道编号 | |
| 31 | + * @param apiTemplateId 短信模板编号 | |
| 30 | 32 | * @param templateParams 短信模板参数 |
| 31 | - * @param userId 用户编号 | |
| 32 | - * @param userType 用户类型 | |
| 33 | + * @param sendLogId 发送日志编号 | |
| 33 | 34 | */ |
| 34 | - public void sendSmsSendMessage(String mobile, String templateCode, Map<String, Object> templateParams, | |
| 35 | - Integer userId, Integer userType) { | |
| 36 | - SysSmsSendMessage message = new SysSmsSendMessage(); | |
| 37 | - message.setMobile(mobile).setTemplateCode(templateCode).setTemplateParams(templateParams); | |
| 38 | - message.setUserId(userId).setUserType(userType); | |
| 35 | + public void sendSmsSendMessage(Long sendLogId, String mobile, | |
| 36 | + Long channelId, String apiTemplateId, Map<String, Object> templateParams) { | |
| 37 | + SysSmsSendMessage message = new SysSmsSendMessage().setSendLogId(sendLogId).setMobile(mobile); | |
| 38 | + message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams); | |
| 39 | 39 | RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message); |
| 40 | 40 | } |
| 41 | 41 | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsSendLogService.java
| ... | ... | @@ -15,6 +15,14 @@ public interface SysSmsSendLogService { |
| 15 | 15 | Long createSmsSendLog(String mobile, Long userId, Integer userType, |
| 16 | 16 | SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams); |
| 17 | 17 | |
| 18 | + /** | |
| 19 | + * 更新发送日志为失败 | |
| 20 | + * | |
| 21 | + * @param id 发送日志编号 | |
| 22 | + * @param sendFailureType 失败类型 | |
| 23 | + */ | |
| 24 | + void updateSmsSendLogFailure(Long id, Integer sendFailureType); | |
| 25 | + | |
| 18 | 26 | void getAndSaveSmsSendLog(); |
| 19 | 27 | |
| 20 | 28 | } | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java
| 1 | 1 | package cn.iocoder.dashboard.modules.system.service.sms; |
| 2 | 2 | |
| 3 | +import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage; | |
| 4 | + | |
| 3 | 5 | import javax.servlet.ServletRequest; |
| 4 | 6 | import java.util.List; |
| 5 | 7 | import java.util.Map; |
| ... | ... | @@ -19,7 +21,7 @@ public interface SysSmsService { |
| 19 | 21 | void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType, |
| 20 | 22 | String templateCode, Map<String, Object> templateParams); |
| 21 | 23 | |
| 22 | - void doSendSms(); | |
| 24 | + void doSendSms(SysSmsSendMessage message); | |
| 23 | 25 | |
| 24 | 26 | /** |
| 25 | 27 | * 处理短信发送回调函数 | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java
| ... | ... | @@ -42,7 +42,6 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { |
| 42 | 42 | */ |
| 43 | 43 | private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L; |
| 44 | 44 | |
| 45 | - | |
| 46 | 45 | @Override |
| 47 | 46 | public Long createSmsSendLog(String mobile, Long userId, Integer userType, |
| 48 | 47 | SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams) { |
| ... | ... | @@ -62,6 +61,11 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { |
| 62 | 61 | } |
| 63 | 62 | |
| 64 | 63 | @Override |
| 64 | + public void updateSmsSendLogFailure(Long id, Integer sendFailureType) { | |
| 65 | + smsSendLogMapper.updateById(new SysSmsSendLogDO().setId(id).setSendFailureType(sendFailureType)); | |
| 66 | + } | |
| 67 | + | |
| 68 | + @Override | |
| 65 | 69 | public void getAndSaveSmsSendLog() { |
| 66 | 70 | |
| 67 | 71 | List<SysSmsSendLogDO> noResultQueryLogList = smsQueryLogMapper.selectNoResultQueryLogList(); | ... | ... |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java
| 1 | 1 | package cn.iocoder.dashboard.modules.system.service.sms.impl; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.map.MapUtil; | |
| 5 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | +import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | |
| 6 | 6 | import cn.iocoder.dashboard.common.enums.UserTypeEnum; |
| 7 | -import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | |
| 8 | -import cn.iocoder.dashboard.framework.sms.core.SmsBody; | |
| 9 | 7 | import cn.iocoder.dashboard.framework.sms.core.SmsClientFactory; |
| 10 | 8 | import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; |
| 9 | +import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; | |
| 11 | 10 | import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; |
| 12 | 11 | import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; |
| 13 | -import cn.iocoder.dashboard.modules.system.mq.producer.sms.SmsSendStreamProducer; | |
| 12 | +import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage; | |
| 13 | +import cn.iocoder.dashboard.modules.system.mq.producer.sms.SysSmsProducer; | |
| 14 | 14 | import cn.iocoder.dashboard.modules.system.service.sms.*; |
| 15 | 15 | import cn.iocoder.dashboard.modules.system.service.user.SysUserService; |
| 16 | 16 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -20,8 +20,6 @@ import javax.servlet.ServletRequest; |
| 20 | 20 | import java.util.List; |
| 21 | 21 | import java.util.Map; |
| 22 | 22 | import java.util.Objects; |
| 23 | -import java.util.function.Consumer; | |
| 24 | -import java.util.function.Predicate; | |
| 25 | 23 | |
| 26 | 24 | import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; |
| 27 | 25 | import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; |
| ... | ... | @@ -51,7 +49,7 @@ public class SysSmsServiceImpl implements SysSmsService { |
| 51 | 49 | private SysSmsQueryLogService logService; |
| 52 | 50 | |
| 53 | 51 | @Resource |
| 54 | - private SmsSendStreamProducer smsProducer; | |
| 52 | + private SysSmsProducer smsProducer; | |
| 55 | 53 | |
| 56 | 54 | @Resource |
| 57 | 55 | private SmsClientFactory smsClientFactory; |
| ... | ... | @@ -68,8 +66,13 @@ public class SysSmsServiceImpl implements SysSmsService { |
| 68 | 66 | String content = smsTemplateService.formatSmsTemplateContent(template.getContent(), templateParams); |
| 69 | 67 | Long sendLogId = smsSendLogService.createSmsSendLog(mobile, userId, userType, template, content, templateParams); |
| 70 | 68 | |
| 71 | - // 发送 MQ 消息 | |
| 72 | - | |
| 69 | + // 如果模板被禁用,则直接标记发送失败。也就说,不发短信,嘿嘿。 | |
| 70 | + if (CommonStatusEnum.DISABLE.getStatus().equals(template.getStatus())) { | |
| 71 | + smsSendLogService.updateSmsSendLogFailure(sendLogId, SmsSendFailureTypeEnum.SMS_TEMPLATE_DISABLE.getType()); | |
| 72 | + return; | |
| 73 | + } | |
| 74 | + // 如果模板未禁用,发送 MQ 消息。目的是,异步化调用短信平台 | |
| 75 | + smsProducer.sendSmsSendMessage(sendLogId, mobile, template.getChannelId(), template.getApiTemplateId(), templateParams); | |
| 73 | 76 | } |
| 74 | 77 | |
| 75 | 78 | @Override |
| ... | ... | @@ -79,11 +82,6 @@ public class SysSmsServiceImpl implements SysSmsService { |
| 79 | 82 | SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode, templateParams); |
| 80 | 83 | } |
| 81 | 84 | |
| 82 | - @Override | |
| 83 | - public void doSendSms() { | |
| 84 | - | |
| 85 | - } | |
| 86 | - | |
| 87 | 85 | private SysSmsTemplateDO checkSmsTemplateValid(String templateCode, Map<String, Object> templateParams) { |
| 88 | 86 | // 短信模板不存在 |
| 89 | 87 | SysSmsTemplateDO template = smsTemplateService.getSmsTemplateByCode(templateCode); |
| ... | ... | @@ -132,10 +130,8 @@ public class SysSmsServiceImpl implements SysSmsService { |
| 132 | 130 | } |
| 133 | 131 | |
| 134 | 132 | @Override |
| 135 | - public void send(SmsBody smsBody, String targetPhone) { | |
| 136 | - AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode()); | |
| 137 | - logService.beforeSendLog(smsBody, targetPhone, client); | |
| 138 | - smsProducer.sendSmsSendMessage(smsBody, targetPhone); | |
| 133 | + public void doSendSms(SysSmsSendMessage message) { | |
| 134 | + | |
| 139 | 135 | } |
| 140 | 136 | |
| 141 | 137 | @Override | ... | ... |