diff --git a/pom.xml b/pom.xml index fe7db59..e55430c 100644 --- a/pom.xml +++ b/pom.xml @@ -57,6 +57,23 @@ spring-boot-starter-test test + + + cn.hutool + hutool-all + 5.8.38 + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + 4.4.0 + + + org.springframework.boot + spring-boot-starter-actuator + + diff --git a/src/main/java/com/huangge1199/longaicodemother/common/DeleteRequest.java b/src/main/java/com/huangge1199/longaicodemother/common/DeleteRequest.java new file mode 100644 index 0000000..283e2a3 --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/common/DeleteRequest.java @@ -0,0 +1,22 @@ +package com.huangge1199.longaicodemother.common; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 通用的删除请求类 + * + * @author huangge1199 + * @since 2025/6/30 16:21:47 + */ +@Data +public class DeleteRequest implements Serializable { + + /** + * id + */ + private Long id; + + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/huangge1199/longaicodemother/common/HttpStatus.java b/src/main/java/com/huangge1199/longaicodemother/common/HttpStatus.java new file mode 100644 index 0000000..ec3b0c6 --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/common/HttpStatus.java @@ -0,0 +1,94 @@ +package com.huangge1199.longaicodemother.common; + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/src/main/java/com/huangge1199/longaicodemother/common/PageRequest.java b/src/main/java/com/huangge1199/longaicodemother/common/PageRequest.java new file mode 100644 index 0000000..f038a31 --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/common/PageRequest.java @@ -0,0 +1,33 @@ +package com.huangge1199.longaicodemother.common; + +import lombok.Data; + +/** + * 通用的分页请求类 + * + * @author huangge1199 + * @since 2025/6/30 16:07:29 + */ +@Data +public class PageRequest { + + /** + * 当前页号 + */ + private int current = 1; + + /** + * 页面大小 + */ + private int pageSize = 10; + + /** + * 排序字段 + */ + private String sortField; + + /** + * 排序顺序(默认升序) + */ + private String sortOrder = "descend"; +} diff --git a/src/main/java/com/huangge1199/longaicodemother/common/R.java b/src/main/java/com/huangge1199/longaicodemother/common/R.java new file mode 100644 index 0000000..1961024 --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/common/R.java @@ -0,0 +1,113 @@ +package com.huangge1199.longaicodemother.common; + +import java.io.Serializable; + +/** + * 响应信息主体 + * + * @author ruoyi + */ +public class R implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 成功 + */ + public static final int SUCCESS = HttpStatus.SUCCESS; + + /** + * 失败 + */ + public static final int FAIL = HttpStatus.ERROR; + + private int code; + + private String msg; + + private T data; + + public static R ok() { + return restResult(null, SUCCESS, "操作成功"); + } + + public static R ok(T data) { + return restResult(data, SUCCESS, "操作成功"); + } + + public static R ok(T data, String msg) { + return restResult(data, SUCCESS, msg); + } + + public static R fail() { + return restResult(null, FAIL, "操作失败"); + } + + public static R fail(String msg) { + return restResult(null, FAIL, msg); + } + + public static R fail(Exception e) { + String msg = e.getMessage(); + if (e.getCause() != null) { + msg = e.getCause().getMessage(); + } else { + return restResult(null, FAIL, msg); + } + if (e.getCause().getCause() != null) { + msg = e.getCause().getCause().getMessage(); + } + return restResult(null, FAIL, msg); + } + + public static R fail(T data) { + return restResult(data, FAIL, "操作失败"); + } + + public static R fail(T data, String msg) { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public static Boolean isError(R ret) { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/src/main/java/com/huangge1199/longaicodemother/config/CorsConfig.java b/src/main/java/com/huangge1199/longaicodemother/config/CorsConfig.java new file mode 100644 index 0000000..099739e --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/config/CorsConfig.java @@ -0,0 +1,29 @@ +package com.huangge1199.longaicodemother.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * CorsConfig + * 全局跨域配置 + * + * @author huangge1199 + * @since 2025/6/27 16:37:44 + */ +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + // 覆盖所有请求 + registry.addMapping("/**") + // 允许发送 Cookie + .allowCredentials(true) + // 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突) + .allowedOriginPatterns("*") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*") + .exposedHeaders("*"); + } +} diff --git a/src/main/java/com/huangge1199/longaicodemother/controller/HealthController.java b/src/main/java/com/huangge1199/longaicodemother/controller/HealthController.java new file mode 100644 index 0000000..578ea3d --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/controller/HealthController.java @@ -0,0 +1,28 @@ +package com.huangge1199.longaicodemother.controller; + +import com.huangge1199.longaicodemother.common.R; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 健康检测controller + * HealthController + * + * @author huangge1199 + * @since 2025/8/4 14:05:38 + */ +@RestController +@RequestMapping("/health") +public class HealthController { + + /** + * 健康检测接口 + * @return 结果 + */ + @GetMapping("/") + public R healthCheck() { + return R.ok(); + } +} + diff --git a/src/main/java/com/huangge1199/longaicodemother/exception/ErrorCode.java b/src/main/java/com/huangge1199/longaicodemother/exception/ErrorCode.java new file mode 100644 index 0000000..0b930bd --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/exception/ErrorCode.java @@ -0,0 +1,38 @@ +package com.huangge1199.longaicodemother.exception; + +import lombok.Getter; + +/** + * 异常信息 + * + * @author huangge1199 + * @since 2025/6/27 16:26:54 + */ +@Getter +public enum ErrorCode { + + SUCCESS(200, "ok"), + PARAMS_ERROR(40000, "请求参数错误"), + NOT_LOGIN_ERROR(40100, "未登录"), + NO_AUTH_ERROR(40101, "无权限"), + NOT_FOUND_ERROR(40400, "请求数据不存在"), + FORBIDDEN_ERROR(40300, "禁止访问"), + SYSTEM_ERROR(50000, "系统内部异常"), + OPERATION_ERROR(50001, "操作失败"); + + /** + * 状态码 + */ + private final int code; + + /** + * 信息 + */ + private final String message; + + ErrorCode(int code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/src/main/java/com/huangge1199/longaicodemother/exception/GlobalExceptionHandler.java b/src/main/java/com/huangge1199/longaicodemother/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..423aff2 --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/exception/GlobalExceptionHandler.java @@ -0,0 +1,29 @@ +package com.huangge1199.longaicodemother.exception; + +import com.huangge1199.longaicodemother.common.R; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 全局异常处理器 + * + * @author huangge1199 + * @since 2025/6/30 10:56:33 + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + @ExceptionHandler(MyException.class) + public R businessExceptionHandler(MyException e) { + log.error("BusinessException", e); + return R.fail(e.getCode(), e.getMessage()); + } + + @ExceptionHandler(RuntimeException.class) + public R businessExceptionHandler(RuntimeException e) { + log.error("RuntimeException", e); + return R.fail(ErrorCode.SYSTEM_ERROR, "系统错误"); + } +} diff --git a/src/main/java/com/huangge1199/longaicodemother/exception/MyException.java b/src/main/java/com/huangge1199/longaicodemother/exception/MyException.java new file mode 100644 index 0000000..9fab075 --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/exception/MyException.java @@ -0,0 +1,36 @@ +package com.huangge1199.longaicodemother.exception; + +import lombok.Getter; +import lombok.Setter; + +/** + * 自定义业务异常 + * + * @author huangge1199 + * @since 2025/6/30 10:42:10 + */ +@Setter +@Getter +public class MyException extends RuntimeException { + + /** + * 错误码 + */ + private final int code; + + public MyException(int code, String message) { + super(message); + this.code = code; + } + + public MyException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.code = errorCode.getCode(); + } + + public MyException(ErrorCode errorCode, String message) { + super(message); + this.code = errorCode.getCode(); + } + +} diff --git a/src/main/java/com/huangge1199/longaicodemother/exception/ThrowUtils.java b/src/main/java/com/huangge1199/longaicodemother/exception/ThrowUtils.java new file mode 100644 index 0000000..f34f22f --- /dev/null +++ b/src/main/java/com/huangge1199/longaicodemother/exception/ThrowUtils.java @@ -0,0 +1,44 @@ +package com.huangge1199.longaicodemother.exception; + +/** + * 异常处理工具类 + * + * @author huangge1199 + * @since 2025/6/30 11:00:12 + */ +public class ThrowUtils { + + /** + * 条件成立则抛异常 + * + * @param condition 条件 + * @param runtimeException 异常 + */ + public static void throwIf(boolean condition, RuntimeException runtimeException) { + if (condition) { + throw runtimeException; + } + } + + /** + * 条件成立则抛异常 + * + * @param condition 条件 + * @param errorCode 错误码 + */ + public static void throwIf(boolean condition, ErrorCode errorCode) { + throwIf(condition, new MyException(errorCode)); + } + + /** + * 条件成立则抛异常 + * + * @param condition 条件 + * @param errorCode 错误码 + * @param message 错误信息 + */ + public static void throwIf(boolean condition, ErrorCode errorCode, String message) { + throwIf(condition, new MyException(errorCode, message)); + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 42c1856..677ebd7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,4 +4,14 @@ spring: server: port: 8123 servlet: - context-path: /api \ No newline at end of file + context-path: /api +# springdoc-openapi +springdoc: + group-configs: + - group: 'default' + packages-to-scan: com.huangge1199.longaicodemother.controller +# knife4j +knife4j: + enable: true + setting: + language: zh_cn