diff --git a/AGENTS.md b/AGENTS.md index 4b43e37..4fabb83 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,11 +4,12 @@ ## Git 提交规范 -- 提交信息使用中文,简洁描述变更内容。 +- 提交信息必须简短且使用中文,不要使用英文长句。 - 格式:`类型: 简述`,例如 `feat: 新增用户登录接口`、`fix: 修复多租户拦截器空指针`、`docs: 补充API文档`。 ## 技术栈 +- Java 17 - 框架:Spring Boot 3.2.5 - ORM:MyBatis-Plus 3.5.5 - 数据库:MySQL 8.0 @@ -18,6 +19,7 @@ - 连接池:Druid 1.2.8 - 密码加密:jBCrypt 0.4 - API 文档:Knife4j (OpenAPI 3) +- Lombok(@Data, @Slf4j) ## 项目结构 @@ -36,6 +38,12 @@ lpt-be/src/main/java/com/guo/learningprogresstracker/ └── utils/ → 工具类 ``` +- controller 只做参数校验和路由。 +- service/impl 承载业务逻辑。 +- mapper 使用 MyBatis-Plus BaseMapper。 +- entity 使用 `@TableName`、`@TableField` 映射数据库字段。 +- mapStruct 承载 DTO 转换。 + ## API 端点总览(32 个) | 模块 | 端点数 | 端点 | @@ -59,6 +67,35 @@ lpt-be/src/main/java/com/guo/learningprogresstracker/ - 响应格式:`CommonResult` 统一包装 `{ code, message, data }`。 - CORS:可配置,local profile 允许所有来源。 +## 响应规范 + +- 成功:`CommonResult.success(data)`,code=200。 +- 业务错误:`CommonResult.error(msg)`,code=400,HTTP 200。 +- 未登录:`GlobalExceptionHandler.handleNotLogin()`,HTTP 401 + code=401。 +- 参数校验失败:`MethodArgumentNotValidException`,code=400。 + +## DTO 转换 + +- MapStruct 编译期生成 `*ConvertImpl.java`,同名属性自动映射。 +- 默认 `unmappedTargetPolicy = IGNORE`。 +- 自定义映射使用 `@Mapping(source, target)`。 +- 增删 DTO 字段后必须重新编译,否则生成代码不含新字段。 + +## CORS + +- 由 `CorsProperties` 读取各 profile 的 `cors.allowed-origins`。 +- `allowed-origins: "*"` 时自动切换为 `allowedOriginPatterns("*")`,兼容 `allowCredentials`。 + +## 标题抓取 + +- `TitleFetcher`:静态工具类,支持 HTTP→HTTPS 重定向和宽松 SSL。 +- `UtilsController`:`GET /utils/fetch-title?url=...` 代理端点。 + +## 运行环境 + +- 默认 profile:local(`application.yml` 中 `spring.profiles.active: local`)。 +- 编译命令:`mvn clean compile -DskipTests`,需要 JDK 17。 + ## 配置文件 | Profile | 文件 | diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 6833059..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,63 +0,0 @@ -# LPT 后端规范 - -## 技术栈 -- Java 17, Spring Boot 3.2.5 -- MyBatis-Plus 3.5.5 + MySQL -- MapStruct 1.5.5(编译期生成代码,DTO 增删字段后需重新编译) -- Sa-Token 1.38.0(认证/鉴权) -- Flyway(数据库迁移) -- Lombok(@Data, @Slf4j) - -## 项目结构 -``` -controller/ → REST 接口,只做参数校验和路由 -service/ → 业务逻辑 - impl/ -mapper/ → MyBatis-Plus BaseMapper -entity/ → 数据库实体(@TableName, @TableField) -dto/ → 请求/响应 DTO - request/ - response/ -config/ → Spring 配置(WebMvcConfig, JacksonConfig 等) -utils/ → 工具类 -common/ → GlobalExceptionHandler, Ops 等 -mapStruct/ → MapStruct Converter 接口 -``` - -## 响应规范 -- 统一使用 `CommonResult` 包装:`{ code, message, data }` -- 成功:`CommonResult.success(data)` → code=200 -- 业务错误:`CommonResult.error(msg)` → code=400, HTTP 200 -- 未登录:`GlobalExceptionHandler.handleNotLogin()` → HTTP 401 + code=401 -- 参数校验失败走 `MethodArgumentNotValidException` → code=400 - -## 认证 -- SaInterceptor 注册在 `WebMvcConfig`(无 @Profile 限制,所有环境生效) -- 拦截 `/**`,排除 `/login` -- `StpUtil.checkLogin()` 失败 → NotLoginException → GlobalExceptionHandler → 401 -- Cookie 名 `satoken`,前端 axios 需 `withCredentials: true` - -## 数据库变更 -- Flyway 迁移文件:`src/main/resources/db/migration/V{日期}_{序号}__{描述}.sql` -- 文件名日期格式:`yyyyMMdd` - -## DTO 转换 -- MapStruct 编译期生成 `*ConvertImpl.java`(target/generated-sources/) -- 同名属性自动映射,`unmappedTargetPolicy = IGNORE` -- 如需自定义映射用 `@Mapping(source, target)` -- **增删 DTO 字段后必须重新编译**,否则 MapStruct 生成代码不含新字段 - -## CORS -- 由 `CorsProperties` 读取各 profile 的 `cors.allowed-origins` 配置 -- `allowed-origins: "*"` 时自动切换为 `allowedOriginPatterns("*")`(兼容 allowCredentials) -- local profile:`allow-credentials: true`, `allowed-origins: '*'` - -## 标题抓取 -- `TitleFetcher`:静态工具类,支持手动跟随 HTTP→HTTPS 重定向、宽松 SSL -- `UtilsController`:`GET /utils/fetch-title?url=...` 代理端点 - -## 运行 -- 默认 profile:local(application.yml 中 `spring.profiles.active: local`) -- IDEA JDK:`C:/Users/cat-win/.jdks/ms-17.0.19` -- Maven:IDEA 内置 `C:/Program Files/JetBrains/IntelliJ IDEA 2026.1.3/plugins/maven/lib/maven3/bin/mvn` -- 编译:`mvn clean compile -DskipTests`(须用 JDK 17)