You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

3.7 KiB

项目列表树形视图实现

日期: 2026-01-21
类型: 功能增强
影响范围: 前端 + 后端

变更概述

实现了项目列表页面的树形视图功能,支持文件夹和项目的层级展示与展开/折叠交互。

问题描述

列表视图切换后无法显示内容,缺少树形展开/折叠功能:

  • treeData 被硬编码为空数组
  • 缺少展开状态管理
  • 没有树形数据构建逻辑

解决方案

后端改动

扩展 /api/v1/folders/tree 接口,添加可选参数 include_projects

  1. folder_repository.py

    • 修改 get_tree_structure 方法,添加 include_projects 参数
    • 新增 _get_folder_projects 方法,获取文件夹内的项目列表
    • include_projects=true 时,在每个文件夹节点添加 projects 字段
  2. folder_service.py

    • 更新 get_folder_tree 方法签名,支持 include_projects 参数
    • 传递参数到 repository 层
  3. folders.py (API 路由)

    • 添加 include_projects 查询参数(默认 false
    • 更新接口文档

前端改动

  1. services/api/folders.ts

    • 修改 getTree 方法,支持 includeProjects 参数
    • 更新 FolderTreeNode 类型,添加 projectsfolderCategory 字段
  2. hooks/api/useFolders.ts

    • 更新 useFolderTree hook,支持传入 includeProjects 参数
    • 修改 query key 生成逻辑
  3. utils/treeFlattener.ts (新建)

    • flattenTree: 将嵌套树形结构扁平化为带层级的列表
    • filterTreeByCategory: 根据文件夹分类过滤树
    • 支持展开/折叠状态管理
  4. pages/ProjectsPage.tsx

    • 导入 useFolderTree hook
    • 添加 expandedFolders 状态管理
    • 实现 toggleFolder 函数
    • 使用 flattenTree 将树形数据转换为 TreeItem[]
    • 根据 activeRootId 过滤对应分类的树

API 变更

请求

GET /api/v1/folders/tree?include_projects=true&max_depth=3

响应

{
  "tree": [
    {
      "id": "folder-1",
      "name": "我的文件夹",
      "folderCategory": 1,
      "projectCount": 2,
      "subfolderCount": 1,
      "children": [...],
      "projects": [
        {
          "id": "project-1",
          "name": "项目A",
          "contentType": "video",
          "status": 1,
          "updatedAt": "2026-01-21T10:00:00Z",
          "createdAt": "2026-01-20T10:00:00Z"
        }
      ]
    }
  ]
}

技术细节

树形数据扁平化

// 输入:嵌套树形结构
{
  id: "folder-1",
  children: [
    { id: "folder-2", projects: [...] }
  ]
}

// 输出:扁平化列表
[
  { id: "folder-1", level: 0, isExpanded: true },
  { id: "folder-2", level: 1, isExpanded: false },
  { id: "project-1", level: 2, type: "project" }
]

展开/折叠逻辑

  • 使用 Set<string> 存储已展开的文件夹 ID
  • 点击箭头时切换展开状态
  • 根据展开状态动态显示/隐藏子项

性能优化

  • 仅在列表视图时调用 tree API(includeProjects: viewMode === 'list'
  • 使用 TanStack Query 缓存树形数据(5分钟 staleTime)
  • useMemo 优化扁平化计算

向后兼容

  • 默认 include_projects=false,不影响现有的纯文件夹树功能
  • FolderSelector 等组件继续使用原有 API

测试建议

  1. 切换到列表视图,验证文件夹和项目显示
  2. 点击文件夹左侧箭头,验证展开/折叠功能
  3. 切换"我的项目"和"协作项目",验证分类过滤
  4. 检查多层级嵌套的展示效果
  5. 验证项目点击跳转功能

后续优化

  • 添加搜索时的树形过滤
  • 支持拖拽排序
  • 添加虚拟滚动(大量数据时)
  • 记住展开状态到 localStorage