短信提交 2021-03-28,增加发送日志
This commit is contained in:
parent
f3b6783cc3
commit
46ed64ba40
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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,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;
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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";
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
* 处理短信发送回调函数
|
||||
|
@ -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() {
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user