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

pull/2/head
YunaiV 2021-04-01 01:31:35 +08:00
parent 9528698a5f
commit 5a1491d7fd
21 changed files with 174 additions and 140 deletions

View File

@ -1,12 +1,13 @@
package cn.iocoder.dashboard.common.exception;
import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.dashboard.common.exception.enums.ServiceErrorCodeRange;
import lombok.Data;
/**
*
*
* [0, 999] {@link GlobalException}
* [0, 999], {@link GlobalErrorCodeConstants}
* [1 000 000 000, +) {@link ServiceErrorCodeRange}
*
* TODO i18
@ -21,11 +22,11 @@ public class ErrorCode {
/**
*
*/
private final String message;
private final String msg;
public ErrorCode(Integer code, String message) {
this.code = code;
this.message = message;
this.msg = message;
}
}

View File

@ -30,7 +30,7 @@ public final class ServiceException extends RuntimeException {
public ServiceException(ErrorCode errorCode) {
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
this.message = errorCode.getMsg();
}
public ServiceException(Integer code, String message) {

View File

@ -47,12 +47,12 @@ public class ServiceExceptionUtil {
// ========== 和 ServiceException 的集成 ==========
public static ServiceException exception(ErrorCode errorCode) {
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMessage());
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg());
return exception0(errorCode.getCode(), messagePattern);
}
public static ServiceException exception(ErrorCode errorCode, Object... params) {
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMessage());
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg());
return exception0(errorCode.getCode(), messagePattern, params);
}

View File

@ -30,7 +30,7 @@ public class CommonResult<T> implements Serializable {
/**
*
*
* @see ErrorCode#getMessage() ()
* @see ErrorCode#getMsg() ()
*/
private String msg;
@ -56,7 +56,7 @@ public class CommonResult<T> implements Serializable {
}
public static <T> CommonResult<T> error(ErrorCode errorCode) {
return error(errorCode.getCode(), errorCode.getMessage());
return error(errorCode.getCode(), errorCode.getMsg());
}
public static <T> CommonResult<T> success(T data) {

View File

@ -1,6 +1,6 @@
package cn.iocoder.dashboard.framework.sms.core.client;
import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsResultDetail;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
import javax.servlet.ServletRequest;

View File

@ -0,0 +1,17 @@
package cn.iocoder.dashboard.framework.sms.core.client;
import cn.iocoder.dashboard.common.exception.ErrorCode;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import java.util.function.Function;
/**
* API
*
* @see SmsCommonResult
* @see SmsFrameworkErrorCodeConstants
*
* @author
*/
public interface SmsCodeMapping extends Function<String, ErrorCode> {
}

View File

@ -1,8 +1,10 @@
package cn.iocoder.dashboard.framework.sms.core.client;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.dashboard.common.exception.ErrorCode;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@ -40,20 +42,27 @@ public class SmsCommonResult<T> extends CommonResult<T> {
private SmsCommonResult() {
}
public static SmsCommonResult success(SmsSendFailureTypeEnum sendFailureType,
String apiSendCode, String apiSendMsg, String apiRequestId, String apiSerialNo) {
SmsCommonResult result = new SmsCommonResult().setSuccess(true).setApiSendCode(apiSendCode).setApiSendMsg(apiSendMsg)
.setApiRequestId(apiRequestId).setApiSerialNo(apiSerialNo);
if (sendFailureType != null) {
result.setSendFailureType(sendFailureType.getType()).setSendFailureMsg(sendFailureType.getMsg());
public static <T> SmsCommonResult<T> build(String apiCode, String apiMsg, String apiRequestId,
T data, SmsCodeMapping codeMapping) {
Assert.notNull(codeMapping, "参数 codeMapping 不能为空");
SmsCommonResult<T> result = new SmsCommonResult<T>().setApiCode(apiCode).setApiMsg(apiMsg).setApiRequestId(apiRequestId);
result.setData(data);
// 翻译错误码
if (codeMapping != null) {
ErrorCode errorCode = codeMapping.apply(apiCode);
if (errorCode == null) {
errorCode = SmsFrameworkErrorCodeConstants.SMS_UNKNOWN;
}
result.setCode(errorCode.getCode()).setMsg(errorCode.getMsg());
}
return result;
}
public static SmsCommonResult error(Throwable ex) {
return new SmsCommonResult().setSuccess(false)
.setSendFailureType(SmsSendFailureTypeEnum.SMS_SEND_EXCEPTION.getType())
.setSendFailureMsg(ExceptionUtil.getRootCauseMessage(ex));
public static <T> SmsCommonResult<T> error(Throwable ex) {
SmsCommonResult<T> result = new SmsCommonResult<>();
result.setCode(SmsFrameworkErrorCodeConstants.EXCEPTION.getCode());
result.setMsg(ExceptionUtil.getRootCauseMessage(ex));
return result;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.dashboard.framework.sms.core;
package cn.iocoder.dashboard.framework.sms.core.client.dto;
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
import lombok.Data;

View File

@ -1,10 +1,13 @@
package cn.iocoder.dashboard.framework.sms.core.client.dto;
import lombok.Data;
/**
* DTO
*
* @author
*/
@Data
public class SmsSendRespDTO {
/**

View File

@ -1,5 +1,6 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl;
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.SmsClient;
import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsSendRespDTO;
@ -21,14 +22,19 @@ public abstract class AbstractSmsClient implements SmsClient {
*
*/
protected volatile SmsChannelProperties properties;
/**
*
*/
protected final SmsCodeMapping codeMapping;
/**
*
*
* @param properties
*/
public AbstractSmsClient(SmsChannelProperties properties) {
public AbstractSmsClient(SmsChannelProperties properties, SmsCodeMapping codeMapping) {
this.properties = properties;
this.codeMapping = codeMapping;
}
/**

View File

@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.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.impl.AbstractSmsClient;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
import cn.iocoder.dashboard.util.json.JsonUtils;
@ -48,7 +48,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
private volatile IAcsClient acsClient;
public AliyunSmsClient(SmsChannelProperties properties) {
super(properties);
super(properties, new AliyunSmsCodeMapping());
}
@Override
@ -59,7 +59,8 @@ public class AliyunSmsClient extends AbstractSmsClient {
}
@Override
protected SmsCommonResult doSend(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams) throws Exception {
protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile,
String apiTemplateId, Map<String, Object> templateParams) throws Throwable {
// 构建参数
SendSmsRequest request = new SendSmsRequest();
request.setSysMethod(MethodType.POST);
@ -73,25 +74,16 @@ public class AliyunSmsClient extends AbstractSmsClient {
// 执行发送
SendSmsResponse sendResult = acsClient.getAcsResponse(request);
// 解析结果
return SmsCommonResult.success(parseSendFailureType(sendResult.getCode()), // 将 API 短信平台,解析成统一的错误码
sendResult.getCode(), sendResult.getMessage(), sendResult.getRequestId(), sendResult.getBizId());
SmsSendRespDTO data = null;
if (sendResult.getBizId() != null) {
data = new SmsSendRespDTO().setSerialNo(sendResult.getBizId());
}
return SmsCommonResult.build(sendResult.getCode(), sendResult.getMessage(), sendResult.getRequestId(), data, codeMapping);
} catch (ClientException ex) {
return SmsCommonResult.success(parseSendFailureType(ex.getErrCode()), // 将 API 短信平台,解析成统一的错误码
ex.getErrCode(), formatResultMsg(ex), ex.getRequestId(), null);
return SmsCommonResult.build(ex.getErrCode(), formatResultMsg(ex), ex.getRequestId(), null, codeMapping);
}
}
private static SmsSendFailureTypeEnum parseSendFailureType(String code) {
switch (code) {
case "OK": return null;
case "MissingAccessKeyId": return SmsSendFailureTypeEnum.SMS_CHANNEL_API_KEY_MISSING;
case "isp.RAM_PERMISSION_DENY": return SmsSendFailureTypeEnum.SMS_CHANNEL_PERMISSION_DENY;
case "isv.INVALID_PARAMETERS": return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR;
case "isv.BUSINESS_LIMIT_CONTROL": return SmsSendFailureTypeEnum.SMS_SEND_LIMIT_CONTROL;
}
return SmsSendFailureTypeEnum.SMS_UNKNOWN;
}
private static String formatResultMsg(ClientException ex) {
if (StrUtil.isEmpty(ex.getErrorDescription())) {
return ex.getMessage();

View File

@ -0,0 +1,27 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.aliyun;
import cn.iocoder.dashboard.common.exception.ErrorCode;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping;
import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.*;
/**
* SmsCodeMapping
*
* @author
*/
public class AliyunSmsCodeMapping implements SmsCodeMapping {
@Override
public ErrorCode apply(String apiCode) {
switch (apiCode) {
case "OK": return null;
case "MissingAccessKeyId": return SMS_CHANNEL_API_KEY_MISSING;
case "isp.RAM_PERMISSION_DENY": return SMS_CHANNEL_PERMISSION_DENY;
case "isv.INVALID_PARAMETERS": return SMS_API_PARAM_ERROR;
case "isv.BUSINESS_LIMIT_CONTROL": return SMS_SEND_LIMIT_CONTROL;
}
return SMS_UNKNOWN;
}
}

View File

@ -6,11 +6,11 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.iocoder.dashboard.framework.sms.core.SmsConstants;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
import cn.iocoder.dashboard.framework.sms.core.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.impl.AbstractSmsClient;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsConstants;
import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperties;
import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
import cn.iocoder.dashboard.util.json.JsonUtils;
@ -29,8 +29,6 @@ import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import static com.yunpian.sdk.constant.Code.*;
/**
*
*
@ -49,7 +47,7 @@ public class YunpianSmsClient extends AbstractSmsClient {
};
public YunpianSmsClient(SmsChannelProperties properties) {
super(properties);
super(properties, new YunpianSmsCodeMapping());
}
@Override
@ -66,7 +64,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
}
@Override
protected SmsCommonResult doSend(Long sendLogId, String mobile, String apiTemplateId, Map<String, Object> templateParams) throws Throwable {
protected SmsCommonResult<SmsSendRespDTO> doSend(Long sendLogId, String mobile,
String apiTemplateId, Map<String, Object> templateParams) throws Throwable {
// 构建参数
Map<String, String> request = new HashMap<>();
request.put(YunpianConstant.APIKEY, properties.getApiKey());
@ -82,8 +81,12 @@ public class YunpianSmsClient extends AbstractSmsClient {
throw sendResult.getThrowable();
}
// 解析结果
return SmsCommonResult.success(parseSendFailureType(sendResult), // 将 API 短信平台,解析成统一的错误码
String.valueOf(sendResult.getCode()), formatResultMsg(sendResult), null, getApiSerialNo(sendResult));
SmsSendRespDTO data = null;
if (sendResult.getData() != null) {
data = new SmsSendRespDTO().setSerialNo(String.valueOf(sendResult.getData().getSid()));
}
return SmsCommonResult.build(String.valueOf(sendResult.getCode()), formatResultMsg(sendResult), null,
data, codeMapping);
}
private static String formatTplValue(Map<String, Object> templateParams) {
@ -103,25 +106,6 @@ public class YunpianSmsClient extends AbstractSmsClient {
return sendResult.getMsg() + " => " + sendResult.getDetail();
}
private static SmsSendFailureTypeEnum parseSendFailureType(Result<SmsSingleSend> sendResult) {
Integer code = sendResult.getCode();
switch (code) {
case OK: return null;
case ARGUMENT_MISSING: return SmsSendFailureTypeEnum.SMS_API_PARAM_ERROR;
case BAD_ARGUMENT_FORMAT: return SmsSendFailureTypeEnum.SMS_TEMPLATE_PARAM_ERROR;
case TPL_NOT_FOUND: return SmsSendFailureTypeEnum.SMS_TEMPLATE_NOT_EXISTS;
case TPL_NOT_VALID: return SmsSendFailureTypeEnum.SMS_TEMPLATE_INVALID;
}
return SmsSendFailureTypeEnum.SMS_UNKNOWN;
}
private static String getApiSerialNo(Result<SmsSingleSend> sendResult) {
if (sendResult.getData() == null) {
return null;
}
return String.valueOf(sendResult.getData().getSid());
}
/**
*
*/

View File

@ -0,0 +1,30 @@
package cn.iocoder.dashboard.framework.sms.core.client.impl.yunpian;
import cn.iocoder.dashboard.common.exception.ErrorCode;
import cn.iocoder.dashboard.framework.sms.core.client.SmsCodeMapping;
import static cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants.SUCCESS;
import static cn.iocoder.dashboard.framework.sms.core.enums.SmsFrameworkErrorCodeConstants.*;
import static com.yunpian.sdk.constant.Code.*;
/**
* SmsCodeMapping
*
* @author
*/
public class YunpianSmsCodeMapping implements SmsCodeMapping {
@Override
public ErrorCode apply(String apiCode) {
int code = Integer.parseInt(apiCode);
switch (code) {
case OK: return SUCCESS;
case ARGUMENT_MISSING: return SMS_API_PARAM_ERROR;
case BAD_ARGUMENT_FORMAT: return SMS_TEMPLATE_PARAM_ERROR;
case TPL_NOT_FOUND: return SMS_TEMPLATE_NOT_EXISTS;
case TPL_NOT_VALID: return SMS_TEMPLATE_INVALID;
}
return SMS_UNKNOWN;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.dashboard.framework.sms.core;
package cn.iocoder.dashboard.framework.sms.core.enums;
/**
*

View File

@ -0,0 +1,32 @@
package cn.iocoder.dashboard.framework.sms.core.enums;
import cn.iocoder.dashboard.common.exception.ErrorCode;
/**
*
*
* 使 2-001-000-000
*
* @author
*/
public interface SmsFrameworkErrorCodeConstants {
// ========== 渠道相关 2001000100 ==========
ErrorCode SMS_CHANNEL_CLIENT_NOT_EXISTS = new ErrorCode(2001000100, "短信渠道的客户端不存在");
ErrorCode SMS_CHANNEL_API_KEY_MISSING = new ErrorCode(2001000101, "API Key 不存在");
ErrorCode SMS_CHANNEL_PERMISSION_DENY = new ErrorCode(2001000102, "没有发送短信的权限");
// ========== 模板相关(200 开头) ==========
ErrorCode SMS_TEMPLATE_NOT_EXISTS = new ErrorCode(200, "短信模板不存在");
ErrorCode SMS_TEMPLATE_DISABLE = new ErrorCode(201, "短信模板被禁用"); // 例如说,我们在管理后台禁用了
ErrorCode SMS_TEMPLATE_INVALID = new ErrorCode(202, "短信模板不可用"); // 例如说,短信模板正在审核中
ErrorCode SMS_TEMPLATE_PARAM_ERROR = new ErrorCode(203, "模板参数不正确");
// ========== 其它相关(900 开头) ==========
ErrorCode SMS_API_PARAM_ERROR = new ErrorCode(900, "请求参数缺失");
ErrorCode SMS_SEND_LIMIT_CONTROL = new ErrorCode(997, "业务限流"); // 将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟5 条 / 小时,累计 10 条 / 天。
ErrorCode EXCEPTION = new ErrorCode(998, "调用异常");
ErrorCode SMS_UNKNOWN = new ErrorCode(999, "未知错误,需要解析");
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.dashboard.framework.sms.core.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author
*/
@Getter
@AllArgsConstructor
public enum SmsSendFailureTypeEnum {
// ========== 渠道相关(100 开头) ==========
SMS_CHANNEL_CLIENT_NOT_EXISTS(100, "短信渠道的客户端不存在"),
SMS_CHANNEL_API_KEY_MISSING(101, "API Key 不存在"),
SMS_CHANNEL_PERMISSION_DENY(102, "没有发送短信的权限"),
// ========== 模板相关(200 开头) ==========
SMS_TEMPLATE_NOT_EXISTS(200, "短信模板不存在"),
SMS_TEMPLATE_DISABLE(201, "短信模板被禁用"), // 例如说,我们在管理后台禁用了
SMS_TEMPLATE_INVALID(202, "短信模板不可用"), // 例如说,短信模板正在审核中
SMS_TEMPLATE_PARAM_ERROR(203, "模板参数不正确"),
// ========== 其它相关(900 开头) ==========
SMS_API_PARAM_ERROR(900, "请求参数缺失"),
SMS_SEND_LIMIT_CONTROL(997, "业务限流"), // 将短信发送频率限制在正常的业务限流范围内。默认短信验证码:使用同一签名,对同一个手机号验证码,支持 1 条 / 分钟5 条 / 小时,累计 10 条 / 天。
SMS_SEND_EXCEPTION(998, "发送异常"),
SMS_UNKNOWN(999, "未知错误,需要解析")
;
/**
*
*/
private final int type;
/**
*
*/
private final String msg;
}

View File

@ -3,7 +3,6 @@ package cn.iocoder.dashboard.framework.web.core.handler;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.iocoder.dashboard.common.exception.GlobalException;
import cn.iocoder.dashboard.common.exception.ServiceException;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.logger.apilog.core.service.ApiErrorLogFrameworkService;
@ -96,9 +95,6 @@ public class GlobalExceptionHandler {
if (ex instanceof AccessDeniedException) {
return accessDeniedExceptionHandler(request, (AccessDeniedException) ex);
}
if (ex instanceof GlobalException) {
return globalExceptionHandler(request, (GlobalException) ex);
}
return defaultExceptionHandler(request, ex);
}
@ -222,25 +218,6 @@ public class GlobalExceptionHandler {
return CommonResult.error(ex.getCode(), ex.getMessage());
}
/**
* ServiceException
*
* Dubbo Dubbo
*/
@ExceptionHandler(value = GlobalException.class)
public CommonResult<?> globalExceptionHandler(HttpServletRequest req, GlobalException ex) {
// 系统异常时,才打印异常日志
if (INTERNAL_SERVER_ERROR.getCode().equals(ex.getCode())) {
// 插入异常日志
this.createExceptionLog(req, ex);
// 普通全局异常,打印 info 日志即可
} else {
log.info("[globalExceptionHandler]", ex);
}
// 返回 ERROR CommonResult
return CommonResult.error(ex);
}
/**
*
*/
@ -250,7 +227,7 @@ public class GlobalExceptionHandler {
// 插入异常日志
this.createExceptionLog(req, ex);
// 返回 ERROR CommonResult
return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMessage());
return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), INTERNAL_SERVER_ERROR.getMsg());
}
private void createExceptionLog(HttpServletRequest req, Throwable e) {

View File

@ -1,6 +1,5 @@
package cn.iocoder.dashboard.modules.system.service.sms;
import cn.iocoder.dashboard.framework.sms.core.enums.SmsSendFailureTypeEnum;
import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
import java.util.Map;

View File

@ -358,7 +358,7 @@ public class SysUserServiceImpl implements SysUserService {
}
// 如果存在,判断是否允许更新
if (!isUpdateSupport) {
respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMessage());
respVO.getFailureUsernames().put(importUser.getUsername(), USER_USERNAME_EXISTS.getMsg());
return;
}
SysUserDO updateUser = SysUserConvert.INSTANCE.convert(importUser);

View File

@ -62,7 +62,7 @@ public class AssertUtils {
ServiceException serviceException = assertThrows(ServiceException.class, executable);
// 校验错误码
Assertions.assertEquals(errorCode.getCode(), serviceException.getCode(), "错误码不匹配");
String message = ServiceExceptionUtil.doFormat(errorCode.getCode(), errorCode.getMessage(), messageParams);
String message = ServiceExceptionUtil.doFormat(errorCode.getCode(), errorCode.getMsg(), messageParams);
Assertions.assertEquals(message, serviceException.getMessage(), "错误提示不匹配");
}