本文引用的文件
本文件面向“AI有声书生成平台”的状态管理,围绕 Pinia 在 uni-app/Vue3 中的应用进行系统化梳理。重点覆盖以下方面:
前端采用 uni-app + Vue3 + Pinia 架构,状态集中在 src/store 目录,类型定义在 src/types,网络层在 src/utils。
graph TB
subgraph "应用入口"
M["main.ts<br/>创建 Pinia 并初始化用户状态"]
end
subgraph "状态模块"
U["store/user.ts<br/>用户状态与登录态"]
A["store/audio.ts<br/>音频播放与播放列表"]
end
subgraph "页面与组件"
P["pages/player/index.vue<br/>播放器页面"]
L["pages/login/index.vue<br/>登录页"]
MI["pages/mine/index.vue<br/>我的页面"]
end
subgraph "工具与类型"
R["utils/request.ts<br/>统一请求封装"]
S["utils/storage.ts<br/>本地存储工具"]
C["utils/config.ts<br/>环境与 API 地址配置"]
D["utils/debug.ts<br/>全局调试工具"]
T["types/index.ts<br/>类型定义"]
end
M --> U
M --> A
P --> A
L --> U
MI --> U
U --> R
A --> R
U --> S
R --> C
R --> D
U --> T
A --> T
图表来源
章节来源
章节来源
Pinia Store 作为单一事实来源,页面通过组合式 API 使用 Store 实例,实现跨页面状态共享与同步。网络层统一走 request.ts,按环境动态选择 API 基地址;本地持久化通过 storage.ts 封装 token 与用户信息;类型定义集中于 types/index.ts,确保类型安全。
sequenceDiagram
participant App as "应用入口(main.ts)"
participant Pinia as "Pinia实例"
participant User as "用户Store(user.ts)"
participant Audio as "音频Store(audio.ts)"
participant PageP as "播放器页面(player/index.vue)"
participant PageL as "登录页(login/index.vue)"
participant PageM as "我的页面(mine/index.vue)"
participant Req as "请求封装(request.ts)"
App->>Pinia : 创建并挂载
App->>User : initUser()
PageP->>Audio : 读取播放状态/列表
PageP->>Req : 播放/生成/列表请求
PageL->>User : login()/sendCode()
PageL->>Req : 登录/验证码请求
PageM->>User : fetchMemberStatus()
PageM->>Req : 历史/统计请求
图表来源
类型与持久化
存储:storage.ts 提供 getToken/setToken/removeToken 与 getUserInfo/setUserInfo/removeUserInfo
flowchart TD
Start(["initUser 入口"]) --> CheckSaved["检查本地 token 与 userInfo"]
CheckSaved --> HasSaved{"存在有效登录态?"}
HasSaved --> |是| LoadState["设置 token 与 userInfo"]
LoadState --> FetchMember["拉取会员状态"]
HasSaved --> |否| WaitLogin["等待用户主动登录"]
FetchMember --> End(["完成"])
WaitLogin --> End
图表来源
章节来源
音频上下文生命周期
onCanplay:日志提示
sequenceDiagram
participant Page as "播放器页面"
participant Store as "音频Store"
participant Ctx as "InnerAudioContext"
Page->>Store : setPlaylist(list, index, autoPlay)
Store->>Ctx : initAudioContext()
Store->>Store : play(list[index])
Store->>Ctx : 设置 src 与 play()
Ctx-->>Store : onPlay -> isPlaying=true
Ctx-->>Store : onTimeUpdate -> 更新 currentTime/duration
Ctx-->>Store : onEnded -> isPlaying=false
Store->>Store : hasNext? -> playNext() 或 handlePlayMode()
Store->>Store : onError -> 记录错误
图表来源
章节来源
我的页面(mine/index.vue)
未登录时跳转登录页
sequenceDiagram
participant Login as "登录页"
participant User as "用户Store"
participant Req as "请求封装"
participant Mine as "我的页面"
Login->>User : sendCode(phone)
User->>Req : POST /auth/send-code
Login->>User : login(phone, code)
User->>Req : POST /auth/login
Req-->>User : 返回 token 与 user
User-->>Login : 完成登录
Mine->>User : fetchMemberStatus()
User->>Req : GET /member/status
图表来源
章节来源
类型依赖
types/index.ts 为所有 Store 与页面提供强类型支撑
graph LR
Main["main.ts"] --> User["store/user.ts"]
Main --> Audio["store/audio.ts"]
User --> Types["types/index.ts"]
Audio --> Types
User --> Storage["utils/storage.ts"]
Audio --> Request["utils/request.ts"]
User --> Request
Request --> Config["utils/config.ts"]
Request --> Debug["utils/debug.ts"]
PageP["pages/player/index.vue"] --> Audio
PageL["pages/login/index.vue"] --> User
PageM["pages/mine/index.vue"] --> User
图表来源
章节来源
章节来源
章节来源
本项目采用 Pinia 实现清晰的模块化状态管理,结合类型定义与统一请求封装,实现了用户登录态、音频播放状态与跨页面共享的稳定方案。通过本地持久化与环境适配,兼顾了多端一致性与性能。建议持续完善: