From 75fa00a66de32b6ccbe3abb26ef6d630ff090105 Mon Sep 17 00:00:00 2001 From: zichun Date: Fri, 8 May 2026 09:47:15 +0800 Subject: [PATCH] feat(usr): common Result/BizException/AuthErrorCode/GlobalExceptionHandler REQ-USR-004 --- backend/src/main/java/com/example/erp/common/constants/AuthErrorCode.java | 11 +++++++++++ backend/src/main/java/com/example/erp/common/exception/BizException.java | 14 ++++++++++++++ backend/src/main/java/com/example/erp/common/exception/GlobalExceptionHandler.java | 33 +++++++++++++++++++++++++++++++++ backend/src/main/java/com/example/erp/common/response/Result.java | 27 +++++++++++++++++++++++++++ backend/src/test/java/com/example/erp/common/ResultTest.java | 31 +++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 0 deletions(-) create mode 100644 backend/src/main/java/com/example/erp/common/constants/AuthErrorCode.java create mode 100644 backend/src/main/java/com/example/erp/common/exception/BizException.java create mode 100644 backend/src/main/java/com/example/erp/common/exception/GlobalExceptionHandler.java create mode 100644 backend/src/main/java/com/example/erp/common/response/Result.java create mode 100644 backend/src/test/java/com/example/erp/common/ResultTest.java diff --git a/backend/src/main/java/com/example/erp/common/constants/AuthErrorCode.java b/backend/src/main/java/com/example/erp/common/constants/AuthErrorCode.java new file mode 100644 index 0000000..ef4b70d --- /dev/null +++ b/backend/src/main/java/com/example/erp/common/constants/AuthErrorCode.java @@ -0,0 +1,11 @@ +package com.example.erp.common.constants; + +public final class AuthErrorCode { + + public static final int USERNAME_OR_PASSWORD_ERROR = 40100; + public static final int ACCOUNT_DISABLED = 40101; + public static final int ACCOUNT_LOCKED = 40102; + public static final int REFRESH_TOKEN_INVALID = 40103; + + private AuthErrorCode() {} +} diff --git a/backend/src/main/java/com/example/erp/common/exception/BizException.java b/backend/src/main/java/com/example/erp/common/exception/BizException.java new file mode 100644 index 0000000..554ddd9 --- /dev/null +++ b/backend/src/main/java/com/example/erp/common/exception/BizException.java @@ -0,0 +1,14 @@ +package com.example.erp.common.exception; + +import lombok.Getter; + +@Getter +public class BizException extends RuntimeException { + + private final int code; + + public BizException(int code, String message) { + super(message); + this.code = code; + } +} diff --git a/backend/src/main/java/com/example/erp/common/exception/GlobalExceptionHandler.java b/backend/src/main/java/com/example/erp/common/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..64d4d2a --- /dev/null +++ b/backend/src/main/java/com/example/erp/common/exception/GlobalExceptionHandler.java @@ -0,0 +1,33 @@ +package com.example.erp.common.exception; + +import com.example.erp.common.response.Result; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(BizException.class) + public Result handleBizException(BizException e) { + return Result.fail(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public Result handleValidation(MethodArgumentNotValidException e) { + FieldError fe = e.getBindingResult().getFieldErrors().stream().findFirst().orElse(null); + String msg = fe != null ? fe.getDefaultMessage() : "参数校验失败"; + return Result.fail(40001, msg); + } + + @ExceptionHandler(Exception.class) + public Result handleException(Exception e) { + log.error("未处理异常", e); + return Result.fail(99000, "系统内部错误"); + } +} diff --git a/backend/src/main/java/com/example/erp/common/response/Result.java b/backend/src/main/java/com/example/erp/common/response/Result.java new file mode 100644 index 0000000..c8bb6c1 --- /dev/null +++ b/backend/src/main/java/com/example/erp/common/response/Result.java @@ -0,0 +1,27 @@ +package com.example.erp.common.response; + +import lombok.Getter; + +@Getter +public class Result { + + private final int code; + private final String message; + private final T data; + private final long timestamp; + + private Result(int code, String message, T data) { + this.code = code; + this.message = message; + this.data = data; + this.timestamp = System.currentTimeMillis(); + } + + public static Result ok(T data) { + return new Result<>(200, "操作成功", data); + } + + public static Result fail(int code, String message) { + return new Result<>(code, message, null); + } +} diff --git a/backend/src/test/java/com/example/erp/common/ResultTest.java b/backend/src/test/java/com/example/erp/common/ResultTest.java new file mode 100644 index 0000000..3fb583f --- /dev/null +++ b/backend/src/test/java/com/example/erp/common/ResultTest.java @@ -0,0 +1,31 @@ +package com.example.erp.common; + +import com.example.erp.common.response.Result; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class ResultTest { + + @Test + void ok_setsCode200AndData() { + Result result = Result.ok("hello"); + assertEquals(200, result.getCode()); + assertEquals("hello", result.getData()); + assertEquals("操作成功", result.getMessage()); + } + + @Test + void fail_setsCodeAndNullData() { + Result result = Result.fail(40100, "用户名或密码错误"); + assertEquals(40100, result.getCode()); + assertNull(result.getData()); + assertEquals("用户名或密码错误", result.getMessage()); + } + + @Test + void ok_hasPositiveTimestamp() { + Result result = Result.ok(null); + assertTrue(result.getTimestamp() > 0); + } +} -- libgit2 0.22.2