From 0f1f3ce1025478d90f575c917ee50f257c760b5d Mon Sep 17 00:00:00 2001 From: zichun Date: Wed, 6 May 2026 17:11:36 +0800 Subject: [PATCH] feat(common): unified ApiResponse and ErrorCode REQ-MOD-001 --- backend/src/main/java/com/xly/erp/common/response/ApiResponse.java | 35 +++++++++++++++++++++++++++++++++++ backend/src/main/java/com/xly/erp/common/response/ErrorCode.java | 20 ++++++++++++++++++++ backend/src/test/java/com/xly/erp/common/response/ApiResponseTest.java | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 0 deletions(-) create mode 100644 backend/src/main/java/com/xly/erp/common/response/ApiResponse.java create mode 100644 backend/src/main/java/com/xly/erp/common/response/ErrorCode.java create mode 100644 backend/src/test/java/com/xly/erp/common/response/ApiResponseTest.java diff --git a/backend/src/main/java/com/xly/erp/common/response/ApiResponse.java b/backend/src/main/java/com/xly/erp/common/response/ApiResponse.java new file mode 100644 index 0000000..0fd844e --- /dev/null +++ b/backend/src/main/java/com/xly/erp/common/response/ApiResponse.java @@ -0,0 +1,35 @@ +package com.xly.erp.common.response; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ApiResponse { + private int code; + private String message; + private T data; + private long timestamp; + + public static ApiResponse ok(T data) { + return new ApiResponse<>(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage(), data, System.currentTimeMillis()); + } + + public static ApiResponse ok(String message, T data) { + return new ApiResponse<>(ErrorCode.SUCCESS.getCode(), message, data, System.currentTimeMillis()); + } + + public static ApiResponse fail(ErrorCode ec) { + return new ApiResponse<>(ec.getCode(), ec.getMessage(), null, System.currentTimeMillis()); + } + + public static ApiResponse fail(ErrorCode ec, String detail) { + return new ApiResponse<>(ec.getCode(), detail, null, System.currentTimeMillis()); + } + + public static ApiResponse fail(int code, String message) { + return new ApiResponse<>(code, message, null, System.currentTimeMillis()); + } +} diff --git a/backend/src/main/java/com/xly/erp/common/response/ErrorCode.java b/backend/src/main/java/com/xly/erp/common/response/ErrorCode.java new file mode 100644 index 0000000..1c6af52 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/common/response/ErrorCode.java @@ -0,0 +1,20 @@ +package com.xly.erp.common.response; + +import lombok.Getter; + +@Getter +public enum ErrorCode { + SUCCESS(200, "操作成功"), + PARAM_INVALID(40010, "参数错误"), + MOD_PARENT_NOT_FOUND(40411, "父模块不存在或已删除"), + MOD_PROC_NAME_DUP(40911, "存储过程名称已存在"), + INTERNAL_ERROR(50000, "服务器内部错误"); + + private final int code; + private final String message; + + ErrorCode(int code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/backend/src/test/java/com/xly/erp/common/response/ApiResponseTest.java b/backend/src/test/java/com/xly/erp/common/response/ApiResponseTest.java new file mode 100644 index 0000000..e2d6aab --- /dev/null +++ b/backend/src/test/java/com/xly/erp/common/response/ApiResponseTest.java @@ -0,0 +1,52 @@ +package com.xly.erp.common.response; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class ApiResponseTest { + + @Test + void ok_setsCode200AndDataAndTimestamp() { + long before = System.currentTimeMillis(); + ApiResponse r = ApiResponse.ok("hello"); + long after = System.currentTimeMillis(); + + assertThat(r.getCode()).isEqualTo(200); + assertThat(r.getMessage()).isEqualTo("操作成功"); + assertThat(r.getData()).isEqualTo("hello"); + assertThat(r.getTimestamp()).isBetween(before, after); + } + + @Test + void okWithMessage_overridesDefaultMessage() { + ApiResponse r = ApiResponse.ok("created", 42); + assertThat(r.getCode()).isEqualTo(200); + assertThat(r.getMessage()).isEqualTo("created"); + assertThat(r.getData()).isEqualTo(42); + } + + @Test + void fail_mapsErrorCodeFields() { + ApiResponse r = ApiResponse.fail(ErrorCode.PARAM_INVALID); + assertThat(r.getCode()).isEqualTo(40010); + assertThat(r.getMessage()).isEqualTo("参数错误"); + assertThat(r.getData()).isNull(); + } + + @Test + void failWithDetail_overridesDefaultMessage() { + ApiResponse r = ApiResponse.fail(ErrorCode.PARAM_INVALID, "sUserName: blank"); + assertThat(r.getCode()).isEqualTo(40010); + assertThat(r.getMessage()).isEqualTo("sUserName: blank"); + } + + @Test + void errorCode_constantsMatchDocs05Spec() { + assertThat(ErrorCode.SUCCESS.getCode()).isEqualTo(200); + assertThat(ErrorCode.PARAM_INVALID.getCode()).isEqualTo(40010); + assertThat(ErrorCode.MOD_PARENT_NOT_FOUND.getCode()).isEqualTo(40411); + assertThat(ErrorCode.MOD_PROC_NAME_DUP.getCode()).isEqualTo(40911); + assertThat(ErrorCode.INTERNAL_ERROR.getCode()).isEqualTo(50000); + } +} -- libgit2 0.22.2