Files
lpt-be/AGENTS.md
T
2026-08-01 00:15:56 +08:00

7.1 KiB
Raw Blame History

LPT 后端服务(lpt-be

Java Spring Boot 后端,提供 REST API、数据库访问、认证鉴权。

Git 提交规范

  • 提交信息必须简短且使用中文,不要使用英文长句。
  • 格式:类型: 简述,例如 feat: 新增用户登录接口fix: 修复多租户拦截器空指针docs: 补充API文档

技术栈

  • Java 17
  • 框架:Spring Boot 3.2.5
  • ORMMyBatis-Plus 3.5.5
  • 数据库:MySQL 8.0
  • 认证:Sa-Token 1.38.0Cookie 名 satoken
  • 数据库迁移:Flyway
  • 对象映射:MapStruct 1.5.5
  • 连接池:Druid 1.2.8
  • 密码加密:jBCrypt 0.4
  • API 文档:Knife4j (OpenAPI 3)
  • Lombok@Data, @Slf4j

项目结构

lpt-be/src/main/java/com/guo/learningprogresstracker/
├── controller/   → REST 接口层
├── service/      → 业务逻辑层(接口 + impl)
├── mapper/       → MyBatis-Plus BaseMapper
├── entity/       → 数据库实体
├── dto/          → 请求/响应 DTO
├── config/       → Spring 配置
├── common/       → 全局异常处理、Ops
├── mapStruct/    → MapStruct Converter
├── enums/        → 枚举类
├── exception/    → 自定义异常
└── utils/        → 工具类
  • controller 只做参数校验和路由。
  • service/impl 承载业务逻辑。
  • mapper 使用 MyBatis-Plus BaseMapper。
  • entity 使用 @TableName@TableField 映射数据库字段。
  • mapStruct 承载 DTO 转换。

API 端点总览(32 个)

模块 端点数 端点
学习会话 9 POST /study-sessions/{taskNum}/start, PUT .../pause, PUT .../resume, PUT .../end, POST .../fragments, GET .../history, PUT .../expectation, GET .../expectation, GET .../report-draft
标准思维导图 6 GET /review/standard-mind-map/{taskNum}, POST .../regenerate, PUT ..., POST .../recall, POST .../find-node, GET .../recall-records
复习模块 6 GET /review/feed, GET /review/task/{taskNum}, GET /review/report/{id}, GET /review/fragment/{id}, GET /review/standard-mind-map/recall-records/{recordId}, GET /review/tasks
任务管理 6 GET /tasks, POST /tasks, PUT /tasks/{taskNum}, DELETE /tasks/{taskNum}, GET /tasks/priority-weights, PUT /tasks/priority-weights
应用场景 4 GET/POST/PUT/DELETE /tasks/{taskNum}/applications[/{id}]
工具 1 GET /utils/fetch-title?url=...

数据库(10 个核心表)

users, tasks, study_sessions, study_reports, study_report_fragments, study_expectations, task_applications, review_standard_mind_maps, review_recall_records, user_priority_weights

关键机制

  • 多租户隔离:TenantLineInnerInterceptor 自动注入 WHERE created_by = #{当前用户},排除 user/flyway_schema_history 表。
  • 自动填充:MetaObjectHandler 自动填充 created_by/updated_by/created_time/updated_time
  • 认证鉴权:Sa-Token 拦截 /** 排除 /loginCookie satoken,支持 @SaCheckPermission 注解式权限。
  • 响应格式:CommonResult<T> 统一包装 { code, message, data }
  • CORS:可配置,local profile 允许所有来源。

响应规范

  • 成功:CommonResult.success(data)code=200。
  • 业务错误:CommonResult.error(msg)code=400HTTP 200。
  • 未登录:GlobalExceptionHandler.handleNotLogin()HTTP 401 + code=401。
  • 参数校验失败:MethodArgumentNotValidExceptioncode=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。
  • UtilsControllerGET /utils/fetch-title?url=... 代理端点。

运行环境

  • 默认 profilelocalapplication.ymlspring.profiles.active: local)。
  • 编译命令:mvn clean compile -DskipTests,需要 JDK 17。

配置文件

Profile 文件
local application-local.yml
dev application-dev.yml
uat application-uat.yml
prod application-prod.yml
公共 application.yml

AI 服务依赖

  • 配置:lpt.ai-service.url=http://localhost:5199
  • 超时:600s
  • AI 服务不可用时自动降级到内置规则引擎(BuiltinMindMapGenerator

启动命令

mvn clean compile -DskipTests   # 编译(需要 JDK 17
mvn spring-boot:run              # 启动(默认 profile: local

关联项目

项目 路径 端口 说明
lpt-fe ../lpt-fe/ 5158 Vue 3 前端,通过 /api 代理调用本服务
lpt-ai ../lpt-ai/ 5199 AI 服务,本服务通过 HTTP 调用其异步任务接口

项目规范

数据库迁移(Flyway Migration

命名规则

  • 脚本格式:V{YYYYMMDD}_{序号}__{描述}.sql
  • 日期必须使用实际编写日期,不得使用过去的日期
  • 序号从 1 开始,同一天多个脚本递增
  • 描述使用下划线分隔的英文短语

核心原则

  • 不可变性:已执行的迁移脚本永远不得修改
  • 只增不减:数据库变更只能通过新增迁移脚本实现
  • 向后兼容:新脚本应兼容已有数据

操作规范

  • 删除表:创建新迁移脚本,使用 DROP TABLE IF EXISTS
  • 修改表结构:使用 ALTER TABLE 语句
  • 新增表:创建新迁移脚本,使用 CREATE TABLE

框架机制

行级数据隔离(多租户拦截器)

  • 配置类: MybatisPlusConfig 注册 TenantLineInnerInterceptor
  • 租户字段: created_by(每个业务表的创建人字段)
  • 租户值来源: StpUtil.getLoginIdAsString()(当前登录用户)
  • 自动注入: 所有 SELECT/UPDATE/DELETE 语句自动追加 WHERE created_by = #{当前用户}
  • 归属校验: 查询单条记录时拦截器自动校验 created_by,非本人数据直接返回空
  • 排除表: userflyway_schema_historydatabasechangelogdatabasechangeloglock

自动填充(MetaObjectHandler

  • created_by / updated_by 插入/更新时自动填充为当前登录用户
  • created_time / updated_time 插入/更新时自动填充当前时间

认证鉴权(Sa-Token

  • 会话管理: 基于 StpUtil 的登录/登出/会话查询
  • 权限校验: @SaCheckPermission 注解式权限控制
  • 未登录处理: 全局异常处理器捕获 NotLoginException 返回 401

编码规范

数据访问层

  • 优先使用纯 MyBatis-Plus Java APIWrappers.<T>lambdaQuery()selectListselectById 等),避免手写 XML SQL
  • 复杂查询通过 Wrappers 链式构建条件,必要时使用 .apply() 拼接原生 SQL 片段