短信提交 2021-04-03,重构返回的结果

pull/2/head
YunaiV 2021-04-03 22:05:11 +08:00
parent 5a1491d7fd
commit d843d6a5a8
28 changed files with 232 additions and 227 deletions

View File

@ -0,0 +1,20 @@
package cn.iocoder.dashboard.common.core;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Key Value
*
* @author
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class KeyValue<K, V> {
private K key;
private V value;
}

View File

@ -8,6 +8,7 @@ import lombok.Data;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects;
/** /**
* *
@ -67,9 +68,13 @@ public class CommonResult<T> implements Serializable {
return result; return result;
} }
public static boolean isSuccess(Integer code) {
return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
}
@JsonIgnore // 避免 jackson 序列化 @JsonIgnore // 避免 jackson 序列化
public boolean isSuccess() { public boolean isSuccess() {
return GlobalErrorCodeConstants.SUCCESS.getCode().equals(code); return isSuccess(GlobalErrorCodeConstants.SUCCESS.getCode());
} }
@JsonIgnore // 避免 jackson 序列化 @JsonIgnore // 避免 jackson 序列化

View File

@ -1,10 +1,11 @@
package cn.iocoder.dashboard.framework.sms.core.client; package cn.iocoder.dashboard.framework.sms.core.client;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import java.util.Map; import java.util.List;
/** /**
* *
@ -24,13 +25,13 @@ public interface SmsClient {
/** /**
* *
* *
* @param sendLogId * @param logId
* @param mobile * @param mobile
* @param apiTemplateId API * @param apiTemplateId API
* @param templateParams * @param templateParams
* @return * @return
*/ */
SmsCommonResult<SmsSendRespDTO> send(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams); SmsCommonResult<SmsSendRespDTO> send(Long logId, String mobile, String apiTemplateId, List<KeyValue<String, Object>> templateParams);
// TODO FROM 芋艿 to ZZF是不是可以改成意图更明确的解析返回结果例如说 parseXXXX // TODO FROM 芋艿 to ZZF是不是可以改成意图更明确的解析返回结果例如说 parseXXXX
/** /**

View File

@ -3,7 +3,7 @@ package cn.iocoder.dashboard.framework.sms.core.client.dto;
import lombok.Data; import lombok.Data;
/** /**
* DTO * Response DTO
* *
* @author * @author
*/ */

View File

@ -1,13 +1,14 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl; package cn.iocoder.dashboard.framework.sms.core.client.impl;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClient;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping; import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClient;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.Map; import java.util.List;
/** /**
* *
@ -67,16 +68,16 @@ public abstract class AbstractSmsClient implements SmsClient {
} }
@Override @Override
public final SmsCommonResult<SmsSendRespDTO> send(Long sendLogId, String mobile, public final SmsCommonResult<SmsSendRespDTO> send(Long logId, String mobile,
String apiTemplateId, Map<String, Object> templateParams) { String apiTemplateId, List<KeyValue<String, Object>> templateParams) {
// 执行短信发送 // 执行短信发送
SmsCommonResult<SmsSendRespDTO> result; SmsCommonResult<SmsSendRespDTO> result;
try { try {
result = doSend(sendLogId, mobile, apiTemplateId, templateParams); result = doSend(logId, mobile, apiTemplateId, templateParams);
} catch (Throwable ex) { } catch (Throwable ex) {
// 打印异常日志 // 打印异常日志
log.error("[send][发送短信异常sendLogId({}) mobile({}) apiTemplateId({}) templateParams({})]", log.error("[send][发送短信异常sendLogId({}) mobile({}) apiTemplateId({}) templateParams({})]",
sendLogId, mobile, apiTemplateId, templateParams, ex); logId, mobile, apiTemplateId, templateParams, ex);
// 封装返回 // 封装返回
return SmsCommonResult.error(ex); return SmsCommonResult.error(ex);
} }
@ -93,6 +94,7 @@ public abstract class AbstractSmsClient implements SmsClient {
* @return * @return
*/ */
protected abstract SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile, protected abstract SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile,
String apiTemplateId, Map<String, Object> templateParams) throws Throwable; String apiTemplateId, List<KeyValue<String, Object>> templateParams)
throws Throwable;
} }

View File

@ -3,12 +3,14 @@ package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient; import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
import cn.iocoder.dashboard.util.collection.MapUtils;
import cn.iocoder.dashboard.util.json.JsonUtils; import cn.iocoder.dashboard.util.json.JsonUtils;
import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient; import com.aliyuncs.IAcsClient;
@ -60,14 +62,14 @@ public class AliyunSmsClient extends AbstractSmsClient {
@Override @Override
protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile, protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile,
String apiTemplateId, Map<String, Object> templateParams) throws Throwable { String apiTemplateId, List<KeyValue<String, Object>> templateParams) {
// 构建参数 // 构建参数
SendSmsRequest request = new SendSmsRequest(); SendSmsRequest request = new SendSmsRequest();
request.setSysMethod(MethodType.POST); request.setSysMethod(MethodType.POST);
request.setPhoneNumbers(mobile); request.setPhoneNumbers(mobile);
request.setSignName(properties.getSignature()); request.setSignName(properties.getSignature());
request.setTemplateCode(apiTemplateId); request.setTemplateCode(apiTemplateId);
request.setTemplateParam(JsonUtils.toJsonString(templateParams)); request.setTemplateParam(JsonUtils.toJsonString(MapUtils.convertMap(templateParams)));
request.setOutId(String.valueOf(sendLogId)); request.setOutId(String.valueOf(sendLogId));
try { try {

View File

@ -1,6 +1,7 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun; package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
import cn.iocoder.dashboard.common.exception.ErrorCode; import cn.iocoder.dashboard.common.exception.ErrorCode;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping; import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping;
import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.*; import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.*;
@ -15,7 +16,7 @@ public class AliyunSmsCodeMapping implements SmsCodeMapping {
@Override @Override
public ErrorCode apply(String apiCode) { public ErrorCode apply(String apiCode) {
switch (apiCode) { switch (apiCode) {
case "OK": return null; case "OK": return GlobalErrorCodeConstants.SUCCESS;
case "MissingAccessKeyId": return SMS_CHANNEL_API_KEY_MISSING; case "MissingAccessKeyId": return SMS_CHANNEL_API_KEY_MISSING;
case "isp.RAM_PERMISSION_DENY": return SMS_CHANNEL_PERMISSION_DENY; case "isp.RAM_PERMISSION_DENY": return SMS_CHANNEL_PERMISSION_DENY;
case "isv.INVALID_PARAMETERS": return SMS_API_PARAM_ERROR; case "isv.INVALID_PARAMETERS": return SMS_API_PARAM_ERROR;

View File

@ -6,6 +6,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil; import cn.hutool.core.util.URLUtil;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
@ -65,7 +66,7 @@ public class YunpianSmsClient extends AbstractSmsClient {
@Override @Override
protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile, protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile,
String apiTemplateId, Map<String, Object> templateParams) throws Throwable { String apiTemplateId, List<KeyValue<String, Object>> templateParams) throws Throwable {
// 构建参数 // 构建参数
Map<String, String> request = new HashMap<>(); Map<String, String> request = new HashMap<>();
request.put(YunpianConstant.APIKEY, properties.getApiKey()); request.put(YunpianConstant.APIKEY, properties.getApiKey());
@ -89,13 +90,13 @@ public class YunpianSmsClient extends AbstractSmsClient {
data, codeMapping); data, codeMapping);
} }
private static String formatTplValue(Map<String, Object> templateParams) { private static String formatTplValue(List<KeyValue<String, Object>> templateParams) {
if (CollUtil.isEmpty(templateParams)) { if (CollUtil.isEmpty(templateParams)) {
return ""; return "";
} }
// 参考 https://www.yunpian.com/official/document/sms/zh_cn/introduction_demos_encode_sample 格式化 // 参考 https://www.yunpian.com/official/document/sms/zh_cn/introduction_demos_encode_sample 格式化
StringJoiner joiner = new StringJoiner("&"); StringJoiner joiner = new StringJoiner("&");
templateParams.forEach((key, value) -> joiner.add(String.format("#%s#=%s", key, URLUtil.encode(String.valueOf(value))))); templateParams.forEach(param -> joiner.add(String.format("#%s#=%s", param.getKey(), URLUtil.encode(String.valueOf(param.getValue())))));
return joiner.toString(); return joiner.toString();
} }

View File

@ -12,7 +12,6 @@ import cn.iocoder.dashboard.common.exception.ErrorCode;
public interface SmsFrameworkErrorCodeConstants { public interface SmsFrameworkErrorCodeConstants {
// ========== 渠道相关 2001000100 ========== // ========== 渠道相关 2001000100 ==========
ErrorCode SMS_CHANNEL_CLIENT_NOT_EXISTS = new ErrorCode(2001000100, "短信渠道的客户端不存在");
ErrorCode SMS_CHANNEL_API_KEY_MISSING = new ErrorCode(2001000101, "API Key 不存在"); ErrorCode SMS_CHANNEL_API_KEY_MISSING = new ErrorCode(2001000101, "API Key 不存在");
ErrorCode SMS_CHANNEL_PERMISSION_DENY = new ErrorCode(2001000102, "没有发送短信的权限"); ErrorCode SMS_CHANNEL_PERMISSION_DENY = new ErrorCode(2001000102, "没有发送短信的权限");

View File

@ -4,7 +4,6 @@ import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -13,7 +12,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.dashboard.common.pojo.CommonResult.success; import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
@ -31,12 +29,6 @@ public class SmsChannelController {
return success(service.pageSmsChannels(reqVO)); return success(service.pageSmsChannels(reqVO));
} }
@ApiOperation("获取渠道枚举")
@GetMapping("/list/channel-enum")
public CommonResult<List<SmsChannelEnumRespVO>> getChannelEnums() {
return success(service.getSmsChannelEnums());
}
@ApiOperation("添加消息渠道") @ApiOperation("添加消息渠道")
@PostMapping("/create") @PostMapping("/create")
public CommonResult<Long> add(@Validated @RequestBody SmsChannelCreateReqVO reqVO) { public CommonResult<Long> add(@Validated @RequestBody SmsChannelCreateReqVO reqVO) {

View File

@ -1,21 +0,0 @@
package cn.iocoder.dashboard.modules.system.controller.sms.vo.resp;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@ApiModel("用户分页 Request VO")
@Data
@NoArgsConstructor
@EqualsAndHashCode
public class SmsChannelEnumRespVO implements Serializable {
private String code;
private String name;
}

View File

@ -1,10 +1,8 @@
package cn.iocoder.dashboard.modules.system.convert.sms; package cn.iocoder.dashboard.modules.system.convert.sms;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
@ -21,8 +19,6 @@ public interface SmsChannelConvert {
SysSmsChannelDO convert(SysUserUpdateReqVO bean); SysSmsChannelDO convert(SysUserUpdateReqVO bean);
List<SmsChannelEnumRespVO> convertEnum(List<SmsChannelEnum> bean);
List<SmsChannelAllVO> convert(List<SysSmsChannelDO> bean); List<SmsChannelAllVO> convert(List<SysSmsChannelDO> bean);
List<SmsChannelProperties> convertProperty(List<SmsChannelAllVO> list); List<SmsChannelProperties> convertProperty(List<SmsChannelAllVO> list);

View File

@ -6,16 +6,18 @@ import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString;
/** /**
* * DO
* *
* @author zzf * @author zzf
* @since 2021-01-25 * @since 2021-01-25
*/ */
@TableName(value = "sms_channel", autoResultMap = true) @TableName(value = "sys_sms_channel", autoResultMap = true)
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SysSmsChannelDO extends BaseDO { public class SysSmsChannelDO extends BaseDO {
/** /**

View File

@ -2,28 +2,30 @@ package cn.iocoder.dashboard.modules.system.dal.dataobject.sms;
import cn.iocoder.dashboard.common.enums.UserTypeEnum; import cn.iocoder.dashboard.common.enums.UserTypeEnum;
import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*; import lombok.*;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
/** /**
* * DO
* *
* @author zzf * @author zzf
* @since 2021-01-25 * @since 2021-01-25
*/ */
@TableName(value = "sms_send_log", autoResultMap = true) @TableName(value = "sys_sms_log", autoResultMap = true)
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@Builder @Builder
public class SysSmsSendLogDO extends BaseDO { public class SysSmsLogDO extends BaseDO {
/** /**
* *
@ -48,7 +50,7 @@ public class SysSmsSendLogDO extends BaseDO {
// ========= 模板相关字段 ========= // ========= 模板相关字段 =========
/** /**
* *
* *
* {@link SysSmsTemplateDO#getId()} * {@link SysSmsTemplateDO#getId()}
*/ */
@ -70,8 +72,9 @@ public class SysSmsSendLogDO extends BaseDO {
*/ */
private String templateContent; private String templateContent;
/** /**
* {@link SysSmsTemplateDO#getParams()} * {@link SysSmsTemplateDO#getParams()}
*/ */
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, Object> templateParams; private Map<String, Object> templateParams;
/** /**
* API * API
@ -106,32 +109,32 @@ public class SysSmsSendLogDO extends BaseDO {
*/ */
private Integer sendStatus; private Integer sendStatus;
/** /**
* *
*/ */
private Date sendTime; private Date sendTime;
/** /**
* *
* *
* {@link SmsSendFailureTypeEnum#getType()} * {@link SmsFrameworkErrorCodeConstants}
*/ */
private Integer sendFailureType; private Integer sendCode;
/** /**
* *
* *
* 使 {@link SmsSendFailureTypeEnum#getMsg()} * 使 {@link SmsFrameworkErrorCodeConstants}
* Exception * Exception
*/ */
private String sendFailureMsg; private String sendMsg;
/** /**
* API * API
* *
* 使 String * 使 String
*/ */
private String apiSendFailureType; private String apiSendCode;
/** /**
* API * API
*/ */
private String apiSendFailureMsg; private String apiSendMsg;
/** /**
* API ID * API ID
* *
@ -147,9 +150,9 @@ public class SysSmsSendLogDO extends BaseDO {
// ========= 接收相关字段 ========= // ========= 接收相关字段 =========
/** // /**
* [0 1] // * 是否获取过结果[0否 1是]
*/ // */
private Integer gotResult; // private Integer gotResult;
} }

View File

@ -8,18 +8,20 @@ import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List; import java.util.List;
/** /**
* * DO
* *
* @author zzf * @author zzf
* @since 2021-01-25 * @since 2021-01-25
*/ */
@TableName(value = "sys_sms_template", autoResultMap = true)
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@TableName(value = "sms_template", autoResultMap = true) @ToString(callSuper = true)
public class SysSmsTemplateDO extends BaseDO { public class SysSmsTemplateDO extends BaseDO {
/** /**
@ -46,11 +48,11 @@ public class SysSmsTemplateDO extends BaseDO {
*/ */
private String code; private String code;
/** /**
* *
*/ */
private String name; private String name;
/** /**
* *
* *
* 使 {} {name} * 使 {} {name}
*/ */

View File

@ -1,9 +1,9 @@
package cn.iocoder.dashboard.modules.system.dal.mysql.sms; package cn.iocoder.dashboard.modules.system.dal.mysql.sms;
import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.dashboard.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsSendLogDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsLogDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface SysSmsSendLogMapper extends BaseMapperX<SysSmsSendLogDO> { public interface SysSmsLogMapper extends BaseMapperX<SysSmsLogDO> {
} }

View File

@ -16,6 +16,7 @@ public enum SysSmsSendStatusEnum {
INIT(0), // 初始化 INIT(0), // 初始化
SUCCESS(10), // 发送成功 SUCCESS(10), // 发送成功
FAILURE(20), // 发送失败 FAILURE(20), // 发送失败
IGNORE(30), // 忽略,即不发送
; ;
private final int status; private final int status;

View File

@ -1,10 +1,11 @@
package cn.iocoder.dashboard.modules.system.mq.message.sms; package cn.iocoder.dashboard.modules.system.mq.message.sms;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage; import cn.iocoder.dashboard.framework.redis.core.stream.StreamMessage;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.Map; import java.util.List;
/** /**
* *
@ -15,10 +16,10 @@ import java.util.Map;
public class SysSmsSendMessage implements StreamMessage { public class SysSmsSendMessage implements StreamMessage {
/** /**
* *
*/ */
@NotNull(message = "发送日志编号不能为空") @NotNull(message = "短信日志编号不能为空")
private Long sendLogId; private Long logId;
/** /**
* *
*/ */
@ -37,7 +38,7 @@ public class SysSmsSendMessage implements StreamMessage {
/** /**
* *
*/ */
private Map<String, Object> templateParams; private List<KeyValue<String, Object>> templateParams;
@Override @Override
public String getStreamKey() { public String getStreamKey() {

View File

@ -1,5 +1,6 @@
package cn.iocoder.dashboard.modules.system.mq.producer.sms; package cn.iocoder.dashboard.modules.system.mq.producer.sms;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils;
import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage; import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -7,7 +8,7 @@ import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Map; import java.util.List;
/** /**
* *
@ -25,16 +26,15 @@ public class SysSmsProducer {
/** /**
* Message * Message
* *
* @param sendLogId * @param logId
* @param mobile * @param mobile
* @param channelId * @param channelId
* @param apiTemplateId * @param apiTemplateId
* @param templateParams * @param templateParams
* @param sendLogId
*/ */
public void sendSmsSendMessage(Long sendLogId, String mobile, public void sendSmsSendMessage(Long logId, String mobile,
Long channelId, String apiTemplateId, Map<String, Object> templateParams) { Long channelId, String apiTemplateId, List<KeyValue<String, Object>> templateParams) {
SysSmsSendMessage message = new SysSmsSendMessage().setSendLogId(sendLogId).setMobile(mobile); SysSmsSendMessage message = new SysSmsSendMessage().setLogId(logId).setMobile(mobile);
message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams); message.setChannelId(channelId).setApiTemplateId(apiTemplateId).setTemplateParams(templateParams);
RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message); RedisMessageUtils.sendStreamMessage(stringRedisTemplate, message);
} }

View File

@ -3,11 +3,8 @@ package cn.iocoder.dashboard.modules.system.service.sms;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import java.util.List;
/** /**
* Service * Service
* *
@ -17,9 +14,9 @@ import java.util.List;
public interface SysSmsChannelService { public interface SysSmsChannelService {
/** /**
* *
*/ */
void initSmsClientAndCacheSmsTemplate(); void initSmsClients();
/** /**
* *
@ -37,11 +34,4 @@ public interface SysSmsChannelService {
*/ */
Long createSmsChannel(SmsChannelCreateReqVO reqVO); Long createSmsChannel(SmsChannelCreateReqVO reqVO);
/**
* /
*
* @return /
*/
List<SmsChannelEnumRespVO> getSmsChannelEnums();
} }

View File

@ -0,0 +1,44 @@
package cn.iocoder.dashboard.modules.system.service.sms;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
import java.util.Map;
/**
*
*
* @author zzf
* @date 13:48 2021/3/2
*/
public interface SysSmsLogService {
/**
*
*
* @param mobile
* @param userId
* @param userType
* @param isSend
* @param template
* @param templateContent
* @param templateParams
* @return
*/
Long createSmsLog(String mobile, Long userId, Integer userType, Boolean isSend,
SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams);
/**
*
*
* @param id
* @param sendCode
* @param sendMsg
* @param apiSendCode API
* @param apiSendMsg API
* @param apiRequestId API ID
* @param apiSerialNo API
*/
void updateSmsSendResult(Long id, Integer sendCode, String sendMsg,
String apiSendCode, String apiSendMsg, String apiRequestId, String apiSerialNo);
}

View File

@ -1,49 +0,0 @@
package cn.iocoder.dashboard.modules.system.service.sms;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
import java.util.Map;
/**
*
*
* @author zzf
* @date 13:48 2021/3/2
*/
public interface SysSmsSendLogService {
/**
*
*
* @param mobile
* @param userId
* @param userType
* @param template
* @param templateContent
* @param templateParams
* @return
*/
Long createSmsSendLog(String mobile, Long userId, Integer userType,
SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams);
/**
*
*
* @param id
* @param success
* @param sendFailureType
* @param sendFailureMsg
* @param apiSendFailureType API
* @param apiSendFailureMsg API
* @param apiRequestId API ID
* @param apiSerialNo API
*/
void updateSmsSendLogResult(Long id, Boolean success, Integer sendFailureType, String sendFailureMsg,
String apiSendFailureType, String apiSendFailureMsg, String apiRequestId, String apiSerialNo);
default void updateSmsSendLogFailure(Long id, SmsSendFailureTypeEnum sendFailureType) {
updateSmsSendLogResult(id, false, sendFailureType.getType(), sendFailureType.getMsg(),
null, null, null, null);
}
}

View File

@ -3,21 +3,17 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum; import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.pojo.PageResult; import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory; import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO;
import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert; import cn.iocoder.dashboard.modules.system.convert.sms.SmsChannelConvert;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsChannelMapper; import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsChannelMapper;
import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsTemplateMapper;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -35,12 +31,9 @@ public class SysSmsChannelServiceImpl implements SysSmsChannelService {
@Resource @Resource
private SysSmsChannelMapper channelMapper; private SysSmsChannelMapper channelMapper;
@Resource
private SysSmsTemplateMapper templateMapper;
@Override @Override
@PostConstruct @PostConstruct
public void initSmsClientAndCacheSmsTemplate() { public void initSmsClients() {
// 查询有效渠道信息 // 查询有效渠道信息
List<SysSmsChannelDO> channelDOList = channelMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); List<SysSmsChannelDO> channelDOList = channelMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
// 创建渠道 Client // 创建渠道 Client
@ -48,6 +41,8 @@ public class SysSmsChannelServiceImpl implements SysSmsChannelService {
propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties)); propertiesList.forEach(properties -> smsClientFactory.createOrUpdateSmsClient(properties));
} }
// TODO 芋艿:刷新缓存
@Override @Override
public PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO) { public PageResult<SysSmsChannelDO> pageSmsChannels(SmsChannelPageReqVO reqVO) {
return channelMapper.selectChannelPage(reqVO); return channelMapper.selectChannelPage(reqVO);
@ -60,11 +55,6 @@ public class SysSmsChannelServiceImpl implements SysSmsChannelService {
return channelDO.getId(); return channelDO.getId();
} }
@Override
public List<SmsChannelEnumRespVO> getSmsChannelEnums() {
return SmsChannelConvert.INSTANCE.convertEnum(Arrays.asList(SmsChannelEnum.values()));
}
// @Override // @Override
// public List<SmsChannelAllVO> listSmsChannelAllEnabledInfo() { // public List<SmsChannelAllVO> listSmsChannelAllEnabledInfo() {
// List<SysSmsChannelDO> channelDOList = channelMapper.selectListByStatus(); // List<SysSmsChannelDO> channelDOList = channelMapper.selectListByStatus();

View File

@ -1,10 +1,11 @@
package cn.iocoder.dashboard.modules.system.service.sms.impl; package cn.iocoder.dashboard.modules.system.service.sms.impl;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsSendLogDO; import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsLogDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsSendLogMapper; import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsLogMapper;
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsSendLogService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsLogService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -21,15 +22,18 @@ import java.util.Objects;
*/ */
@Slf4j @Slf4j
@Service @Service
public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { public class SysSmsSendLogServiceImpl implements SysSmsLogService {
@Resource @Resource
private SysSmsSendLogMapper smsSendLogMapper; private SysSmsLogMapper smsLogMapper;
@Override @Override
public Long createSmsSendLog(String mobile, Long userId, Integer userType, public Long createSmsLog(String mobile, Long userId, Integer userType, Boolean isSend,
SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams) { SysSmsTemplateDO template, String templateContent, Map<String, Object> templateParams) {
SysSmsSendLogDO.SysSmsSendLogDOBuilder logBuilder = SysSmsSendLogDO.builder(); SysSmsLogDO.SysSmsLogDOBuilder logBuilder = SysSmsLogDO.builder();
// 根据是否要发送,设置状态
logBuilder.sendStatus(Objects.equals(isSend, true) ? SysSmsSendStatusEnum.INIT.getStatus()
: SysSmsSendStatusEnum.IGNORE.getStatus());
// 设置手机相关字段 // 设置手机相关字段
logBuilder.mobile(mobile).userId(userId).userType(userType); logBuilder.mobile(mobile).userId(userId).userType(userType);
// 设置模板相关字段 // 设置模板相关字段
@ -39,18 +43,18 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService {
logBuilder.channelId(template.getChannelId()).channelCode(template.getChannelCode()); logBuilder.channelId(template.getChannelId()).channelCode(template.getChannelCode());
// 插入数据库 // 插入数据库
SysSmsSendLogDO logDO = logBuilder.build(); SysSmsLogDO logDO = logBuilder.build();
smsSendLogMapper.insert(logDO); smsLogMapper.insert(logDO);
return logDO.getId(); return logDO.getId();
} }
@Override @Override
public void updateSmsSendLogResult(Long id, Boolean success, Integer sendFailureType, String sendFailureMsg, public void updateSmsSendResult(Long id, Integer sendCode, String sendMsg,
String apiSendFailureType, String apiSendFailureMsg, String apiRequestId, String apiSerialNo) { String apiSendCode, String apiSendMsg, String apiRequestId, String apiSerialNo) {
SysSmsSendStatusEnum sendStatus = Objects.equals(success, true) ? SysSmsSendStatusEnum.SUCCESS : SysSmsSendStatusEnum.FAILURE; SysSmsSendStatusEnum sendStatus = CommonResult.isSuccess(sendCode) ? SysSmsSendStatusEnum.SUCCESS : SysSmsSendStatusEnum.FAILURE;
smsSendLogMapper.updateById(new SysSmsSendLogDO().setId(id).setSendStatus(sendStatus.getStatus()).setSendTime(new Date()) smsLogMapper.updateById(SysSmsLogDO.builder().id(id).sendStatus(sendStatus.getStatus()).sendTime(new Date())
.setSendFailureType(sendFailureType).setSendFailureMsg(sendFailureMsg) .sendCode(sendCode).sendMsg(sendMsg).apiSendCode(apiSendCode).apiSendMsg(apiSendMsg)
.setApiSendFailureType(apiSendFailureType).setApiSendFailureMsg(apiSendFailureMsg).setApiRequestId(apiRequestId).setApiSerialNo(apiSerialNo)); .apiRequestId(apiRequestId).apiSerialNo(apiSerialNo).build());
} }
} }

View File

@ -1,29 +1,32 @@
package cn.iocoder.dashboard.modules.system.service.sms.impl; package cn.iocoder.dashboard.modules.system.service.sms.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.common.enums.CommonStatusEnum; import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
import cn.iocoder.dashboard.common.enums.UserTypeEnum; import cn.iocoder.dashboard.common.enums.UserTypeEnum;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClient; import cn.iocoder.dashboard.framework.sms.core.client.SmsClient;
import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory; import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; 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.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.mq.message.sms.SysSmsSendMessage; 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.mq.producer.sms.SysSmsProducer;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsSendLogService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsLogService;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService;
import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService;
import cn.iocoder.dashboard.modules.system.service.user.SysUserService; import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@ -38,10 +41,12 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@Slf4j @Slf4j
public class SysSmsServiceImpl implements SysSmsService { public class SysSmsServiceImpl implements SysSmsService {
@Resource
private SysSmsChannelService smsChannelService;
@Resource @Resource
private SysSmsTemplateService smsTemplateService; private SysSmsTemplateService smsTemplateService;
@Resource @Resource
private SysSmsSendLogService smsSendLogService; private SysSmsLogService smsLogService;
@Resource @Resource
private SysSmsProducer smsProducer; private SysSmsProducer smsProducer;
@Resource @Resource
@ -54,53 +59,58 @@ public class SysSmsServiceImpl implements SysSmsService {
public void sendSingleSms(String mobile, Long userId, Integer userType, public void sendSingleSms(String mobile, Long userId, Integer userType,
String templateCode, Map<String, Object> templateParams) { String templateCode, Map<String, Object> templateParams) {
// 校验短信模板是否合法 // 校验短信模板是否合法
SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode, templateParams); SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode);
// 校验手机号码是否存在 // 校验手机号码是否存在
mobile = this.checkMobile(mobile, userId, userType); mobile = this.checkMobile(mobile, userId, userType);
// 创建发送日志 // 创建发送日志
Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus()); // 如果模板被禁用,则不发送短信,只记录日志
String content = smsTemplateService.formatSmsTemplateContent(template.getContent(), templateParams); String content = smsTemplateService.formatSmsTemplateContent(template.getContent(), templateParams);
Long sendLogId = smsSendLogService.createSmsSendLog(mobile, userId, userType, template, content, templateParams); Long sendLogId = smsLogService.createSmsLog(mobile, userId, userType, isSend, template, content, templateParams);
// 如果模板被禁用,则直接标记发送失败。也就说,不发短信,嘿嘿。 // 发送 MQ 消息,异步执行发送短信
if (CommonStatusEnum.DISABLE.getStatus().equals(template.getStatus())) { if (!isSend) {
smsSendLogService.updateSmsSendLogFailure(sendLogId, SmsSendFailureTypeEnum.SMS_TEMPLATE_DISABLE);
return; return;
} }
// 如果模板未禁用,发送 MQ 消息。目的是,异步化调用短信平台 List<KeyValue<String, Object>> newTemplateParams = this.buildTemplateParams(template, templateParams);
smsProducer.sendSmsSendMessage(sendLogId, mobile, template.getChannelId(), template.getApiTemplateId(), templateParams); smsProducer.sendSmsSendMessage(sendLogId, mobile, template.getChannelId(), template.getApiTemplateId(), newTemplateParams);
} }
@Override @Override
public void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType, public void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType,
String templateCode, Map<String, Object> templateParams) { String templateCode, Map<String, Object> templateParams) {
// 校验短信模板是否存在 // 校验短信模板是否存在
SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode, templateParams); SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode);
} }
private SysSmsTemplateDO checkSmsTemplateValid(String templateCode, Map<String, Object> templateParams) { private SysSmsTemplateDO checkSmsTemplateValid(String templateCode) {
// 短信模板不存在 // 短信模板不存在
SysSmsTemplateDO template = smsTemplateService.getSmsTemplateByCode(templateCode); SysSmsTemplateDO template = smsTemplateService.getSmsTemplateByCode(templateCode);
if (template == null) { if (template == null) {
throw exception(SMS_TEMPLATE_NOT_EXISTS); throw exception(SMS_TEMPLATE_NOT_EXISTS);
} }
// 参数不够
if (CollUtil.isNotEmpty(template.getParams())) {
template.getParams().forEach(param -> {
if (!templateParams.containsKey(param)) {
throw exception(SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS);
}
});
}
// 移除多余参数
if (CollUtil.isEmpty(template.getParams())) {
templateParams.clear();
} else {
templateParams.entrySet().removeIf(entry -> !template.getParams().contains(entry.getKey()));
}
return template; return template;
} }
/**
* KeyValue
*
* 使 key https://cloud.tencent.com/document/product/382/39023
*
* @param template
* @param templateParams
* @return
*/
private List<KeyValue<String, Object>> buildTemplateParams(SysSmsTemplateDO template, Map<String, Object> templateParams) {
return template.getParams().stream().map(key -> {
Object value = templateParams.get(key);
if (value == null) {
throw exception(SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS, key);
}
return new KeyValue<>(key, value);
}).collect(Collectors.toList());
}
private String checkMobile(String mobile, Long userId, Integer userType) { private String checkMobile(String mobile, Long userId, Integer userType) {
mobile = getMobile(mobile, userId, userType); mobile = getMobile(mobile, userId, userType);
if (StrUtil.isEmpty(mobile)) { if (StrUtil.isEmpty(mobile)) {
@ -130,15 +140,12 @@ public class SysSmsServiceImpl implements SysSmsService {
public void doSendSms(SysSmsSendMessage message) { public void doSendSms(SysSmsSendMessage message) {
// 获得渠道对应的 SmsClient 客户端 // 获得渠道对应的 SmsClient 客户端
SmsClient smsClient = smsClientFactory.getSmsClient(message.getChannelId()); SmsClient smsClient = smsClientFactory.getSmsClient(message.getChannelId());
if (smsClient == null) { Assert.notNull(smsClient, String.format("短信客户端(%d) 不存在", message.getChannelId()));
log.error("[doSendSms][短信 message({}) 找不到对应的客户端]", message);
smsSendLogService.updateSmsSendLogFailure(message.getSendLogId(), SmsSendFailureTypeEnum.SMS_CHANNEL_CLIENT_NOT_EXISTS);
return;
}
// 发送短信 // 发送短信
SmsCommonResult sendResult = smsClient.send(message.getSendLogId(), message.getMobile(), SmsCommonResult<SmsSendRespDTO> sendResult = smsClient.send(message.getLogId(), message.getMobile(),
message.getApiTemplateId(), message.getTemplateParams()); message.getApiTemplateId(), message.getTemplateParams());
smsLogService.updateSmsSendResult(message.getLogId(), sendResult.getCode(), sendResult.getMsg(),
sendResult.getApiCode(), sendResult.getApiMsg(), sendResult.getApiRequestId(), sendResult.getData().getSerialNo());
} }
@Override @Override

View File

@ -2,6 +2,8 @@ package cn.iocoder.dashboard.util.collection;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.dashboard.common.core.KeyValue;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import java.util.ArrayList; import java.util.ArrayList;
@ -55,4 +57,10 @@ public class MapUtils {
consumer.accept(value); consumer.accept(value);
} }
public static <K, V> Map<K, V> convertMap(List<KeyValue<K, V>> keyValues) {
Map<K, V> map = Maps.newLinkedHashMapWithExpectedSize(keyValues.size());
keyValues.forEach(keyValue -> map.put(keyValue.getKey(), keyValue.getValue()));
return map;
}
} }

View File

@ -1,12 +1,14 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun; package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum; import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.HashMap; import java.util.ArrayList;
import java.util.Map; import java.util.List;
/** /**
* {@link AliyunSmsClient} * {@link AliyunSmsClient}
@ -26,11 +28,11 @@ public class AliyunSmsClientTest {
AliyunSmsClient smsClient = new AliyunSmsClient(properties); AliyunSmsClient smsClient = new AliyunSmsClient(properties);
smsClient.init(); smsClient.init();
// 发送短信 // 发送短信
Map<String, Object> templateParams = new HashMap<>(); List<KeyValue<String, Object>> templateParams = new ArrayList<>();
templateParams.put("code", "1024"); templateParams.add(new KeyValue<>("code", "1024"));
// templateParams.put("operation", "嘿嘿"); // templateParams.put("operation", "嘿嘿");
// SmsResult result = smsClient.send(1L, "15601691399", "4372216", templateParams); // SmsResult result = smsClient.send(1L, "15601691399", "4372216", templateParams);
SmsCommonResult result = smsClient.send(1L, "15601691399", "SMS_207945135", templateParams); SmsCommonResult<SmsSendRespDTO> result = smsClient.send(1L, "15601691399", "SMS_207945135", templateParams);
System.out.println(result); System.out.println(result);
} }

View File

@ -1,12 +1,14 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian; package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
import cn.iocoder.dashboard.common.core.KeyValue;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum; import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.HashMap; import java.util.ArrayList;
import java.util.Map; import java.util.List;
/** /**
* {@link YunpianSmsClient} * {@link YunpianSmsClient}
@ -25,11 +27,11 @@ public class YunpianSmsClientIntegrationTest {
YunpianSmsClient smsClient = new YunpianSmsClient(properties); YunpianSmsClient smsClient = new YunpianSmsClient(properties);
smsClient.init(); smsClient.init();
// 发送短信 // 发送短信
Map<String, Object> templateParams = new HashMap<>(); List<KeyValue<String, Object>> templateParams = new ArrayList<>();
templateParams.put("code", "1024"); templateParams.add(new KeyValue<>("code", "1024"));
templateParams.put("operation", "嘿嘿"); templateParams.add(new KeyValue<>("operation", "嘿嘿"));
// SmsResult result = smsClient.send(1L, "15601691399", "4372216", templateParams); // SmsResult result = smsClient.send(1L, "15601691399", "4372216", templateParams);
SmsCommonResult result = smsClient.send(1L, "15601691399", "4383920", templateParams); SmsCommonResult<SmsSendRespDTO> result = smsClient.send(1L, "15601691399", "4383920", templateParams);
System.out.println(result); System.out.println(result);
} }