传输列表“清空”按钮作用范围问题

December 14, 2025
2 min read
By devshan

Table of Contents

This is a list of all the sections in this post. Click on any of them to jump to that section.

问题背景

传输列表页支持按类型切换上传、下载、全部三个 Tab。最初实现时,“清空”按钮会删除所有已完成的传输记录,不区分当前 Tab。

这会导致:

  • 我在“上传”Tab 点击清空时,“下载”Tab 的已完成记录也被清空;
  • 体验与使用直觉不一致,难以追踪不同方向的历史任务。

问题分析

  • 数据层:本地数据库里,传输记录有类型字段(upload/download),但 clearCompletedTransfers 的 SQL 最初是无条件删除所有 success 记录。
  • 状态层:AppState.clearCompletedTransfers 也没有 type 参数,直接在内存列表中过滤所有 success 记录。
  • UI 层:Tab 切换只是视图过滤,点击清空按钮没有把“当前 Tab 类型”信息传下去。

这意味着 UI 的“按 Tab 清空”需求在三层都缺少了类型约束。

解决方案

整体思路:从 UI 一直把 “TransferType?” 传递到状态层和数据库层,做到层层按类型过滤。

  • 数据库层:为 clearCompletedTransfers 增加可选 type 参数:
    • 如果传入 null,保持原行为:清空全部已完成记录;
    • 如果传入具体类型,只删除对应类型的 success 记录。
  • 状态层 (AppState):
    • clearCompletedTransfers({TransferType? type}) 接收可选类型;
    • 写入数据库时传下去;
    • 同步更新内存中的 _transfers 列表,只移除对应类型的 success 记录。
  • UI 层(传输页):
    • 根据当前 Tab 推导出 TransferType?
      • “全部”:传 null,清空所有;
      • “上传”:传 TransferType.upload
      • “下载”:传 TransferType.download

实现要点

  • AppState.clearCompletedTransfers 增加 type 参数并透传到数据库,见 client/lib/core/state/app_state.dart:840-853
  • 传输页根据当前 Tab 调用带参数的清空方法,只影响该 Tab 类型的数据。

收获

  • 很典型的“UI 需求没有贯穿到底层”的问题,解决方式是:
    • 明确数据模型(传输类型);
    • 从 UI → State → DB 一路把语义补齐;
    • 避免在 UI 层“假装过滤”,但实际数据操作是全局的。