本文引用的文件
本技术文档围绕“历史记录”功能进行全面梳理,涵盖以下方面:
历史记录相关能力横跨后端模块与前端页面:
前端
搜索页面:历史与热门词展示
graph TB
subgraph "前端"
FE_History["历史页面<br/>my-uniapp-vue3/src/pages/history/index.vue"]
FE_Search["搜索页面<br/>my-uniapp-vue3/src/pages/search/index.vue"]
end
subgraph "后端"
APP["应用入口<br/>server/src/app.ts"]
AUTH["认证中间件<br/>server/src/middleware/auth.ts"]
subgraph "历史模块"
HIST_CTRL["历史控制器<br/>history.controller.ts"]
HIST_BATCH["批量删除控制器<br/>history-batch.controller.ts"]
end
subgraph "播放历史模块"
PLAYER_CTRL["播放控制器<br/>player.controller.ts"]
PLAYER_SRV["播放服务<br/>player.service.ts"]
end
subgraph "搜索历史模块"
SEARCH_CTRL["搜索控制器<br/>search.controller.ts"]
SEARCH_SRV["搜索服务<br/>search.service.ts"]
end
PRISMA["数据模型<br/>server/prisma/schema.prisma"]
end
FE_History --> |HTTP| HIST_CTRL
FE_History --> |HTTP| HIST_BATCH
FE_Search --> |HTTP| SEARCH_CTRL
FE_History --> |HTTP| PLAYER_CTRL
FE_History --> |HTTP| PLAYER_SRV
HIST_CTRL --> AUTH --> PRISMA
HIST_BATCH --> AUTH --> PRISMA
PLAYER_CTRL --> AUTH --> PRISMA
PLAYER_SRV --> PRISMA
SEARCH_CTRL --> AUTH --> PRISMA
SEARCH_SRV --> PRISMA
APP --> HIST_CTRL
APP --> HIST_BATCH
APP --> PLAYER_CTRL
APP --> SEARCH_CTRL
图表来源
章节来源
章节来源
历史记录系统采用“模块化控制器 + 服务层 + Prisma ORM”的分层架构:
optionalAuth 中间件在未登录时提供测试用户兜底,便于前端联调
sequenceDiagram
participant FE as "前端历史页面"
participant CTRL as "历史控制器"
participant AUTH as "optionalAuth"
participant PRISMA as "Prisma ORM"
FE->>CTRL : GET /api/history?page=&pageSize=&startDate=
CTRL->>AUTH : 校验可选认证
AUTH-->>CTRL : 设置用户上下文(测试用户或真实用户)
CTRL->>PRISMA : 查询 AudioRecord 列表+总数
PRISMA-->>CTRL : 返回记录与总数
CTRL-->>FE : 分页列表与分页信息
图表来源
关键实现
模型:AudioRecord 定义字段与索引(userId、audioId、bookId)
flowchart TD
Start(["进入历史列表接口"]) --> Parse["解析分页参数<br/>page/pageSize"]
Parse --> BuildWhere["构建查询条件<br/>startDate -> createdAt >= ..."]
BuildWhere --> Parallel["并行查询<br/>列表 + 总数"]
Parallel --> MapFields["字段映射与格式化"]
MapFields --> Return["返回分页数据"]
图表来源
章节来源
关键实现
模型:基于 audioId 唯一键进行批量删除
sequenceDiagram
participant FE as "前端历史页面"
participant BATCH as "批量删除控制器"
participant AUTH as "optionalAuth"
participant PRISMA as "Prisma ORM"
FE->>BATCH : POST /api/history/batch-delete {ids[]}
BATCH->>AUTH : 校验可选认证
AUTH-->>BATCH : 设置用户上下文
BATCH->>BATCH : 校验ids数组
BATCH->>PRISMA : deleteMany({audioId : {in : ids}})
PRISMA-->>BATCH : 返回删除计数
BATCH-->>FE : {deletedCount}
图表来源
章节来源
关键实现
模型:PlayRecord 唯一索引(userId, chapterId),支持关联章节与书籍
classDiagram
class PlayRecord {
+int id
+int userId
+int chapterId
+float progress
+float duration
+DateTime createdAt
+DateTime updatedAt
}
class BookChapter {
+int id
+int bookId
+int level
+int number
+String title
+String audioUrl
+int audioDuration
}
class Book {
+int id
+String title
+String coverUrl
}
PlayRecord --> BookChapter : "属于"
BookChapter --> Book : "属于"
图表来源
章节来源
关键实现
模型:SearchHistory、HotSearch
flowchart TD
Save["保存搜索历史"] --> Dedup["删除同用户同关键词旧记录"]
Dedup --> InsertNew["插入新记录"]
InsertNew --> Limit["查询用户历史并限制数量<=20"]
Limit --> Cleanup["删除超出部分"]
Cleanup --> UpdateHot["更新/新增热门词计数"]
UpdateHot --> Done["完成"]
图表来源
章节来源
章节来源
数据模型依赖
AudioRecord、PlayRecord、SearchHistory 等模型定义字段与索引,支撑查询与去重
graph LR
APP["app.ts"] --> HIST["/api/history"]
APP --> PLAYER["/api/player"]
APP --> SEARCH["/api/search"]
HIST --> AUTH["optionalAuth"]
PLAYER --> AUTH
SEARCH --> AUTH
HIST --> PRISMA["Prisma模型"]
PLAYER --> PRISMA
SEARCH --> PRISMA
图表来源
章节来源
章节来源
章节来源
历史记录系统通过清晰的模块划分与合理的数据模型设计,实现了播放历史、搜索历史与批量操作的完整闭环。配合 optionalAuth 的可选认证与前端的友好交互,既满足开发调试需求,也保障了生产可用性。后续可在热点数据缓存、冷数据归档与更细粒度的隐私控制上进一步优化。
获取历史列表
批量删除历史
兼容删除(保留 DELETE)
播放历史相关接口
搜索历史相关接口
AudioRecord
PlayRecord
SearchHistory
HotSearch
章节来源
章节来源