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

This commit is contained in:
YunaiV 2021-03-28 18:07:55 +08:00
parent f3b6783cc3
commit 46ed64ba40
13 changed files with 108 additions and 96 deletions

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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;
}

View File

@ -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;
/**

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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<String, Object> templateParams;
/**
* 用户编号允许空
*/
private Integer userId;
/**
* 用户类型允许空
*/
private Integer userType;
@Override
public String getStreamKey() {
return "system.sms.send";

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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);
/**
* 处理短信发送回调函数

View File

@ -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() {

View File

@ -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