Commit 5a1491d7fdc510c2fb20e85ad99d1a3e10c4dc92
1 parent
9528698a
短信提交 2021-04-01,重构返回的结果
Showing
21 changed files
with
174 additions
and
140 deletions
src/main/java/cn/iocoder/dashboard/common/exception/ErrorCode.java
| 1 | package cn.iocoder.dashboard.common.exception; | 1 | package cn.iocoder.dashboard.common.exception; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; | ||
| 3 | import cn.iocoder.dashboard.common.exception.enums.ServiceErrorCodeRange; | 4 | import cn.iocoder.dashboard.common.exception.enums.ServiceErrorCodeRange; |
| 4 | import lombok.Data; | 5 | import lombok.Data; |
| 5 | 6 | ||
| 6 | /** | 7 | /** |
| 7 | * 错误码对象 | 8 | * 错误码对象 |
| 8 | * | 9 | * |
| 9 | - * 全局错误码,占用 [0, 999],参见 {@link GlobalException} | 10 | + * 全局错误码,占用 [0, 999], 参见 {@link GlobalErrorCodeConstants} |
| 10 | * 业务异常错误码,占用 [1 000 000 000, +∞),参见 {@link ServiceErrorCodeRange} | 11 | * 业务异常错误码,占用 [1 000 000 000, +∞),参见 {@link ServiceErrorCodeRange} |
| 11 | * | 12 | * |
| 12 | * TODO 错误码设计成对象的原因,为未来的 i18 国际化做准备 | 13 | * TODO 错误码设计成对象的原因,为未来的 i18 国际化做准备 |
| @@ -21,11 +22,11 @@ public class ErrorCode { | @@ -21,11 +22,11 @@ public class ErrorCode { | ||
| 21 | /** | 22 | /** |
| 22 | * 错误提示 | 23 | * 错误提示 |
| 23 | */ | 24 | */ |
| 24 | - private final String message; | 25 | + private final String msg; |
| 25 | 26 | ||
| 26 | public ErrorCode(Integer code, String message) { | 27 | public ErrorCode(Integer code, String message) { |
| 27 | this.code = code; | 28 | this.code = code; |
| 28 | - this.message = message; | 29 | + this.msg = message; |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | } | 32 | } |
src/main/java/cn/iocoder/dashboard/common/exception/ServiceException.java
| @@ -30,7 +30,7 @@ public final class ServiceException extends RuntimeException { | @@ -30,7 +30,7 @@ public final class ServiceException extends RuntimeException { | ||
| 30 | 30 | ||
| 31 | public ServiceException(ErrorCode errorCode) { | 31 | public ServiceException(ErrorCode errorCode) { |
| 32 | this.code = errorCode.getCode(); | 32 | this.code = errorCode.getCode(); |
| 33 | - this.message = errorCode.getMessage(); | 33 | + this.message = errorCode.getMsg(); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | public ServiceException(Integer code, String message) { | 36 | public ServiceException(Integer code, String message) { |
src/main/java/cn/iocoder/dashboard/common/exception/util/ServiceExceptionUtil.java
| @@ -47,12 +47,12 @@ public class ServiceExceptionUtil { | @@ -47,12 +47,12 @@ public class ServiceExceptionUtil { | ||
| 47 | // ========== 和 ServiceException 的集成 ========== | 47 | // ========== 和 ServiceException 的集成 ========== |
| 48 | 48 | ||
| 49 | public static ServiceException exception(ErrorCode errorCode) { | 49 | public static ServiceException exception(ErrorCode errorCode) { |
| 50 | - String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMessage()); | 50 | + String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg()); |
| 51 | return exception0(errorCode.getCode(), messagePattern); | 51 | return exception0(errorCode.getCode(), messagePattern); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | public static ServiceException exception(ErrorCode errorCode, Object... params) { | 54 | public static ServiceException exception(ErrorCode errorCode, Object... params) { |
| 55 | - String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMessage()); | 55 | + String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg()); |
| 56 | return exception0(errorCode.getCode(), messagePattern, params); | 56 | return exception0(errorCode.getCode(), messagePattern, params); |
| 57 | } | 57 | } |
| 58 | 58 |
src/main/java/cn/iocoder/dashboard/common/pojo/CommonResult.java
| @@ -30,7 +30,7 @@ public class CommonResult<T> implements Serializable { | @@ -30,7 +30,7 @@ public class CommonResult<T> implements Serializable { | ||
| 30 | /** | 30 | /** |
| 31 | * 错误提示,用户可阅读 | 31 | * 错误提示,用户可阅读 |
| 32 | * | 32 | * |
| 33 | - * @see ErrorCode#getMessage() () | 33 | + * @see ErrorCode#getMsg() () |
| 34 | */ | 34 | */ |
| 35 | private String msg; | 35 | private String msg; |
| 36 | 36 | ||
| @@ -56,7 +56,7 @@ public class CommonResult<T> implements Serializable { | @@ -56,7 +56,7 @@ public class CommonResult<T> implements Serializable { | ||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | public static <T> CommonResult<T> error(ErrorCode errorCode) { | 58 | public static <T> CommonResult<T> error(ErrorCode errorCode) { |
| 59 | - return error(errorCode.getCode(), errorCode.getMessage()); | 59 | + return error(errorCode.getCode(), errorCode.getMsg()); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | public static <T> CommonResult<T> success(T data) { | 62 | public static <T> CommonResult<T> success(T data) { |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/SmsClient.java
| 1 | package cn.iocoder.dashboard.framework.sms.core.client; | 1 | package cn.iocoder.dashboard.framework.sms.core.client; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | 3 | +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail; |
| 4 | import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; | 4 | import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; |
| 5 | 5 | ||
| 6 | import javax.servlet.ServletRequest; | 6 | import javax.servlet.ServletRequest; |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/SmsCodeMapping.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.sms.core.client; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.exception.ErrorCode; | ||
| 4 | +import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants; | ||
| 5 | + | ||
| 6 | +import java.util.function.Function; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * 将 API 的错误码,转换为通用的错误码 | ||
| 10 | + * | ||
| 11 | + * @see SmsCommonResult | ||
| 12 | + * @see SmsFrameworkErrorCodeConstants | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +public interface SmsCodeMapping extends Function<String, ErrorCode> { | ||
| 17 | +} |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/SmsCommonResult.java
| 1 | package cn.iocoder.dashboard.framework.sms.core.client; | 1 | package cn.iocoder.dashboard.framework.sms.core.client; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.exceptions.ExceptionUtil; | 3 | import cn.hutool.core.exceptions.ExceptionUtil; |
| 4 | +import cn.hutool.core.lang.Assert; | ||
| 5 | +import cn.iocoder.dashboard.common.exception.ErrorCode; | ||
| 4 | import cn.iocoder.dashboard.common.pojo.CommonResult; | 6 | import cn.iocoder.dashboard.common.pojo.CommonResult; |
| 5 | -import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; | 7 | +import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants; |
| 6 | import lombok.Data; | 8 | import lombok.Data; |
| 7 | import lombok.EqualsAndHashCode; | 9 | import lombok.EqualsAndHashCode; |
| 8 | import lombok.ToString; | 10 | import lombok.ToString; |
| @@ -40,20 +42,27 @@ public class SmsCommonResult<T> extends CommonResult<T> { | @@ -40,20 +42,27 @@ public class SmsCommonResult<T> extends CommonResult<T> { | ||
| 40 | private SmsCommonResult() { | 42 | private SmsCommonResult() { |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | - public static SmsCommonResult success(SmsSendFailureTypeEnum sendFailureType, | ||
| 44 | - String apiSendCode, String apiSendMsg, String apiRequestId, String apiSerialNo) { | ||
| 45 | - SmsCommonResult result = new SmsCommonResult().setSuccess(true).setApiSendCode(apiSendCode).setApiSendMsg(apiSendMsg) | ||
| 46 | - .setApiRequestId(apiRequestId).setApiSerialNo(apiSerialNo); | ||
| 47 | - if (sendFailureType != null) { | ||
| 48 | - result.setSendFailureType(sendFailureType.getType()).setSendFailureMsg(sendFailureType.getMsg()); | 45 | + public static <T> SmsCommonResult<T> build(String apiCode, String apiMsg, String apiRequestId, |
| 46 | + T data, SmsCodeMapping codeMapping) { | ||
| 47 | + Assert.notNull(codeMapping, "参数 codeMapping 不能为空"); | ||
| 48 | + SmsCommonResult<T> result = new SmsCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg).setApiRequestId(apiRequestId); | ||
| 49 | + result.setData(data); | ||
| 50 | + // 翻译错误码 | ||
| 51 | + if (codeMapping != null) { | ||
| 52 | + ErrorCode errorCode = codeMapping.apply(apiCode); | ||
| 53 | + if (errorCode == null) { | ||
| 54 | + errorCode = SmsFrameworkErrorCodeConstants.SMS_UNKNOWN; | ||
| 55 | + } | ||
| 56 | + result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg()); | ||
| 49 | } | 57 | } |
| 50 | return result; | 58 | return result; |
| 51 | } | 59 | } |
| 52 | 60 | ||
| 53 | - public static SmsCommonResult error(Throwable ex) { | ||
| 54 | - return new SmsCommonResult().setSuccess(false) | ||
| 55 | - .setSendFailureType(SmsSendFailureTypeEnum.SMS_SEND_EXCEPTION.getType()) | ||
| 56 | - .setSendFailureMsg(ExceptionUtil.getRootCauseMessage(ex)); | 61 | + public static <T> SmsCommonResult<T> error(Throwable ex) { |
| 62 | + SmsCommonResult<T> result = new SmsCommonResult<>(); | ||
| 63 | + result.setCode(SmsFrameworkErrorCodeConstants.EXCEPTION.getCode()); | ||
| 64 | + result.setMsg(ExceptionUtil.getRootCauseMessage(ex)); | ||
| 65 | + return result; | ||
| 57 | } | 66 | } |
| 58 | 67 | ||
| 59 | } | 68 | } |
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/core/client/dto/SmsResultDetail.java
| 1 | -package cn.iocoder.dashboard.framework.sms.core; | 1 | +package cn.iocoder.dashboard.framework.sms.core.client.dto; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; | 3 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/dto/SmsSendRespDTO.java
| 1 | package cn.iocoder.dashboard.framework.sms.core.client.dto; | 1 | package cn.iocoder.dashboard.framework.sms.core.client.dto; |
| 2 | 2 | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 3 | /** | 5 | /** |
| 4 | * 短信发送响应 DTO | 6 | * 短信发送响应 DTO |
| 5 | * | 7 | * |
| 6 | * @author 芋道源码 | 8 | * @author 芋道源码 |
| 7 | */ | 9 | */ |
| 10 | +@Data | ||
| 8 | public class SmsSendRespDTO { | 11 | public class SmsSendRespDTO { |
| 9 | 12 | ||
| 10 | /** | 13 | /** |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/AbstractSmsClient.java
| 1 | package cn.iocoder.dashboard.framework.sms.core.client.impl; | 1 | package cn.iocoder.dashboard.framework.sms.core.client.impl; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping; | ||
| 3 | import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; | 4 | import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; |
| 4 | import cn.iocoder.dashboard.framework.sms.core.client.SmsClient; | 5 | import cn.iocoder.dashboard.framework.sms.core.client.SmsClient; |
| 5 | import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; | 6 | import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; |
| @@ -21,14 +22,19 @@ public abstract class AbstractSmsClient implements SmsClient { | @@ -21,14 +22,19 @@ public abstract class AbstractSmsClient implements SmsClient { | ||
| 21 | * 短信渠道配置 | 22 | * 短信渠道配置 |
| 22 | */ | 23 | */ |
| 23 | protected volatile SmsChannelProperties properties; | 24 | protected volatile SmsChannelProperties properties; |
| 25 | + /** | ||
| 26 | + * 错误码枚举类 | ||
| 27 | + */ | ||
| 28 | + protected final SmsCodeMapping codeMapping; | ||
| 24 | 29 | ||
| 25 | /** | 30 | /** |
| 26 | * 短信客户端有参构造函数 | 31 | * 短信客户端有参构造函数 |
| 27 | * | 32 | * |
| 28 | * @param properties 短信配置 | 33 | * @param properties 短信配置 |
| 29 | */ | 34 | */ |
| 30 | - public AbstractSmsClient(SmsChannelProperties properties) { | 35 | + public AbstractSmsClient(SmsChannelProperties properties, SmsCodeMapping codeMapping) { |
| 31 | this.properties = properties; | 36 | this.properties = properties; |
| 37 | + this.codeMapping = codeMapping; | ||
| 32 | } | 38 | } |
| 33 | 39 | ||
| 34 | /** | 40 | /** |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/aliyun/AliyunSmsClient.java
| @@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollectionUtil; | @@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | import cn.hutool.core.date.DateUtil; | 4 | import cn.hutool.core.date.DateUtil; |
| 5 | import cn.hutool.core.util.StrUtil; | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; | 6 | import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; |
| 7 | -import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | 7 | +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail; |
| 8 | +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; | ||
| 8 | import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient; | 9 | import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient; |
| 9 | -import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; | ||
| 10 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; | 10 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; |
| 11 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; | 11 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; |
| 12 | import cn.iocoder.dashboard.util.json.JsonUtils; | 12 | import cn.iocoder.dashboard.util.json.JsonUtils; |
| @@ -48,7 +48,7 @@ public class AliyunSmsClient extends AbstractSmsClient { | @@ -48,7 +48,7 @@ public class AliyunSmsClient extends AbstractSmsClient { | ||
| 48 | private volatile IAcsClient acsClient; | 48 | private volatile IAcsClient acsClient; |
| 49 | 49 | ||
| 50 | public AliyunSmsClient(SmsChannelProperties properties) { | 50 | public AliyunSmsClient(SmsChannelProperties properties) { |
| 51 | - super(properties); | 51 | + super(properties, new AliyunSmsCodeMapping()); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | @Override | 54 | @Override |
| @@ -59,7 +59,8 @@ public class AliyunSmsClient extends AbstractSmsClient { | @@ -59,7 +59,8 @@ public class AliyunSmsClient extends AbstractSmsClient { | ||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | @Override | 61 | @Override |
| 62 | - protected SmsCommonResult doSend(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams) throws Exception { | 62 | + protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile, |
| 63 | + String apiTemplateId, Map<String, Object> templateParams) throws Throwable { | ||
| 63 | // 构建参数 | 64 | // 构建参数 |
| 64 | SendSmsRequest request = new SendSmsRequest(); | 65 | SendSmsRequest request = new SendSmsRequest(); |
| 65 | request.setSysMethod(MethodType.POST); | 66 | request.setSysMethod(MethodType.POST); |
| @@ -73,25 +74,16 @@ public class AliyunSmsClient extends AbstractSmsClient { | @@ -73,25 +74,16 @@ public class AliyunSmsClient extends AbstractSmsClient { | ||
| 73 | // 执行发送 | 74 | // 执行发送 |
| 74 | SendSmsResponse sendResult = acsClient.getAcsResponse(request); | 75 | SendSmsResponse sendResult = acsClient.getAcsResponse(request); |
| 75 | // 解析结果 | 76 | // 解析结果 |
| 76 | - return SmsCommonResult.success(parseSendFailureType(sendResult.getCode()), // 将 API 短信平台,解析成统一的错误码 | ||
| 77 | - sendResult.getCode(), sendResult.getMessage(), sendResult.getRequestId(), sendResult.getBizId()); | 77 | + SmsSendRespDTO data = null; |
| 78 | + if (sendResult.getBizId() != null) { | ||
| 79 | + data = new SmsSendRespDTO().setSerialNo(sendResult.getBizId()); | ||
| 80 | + } | ||
| 81 | + return SmsCommonResult.build(sendResult.getCode(), sendResult.getMessage(), sendResult.getRequestId(), data, codeMapping); | ||
| 78 | } catch (ClientException ex) { | 82 | } catch (ClientException ex) { |
| 79 | - return SmsCommonResult.success(parseSendFailureType(ex.getErrCode()), // 将 API 短信平台,解析成统一的错误码 | ||
| 80 | - ex.getErrCode(), formatResultMsg(ex), ex.getRequestId(), null); | 83 | + return SmsCommonResult.build(ex.getErrCode(), formatResultMsg(ex), ex.getRequestId(), null, codeMapping); |
| 81 | } | 84 | } |
| 82 | } | 85 | } |
| 83 | 86 | ||
| 84 | - private static SmsSendFailureTypeEnum parseSendFailureType(String code) { | ||
| 85 | - switch (code) { | ||
| 86 | - case "OK": return null; | ||
| 87 | - case "MissingAccessKeyId": return SmsSendFailureTypeEnum.SMS_CHANNEL_API_KEY_MISSING; | ||
| 88 | - case "isp.RAM_PERMISSION_DENY": return SmsSendFailureTypeEnum.SMS_CHANNEL_PERMISSION_DENY; | ||
| 89 | - case "isv.INVALID_PARAMETERS": return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR; | ||
| 90 | - case "isv.BUSINESS_LIMIT_CONTROL": return SmsSendFailureTypeEnum.SMS_SEND_LIMIT_CONTROL; | ||
| 91 | - } | ||
| 92 | - return SmsSendFailureTypeEnum.SMS_UNKNOWN; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | private static String formatResultMsg(ClientException ex) { | 87 | private static String formatResultMsg(ClientException ex) { |
| 96 | if (StrUtil.isEmpty(ex.getErrorDescription())) { | 88 | if (StrUtil.isEmpty(ex.getErrorDescription())) { |
| 97 | return ex.getMessage(); | 89 | return ex.getMessage(); |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/aliyun/AliyunSmsCodeMapping.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.exception.ErrorCode; | ||
| 4 | +import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping; | ||
| 5 | + | ||
| 6 | +import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.*; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * 阿里云的 SmsCodeMapping 实现类 | ||
| 10 | + * | ||
| 11 | + * @author 芋道源码 | ||
| 12 | + */ | ||
| 13 | +public class AliyunSmsCodeMapping implements SmsCodeMapping { | ||
| 14 | + | ||
| 15 | + @Override | ||
| 16 | + public ErrorCode apply(String apiCode) { | ||
| 17 | + switch (apiCode) { | ||
| 18 | + case "OK": return null; | ||
| 19 | + case "MissingAccessKeyId": return SMS_CHANNEL_API_KEY_MISSING; | ||
| 20 | + case "isp.RAM_PERMISSION_DENY": return SMS_CHANNEL_PERMISSION_DENY; | ||
| 21 | + case "isv.INVALID_PARAMETERS": return SMS_API_PARAM_ERROR; | ||
| 22 | + case "isv.BUSINESS_LIMIT_CONTROL": return SMS_SEND_LIMIT_CONTROL; | ||
| 23 | + } | ||
| 24 | + return SMS_UNKNOWN; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | +} |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/yunpian/YunpianSmsClient.java
| @@ -6,11 +6,11 @@ import cn.hutool.core.date.DateUtil; | @@ -6,11 +6,11 @@ import cn.hutool.core.date.DateUtil; | ||
| 6 | import cn.hutool.core.util.CharsetUtil; | 6 | import cn.hutool.core.util.CharsetUtil; |
| 7 | import cn.hutool.core.util.StrUtil; | 7 | import cn.hutool.core.util.StrUtil; |
| 8 | import cn.hutool.core.util.URLUtil; | 8 | import cn.hutool.core.util.URLUtil; |
| 9 | -import cn.iocoder.dashboard.framework.sms.core.SmsConstants; | ||
| 10 | import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; | 9 | import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; |
| 11 | -import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | 10 | +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail; |
| 11 | +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO; | ||
| 12 | import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient; | 12 | import cn.iocoder.dashboard.framework.sms.core.client.impl.AbstractSmsClient; |
| 13 | -import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; | 13 | +import cn.iocoder.dashboard.framework.sms.core.enums.SmsConstants; |
| 14 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; | 14 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties; |
| 15 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; | 15 | import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum; |
| 16 | import cn.iocoder.dashboard.util.json.JsonUtils; | 16 | import cn.iocoder.dashboard.util.json.JsonUtils; |
| @@ -29,8 +29,6 @@ import java.util.List; | @@ -29,8 +29,6 @@ import java.util.List; | ||
| 29 | import java.util.Map; | 29 | import java.util.Map; |
| 30 | import java.util.StringJoiner; | 30 | import java.util.StringJoiner; |
| 31 | 31 | ||
| 32 | -import static com.yunpian.sdk.constant.Code.*; | ||
| 33 | - | ||
| 34 | /** | 32 | /** |
| 35 | * 云片短信客户端的实现类 | 33 | * 云片短信客户端的实现类 |
| 36 | * | 34 | * |
| @@ -49,7 +47,7 @@ public class YunpianSmsClient extends AbstractSmsClient { | @@ -49,7 +47,7 @@ public class YunpianSmsClient extends AbstractSmsClient { | ||
| 49 | }; | 47 | }; |
| 50 | 48 | ||
| 51 | public YunpianSmsClient(SmsChannelProperties properties) { | 49 | public YunpianSmsClient(SmsChannelProperties properties) { |
| 52 | - super(properties); | 50 | + super(properties, new YunpianSmsCodeMapping()); |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | @Override | 53 | @Override |
| @@ -66,7 +64,8 @@ public class YunpianSmsClient extends AbstractSmsClient { | @@ -66,7 +64,8 @@ public class YunpianSmsClient extends AbstractSmsClient { | ||
| 66 | } | 64 | } |
| 67 | 65 | ||
| 68 | @Override | 66 | @Override |
| 69 | - protected SmsCommonResult doSend(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams) throws Throwable { | 67 | + protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile, |
| 68 | + String apiTemplateId, Map<String, Object> templateParams) throws Throwable { | ||
| 70 | // 构建参数 | 69 | // 构建参数 |
| 71 | Map<String, String> request = new HashMap<>(); | 70 | Map<String, String> request = new HashMap<>(); |
| 72 | request.put(YunpianConstant.APIKEY, properties.getApiKey()); | 71 | request.put(YunpianConstant.APIKEY, properties.getApiKey()); |
| @@ -82,8 +81,12 @@ public class YunpianSmsClient extends AbstractSmsClient { | @@ -82,8 +81,12 @@ public class YunpianSmsClient extends AbstractSmsClient { | ||
| 82 | throw sendResult.getThrowable(); | 81 | throw sendResult.getThrowable(); |
| 83 | } | 82 | } |
| 84 | // 解析结果 | 83 | // 解析结果 |
| 85 | - return SmsCommonResult.success(parseSendFailureType(sendResult), // 将 API 短信平台,解析成统一的错误码 | ||
| 86 | - String.valueOf(sendResult.getCode()), formatResultMsg(sendResult), null, getApiSerialNo(sendResult)); | 84 | + SmsSendRespDTO data = null; |
| 85 | + if (sendResult.getData() != null) { | ||
| 86 | + data = new SmsSendRespDTO().setSerialNo(String.valueOf(sendResult.getData().getSid())); | ||
| 87 | + } | ||
| 88 | + return SmsCommonResult.build(String.valueOf(sendResult.getCode()), formatResultMsg(sendResult), null, | ||
| 89 | + data, codeMapping); | ||
| 87 | } | 90 | } |
| 88 | 91 | ||
| 89 | private static String formatTplValue(Map<String, Object> templateParams) { | 92 | private static String formatTplValue(Map<String, Object> templateParams) { |
| @@ -103,25 +106,6 @@ public class YunpianSmsClient extends AbstractSmsClient { | @@ -103,25 +106,6 @@ public class YunpianSmsClient extends AbstractSmsClient { | ||
| 103 | return sendResult.getMsg() + " => " + sendResult.getDetail(); | 106 | return sendResult.getMsg() + " => " + sendResult.getDetail(); |
| 104 | } | 107 | } |
| 105 | 108 | ||
| 106 | - private static SmsSendFailureTypeEnum parseSendFailureType(Result<SmsSingleSend> sendResult) { | ||
| 107 | - Integer code = sendResult.getCode(); | ||
| 108 | - switch (code) { | ||
| 109 | - case OK: return null; | ||
| 110 | - case ARGUMENT_MISSING: return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR; | ||
| 111 | - case BAD_ARGUMENT_FORMAT: return SmsSendFailureTypeEnum.SMS_TEMPLATE_PARAM_ERROR; | ||
| 112 | - case TPL_NOT_FOUND: return SmsSendFailureTypeEnum.SMS_TEMPLATE_NOT_EXISTS; | ||
| 113 | - case TPL_NOT_VALID: return SmsSendFailureTypeEnum.SMS_TEMPLATE_INVALID; | ||
| 114 | - } | ||
| 115 | - return SmsSendFailureTypeEnum.SMS_UNKNOWN; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - private static String getApiSerialNo(Result<SmsSingleSend> sendResult) { | ||
| 119 | - if (sendResult.getData() == null) { | ||
| 120 | - return null; | ||
| 121 | - } | ||
| 122 | - return String.valueOf(sendResult.getData().getSid()); | ||
| 123 | - } | ||
| 124 | - | ||
| 125 | /** | 109 | /** |
| 126 | * 云片的比较复杂,又是加密又是套娃的 | 110 | * 云片的比较复杂,又是加密又是套娃的 |
| 127 | */ | 111 | */ |
src/main/java/cn/iocoder/dashboard/framework/sms/core/client/impl/yunpian/YunpianSmsCodeMapping.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.exception.ErrorCode; | ||
| 4 | +import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping; | ||
| 5 | + | ||
| 6 | +import static cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants.SUCCESS; | ||
| 7 | +import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.*; | ||
| 8 | +import static com.yunpian.sdk.constant.Code.*; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 云片的 SmsCodeMapping 实现类 | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +public class YunpianSmsCodeMapping implements SmsCodeMapping { | ||
| 16 | + | ||
| 17 | + @Override | ||
| 18 | + public ErrorCode apply(String apiCode) { | ||
| 19 | + int code = Integer.parseInt(apiCode); | ||
| 20 | + switch (code) { | ||
| 21 | + case OK: return SUCCESS; | ||
| 22 | + case ARGUMENT_MISSING: return SMS_API_PARAM_ERROR; | ||
| 23 | + case BAD_ARGUMENT_FORMAT: return SMS_TEMPLATE_PARAM_ERROR; | ||
| 24 | + case TPL_NOT_FOUND: return SMS_TEMPLATE_NOT_EXISTS; | ||
| 25 | + case TPL_NOT_VALID: return SMS_TEMPLATE_INVALID; | ||
| 26 | + } | ||
| 27 | + return SMS_UNKNOWN; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | +} |
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsConstants.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsConstants.java
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsFrameworkErrorCodeConstants.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.sms.core.enums; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.common.exception.ErrorCode; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 短信框架的错误码枚举 | ||
| 7 | + * | ||
| 8 | + * 短信框架,使用 2-001-000-000 段 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public interface SmsFrameworkErrorCodeConstants { | ||
| 13 | + | ||
| 14 | + // ========== 渠道相关 2001000100 ========== | ||
| 15 | + ErrorCode SMS_CHANNEL_CLIENT_NOT_EXISTS = new ErrorCode(2001000100, "短信渠道的客户端不存在"); | ||
| 16 | + ErrorCode SMS_CHANNEL_API_KEY_MISSING = new ErrorCode(2001000101, "API Key 不存在"); | ||
| 17 | + ErrorCode SMS_CHANNEL_PERMISSION_DENY = new ErrorCode(2001000102, "没有发送短信的权限"); | ||
| 18 | + | ||
| 19 | + // ========== 模板相关(200 开头) ========== | ||
| 20 | + ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(200, "短信模板不存在"); | ||
| 21 | + ErrorCode SMS_TEMPLATE_DISABLE = new ErrorCode(201, "短信模板被禁用"); // 例如说,我们在管理后台禁用了 | ||
| 22 | + ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(202, "短信模板不可用"); // 例如说,短信模板正在审核中 | ||
| 23 | + ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(203, "模板参数不正确"); | ||
| 24 | + | ||
| 25 | + // ========== 其它相关(900 开头) ========== | ||
| 26 | + ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(900, "请求参数缺失"); | ||
| 27 | + | ||
| 28 | + ErrorCode SMS_SEND_LIMIT_CONTROL = new ErrorCode(997, "业务限流"); // 将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。 | ||
| 29 | + ErrorCode EXCEPTION = new ErrorCode(998, "调用异常"); | ||
| 30 | + ErrorCode SMS_UNKNOWN = new ErrorCode(999, "未知错误,需要解析"); | ||
| 31 | + | ||
| 32 | +} |
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsSendFailureTypeEnum.java deleted
| 1 | -package cn.iocoder.dashboard.framework.sms.core.enums; | ||
| 2 | - | ||
| 3 | -import lombok.AllArgsConstructor; | ||
| 4 | -import lombok.Getter; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 短信的发送失败类型的枚举 | ||
| 8 | - * | ||
| 9 | - * @author 芋道源码 | ||
| 10 | - */ | ||
| 11 | -@Getter | ||
| 12 | -@AllArgsConstructor | ||
| 13 | -public enum SmsSendFailureTypeEnum { | ||
| 14 | - | ||
| 15 | - // ========== 渠道相关(100 开头) ========== | ||
| 16 | - SMS_CHANNEL_CLIENT_NOT_EXISTS(100, "短信渠道的客户端不存在"), | ||
| 17 | - SMS_CHANNEL_API_KEY_MISSING(101, "API Key 不存在"), | ||
| 18 | - SMS_CHANNEL_PERMISSION_DENY(102, "没有发送短信的权限"), | ||
| 19 | - | ||
| 20 | - // ========== 模板相关(200 开头) ========== | ||
| 21 | - SMS_TEMPLATE_NOT_EXISTS(200, "短信模板不存在"), | ||
| 22 | - SMS_TEMPLATE_DISABLE(201, "短信模板被禁用"), // 例如说,我们在管理后台禁用了 | ||
| 23 | - SMS_TEMPLATE_INVALID(202, "短信模板不可用"), // 例如说,短信模板正在审核中 | ||
| 24 | - SMS_TEMPLATE_PARAM_ERROR(203, "模板参数不正确"), | ||
| 25 | - | ||
| 26 | - // ========== 其它相关(900 开头) ========== | ||
| 27 | - SMS_API_PARAM_ERROR(900, "请求参数缺失"), | ||
| 28 | - | ||
| 29 | - SMS_SEND_LIMIT_CONTROL(997, "业务限流"), // 将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟,5 条 / 小时,累计 10 条 / 天。 | ||
| 30 | - SMS_SEND_EXCEPTION(998, "发送异常"), | ||
| 31 | - SMS_UNKNOWN(999, "未知错误,需要解析") | ||
| 32 | - ; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * 失败类型 | ||
| 36 | - */ | ||
| 37 | - private final int type; | ||
| 38 | - /** | ||
| 39 | - * 失败提示 | ||
| 40 | - */ | ||
| 41 | - private final String msg; | ||
| 42 | - | ||
| 43 | -} |
src/main/java/cn/iocoder/dashboard/framework/web/core/handler/GlobalExceptionHandler.java
| @@ -3,7 +3,6 @@ package cn.iocoder.dashboard.framework.web.core.handler; | @@ -3,7 +3,6 @@ package cn.iocoder.dashboard.framework.web.core.handler; | ||
| 3 | import cn.hutool.core.exceptions.ExceptionUtil; | 3 | import cn.hutool.core.exceptions.ExceptionUtil; |
| 4 | import cn.hutool.core.map.MapUtil; | 4 | import cn.hutool.core.map.MapUtil; |
| 5 | import cn.hutool.extra.servlet.ServletUtil; | 5 | import cn.hutool.extra.servlet.ServletUtil; |
| 6 | -import cn.iocoder.dashboard.common.exception.GlobalException; | ||
| 7 | import cn.iocoder.dashboard.common.exception.ServiceException; | 6 | import cn.iocoder.dashboard.common.exception.ServiceException; |
| 8 | import cn.iocoder.dashboard.common.pojo.CommonResult; | 7 | import cn.iocoder.dashboard.common.pojo.CommonResult; |
| 9 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.ApiErrorLogFrameworkService; | 8 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.ApiErrorLogFrameworkService; |
| @@ -96,9 +95,6 @@ public class GlobalExceptionHandler { | @@ -96,9 +95,6 @@ public class GlobalExceptionHandler { | ||
| 96 | if (ex instanceof AccessDeniedException) { | 95 | if (ex instanceof AccessDeniedException) { |
| 97 | return accessDeniedExceptionHandler(request, (AccessDeniedException) ex); | 96 | return accessDeniedExceptionHandler(request, (AccessDeniedException) ex); |
| 98 | } | 97 | } |
| 99 | - if (ex instanceof GlobalException) { | ||
| 100 | - return globalExceptionHandler(request, (GlobalException) ex); | ||
| 101 | - } | ||
| 102 | return defaultExceptionHandler(request, ex); | 98 | return defaultExceptionHandler(request, ex); |
| 103 | } | 99 | } |
| 104 | 100 | ||
| @@ -223,25 +219,6 @@ public class GlobalExceptionHandler { | @@ -223,25 +219,6 @@ public class GlobalExceptionHandler { | ||
| 223 | } | 219 | } |
| 224 | 220 | ||
| 225 | /** | 221 | /** |
| 226 | - * 处理全局异常 ServiceException | ||
| 227 | - * | ||
| 228 | - * 例如说,Dubbo 请求超时,调用的 Dubbo 服务系统异常 | ||
| 229 | - */ | ||
| 230 | - @ExceptionHandler(value = GlobalException.class) | ||
| 231 | - public CommonResult<?> globalExceptionHandler(HttpServletRequest req, GlobalException ex) { | ||
| 232 | - // 系统异常时,才打印异常日志 | ||
| 233 | - if (INTERNAL_SERVER_ERROR.getCode().equals(ex.getCode())) { | ||
| 234 | - // 插入异常日志 | ||
| 235 | - this.createExceptionLog(req, ex); | ||
| 236 | - // 普通全局异常,打印 info 日志即可 | ||
| 237 | - } else { | ||
| 238 | - log.info("[globalExceptionHandler]", ex); | ||
| 239 | - } | ||
| 240 | - // 返回 ERROR CommonResult | ||
| 241 | - return CommonResult.error(ex); | ||
| 242 | - } | ||
| 243 | - | ||
| 244 | - /** | ||
| 245 | * 处理系统异常,兜底处理所有的一切 | 222 | * 处理系统异常,兜底处理所有的一切 |
| 246 | */ | 223 | */ |
| 247 | @ExceptionHandler(value = Exception.class) | 224 | @ExceptionHandler(value = Exception.class) |
| @@ -250,7 +227,7 @@ public class GlobalExceptionHandler { | @@ -250,7 +227,7 @@ public class GlobalExceptionHandler { | ||
| 250 | // 插入异常日志 | 227 | // 插入异常日志 |
| 251 | this.createExceptionLog(req, ex); | 228 | this.createExceptionLog(req, ex); |
| 252 | // 返回 ERROR CommonResult | 229 | // 返回 ERROR CommonResult |
| 253 | - return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMessage()); | 230 | + return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg()); |
| 254 | } | 231 | } |
| 255 | 232 | ||
| 256 | private void createExceptionLog(HttpServletRequest req, Throwable e) { | 233 | private void createExceptionLog(HttpServletRequest req, Throwable e) { |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsSendLogService.java
| 1 | package cn.iocoder.dashboard.modules.system.service.sms; | 1 | package cn.iocoder.dashboard.modules.system.service.sms; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum; | ||
| 4 | import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; | 3 | import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; |
| 5 | 4 | ||
| 6 | import java.util.Map; | 5 | import java.util.Map; |
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
| @@ -358,7 +358,7 @@ public class SysUserServiceImpl implements SysUserService { | @@ -358,7 +358,7 @@ public class SysUserServiceImpl implements SysUserService { | ||
| 358 | } | 358 | } |
| 359 | // 如果存在,判断是否允许更新 | 359 | // 如果存在,判断是否允许更新 |
| 360 | if (!isUpdateSupport) { | 360 | if (!isUpdateSupport) { |
| 361 | - respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMessage()); | 361 | + respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg()); |
| 362 | return; | 362 | return; |
| 363 | } | 363 | } |
| 364 | SysUserDO updateUser = SysUserConvert.INSTANCE.convert(importUser); | 364 | SysUserDO updateUser = SysUserConvert.INSTANCE.convert(importUser); |
src/test/java/cn/iocoder/dashboard/util/AssertUtils.java
| @@ -62,7 +62,7 @@ public class AssertUtils { | @@ -62,7 +62,7 @@ public class AssertUtils { | ||
| 62 | ServiceException serviceException = assertThrows(ServiceException.class, executable); | 62 | ServiceException serviceException = assertThrows(ServiceException.class, executable); |
| 63 | // 校验错误码 | 63 | // 校验错误码 |
| 64 | Assertions.assertEquals(errorCode.getCode(), serviceException.getCode(), "错误码不匹配"); | 64 | Assertions.assertEquals(errorCode.getCode(), serviceException.getCode(), "错误码不匹配"); |
| 65 | - String message = ServiceExceptionUtil.doFormat(errorCode.getCode(), errorCode.getMessage(), messageParams); | 65 | + String message = ServiceExceptionUtil.doFormat(errorCode.getCode(), errorCode.getMsg(), messageParams); |
| 66 | Assertions.assertEquals(message, serviceException.getMessage(), "错误提示不匹配"); | 66 | Assertions.assertEquals(message, serviceException.getMessage(), "错误提示不匹配"); |
| 67 | } | 67 | } |
| 68 | 68 |