播放记录数据模型.md 16 KB

播放记录数据模型

本文档引用的文件

  • schema.prisma
  • player.controller.ts
  • player.service.ts
  • history.controller.ts
  • history-batch.controller.ts
  • index.vue
  • audio.ts

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论

简介

AI有声书生成平台的播放记录功能是一个关键的用户体验优化模块,它通过精确记录用户的播放进度、音频时长和章节关联信息,实现了无缝的跨设备播放体验。该系统支持实时进度更新、离线播放恢复、播放历史管理和跨设备同步等功能。

播放记录数据模型采用Prisma ORM进行数据库持久化,通过User和BookChapter两个实体建立了强关联关系,确保了数据的一致性和完整性。系统设计充分考虑了移动端播放场景的特殊需求,提供了灵活的API接口和高效的查询机制。

项目结构

播放记录功能涉及前后端多个层次的协作:

graph TB
subgraph "前端层"
FE_Player[播放器页面<br/>index.vue]
FE_Store[音频状态管理<br/>audio.ts]
FE_API[API调用封装<br/>request.ts]
end
subgraph "后端层"
BE_Controller[播放记录控制器<br/>player.controller.ts]
BE_Service[播放记录服务<br/>player.service.ts]
BE_DB[(数据库)]
end
subgraph "数据模型"
DM_PlayRecord[PlayRecord模型]
DM_User[User模型]
DM_Chapter[BookChapter模型]
end
FE_Player --> FE_Store
FE_Store --> BE_Controller
BE_Controller --> BE_Service
BE_Service --> BE_DB
BE_DB --> DM_PlayRecord
DM_PlayRecord --> DM_User
DM_PlayRecord --> DM_Chapter

图表来源

  • player.controller.ts:1-344
  • player.service.ts:1-280
  • schema.prisma:63-77

章节来源

  • player.controller.ts:1-344
  • player.service.ts:1-280
  • schema.prisma:63-77

核心组件

PlayRecord数据模型

PlayRecord模型是整个播放记录系统的核心,它定义了用户播放行为的完整数据结构:

字段名 类型 默认值 约束 描述
id Int 自增主键 @id 记录唯一标识符
userId Int - - 关联用户ID
chapterId Int - - 关联章节ID
progress Float 0 - 播放进度(秒)
duration Float 0 - 音频总时长(秒)
createdAt DateTime now() @default 创建时间
updatedAt DateTime @updatedAt - 更新时间

关系映射

erDiagram
User ||--o{ PlayRecord : "拥有"
BookChapter ||--o{ PlayRecord : "被播放"
PlayRecord {
int id PK
int userId FK
int chapterId FK
float progress
float duration
datetime createdAt
datetime updatedAt
}
User {
int id PK
string phone
string openid
string nickname
string avatar
int memberLevel
datetime createdAt
datetime updatedAt
}
BookChapter {
int id PK
int bookId FK
int parentId
int level
int number
string title
string audioUrl
int audioDuration
datetime createdAt
datetime updatedAt
}

图表来源

  • schema.prisma:10-38
  • schema.prisma:63-77
  • schema.prisma:161-192

数据库索引策略

系统采用了多层次的索引策略来优化查询性能:

  • 唯一约束: userId_chapterId 确保每个用户对特定章节只有一个播放记录
  • 用户索引: userId 索引支持用户播放历史的快速检索
  • 章节索引: chapterId 索引支持章节维度的统计分析

章节来源

  • schema.prisma:74-76

架构概览

播放记录系统的整体架构采用分层设计,从前端交互到后端服务再到数据库存储形成了清晰的职责分离:

sequenceDiagram
participant Client as "客户端应用"
participant Store as "音频状态管理"
participant Controller as "播放记录控制器"
participant Service as "播放记录服务"
participant DB as "数据库"
Client->>Store : 播放状态变化
Store->>Controller : 更新播放进度请求
Controller->>Service : savePlayProgress(userId, chapterId, progress, duration)
Service->>DB : upsert PlayRecord
DB-->>Service : 更新结果
Service-->>Controller : 播放记录
Controller-->>Store : 响应结果
Store-->>Client : 更新UI状态
Note over Client,DB : 实时同步机制

图表来源

  • player.controller.ts:32-53
  • player.service.ts:39-81

详细组件分析

后端控制器实现

播放进度管理API

系统提供了完整的播放进度管理API集合:

flowchart TD
Start([API请求到达]) --> Auth{身份验证}
Auth --> |通过| Route{路由分发}
Auth --> |失败| Error401[401 未授权]
Route --> GetProgress[GET /progress<br/>获取播放进度]
Route --> SaveProgress[POST /progress<br/>保存播放进度]
Route --> UpdateProgress[PUT /progress/:chapterId<br/>更新播放进度]
Route --> DeleteRecord[DELETE /progress/:chapterId<br/>删除播放记录]
Route --> BatchDelete[DELETE /progress/batch<br/>批量删除]
GetProgress --> ServiceCall1[调用服务层]
SaveProgress --> ServiceCall2[调用服务层]
UpdateProgress --> ServiceCall3[调用服务层]
DeleteRecord --> ServiceCall4[调用服务层]
BatchDelete --> ServiceCall5[调用服务层]
ServiceCall1 --> DB1[数据库查询]
ServiceCall2 --> DB2[数据库upsert]
ServiceCall3 --> DB3[数据库更新]
ServiceCall4 --> DB4[数据库删除]
ServiceCall5 --> DB5[批量删除]
DB1 --> Response1[返回进度列表]
DB2 --> Response2[返回更新记录]
DB3 --> Response3[返回更新结果]
DB4 --> Response4[删除成功]
DB5 --> Response5[批量删除成功]
Response1 --> End([响应客户端])
Response2 --> End
Response3 --> End
Response4 --> End
Response5 --> End
Error401 --> End

图表来源

  • player.controller.ts:14-107

播放历史获取功能

系统还提供了专门的播放历史获取功能:

sequenceDiagram
participant Client as "客户端"
participant HistoryCtrl as "历史控制器"
participant DB as "数据库"
Client->>HistoryCtrl : GET /history
HistoryCtrl->>HistoryCtrl : 解析查询参数
HistoryCtrl->>DB : 查询AudioRecord
DB-->>HistoryCtrl : 历史记录列表
HistoryCtrl->>HistoryCtrl : 格式化响应数据
HistoryCtrl-->>Client : 历史记录JSON

图表来源

  • history.controller.ts:11-64

章节来源

  • player.controller.ts:14-107
  • history.controller.ts:11-64

服务层实现

播放进度更新策略

服务层实现了智能的播放进度更新策略,采用upsert语义确保数据一致性:

flowchart TD
Input[接收更新请求] --> Validate{验证参数}
Validate --> |失败| Error[抛出错误]
Validate --> |成功| CheckExisting[检查记录是否存在]
CheckExisting --> |存在| UpdateRecord[更新现有记录]
CheckExisting --> |不存在| CreateRecord[创建新记录]
UpdateRecord --> SetFields[设置progress和duration字段]
CreateRecord --> BuildData[构建完整数据]
SetFields --> SaveChanges[保存到数据库]
BuildData --> SaveChanges
SaveChanges --> ReturnResult[返回更新结果]
Error --> ReturnError[返回错误信息]

图表来源

  • player.service.ts:46-81

最近播放记录功能

系统提供了最近播放记录的聚合查询功能:

classDiagram
class PlayRecordService {
+getPlayProgress(userId, chapterId) Promise~PlayRecord[]~
+savePlayProgress(userId, chapterId, progress, duration) Promise~PlayRecord~
+updatePlayProgress(userId, chapterId, progress, duration) Promise~PlayRecord~
+deletePlayRecord(userId, chapterId) Promise~PlayRecord~
+getSingleProgress(userId, chapterId) Promise~PlayRecord~
+getRecentPlayRecords(userId, limit) Promise~RecentRecord[]~
}
class RecentRecord {
+string id
+string title
+string coverUrl
+number progress
+string updatedAt
}
PlayRecordService --> RecentRecord : "返回"

图表来源

  • player.service.ts:10-34
  • player.service.ts:250-279

章节来源

  • player.service.ts:10-122
  • player.service.ts:250-279

前端集成实现

播放器状态管理

前端使用Pinia状态管理库实现播放器的全局状态控制:

stateDiagram-v2
[*] --> 初始化
初始化 --> 空闲 : 应用启动
空闲 --> 播放中 : 开始播放
播放中 --> 暂停 : 用户暂停
暂停 --> 播放中 : 继续播放
播放中 --> 结束 : 播放完成
结束 --> 空闲 : 重置状态
暂停 --> 空闲 : 停止播放
播放中 --> 空闲 : 切换音频
播放中 --> 发送进度 : 定时器触发
发送进度 --> 播放中 : 更新UI
state 发送进度 {
[*] --> 准备数据
准备数据 --> 验证状态
验证状态 --> 调用API
调用API --> [*]
}

图表来源

  • audio.ts:53-62

播放进度同步机制

前端实现了基于定时器的播放进度同步机制:

sequenceDiagram
participant Timer as "定时器"
participant Store as "音频状态管理"
participant API as "播放记录API"
participant Server as "服务器"
Timer->>Store : onTimeUpdate回调
Store->>Store : 更新currentTime
Store->>Store : 计算进度百分比
Store->>API : 保存播放进度
API->>Server : POST /player/progress
Server-->>API : 进度更新结果
API-->>Store : 响应数据
Store-->>Timer : 继续监听
Note over Timer,Store : 每30秒同步一次进度

图表来源

  • audio.ts:53-62
  • player.controller.ts:32-53

章节来源

  • audio.ts:53-79
  • index.vue:309-348

依赖分析

数据模型依赖关系

播放记录系统的核心依赖关系如下:

graph LR
subgraph "核心模型"
PR[PlayRecord]
U[User]
BC[BookChapter]
end
subgraph "业务逻辑"
PC[播放记录控制器]
PS[播放记录服务]
HC[历史控制器]
end
subgraph "前端集成"
FE[播放器页面]
AS[音频状态]
end
U --> PR
BC --> PR
PC --> PS
PS --> PR
HC --> PR
FE --> PC
AS --> PC

图表来源

  • schema.prisma:63-77
  • player.controller.ts:1-344
  • player.service.ts:1-280

外部依赖

系统主要依赖以下外部组件:

  • Prisma ORM: 数据库抽象层,提供类型安全的数据库操作
  • Koa Router: HTTP路由框架,处理RESTful API请求
  • Pinia: Vue.js状态管理库,管理播放器全局状态
  • UniApp: 跨平台移动应用开发框架

章节来源

  • schema.prisma:1-8
  • player.controller.ts:1-6

性能考虑

查询优化策略

系统采用了多种查询优化策略来提升性能:

  1. 索引优化: 在userIdchapterId字段上建立索引,支持高频查询
  2. 唯一约束: 使用userId_chapterId唯一约束避免重复记录
  3. 延迟加载: 使用include选项按需加载关联数据
  4. 批量操作: 提供批量删除功能减少数据库往返次数

缓存策略

虽然当前实现主要依赖数据库查询,但可以考虑以下缓存优化:

  • 热点数据缓存: 缓存用户最近播放的章节信息
  • 进度缓存: 缓存播放进度到本地存储,支持离线恢复
  • 批量更新: 合并多次进度更新请求,减少网络请求

并发控制

系统通过数据库事务和唯一约束确保并发安全性:

flowchart TD
Request[并发请求] --> CheckLock{检查锁}
CheckLock --> |无锁| AcquireLock[获取锁]
CheckLock --> |有锁| WaitQueue[等待队列]
AcquireLock --> ProcessRequest[处理请求]
ProcessRequest --> ReleaseLock[释放锁]
ReleaseLock --> NotifyQueue[通知等待队列]
WaitQueue --> CheckLock

故障排除指南

常见问题及解决方案

播放进度不同步

问题描述: 播放进度与实际播放位置不一致

可能原因:

  1. 定时器更新频率过高导致数据库压力
  2. 网络延迟导致进度更新失败
  3. 前端状态与后端状态不一致

解决方案:

  1. 调整进度更新间隔(当前为30秒)
  2. 实现重试机制和错误处理
  3. 添加状态同步检查

数据库连接问题

问题描述: 播放记录无法保存到数据库

可能原因:

  1. 数据库连接池耗尽
  2. SQL查询超时
  3. 数据库权限不足

解决方案:

  1. 检查数据库连接配置
  2. 实现连接池监控和重连机制
  3. 优化SQL查询性能

前端状态异常

问题描述: 播放器UI状态与实际播放状态不符

可能原因:

  1. 音频上下文初始化失败
  2. 事件监听器未正确清理
  3. 异步操作竞态条件

解决方案:

  1. 添加音频上下文初始化检查
  2. 实现完整的生命周期管理
  3. 使用防抖函数处理频繁更新

章节来源

  • audio.ts:64-74
  • player.service.ts:46-81

结论

AI有声书生成平台的播放记录数据模型设计充分体现了现代Web应用的最佳实践。通过精心设计的数据模型、完善的API接口和高效的前端集成,系统实现了以下核心价值:

技术优势

  1. 数据一致性: 通过唯一约束和事务处理确保播放记录的准确性
  2. 性能优化: 多层次索引和查询优化提升了系统响应速度
  3. 用户体验: 实时进度同步和离线恢复功能改善了用户使用体验
  4. 扩展性: 模块化的架构设计便于功能扩展和维护

业务价值

  1. 用户粘性: 精确的播放进度记录提高了用户留存率
  2. 个性化推荐: 播放历史数据为内容推荐算法提供重要依据
  3. 产品优化: 用户行为数据分析指导产品功能改进
  4. 商业价值: 通过提升用户体验间接促进业务增长

未来发展方向

  1. 智能推荐: 基于播放记录的机器学习推荐算法
  2. 跨设备同步: 更完善的多设备播放状态同步机制
  3. 离线播放: 增强离线播放体验和数据同步能力
  4. 社交功能: 基于播放历史的社交分享和互动功能

该播放记录数据模型为AI有声书平台奠定了坚实的技术基础,通过持续优化和功能扩展,将为用户提供更加优质的音频播放体验。