refactor(platform):重构平台模块包结构- 将 shared 包下的文件移动到 platform 包下
- 更新相关类的包引用路径 - 修改 application.yml 中的包扫描路径 -重命名 CaptchaInfo 类为 CaptchaVO 并调整包路径 - 移动 BusinessException 和相关安全类到 core 包- 更新 Codegen 相关类包路径 - 删除无用的条件判断代码块
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
package com.youlai.boot.auth.enums;
|
||||
|
||||
/**
|
||||
* EasyCaptcha 验证码类型枚举
|
||||
*
|
||||
* @author haoxr
|
||||
* @since 2.5.1
|
||||
*/
|
||||
public enum CaptchaTypeEnum {
|
||||
|
||||
/**
|
||||
* 圆圈干扰验证码
|
||||
*/
|
||||
CIRCLE,
|
||||
/**
|
||||
* GIF验证码
|
||||
*/
|
||||
GIF,
|
||||
/**
|
||||
* 干扰线验证码
|
||||
*/
|
||||
LINE,
|
||||
/**
|
||||
* 扭曲干扰验证码
|
||||
*/
|
||||
SHEAR
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.youlai.boot.common.exception;
|
||||
|
||||
import com.youlai.boot.common.result.IResultCode;
|
||||
import lombok.Getter;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
/**
|
||||
* 自定义业务异常
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2022/7/31
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
public IResultCode resultCode;
|
||||
|
||||
public BusinessException(IResultCode errorCode) {
|
||||
super(errorCode.getMsg());
|
||||
this.resultCode = errorCode;
|
||||
}
|
||||
|
||||
|
||||
public BusinessException(IResultCode errorCode,String message) {
|
||||
super(message);
|
||||
this.resultCode = errorCode;
|
||||
}
|
||||
|
||||
|
||||
public BusinessException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public BusinessException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public BusinessException(String message, Object... args) {
|
||||
super(formatMessage(message, args));
|
||||
}
|
||||
|
||||
private static String formatMessage(String message, Object... args) {
|
||||
return MessageFormatter.arrayFormat(message, args).getMessage();
|
||||
}
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
package com.youlai.boot.common.exception;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.youlai.boot.common.result.Result;
|
||||
import com.youlai.boot.common.result.ResultCode;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import java.sql.SQLIntegrityConstraintViolationException;
|
||||
import java.sql.SQLSyntaxErrorException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 全局系统异常处理器
|
||||
* <p>
|
||||
* 调整异常处理的HTTP状态码,丰富异常处理类型
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
/**
|
||||
* 处理绑定异常
|
||||
* <p>
|
||||
* 当请求参数绑定到对象时发生错误,会抛出 BindException 异常。
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(BindException e) {
|
||||
log.error("BindException:{}", e.getMessage());
|
||||
String msg = e.getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
|
||||
return Result.failed(ResultCode.USER_REQUEST_PARAMETER_ERROR, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 @RequestParam 参数校验异常
|
||||
* <p>
|
||||
* 当请求参数在校验过程中发生违反约束条件的异常时(如 @RequestParam 验证不通过),
|
||||
* 会捕获到 ConstraintViolationException 异常。
|
||||
*/
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(ConstraintViolationException e) {
|
||||
log.error("ConstraintViolationException:{}", e.getMessage());
|
||||
String msg = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
|
||||
return Result.failed(ResultCode.INVALID_USER_INPUT, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理方法参数校验异常
|
||||
* <p>
|
||||
* 当使用 @Valid 或 @Validated 注解对方法参数进行验证时,如果验证失败,
|
||||
* 会抛出 MethodArgumentNotValidException 异常。
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(MethodArgumentNotValidException e) {
|
||||
log.error("MethodArgumentNotValidException:{}", e.getMessage());
|
||||
String msg = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
|
||||
return Result.failed(ResultCode.INVALID_USER_INPUT, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理接口不存在的异常
|
||||
* <p>
|
||||
* 当客户端请求一个不存在的路径时,会抛出 NoHandlerFoundException 异常。
|
||||
*/
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
public <T> Result<T> processException(NoHandlerFoundException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(ResultCode.INTERFACE_NOT_EXIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理缺少请求参数的异常
|
||||
* <p>
|
||||
* 当请求缺少必需的参数时,会抛出 MissingServletRequestParameterException 异常。
|
||||
*/
|
||||
@ExceptionHandler(MissingServletRequestParameterException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(MissingServletRequestParameterException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(ResultCode.REQUEST_REQUIRED_PARAMETER_IS_EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理方法参数类型不匹配的异常
|
||||
* <p>
|
||||
* 当请求参数类型不匹配时,会抛出 MethodArgumentTypeMismatchException 异常。
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(MethodArgumentTypeMismatchException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(ResultCode.PARAMETER_FORMAT_MISMATCH, "类型错误");
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 Servlet 异常
|
||||
* <p>
|
||||
* 当 Servlet 处理请求时发生异常时,会抛出 ServletException 异常。
|
||||
*/
|
||||
@ExceptionHandler(ServletException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(ServletException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理非法参数异常
|
||||
* <p>
|
||||
* 当方法接收到非法参数时,会抛出 IllegalArgumentException 异常。
|
||||
*/
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> handleIllegalArgumentException(IllegalArgumentException e) {
|
||||
log.error("非法参数异常,异常原因:{}", e.getMessage(), e);
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 JSON 处理异常
|
||||
* <p>
|
||||
* 当处理 JSON 数据时发生错误,会抛出 JsonProcessingException 异常。
|
||||
*/
|
||||
@ExceptionHandler(JsonProcessingException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> handleJsonProcessingException(JsonProcessingException e) {
|
||||
log.error("Json转换异常,异常原因:{}", e.getMessage(), e);
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求体不可读的异常
|
||||
* <p>
|
||||
* 当请求体不可读时,会抛出 HttpMessageNotReadableException 异常。
|
||||
*/
|
||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(HttpMessageNotReadableException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String errorMessage = "请求体不可为空";
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null) {
|
||||
errorMessage = convertMessage(cause);
|
||||
}
|
||||
return Result.failed(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理类型不匹配异常
|
||||
* <p>
|
||||
* 当方法参数类型不匹配时,会抛出 TypeMismatchException 异常。
|
||||
*/
|
||||
@ExceptionHandler(TypeMismatchException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> processException(TypeMismatchException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 SQL 语法错误异常
|
||||
* <p>
|
||||
* 当 SQL 语法错误时,会抛出 BadSqlGrammarException 异常。
|
||||
*/
|
||||
@ExceptionHandler(BadSqlGrammarException.class)
|
||||
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||
public <T> Result<T> handleBadSqlGrammarException(BadSqlGrammarException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
String errorMsg = e.getMessage();
|
||||
if (StrUtil.isNotBlank(errorMsg) && errorMsg.contains("denied to user")) {
|
||||
return Result.failed(ResultCode.DATABASE_ACCESS_DENIED);
|
||||
} else {
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 SQL 语法错误异常
|
||||
* <p>
|
||||
* 当 SQL 语法错误时,会抛出 SQLSyntaxErrorException 异常。
|
||||
*/
|
||||
@ExceptionHandler(SQLSyntaxErrorException.class)
|
||||
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||
public <T> Result<T> processSQLSyntaxErrorException(SQLSyntaxErrorException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(ResultCode.DATABASE_EXECUTION_SYNTAX_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理 SQL 违反了完整性约束
|
||||
* <p>
|
||||
* 当 SQL 违反了完整性约束时,会抛出 SQLIntegrityConstraintViolationException 异常。
|
||||
*/
|
||||
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
|
||||
@ResponseStatus(HttpStatus.FORBIDDEN)
|
||||
public <T> Result<T> handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.failed(ResultCode.INTEGRITY_CONSTRAINT_VIOLATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理业务异常
|
||||
* <p>
|
||||
* 当业务逻辑发生错误时,会抛出 BusinessException 异常。
|
||||
*/
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> handleBizException(BusinessException e) {
|
||||
log.error("biz exception", e);
|
||||
if (e.getResultCode() != null) {
|
||||
return Result.failed(e.getResultCode(), e.getMessage());
|
||||
}
|
||||
return Result.failed(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理所有未捕获的异常
|
||||
* <p>
|
||||
* 当发生未捕获的异常时,会抛出 Exception 异常。
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public <T> Result<T> handleException(Exception e) throws Exception {
|
||||
// 将 Spring Security 异常继续抛出,以便交给自定义处理器处理
|
||||
if (e instanceof AccessDeniedException
|
||||
|| e instanceof AuthenticationException) {
|
||||
throw e;
|
||||
}
|
||||
log.error("unknown exception", e);
|
||||
return Result.failed(e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 传参类型错误时,用于消息转换
|
||||
*
|
||||
* @param throwable 异常
|
||||
* @return 错误信息
|
||||
*/
|
||||
private String convertMessage(Throwable throwable) {
|
||||
String error = throwable.toString();
|
||||
String regulation = "\\[\"(.*?)\"]+";
|
||||
Pattern pattern = Pattern.compile(regulation);
|
||||
Matcher matcher = pattern.matcher(error);
|
||||
String group = "";
|
||||
if (matcher.find()) {
|
||||
String matchString = matcher.group();
|
||||
matchString = matchString.replace("[", "").replace("]", "");
|
||||
matchString = "%s字段类型错误".formatted(matchString.replaceAll("\"", ""));
|
||||
group += matchString;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package com.youlai.boot.common.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Excel导出响应结构体
|
||||
*
|
||||
* @author Theo
|
||||
* @since 2025/1/14 11:46:08
|
||||
*/
|
||||
@Data
|
||||
public class ExcelResult {
|
||||
|
||||
/**
|
||||
* 响应码,来确定是否导入成功
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 有效条数
|
||||
*/
|
||||
private Integer validCount;
|
||||
|
||||
/**
|
||||
* 无效条数
|
||||
*/
|
||||
private Integer invalidCount;
|
||||
|
||||
/**
|
||||
* 错误提示信息
|
||||
*/
|
||||
private List<String> messageList;
|
||||
|
||||
public ExcelResult() {
|
||||
this.code = ResultCode.SUCCESS.getCode();
|
||||
this.validCount = 0;
|
||||
this.invalidCount = 0;
|
||||
this.messageList = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.youlai.boot.common.result;
|
||||
|
||||
/**
|
||||
* 响应码接口
|
||||
*
|
||||
* @author Ray.Hao
|
||||
* @since 1.0.0
|
||||
**/
|
||||
public interface IResultCode {
|
||||
|
||||
String getCode();
|
||||
|
||||
String getMsg();
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package com.youlai.boot.common.result;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页响应结构体
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2022/2/18
|
||||
*/
|
||||
@Data
|
||||
public class PageResult<T> implements Serializable {
|
||||
|
||||
private String code;
|
||||
|
||||
private Data<T> data;
|
||||
|
||||
private String msg;
|
||||
|
||||
public static <T> PageResult<T> success(IPage<T> page) {
|
||||
PageResult<T> result = new PageResult<>();
|
||||
result.setCode(ResultCode.SUCCESS.getCode());
|
||||
|
||||
Data<T> data = new Data<>();
|
||||
data.setList(page.getRecords());
|
||||
data.setTotal(page.getTotal());
|
||||
|
||||
result.setData(data);
|
||||
result.setMsg(ResultCode.SUCCESS.getMsg());
|
||||
return result;
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
public static class Data<T> {
|
||||
|
||||
private List<T> list;
|
||||
|
||||
private long total;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package com.youlai.boot.common.result;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 统一响应结构体
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2022/1/30
|
||||
**/
|
||||
@Data
|
||||
public class Result<T> implements Serializable {
|
||||
|
||||
private String code;
|
||||
|
||||
private T data;
|
||||
|
||||
private String msg;
|
||||
|
||||
public static <T> Result<T> success() {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> success(T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(ResultCode.SUCCESS.getCode());
|
||||
result.setMsg(ResultCode.SUCCESS.getMsg());
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> Result<T> failed() {
|
||||
return result(ResultCode.SYSTEM_ERROR.getCode(), ResultCode.SYSTEM_ERROR.getMsg(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> failed(String msg) {
|
||||
return result(ResultCode.SYSTEM_ERROR.getCode(), msg, null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> judge(boolean status) {
|
||||
if (status) {
|
||||
return success();
|
||||
} else {
|
||||
return failed();
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Result<T> failed(IResultCode resultCode) {
|
||||
return result(resultCode.getCode(), resultCode.getMsg(), null);
|
||||
}
|
||||
|
||||
public static <T> Result<T> failed(IResultCode resultCode, String msg) {
|
||||
return result(resultCode.getCode(), StrUtil.isNotBlank(msg) ? msg : resultCode.getMsg(), null);
|
||||
}
|
||||
|
||||
private static <T> Result<T> result(IResultCode resultCode, T data) {
|
||||
return result(resultCode.getCode(), resultCode.getMsg(), data);
|
||||
}
|
||||
|
||||
private static <T> Result<T> result(String code, String msg, T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setCode(code);
|
||||
result.setData(data);
|
||||
result.setMsg(msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isSuccess(Result<?> result) {
|
||||
return result != null && ResultCode.SUCCESS.getCode().equals(result.getCode());
|
||||
}
|
||||
}
|
||||
@@ -1,300 +0,0 @@
|
||||
package com.youlai.boot.common.result;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 响应码枚举
|
||||
* <p>
|
||||
* 参考阿里巴巴开发手册响应码规范
|
||||
* 00000 正常
|
||||
* A**** 用户端错误
|
||||
* B**** 系统执行出错
|
||||
* C**** 调用第三方服务出错
|
||||
*
|
||||
* @author Ray.Hao
|
||||
* @since 2020/6/23
|
||||
**/
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public enum ResultCode implements IResultCode, Serializable {
|
||||
|
||||
SUCCESS("00000", "一切ok"),
|
||||
|
||||
/** 一级宏观错误码 */
|
||||
USER_ERROR("A0001", "用户端错误"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_REGISTRATION_ERROR("A0100", "用户注册错误"),
|
||||
USER_NOT_AGREE_PRIVACY_AGREEMENT("A0101", "用户未同意隐私协议"),
|
||||
REGISTRATION_COUNTRY_OR_REGION_RESTRICTED("A0102", "注册国家或地区受限"),
|
||||
|
||||
USERNAME_VERIFICATION_FAILED("A0110", "用户名校验失败"),
|
||||
USERNAME_ALREADY_EXISTS("A0111", "用户名已存在"),
|
||||
USERNAME_CONTAINS_SENSITIVE_WORDS("A0112", "用户名包含敏感词"),
|
||||
USERNAME_CONTAINS_SPECIAL_CHARACTERS("A0113", "用户名包含特殊字符"),
|
||||
|
||||
PASSWORD_VERIFICATION_FAILED("A0120", "密码校验失败"),
|
||||
PASSWORD_LENGTH_NOT_ENOUGH("A0121", "密码长度不够"),
|
||||
PASSWORD_STRENGTH_NOT_ENOUGH("A0122", "密码强度不够"),
|
||||
|
||||
VERIFICATION_CODE_INPUT_ERROR("A0130", "校验码输入错误"),
|
||||
SMS_VERIFICATION_CODE_INPUT_ERROR("A0131", "短信校验码输入错误"),
|
||||
EMAIL_VERIFICATION_CODE_INPUT_ERROR("A0132", "邮件校验码输入错误"),
|
||||
VOICE_VERIFICATION_CODE_INPUT_ERROR("A0133", "语音校验码输入错误"),
|
||||
|
||||
USER_CERTIFICATE_EXCEPTION("A0140", "用户证件异常"),
|
||||
USER_CERTIFICATE_TYPE_NOT_SELECTED("A0141", "用户证件类型未选择"),
|
||||
MAINLAND_ID_NUMBER_VERIFICATION_ILLEGAL("A0142", "大陆身份证编号校验非法"),
|
||||
|
||||
USER_BASIC_INFORMATION_VERIFICATION_FAILED("A0150", "用户基本信息校验失败"),
|
||||
PHONE_FORMAT_VERIFICATION_FAILED("A0151", "手机格式校验失败"),
|
||||
ADDRESS_FORMAT_VERIFICATION_FAILED("A0152", "地址格式校验失败"),
|
||||
EMAIL_FORMAT_VERIFICATION_FAILED("A0153", "邮箱格式校验失败"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_LOGIN_EXCEPTION("A0200", "用户登录异常"),
|
||||
USER_ACCOUNT_FROZEN("A0201", "用户账户被冻结"),
|
||||
USER_ACCOUNT_ABOLISHED("A0202", "用户账户已作废"),
|
||||
|
||||
USER_PASSWORD_ERROR("A0210", "用户名或密码错误"),
|
||||
USER_INPUT_PASSWORD_ERROR_LIMIT_EXCEEDED("A0211", "用户输入密码错误次数超限"),
|
||||
USER_NOT_EXIST("A0212", "用户不存在"),
|
||||
|
||||
USER_IDENTITY_VERIFICATION_FAILED("A0220", "用户身份校验失败"),
|
||||
USER_FINGERPRINT_RECOGNITION_FAILED("A0221", "用户指纹识别失败"),
|
||||
USER_FACE_RECOGNITION_FAILED("A0222", "用户面容识别失败"),
|
||||
USER_NOT_AUTHORIZED_THIRD_PARTY_LOGIN("A0223", "用户未获得第三方登录授权"),
|
||||
|
||||
ACCESS_TOKEN_INVALID("A0230", "访问令牌无效或已过期"),
|
||||
REFRESH_TOKEN_INVALID("A0231", "刷新令牌无效或已过期"),
|
||||
|
||||
// 验证码错误
|
||||
USER_VERIFICATION_CODE_ERROR("A0240", "验证码错误"),
|
||||
USER_VERIFICATION_CODE_ATTEMPT_LIMIT_EXCEEDED("A0241", "用户验证码尝试次数超限"),
|
||||
USER_VERIFICATION_CODE_EXPIRED("A0242", "用户验证码过期"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
ACCESS_PERMISSION_EXCEPTION("A0300", "访问权限异常"),
|
||||
ACCESS_UNAUTHORIZED("A0301", "访问未授权"),
|
||||
AUTHORIZATION_IN_PROGRESS("A0302", "正在授权中"),
|
||||
USER_AUTHORIZATION_APPLICATION_REJECTED("A0303", "用户授权申请被拒绝"),
|
||||
|
||||
ACCESS_OBJECT_PRIVACY_SETTINGS_BLOCKED("A0310", "因访问对象隐私设置被拦截"),
|
||||
AUTHORIZATION_EXPIRED("A0311", "授权已过期"),
|
||||
NO_PERMISSION_TO_USE_API("A0312", "无权限使用 API"),
|
||||
|
||||
USER_ACCESS_BLOCKED("A0320", "用户访问被拦截"),
|
||||
BLACKLISTED_USER("A0321", "黑名单用户"),
|
||||
ACCOUNT_FROZEN("A0322", "账号被冻结"),
|
||||
ILLEGAL_IP_ADDRESS("A0323", "非法 IP 地址"),
|
||||
GATEWAY_ACCESS_RESTRICTED("A0324", "网关访问受限"),
|
||||
REGION_BLACKLIST("A0325", "地域黑名单"),
|
||||
|
||||
SERVICE_ARREARS("A0330", "服务已欠费"),
|
||||
|
||||
USER_SIGNATURE_EXCEPTION("A0340", "用户签名异常"),
|
||||
RSA_SIGNATURE_ERROR("A0341", "RSA 签名错误"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_REQUEST_PARAMETER_ERROR("A0400", "用户请求参数错误"),
|
||||
CONTAINS_ILLEGAL_MALICIOUS_REDIRECT_LINK("A0401", "包含非法恶意跳转链接"),
|
||||
INVALID_USER_INPUT("A0402", "无效的用户输入"),
|
||||
|
||||
REQUEST_REQUIRED_PARAMETER_IS_EMPTY("A0410", "请求必填参数为空"),
|
||||
|
||||
REQUEST_PARAMETER_VALUE_EXCEEDS_ALLOWED_RANGE("A0420", "请求参数值超出允许的范围"),
|
||||
PARAMETER_FORMAT_MISMATCH("A0421", "参数格式不匹配"),
|
||||
|
||||
USER_INPUT_CONTENT_ILLEGAL("A0430", "用户输入内容非法"),
|
||||
CONTAINS_PROHIBITED_SENSITIVE_WORDS("A0431", "包含违禁敏感词"),
|
||||
|
||||
USER_OPERATION_EXCEPTION("A0440", "用户操作异常"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_REQUEST_SERVICE_EXCEPTION("A0500", "用户请求服务异常"),
|
||||
REQUEST_LIMIT_EXCEEDED("A0501", "请求次数超出限制"),
|
||||
REQUEST_CONCURRENCY_LIMIT_EXCEEDED("A0502", "请求并发数超出限制"),
|
||||
USER_OPERATION_PLEASE_WAIT("A0503", "用户操作请等待"),
|
||||
WEBSOCKET_CONNECTION_EXCEPTION("A0504", "WebSocket 连接异常"),
|
||||
WEBSOCKET_CONNECTION_DISCONNECTED("A0505", "WebSocket 连接断开"),
|
||||
USER_DUPLICATE_REQUEST("A0506", "请求过于频繁,请稍后再试。"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_RESOURCE_EXCEPTION("A0600", "用户资源异常"),
|
||||
ACCOUNT_BALANCE_INSUFFICIENT("A0601", "账户余额不足"),
|
||||
USER_DISK_SPACE_INSUFFICIENT("A0602", "用户磁盘空间不足"),
|
||||
USER_MEMORY_SPACE_INSUFFICIENT("A0603", "用户内存空间不足"),
|
||||
USER_OSS_CAPACITY_INSUFFICIENT("A0604", "用户 OSS 容量不足"),
|
||||
USER_QUOTA_EXHAUSTED("A0605", "用户配额已用光"),
|
||||
USER_RESOURCE_NOT_FOUND("A0606", "用户资源不存在"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
UPLOAD_FILE_EXCEPTION("A0700", "上传文件异常"),
|
||||
UPLOAD_FILE_TYPE_MISMATCH("A0701", "上传文件类型不匹配"),
|
||||
UPLOAD_FILE_TOO_LARGE("A0702", "上传文件太大"),
|
||||
UPLOAD_IMAGE_TOO_LARGE("A0703", "上传图片太大"),
|
||||
UPLOAD_VIDEO_TOO_LARGE("A0704", "上传视频太大"),
|
||||
UPLOAD_COMPRESSED_FILE_TOO_LARGE("A0705", "上传压缩文件太大"),
|
||||
|
||||
DELETE_FILE_EXCEPTION("A0710", "删除文件异常"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_CURRENT_VERSION_EXCEPTION("A0800", "用户当前版本异常"),
|
||||
USER_INSTALLED_VERSION_NOT_MATCH_SYSTEM("A0801", "用户安装版本与系统不匹配"),
|
||||
USER_INSTALLED_VERSION_TOO_LOW("A0802", "用户安装版本过低"),
|
||||
USER_INSTALLED_VERSION_TOO_HIGH("A0803", "用户安装版本过高"),
|
||||
USER_INSTALLED_VERSION_EXPIRED("A0804", "用户安装版本已过期"),
|
||||
USER_API_REQUEST_VERSION_NOT_MATCH("A0805", "用户 API 请求版本不匹配"),
|
||||
USER_API_REQUEST_VERSION_TOO_HIGH("A0806", "用户 API 请求版本过高"),
|
||||
USER_API_REQUEST_VERSION_TOO_LOW("A0807", "用户 API 请求版本过低"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_PRIVACY_NOT_AUTHORIZED("A0900", "用户隐私未授权"),
|
||||
USER_PRIVACY_NOT_SIGNED("A0901", "用户隐私未签署"),
|
||||
USER_CAMERA_NOT_AUTHORIZED("A0903", "用户相机未授权"),
|
||||
USER_PHOTO_LIBRARY_NOT_AUTHORIZED("A0904", "用户图片库未授权"),
|
||||
USER_FILE_NOT_AUTHORIZED("A0905", "用户文件未授权"),
|
||||
USER_LOCATION_INFORMATION_NOT_AUTHORIZED("A0906", "用户位置信息未授权"),
|
||||
USER_CONTACTS_NOT_AUTHORIZED("A0907", "用户通讯录未授权"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
USER_DEVICE_EXCEPTION("A1000", "用户设备异常"),
|
||||
USER_CAMERA_EXCEPTION("A1001", "用户相机异常"),
|
||||
USER_MICROPHONE_EXCEPTION("A1002", "用户麦克风异常"),
|
||||
USER_EARPIECE_EXCEPTION("A1003", "用户听筒异常"),
|
||||
USER_SPEAKER_EXCEPTION("A1004", "用户扬声器异常"),
|
||||
USER_GPS_POSITIONING_EXCEPTION("A1005", "用户 GPS 定位异常"),
|
||||
|
||||
/** 一级宏观错误码 */
|
||||
SYSTEM_ERROR("B0001", "系统执行出错"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
SYSTEM_EXECUTION_TIMEOUT("B0100", "系统执行超时"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
SYSTEM_DISASTER_RECOVERY_FUNCTION_TRIGGERED("B0200", "系统容灾功能被触发"),
|
||||
|
||||
SYSTEM_RATE_LIMITING("B0210", "系统限流"),
|
||||
|
||||
SYSTEM_FUNCTION_DEGRADATION("B0220", "系统功能降级"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
SYSTEM_RESOURCE_EXCEPTION("B0300", "系统资源异常"),
|
||||
SYSTEM_RESOURCE_EXHAUSTED("B0310", "系统资源耗尽"),
|
||||
SYSTEM_DISK_SPACE_EXHAUSTED("B0311", "系统磁盘空间耗尽"),
|
||||
SYSTEM_MEMORY_EXHAUSTED("B0312", "系统内存耗尽"),
|
||||
FILE_HANDLE_EXHAUSTED("B0313", "文件句柄耗尽"),
|
||||
SYSTEM_CONNECTION_POOL_EXHAUSTED("B0314", "系统连接池耗尽"),
|
||||
SYSTEM_THREAD_POOL_EXHAUSTED("B0315", "系统线程池耗尽"),
|
||||
|
||||
SYSTEM_RESOURCE_ACCESS_EXCEPTION("B0320", "系统资源访问异常"),
|
||||
SYSTEM_READ_DISK_FILE_FAILED("B0321", "系统读取磁盘文件失败"),
|
||||
|
||||
|
||||
/** 一级宏观错误码 */
|
||||
THIRD_PARTY_SERVICE_ERROR("C0001", "调用第三方服务出错"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
MIDDLEWARE_SERVICE_ERROR("C0100", "中间件服务出错"),
|
||||
|
||||
RPC_SERVICE_ERROR("C0110", "RPC 服务出错"),
|
||||
RPC_SERVICE_NOT_FOUND("C0111", "RPC 服务未找到"),
|
||||
RPC_SERVICE_NOT_REGISTERED("C0112", "RPC 服务未注册"),
|
||||
INTERFACE_NOT_EXIST("C0113", "接口不存在"),
|
||||
|
||||
MESSAGE_SERVICE_ERROR("C0120", "消息服务出错"),
|
||||
MESSAGE_DELIVERY_ERROR("C0121", "消息投递出错"),
|
||||
MESSAGE_CONSUMPTION_ERROR("C0122", "消息消费出错"),
|
||||
MESSAGE_SUBSCRIPTION_ERROR("C0123", "消息订阅出错"),
|
||||
MESSAGE_GROUP_NOT_FOUND("C0124", "消息分组未查到"),
|
||||
|
||||
CACHE_SERVICE_ERROR("C0130", "缓存服务出错"),
|
||||
KEY_LENGTH_EXCEEDS_LIMIT("C0131", "key 长度超过限制"),
|
||||
VALUE_LENGTH_EXCEEDS_LIMIT("C0132", "value 长度超过限制"),
|
||||
STORAGE_CAPACITY_FULL("C0133", "存储容量已满"),
|
||||
UNSUPPORTED_DATA_FORMAT("C0134", "不支持的数据格式"),
|
||||
|
||||
CONFIGURATION_SERVICE_ERROR("C0140", "配置服务出错"),
|
||||
|
||||
NETWORK_RESOURCE_SERVICE_ERROR("C0150", "网络资源服务出错"),
|
||||
VPN_SERVICE_ERROR("C0151", "VPN 服务出错"),
|
||||
CDN_SERVICE_ERROR("C0152", "CDN 服务出错"),
|
||||
DOMAIN_NAME_RESOLUTION_SERVICE_ERROR("C0153", "域名解析服务出错"),
|
||||
GATEWAY_SERVICE_ERROR("C0154", "网关服务出错"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
THIRD_PARTY_SYSTEM_EXECUTION_TIMEOUT("C0200", "第三方系统执行超时"),
|
||||
|
||||
RPC_EXECUTION_TIMEOUT("C0210", "RPC 执行超时"),
|
||||
|
||||
MESSAGE_DELIVERY_TIMEOUT("C0220", "消息投递超时"),
|
||||
|
||||
CACHE_SERVICE_TIMEOUT("C0230", "缓存服务超时"),
|
||||
|
||||
CONFIGURATION_SERVICE_TIMEOUT("C0240", "配置服务超时"),
|
||||
|
||||
DATABASE_SERVICE_TIMEOUT("C0250", "数据库服务超时"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
DATABASE_SERVICE_ERROR("C0300", "数据库服务出错"),
|
||||
|
||||
TABLE_NOT_EXIST("C0311", "表不存在"),
|
||||
COLUMN_NOT_EXIST("C0312", "列不存在"),
|
||||
DATABASE_EXECUTION_SYNTAX_ERROR("C0313", "数据库执行语法错误"),
|
||||
|
||||
MULTIPLE_SAME_NAME_COLUMNS_IN_MULTI_TABLE_ASSOCIATION("C0321", "多表关联中存在多个相同名称的列"),
|
||||
|
||||
DATABASE_DEADLOCK("C0331", "数据库死锁"),
|
||||
|
||||
PRIMARY_KEY_CONFLICT("C0341", "主键冲突"),
|
||||
INTEGRITY_CONSTRAINT_VIOLATION("C0342", "违反了完整性约束"),
|
||||
|
||||
DATABASE_ACCESS_DENIED("C0351", "演示环境已禁用数据库写入功能,请本地部署修改数据库链接或开启Mock模式进行体验"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
THIRD_PARTY_DISASTER_RECOVERY_SYSTEM_TRIGGERED("C0400", "第三方容灾系统被触发"),
|
||||
THIRD_PARTY_SYSTEM_RATE_LIMITING("C0401", "第三方系统限流"),
|
||||
THIRD_PARTY_FUNCTION_DEGRADATION("C0402", "第三方功能降级"),
|
||||
|
||||
/** 二级宏观错误码 */
|
||||
NOTIFICATION_SERVICE_ERROR("C0500", "通知服务出错"),
|
||||
SMS_REMINDER_SERVICE_FAILED("C0501", "短信提醒服务失败"),
|
||||
VOICE_REMINDER_SERVICE_FAILED("C0502", "语音提醒服务失败"),
|
||||
EMAIL_REMINDER_SERVICE_FAILED("C0503", "邮件提醒服务失败");
|
||||
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
private String code;
|
||||
|
||||
private String msg;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"\"code\":\"" + code + '\"' +
|
||||
", \"msg\":\"" + msg + '\"' +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
public static ResultCode getValue(String code) {
|
||||
for (ResultCode value : values()) {
|
||||
if (value.getCode().equals(code)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return SYSTEM_ERROR; // 默认系统执行错误
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package com.youlai.boot.common.util;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.youlai.boot.common.result.Result;
|
||||
import com.youlai.boot.common.result.ResultCode;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* 响应工具类
|
||||
*
|
||||
* @author Ray.Hao
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class ResponseUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 异常消息返回(适用过滤器中处理异常响应)
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param resultCode 响应结果码
|
||||
*/
|
||||
public static void writeErrMsg(HttpServletResponse response, ResultCode resultCode) {
|
||||
int status = getHttpStatus(resultCode);
|
||||
|
||||
response.setStatus(status);
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
|
||||
try (PrintWriter writer = response.getWriter()) {
|
||||
String jsonResponse = JSONUtil.toJsonStr(Result.failed(resultCode));
|
||||
writer.print(jsonResponse);
|
||||
writer.flush(); // 确保将响应内容写入到输出流
|
||||
} catch (IOException e) {
|
||||
log.error("响应异常处理失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常消息返回(适用过滤器中处理异常响应)
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param resultCode 响应结果码
|
||||
*/
|
||||
public static void writeErrMsg(HttpServletResponse response, ResultCode resultCode, String message) {
|
||||
int status = getHttpStatus(resultCode);
|
||||
|
||||
response.setStatus(status);
|
||||
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
|
||||
try (PrintWriter writer = response.getWriter()) {
|
||||
String jsonResponse = JSONUtil.toJsonStr(Result.failed(resultCode, message));
|
||||
writer.print(jsonResponse);
|
||||
writer.flush(); // 确保将响应内容写入到输出流
|
||||
} catch (IOException e) {
|
||||
log.error("响应异常处理失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据结果码获取HTTP状态码
|
||||
*
|
||||
* @param resultCode 结果码
|
||||
* @return HTTP状态码
|
||||
*/
|
||||
private static int getHttpStatus(ResultCode resultCode) {
|
||||
return switch (resultCode) {
|
||||
case ACCESS_UNAUTHORIZED, ACCESS_TOKEN_INVALID, REFRESH_TOKEN_INVALID -> HttpStatus.UNAUTHORIZED.value();
|
||||
default -> HttpStatus.BAD_REQUEST.value();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user