tasks.md 5.7 KB

1. 数据模型与核心序列化

  • 1.1 定义备份 JSON 数据接口:在 viewmodel/ 下新建 PlaylistBackup.ets,定义 PlaylistBackupDataPlaylistBackupItemPlaylistSongBackupItem 接口,包含 versionexportTimeappVersionplaylists 字段
  • 1.2 在 PlaylistTable 中新增 exportAllPlaylists() 方法:查询所有歌单及其关联歌曲,返回 PlaylistBackupData 对象。超过 100 个歌单时分批查询
  • 1.3 在 PlaylistTable 中新增 importPlaylists() 方法:接受 PlaylistBackupData,逐一创建歌单和歌曲关联,返回导入结果统计

2. PlaylistBackupManager 核心类

  • 2.1 新建 common/util/PlaylistBackupManager.ets,实现单例模式和基本结构
  • 2.2 实现 exportToJson() 方法:调用 PlaylistTable.exportAllPlaylists(),序列化为 JSON 字符串
  • 2.3 实现 validateBackupJson() 方法:解析 JSON 并校验 version、必要字段完整性,返回校验结果
  • 2.4 实现 importFromJson() 方法:解析并校验 JSON,调用 PlaylistTable.importPlaylists() 写入数据

3. 本地文件导出导入

  • 3.1 实现 saveToLocal() 方法:使用 DocumentViewPicker 保存 JSON 文件,文件名格式 playlist_backup_YYYYMMDD_HHmmss.json
  • 3.2 实现 loadFromLocal() 方法:使用 DocumentViewPicker 选择 .json 文件,读取并返回文件内容
  • 3.3 导出失败和取消处理:用户取消文件选择器或写入失败时显示错误 toast,确保无残留文件

4. 导入冲突解决

  • 4.1 新建 dialog/ImportConflictDialog.ets:冲突解决对话框,显示冲突歌单名称,提供「覆盖」「跳过」「重命名」三个选项和「应用到全部」复选框
  • 4.2 在 importFromJson() 中集成冲突检测:导入前按歌单名称查询现有歌单,发现冲突时弹出对话框
  • 4.3 实现覆盖逻辑:删除现有歌单及其歌曲关联,重新创建
  • 4.4 实现重命名逻辑:自动生成后缀名称(如 "我的歌单 (2)"),检查后缀名也不冲突
  • 4.5 实现「应用到全部」:记录用户选择,后续冲突自动应用同一策略

5. WebDAV 备份上传

  • 5.1 实现 uploadToWebDav() 方法:接受 WebDAV 账户参数,生成备份 JSON,通过 RemoteDriveManagerrcpSocket 上传到 /TTMusic/backups/
  • 5.2 实现目录自动创建:上传前检查并创建 /TTMusic/backups/ 目录(使用 createWebDavFoldercreateDirectory
  • 5.3 新建 WebDAV 账户选择器对话框:过滤仅显示 RemoteDriveType.WebDav 类型的账户,无账户时提示用户添加(集成在 BackupManageView 弹层中)
  • 5.4 错误处理:网络错误和认证失败时显示具体错误信息

6. WebDAV 备份恢复

  • 6.1 实现 listWebDavBackups() 方法:列出 WebDAV 服务器 /TTMusic/backups/ 下的所有 .json 文件
  • 6.2 实现 downloadFromWebDav() 方法:下载选中的备份文件内容
  • 6.3 新建备份文件选择列表 UI:显示 WebDAV 上的备份文件列表(文件名 + 时间),用户点击后下载并触发导入流程(集成在 BackupManageView 弹层中)
  • 6.4 目录不存在或为空时显示「暂无备份」提示

7. 服务器自动备份(VIP)

  • 7.1 实现 uploadToServer() 方法:通过 POST /backup/playlist/upload 上传备份 JSON,请求携带 userToken
  • 7.2 实现 downloadFromServer() 方法:通过 GET /backup/playlist/download 下载指定备份
  • 7.3 实现 listServerBackups() 方法:通过 GET /backup/playlist/list 获取备份历史列表
  • 7.4 实现 VIP 权限检查:在自动备份和服务器恢复入口检查 hasActiveSubscription,非 VIP 引导到 VipPage
  • 7.5 实现 token 过期处理:服务器返回认证错误时提示用户重新登录,暂停自动备份

8. 自动备份防抖机制

  • 8.1 实现 scheduleAutoBackup() 方法:使用 setTimeout 实现 5 分钟防抖,窗口内多次调用只触发一次上传
  • 8.2 在 PlaylistTable 的增删改方法中添加自动备份触发点:createPlaylistdeletePlaylistupdatePlaylistaddSongToPlaylistremoveSongFromPlaylist 操作完成后调用 scheduleAutoBackup()
  • 8.3 实现自动备份偏好持久化:使用 PreferencesUtil 保存自动备份开关状态
  • 8.4 实现 VIP 过期自动关闭:检测到 VIP 状态变化时关闭自动备份并通知用户

9. 备份管理 UI

  • 9.1 新建 view/BackupManageView.ets:备份管理视图组件,包含导出、导入、WebDAV 备份、WebDAV 恢复、服务器备份(VIP)、服务器恢复(VIP)功能入口
  • 9.2 在 SettingPage.ets 中添加「备份与恢复」菜单项,通过 Sheet 弹层打开 BackupManageView
  • 9.3 实现备份历史列表 UI:显示最近备份记录(类型图标、时间、歌单数量),无记录时显示引导提示
  • 9.4 实现自动备份开关 UI(VIP 标识):开关控件带 VIP 标签,非 VIP 点击引导到会员页面
  • 9.5 实现操作进度展示:导出/导入/上传/下载过程中显示 loading 状态和进度提示

10. 备份历史记录持久化

  • 10.1 定义备份记录数据模型:包含备份类型(local/webdav/server)、时间戳、歌单数量、文件路径/标识
  • 10.2 使用 PreferencesUtil 存储最近备份记录列表(JSON 数组,最多保留 20 条)
  • 10.3 在每次备份/恢复操作完成后写入历史记录

11. 页面路由注册

  • 11.1 备份管理以 Sheet 弹层方式集成在 SettingPage 中,无需单独路由注册
  • 11.2 从 SettingPage 点击「备份与恢复」菜单项即可打开备份管理界面