TTMusic 的歌单数据存储在两个本地 RDB 数据库中:
PlaylistStore.db:包含 playlistTable(歌单信息)和 playlistSongTable(歌单-歌曲关联)mediaDB.db:包含 mediaTable(歌曲元数据),歌单通过 songFilePath 关联到歌曲当前没有任何备份机制。应用已有完善的远程网盘集成(RemoteDriveManager 支持 WebDAV、SMB、百度网盘等 13 种协议),以及基于服务器 API(pay.ss5.xyz)的 VIP 会员体系。VIP 状态通过 PreferencesUtil.getBooleanSync('hasActiveSubscription') 判断。
Goals:
Non-Goals:
选择: 使用单个 JSON 文件作为备份格式
备选方案:
理由: JSON 格式与项目现有的数据交换模式一致(ConfigManager、API 响应均为 JSON),ArkTS 原生支持 JSON.stringify/JSON.parse,无需引入新依赖。
格式结构:
{
"version": 1,
"exportTime": "2026-02-08T12:00:00.000Z",
"appVersion": "1.0.0",
"playlists": [
{
"id": "...",
"name": "...",
"coverPath": "...",
"description": "...",
"createTime": "...",
"updateTime": "...",
"songCount": 10,
"sortOrder": 0,
"songs": [
{
"songFilePath": "...",
"addTime": "...",
"sortOrder": 0
}
]
}
]
}
选择: 导入时按歌单名称检测冲突,让用户选择「覆盖」「跳过」或「重命名」
备选方案:
Date.now() + random,不同设备几乎不会冲突,但无法识别逻辑重复理由: 歌单名称对用户有实际意义,同名歌单大概率是同一歌单的不同版本。提供选择权避免意外数据丢失。
选择: 备份文件存放在 WebDAV 账户的 /TTMusic/backups/ 固定目录下
理由: 使用固定路径避免用户需要手动选择目录,同时与用户的音乐文件隔离。文件名格式为 playlist_backup_YYYYMMDD_HHmmss.json,便于识别和管理。
选择: 通过 pay.ss5.xyz 服务器 API 上传/下载备份数据,需要 userToken 认证
API 设计:
POST /backup/playlist/upload — 上传备份 JSON(需 token + VIP)GET /backup/playlist/download — 下载最新备份(需 token + VIP)GET /backup/playlist/list — 获取备份历史列表(需 token + VIP)理由: 复用已有的用户认证体系(userToken)和服务器架构,与现有 VIP 功能(会员信息、支付等)保持一致。
选择: 在歌单增删改操作后设置 5 分钟延迟窗口,窗口内多次变更合并为一次上传
备选方案:
理由: 用户整理歌单时通常连续操作(添加多首歌、创建多个歌单),延迟合并避免频繁网络请求。使用 setTimeout + 标志位实现防抖。
选择: 新建 PlaylistBackupManager 类统一管理所有备份相关逻辑
模块职责:
exportToJson(): 从 PlaylistTable 读取全部歌单数据,序列化为 JSONimportFromJson(): 解析 JSON,校验格式版本,写入 PlaylistTablesaveToLocal(): 使用 DocumentViewPicker 让用户选择保存位置loadFromLocal(): 使用 DocumentViewPicker 让用户选择备份文件uploadToWebDav(): 通过 RemoteDriveManager 的 rcpSocket 上传到 WebDAVdownloadFromWebDav(): 从 WebDAV 下载备份文件uploadToServer(): VIP 用户上传到服务器 APIdownloadFromServer(): VIP 用户从服务器下载scheduleAutoBackup(): 管理自动备份的防抖定时器理由: 集中管理避免备份逻辑散落在多个文件中,便于测试和维护。
[风险] 大量歌单导出的内存占用 → 分批序列化歌单数据,避免一次性将所有歌单加载到内存中。对于超过 100 个歌单的场景进行分页查询。
[风险] WebDAV 服务器兼容性 → 不同 WebDAV 服务器对大文件上传行为不一致。备份文件通常较小(几十 KB 到几 MB),风险可控。使用现有 rcpSocket.uploadFile 方法,已验证兼容性。
[风险] 备份文件版本不兼容 → JSON 格式包含 version 字段。导入时检查版本号,不兼容的版本给出明确提示。当前版本为 1,预留升级空间。
[风险] 自动备份消耗流量 → 仅 VIP 用户启用,且使用防抖合并。备份数据为纯文本 JSON,体积较小。设置页面提供开关让用户控制。
[风险] 服务器 API 需要后端配合 → 服务器端 API 需要新增三个端点。可以先实现本地导出/导入 + WebDAV 备份,服务器自动备份作为第二阶段上线。
[取舍] 不备份歌曲音频文件 → 降低了备份完整性,但大幅减少备份体积和时间。歌曲文件可以从原始来源重新获取(本地扫描或 WebDAV)。
[取舍] 不支持增量备份 → 实现简单,但每次备份为全量。鉴于歌单数据量通常较小(几十个歌单,几千首歌曲关联),全量备份的开销完全可接受。
deleteAccount 中的签名方式)?