短信提交 2021-03-28,增加发送日志
parent
46ed64ba40
commit
515fca5c41
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.dashboard.framework.sms.config;
|
||||
|
||||
import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
|
||||
import cn.iocoder.dashboard.framework.sms.core.client.impl.SmsClientFactoryImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 短信配置类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Configuration
|
||||
public class SmsConfiguration {
|
||||
|
||||
@Bean
|
||||
public SmsClientFactory smsClientFactory() {
|
||||
return new SmsClientFactoryImpl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
package cn.iocoder.dashboard.framework.sms.core;
|
||||
|
||||
import cn.iocoder.dashboard.util.json.JsonUtils;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 消息内容实体类
|
||||
*/
|
||||
@Data
|
||||
public class SmsBody {
|
||||
|
||||
/**
|
||||
* 消息日志id
|
||||
*/
|
||||
private Long smsLogId;
|
||||
|
||||
/**
|
||||
* 模板编码
|
||||
*/
|
||||
private String templateCode;
|
||||
|
||||
/**
|
||||
* 模板编码
|
||||
*/
|
||||
private String templateContent;
|
||||
|
||||
/**
|
||||
* 参数列表
|
||||
*/
|
||||
private Map<String, String> params;
|
||||
|
||||
public String getParamsStr() {
|
||||
return JsonUtils.toJsonString(params);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.dashboard.framework.sms.core.client;
|
||||
|
||||
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
|
||||
|
||||
/**
|
||||
* 短信客户端工厂接口
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/1/28 14:01
|
||||
*/
|
||||
public interface SmsClientFactory {
|
||||
|
||||
/**
|
||||
* 获得短信 Client
|
||||
*
|
||||
* @param channelId 渠道编号
|
||||
* @return 短信 Client
|
||||
*/
|
||||
SmsClient getSmsClient(Long channelId);
|
||||
|
||||
/**
|
||||
* 创建短信 Client
|
||||
*
|
||||
* @param properties 配置对象
|
||||
*/
|
||||
void createOrUpdateSmsClient(SmsChannelProperties properties);
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package cn.iocoder.dashboard.framework.sms.core.property;
|
||||
|
||||
import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
|
||||
import lombok.Data;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 短信渠道配置类
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/1/25 17:01
|
||||
*/
|
||||
@Data
|
||||
@Validated
|
||||
public class SmsChannelProperties {
|
||||
|
||||
/**
|
||||
* 渠道编号
|
||||
*/
|
||||
@NotNull(message = "短信渠道 ID 不能为空")
|
||||
private Long id;
|
||||
/**
|
||||
* 短信签名
|
||||
*/
|
||||
@NotEmpty(message = "短信签名不能为空")
|
||||
private String signature;
|
||||
/**
|
||||
* 渠道编码
|
||||
*
|
||||
* 枚举 {@link SmsChannelEnum}
|
||||
*/
|
||||
@NotEmpty(message = "渠道编码不能为空")
|
||||
private String code;
|
||||
/**
|
||||
* 短信 API 的账号
|
||||
*/
|
||||
@NotEmpty(message = "短信 API 的账号不能为空")
|
||||
private String apiKey;
|
||||
/**
|
||||
* 短信 API 的秘钥
|
||||
*/
|
||||
@NotEmpty(message = "短信 API 的秘钥不能为空")
|
||||
private String apiSecret;
|
||||
/**
|
||||
* 短信发送回调 URL
|
||||
*/
|
||||
private String callbackUrl;
|
||||
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
package cn.iocoder.dashboard.framework.sms.core.property;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* 渠道模板VO类
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/1/25 17:03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
public class SmsTemplateProperty {
|
||||
|
||||
/**
|
||||
* 渠道id
|
||||
*/
|
||||
@NotEmpty(message = "短信渠道编码不能为空")
|
||||
private Long channelId;
|
||||
|
||||
/**
|
||||
* 业务编码(来自数据字典, 用户自定义业务场景 一个场景可以有多个模板)
|
||||
*/
|
||||
private String bizCode;
|
||||
|
||||
/**
|
||||
* 编码
|
||||
*/
|
||||
@NotEmpty(message = "短信模板编码不能为空")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 实际渠道模板唯一标识
|
||||
*/
|
||||
@NotEmpty(message = "短信模板唯一标识不能为空")
|
||||
private String apiTemplateId;
|
||||
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
@NotEmpty(message = "短信模板内容不能为空")
|
||||
private String content;
|
||||
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
package cn.iocoder.dashboard.modules.system.dal.dataobject.sms;
|
||||
|
||||
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 短信日志
|
||||
*
|
||||
* @author zzf
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "sms_send_log", autoResultMap = true)
|
||||
public class SysSmsSendLogDOX implements Serializable {
|
||||
|
||||
/**
|
||||
* 自增编号
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 短信渠道编码(来自枚举类)
|
||||
*/
|
||||
private String channelCode;
|
||||
|
||||
/**
|
||||
* 短信渠道id
|
||||
*/
|
||||
private Long channelId;
|
||||
|
||||
/**
|
||||
* 模板id
|
||||
*/
|
||||
private String templateCode;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 发送状态
|
||||
*
|
||||
* @see SysSmsSendStatusEnum
|
||||
*/
|
||||
private Integer sendStatus;
|
||||
|
||||
/**
|
||||
* 发送时间
|
||||
*/
|
||||
private Date sendTime;
|
||||
|
||||
}
|
||||
@ -1,31 +1,27 @@
|
||||
package cn.iocoder.dashboard.modules.system.dal.mysql.sms;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.util.MyBatisUtils;
|
||||
import cn.iocoder.dashboard.common.pojo.PageResult;
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
|
||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysSmsChannelMapper extends BaseMapper<SysSmsChannelDO> {
|
||||
public interface SysSmsChannelMapper extends BaseMapperX<SysSmsChannelDO> {
|
||||
|
||||
default IPage<SysSmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) {
|
||||
return selectPage(MyBatisUtils.buildPage(reqVO), new LambdaQueryWrapper<SysSmsChannelDO>()
|
||||
.like(StrUtil.isNotBlank(reqVO.getName()), SysSmsChannelDO::getName, reqVO.getName())
|
||||
.like(StrUtil.isNotBlank(reqVO.getSignature()), SysSmsChannelDO::getName, reqVO.getSignature())
|
||||
);
|
||||
default PageResult<SysSmsChannelDO> selectChannelPage(SmsChannelPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapper<SysSmsChannelDO>()
|
||||
.like(StrUtil.isNotBlank(reqVO.getSignature()), SysSmsChannelDO::getSignature, reqVO.getSignature()));
|
||||
}
|
||||
|
||||
default List<SysSmsChannelDO> selectEnabledList() {
|
||||
default List<SysSmsChannelDO> selectListByStatus(Integer status) {
|
||||
return selectList(new LambdaQueryWrapper<SysSmsChannelDO>()
|
||||
.eq(SysSmsChannelDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
|
||||
.orderByAsc(SysSmsChannelDO::getId)
|
||||
);
|
||||
.eq(SysSmsChannelDO::getStatus, status)
|
||||
.orderByAsc(SysSmsChannelDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
package cn.iocoder.dashboard.modules.system.dal.mysql.sms;
|
||||
|
||||
import cn.iocoder.dashboard.common.enums.DefaultBitFieldEnum;
|
||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsSendLogDO;
|
||||
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface SysSmsQueryLogMapper extends BaseMapper<SysSmsSendLogDO> {
|
||||
|
||||
/**
|
||||
* 查询还没有获取发送结果的短信请求信息
|
||||
*/
|
||||
default List<SysSmsSendLogDO> selectNoResultQueryLogList() {
|
||||
return this.selectList(new LambdaQueryWrapper<SysSmsSendLogDO>()
|
||||
.eq(SysSmsSendLogDO::getSendStatus, SysSmsSendStatusEnum.QUERY_SUCCESS)
|
||||
.eq(SysSmsSendLogDO::getGotResult, DefaultBitFieldEnum.NO)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据APIId修改对象
|
||||
*/
|
||||
default boolean updateByApiId(SysSmsSendLogDO queryLogDO, String apiId) {
|
||||
return update(queryLogDO, new LambdaQueryWrapper<SysSmsSendLogDO>()
|
||||
.eq(SysSmsSendLogDO::getApiId, apiId)
|
||||
) > 0;
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,9 @@
|
||||
package cn.iocoder.dashboard.modules.system.dal.mysql.sms;
|
||||
|
||||
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsSendLogDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysSmsSendLogMapper extends BaseMapper<SysSmsSendLogDO> {
|
||||
|
||||
public interface SysSmsSendLogMapper extends BaseMapperX<SysSmsSendLogDO> {
|
||||
}
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
package cn.iocoder.dashboard.modules.system.service.sms;
|
||||
|
||||
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.framework.sms.core.SmsResultDetail;
|
||||
|
||||
/**
|
||||
* 短信请求日志服务接口
|
||||
*
|
||||
* @author zzf
|
||||
* @date 2021/1/25 9:24
|
||||
*/
|
||||
public interface SysSmsQueryLogService {
|
||||
|
||||
/**
|
||||
* 发送短信前的日志处理
|
||||
*
|
||||
* @param smsBody 短信内容
|
||||
* @param targetPhone 发送对象手机号
|
||||
* @param client 短信客户端
|
||||
* @return 生成的日志id
|
||||
*/
|
||||
void beforeSendLog(SmsBody smsBody, String targetPhone, AbstractSmsClient client);
|
||||
|
||||
/**
|
||||
* 发送消息后的日志处理
|
||||
*
|
||||
* @param logId 日志id
|
||||
* @param result 消息结果
|
||||
*/
|
||||
void afterSendLog(Long logId, SmsResult result);
|
||||
|
||||
void updateSendLogByResultDetail(SmsResultDetail smsResultDetail);
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
package cn.iocoder.dashboard.modules.system.service.sms.impl;
|
||||
|
||||
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.framework.sms.core.SmsResultDetail;
|
||||
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
|
||||
import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsQueryLogMapper;
|
||||
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsSendLogDO;
|
||||
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
|
||||
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 短信请求日志服务实现类
|
||||
*
|
||||
* @author zzf
|
||||
* @date 13:50 2021/3/2
|
||||
*/
|
||||
@Service
|
||||
public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService {
|
||||
|
||||
@Resource
|
||||
private SysSmsQueryLogMapper logMapper;
|
||||
|
||||
@Override
|
||||
public void beforeSendLog(SmsBody smsBody, String targetPhone, AbstractSmsClient client) {
|
||||
SysSmsSendLogDO smsLog = new SysSmsSendLogDO();
|
||||
SmsChannelProperty property = client.getProperty();
|
||||
|
||||
smsLog.setChannelCode(property.getCode())
|
||||
.setChannelId(property.getId())
|
||||
.setTemplateCode(smsBody.getTemplateCode())
|
||||
.setPhone(targetPhone)
|
||||
.setContent(smsBody.getParams().toString());
|
||||
|
||||
smsLog.setSendStatus(SysSmsSendStatusEnum.ASYNC.getStatus());
|
||||
logMapper.insert(smsLog);
|
||||
smsBody.setSmsLogId(smsLog.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSendLog(Long logId, SmsResult result) {
|
||||
SysSmsSendLogDO smsLog = new SysSmsSendLogDO();
|
||||
smsLog.setId(logId);
|
||||
smsLog.setApiId(result.getApiId());
|
||||
smsLog.setSendStatus(SysSmsSendStatusEnum.QUERY_FAIL.getStatus());
|
||||
smsLog.setRemark(result.getCode() + ": " + result.getMessage());
|
||||
logMapper.updateById(smsLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSendLogByResultDetail(SmsResultDetail smsResultDetail) {
|
||||
SysSmsSendLogDO queryLogDO = new SysSmsSendLogDO();
|
||||
queryLogDO.setSendStatus(smsResultDetail.getSendStatus());
|
||||
queryLogDO.setSendTime(smsResultDetail.getSendTime());
|
||||
queryLogDO.setRemark(smsResultDetail.getMessage());
|
||||
logMapper.updateByApiId(queryLogDO, smsResultDetail.getApiId());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue