收藏管理.md 12 KB

收藏管理

本文引用的文件

  • server\src\modules\favorites\favorites.controller.ts
  • server\src\modules\favorites\favorites.service.ts
  • server\src\middleware\auth.ts
  • server\prisma\schema.prisma
  • my-uniapp-vue3\src\pages\favorites\index.vue
  • docs\API.md

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

引言

本指南围绕“收藏管理”功能,系统性阐述后端控制器与服务层、数据库模型、前端页面与交互、以及API接口规范。重点覆盖以下能力:

  • 收藏列表获取
  • 添加收藏
  • 取消收藏
  • 收藏状态检查 并深入说明业务逻辑(用户身份验证、音频ID/书籍ID校验、重复收藏处理)、数据存储结构与查询优化策略,提供API接口文档与前端应用场景及用户交互设计,并给出常见问题与性能优化建议。

项目结构

收藏功能由三层组成:

  • 前端页面:展示收藏列表、触发收藏/取消收藏、跳转播放页
  • 后端控制器:接收请求、解析参数、调用服务层、返回统一响应
  • 后端服务层:封装Prisma访问,执行查询/插入/删除/存在性检查
  • 数据库模型:Favorite、Book、User三者关联,唯一索引避免重复收藏

    graph TB
    FE["前端页面<br/>收藏列表页"] --> API["后端控制器<br/>favorites.controller.ts"]
    API --> SVC["服务层<br/>favorites.service.ts"]
    SVC --> PRISMA["Prisma 客户端"]
    PRISMA --> DB["数据库<br/>schema.prisma 中的 Favorite/Book/User"]
    

图表来源

  • server\src\modules\favorites\favorites.controller.ts:1-76
  • server\src\modules\favorites\favorites.service.ts:1-104
  • server\prisma\schema.prisma:94-105

章节来源

  • server\src\modules\favorites\favorites.controller.ts:1-76
  • server\src\modules\favorites\favorites.service.ts:1-104
  • server\prisma\schema.prisma:94-105

核心组件

  • 控制器层:定义路由、参数解析、鉴权中间件、统一响应格式
  • 服务层:封装Prisma查询,处理重复收藏、排序与关联查询
  • 鉴权中间件:可选认证,开发环境默认测试用户
  • 数据模型:Favorite唯一约束、索引优化、与Book/User关联

章节来源

  • server\src\modules\favorites\favorites.controller.ts:1-76
  • server\src\modules\favorites\favorites.service.ts:1-104
  • server\src\middleware\auth.ts:51-80
  • server\prisma\schema.prisma:94-105

架构总览

收藏功能遵循“控制器-服务-数据模型”的分层架构,前端通过HTTP请求与后端交互,后端通过Prisma访问MySQL数据库。

sequenceDiagram
participant U as "用户"
participant FE as "前端页面"
participant CTRL as "控制器<br/>favorites.controller.ts"
participant SVC as "服务层<br/>favorites.service.ts"
participant DB as "数据库<br/>Prisma/MySQL"
U->>FE : 打开收藏页面
FE->>CTRL : GET /favorites
CTRL->>SVC : getFavorites(userId)
SVC->>DB : 查询收藏记录(含book关联)
DB-->>SVC : 收藏列表
SVC-->>CTRL : 返回结果
CTRL-->>FE : 统一响应
U->>FE : 点击添加收藏
FE->>CTRL : POST /favorites {audioId}
CTRL->>SVC : addFavorite(userId, bookId)
SVC->>DB : 检查重复(唯一索引)
alt 已存在
DB-->>SVC : 存在
SVC-->>CTRL : 返回现有收藏
else 不存在
DB-->>SVC : 插入新收藏
SVC-->>CTRL : 返回新建收藏
end
CTRL-->>FE : 统一响应
U->>FE : 点击取消收藏
FE->>CTRL : DELETE /favorites/ : audioId
CTRL->>SVC : removeFavorite(userId, bookId)
SVC->>DB : 删除收藏
DB-->>SVC : 成功
SVC-->>CTRL : 返回
CTRL-->>FE : 统一响应
U->>FE : 检查收藏状态
FE->>CTRL : GET /favorites/check/ : audioId
CTRL->>SVC : isFavorited(userId, bookId)
SVC->>DB : 查找唯一键
DB-->>SVC : 存在/不存在
SVC-->>CTRL : 返回布尔值
CTRL-->>FE : 统一响应

图表来源

  • server\src\modules\favorites\favorites.controller.ts:13-73
  • server\src\modules\favorites\favorites.service.ts:8-103
  • server\prisma\schema.prisma:94-105

详细组件分析

控制器层(favorites.controller.ts)

  • 路由定义
    • GET /favorites:获取当前用户的收藏列表
    • POST /favorites:添加收藏(请求体包含audioId)
    • DELETE /favorites/:audioId:取消收藏
    • GET /favorites/check/:audioId:检查是否已收藏
  • 鉴权策略
    • 使用可选认证中间件,支持无Token时使用测试用户
    • 开发环境可通过环境变量控制是否强制认证
  • 统一响应
    • 固定返回结构:code、message、data
    • 错误通过错误处理器抛出,由全局中间件捕获

章节来源

  • server\src\modules\favorites\favorites.controller.ts:13-73
  • server\src\middleware\auth.ts:51-80

服务层(favorites.service.ts)

  • 数据访问
    • getFavorites:按用户ID查询收藏,包含book关联字段,按创建时间倒序
    • addFavorite:先查重(唯一索引),存在则返回现有;否则创建新收藏并返回带book的完整信息
    • removeFavorite:按唯一键删除收藏
    • isFavorited:按唯一键判断是否存在
  • 关联查询
    • 通过Prisma include book,减少二次查询
  • 性能要点
    • 唯一键约束避免重复收藏
    • 查询使用索引字段(userId、bookId)

章节来源

  • server\src\modules\favorites\favorites.service.ts:8-103
  • server\prisma\schema.prisma:94-105

数据模型(schema.prisma)

  • Favorite
    • 唯一键:userId + bookId
    • 索引:userId、bookId
    • 关系:属于User、属于Book(级联删除)
  • Book
    • 收藏反向关系:favorites
  • User

    • 收藏反向关系:favorites

      erDiagram
      USER ||--o{ FAVORITE : "拥有"
      BOOK ||--o{ FAVORITE : "被收藏"
      FAVORITE {
      int id PK
      int userId
      int bookId
      datetime createdAt
      }
      USER {
      int id PK
      }
      BOOK {
      int id PK
      }
      

图表来源

  • server\prisma\schema.prisma:94-105

章节来源

  • server\prisma\schema.prisma:94-105

前端应用(favorites/index.vue)

  • 页面职责
    • 加载收藏列表、空状态提示、点击播放、点击取消收藏
  • 交互流程
    • 打开页面即拉取收藏列表
    • 点击条目跳转播放页
    • 点击右侧爱心图标触发取消收藏,成功后从本地列表剔除
  • 类型定义
    • FavoriteItem:包含收藏项ID、音频ID、创建时间、音频信息等

章节来源

  • my-uniapp-vue3\src\pages\favorites\index.vue:47-112

依赖关系分析

  • 控制器依赖服务层
  • 服务层依赖Prisma客户端访问数据库
  • 鉴权中间件贯穿控制器层
  • 前端依赖统一的HTTP请求工具与后端API

    graph LR
    AUTH["鉴权中间件<br/>auth.ts"] --> CTRL["控制器<br/>favorites.controller.ts"]
    CTRL --> SVC["服务层<br/>favorites.service.ts"]
    SVC --> PRISMA["Prisma 客户端"]
    PRISMA --> DB["MySQL 数据库"]
    FE["前端页面<br/>favorites/index.vue"] --> CTRL
    

图表来源

  • server\src\middleware\auth.ts:51-80
  • server\src\modules\favorites\favorites.controller.ts:1-76
  • server\src\modules\favorites\favorites.service.ts:1-104

章节来源

  • server\src\middleware\auth.ts:51-80
  • server\src\modules\favorites\favorites.controller.ts:1-76
  • server\src\modules\favorites\favorites.service.ts:1-104

性能考量

  • 查询优化
    • 使用唯一索引(userId, bookId)保证重复收藏检查高效
    • 对userId、bookId建立索引,提升查询与删除效率
  • 关联查询
    • 通过include book一次性返回所需字段,避免N+1查询
  • 排序与分页
    • 按创建时间倒序,适合“最近收藏”展示
    • 如需分页,可在服务层增加skip/take参数
  • 缓存策略
    • 对热门用户收藏可考虑Redis缓存,降低数据库压力
  • 并发控制
    • 唯一键约束天然防止并发重复插入
  • 日志与监控
    • 记录慢查询与异常,结合数据库慢日志定位瓶颈

故障排查指南

  • 常见问题
    • 未登录或Token无效:确认鉴权中间件配置与Token格式
    • 收藏重复:唯一键约束会阻止重复,检查是否正确处理已存在情况
    • 取消收藏失败:确认传入的audioId是否正确、用户是否匹配
    • 收藏列表为空:确认用户是否有收藏记录、include book是否正常
  • 排查步骤
    • 检查控制器参数解析与类型转换
    • 在服务层打印SQL与参数,核对userId与bookId
    • 核对Prisma schema中的唯一键与索引
    • 前端确认请求URL与请求头(Authorization)
  • 错误处理
    • 控制器层统一抛出错误,响应格式固定
    • 前端根据code与message进行提示

章节来源

  • server\src\modules\favorites\favorites.controller.ts:33-35
  • server\src\modules\favorites\favorites.service.ts:37-49
  • server\src\middleware\auth.ts:51-80

结论

收藏管理功能采用清晰的分层架构与完善的数据库约束,实现了稳定的收藏列表、添加、取消与状态检查能力。通过唯一键与索引优化、关联查询与统一响应,兼顾了易用性与性能。前端页面简洁直观,配合后端API即可快速落地。

附录

API接口文档(收藏相关)

  • 获取收藏列表
    • 方法:GET
    • URL:/favorites
    • 请求头:Authorization: Bearer (可选)
    • 响应:code、message、data(收藏列表)
  • 添加收藏
    • 方法:POST
    • URL:/favorites
    • 请求头:Authorization: Bearer (可选)
    • 请求体:{ audioId: number }
    • 响应:code、message、data(收藏项)
  • 取消收藏
    • 方法:DELETE
    • URL:/favorites/:audioId
    • 请求头:Authorization: Bearer (可选)
    • 响应:code、message
  • 检查是否已收藏
    • 方法:GET
    • URL:/favorites/check/:audioId
    • 请求头:Authorization: Bearer (可选)
    • 响应:code、message、data: { isFavorited: boolean }
  • 章节来源

    • server\src\modules\favorites\favorites.controller.ts:13-73
    • docs\API.md:257-276

    数据模型与查询流程图

    flowchart TD
    Start(["进入收藏服务"]) --> Parse["解析用户ID与音频ID"]
    Parse --> CheckDup{"是否已收藏?"}
    CheckDup --> |是| ReturnExist["返回现有收藏"]
    CheckDup --> |否| Insert["创建新收藏"]
    Insert --> ReturnNew["返回新建收藏"]
    ReturnExist --> End(["结束"])
    ReturnNew --> End
    

    图表来源

    • server\src\modules\favorites\favorites.service.ts:34-69