本文引用的文件
本指南围绕“收藏管理”功能,系统性阐述后端控制器与服务层、数据库模型、前端页面与交互、以及API接口规范。重点覆盖以下能力:
收藏功能由三层组成:
数据库模型: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"]
图表来源
章节来源
章节来源
收藏功能遵循“控制器-服务-数据模型”的分层架构,前端通过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 : 统一响应
图表来源
章节来源
章节来源
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
}
图表来源
章节来源
章节来源
前端依赖统一的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
图表来源
章节来源
章节来源
收藏管理功能采用清晰的分层架构与完善的数据库约束,实现了稳定的收藏列表、添加、取消与状态检查能力。通过唯一键与索引优化、关联查询与统一响应,兼顾了易用性与性能。前端页面简洁直观,配合后端API即可快速落地。
章节来源
flowchart TD
Start(["进入收藏服务"]) --> Parse["解析用户ID与音频ID"]
Parse --> CheckDup{"是否已收藏?"}
CheckDup --> |是| ReturnExist["返回现有收藏"]
CheckDup --> |否| Insert["创建新收藏"]
Insert --> ReturnNew["返回新建收藏"]
ReturnExist --> End(["结束"])
ReturnNew --> End
图表来源