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.
6.5 KiB
6.5 KiB
选择共享资源 - 资源树接口方案分析
日期:2026-02-08
范围:CreateProjectModal → 选择共享资源 → 资源内容数据来源
结论:建议新增「项目资源树」专用接口,或采用前端组合 + 懒加载;不推荐仅靠改造 /api/v1/folders/tree 承载「项目下角色/场景/道具」层级。
1. 现状
1.1 选择共享资源面板需要的数据
- ResourceSelectorPanel(
ResourceSelectorPanel.tsx)当前用 Mock 数据,目标结构为:- 虚拟根「我的项目」→ 文件夹 → 项目 → 项目下的角色 / 场景 / 道具(character / scene / prop)
- 能力:按类型过滤(全部 / 角色 / 场景 / 道具)、搜索、级联选择、展示项目下资源统计(如「角色 15 场景 8 道具 12」)。
- 前端类型:
SharedResource含type: 'project' | 'folder' | 'character' | 'scene' | 'prop',即需要**至少到「项目 + 项目内资源」**这一层。
1.2 现有接口能力
| 接口 | 返回内容 | 是否满足「资源内容」树 |
|---|---|---|
| GET /api/v1/folders/tree | 根 → 文件夹 → 项目;项目的 children 仅为 [] 或子项目,不包含 character/scene/prop |
❌ 只到「文件夹 + 项目」 |
| GET /api/v1/projects/{id}/resources | 某项目的素材分页扁平列表(character/scene/prop 等),非树形 | ✅ 有项目下资源,但需按项目逐个请求、且为列表而非树节点 |
folders/tree当前参数:maxDepth、includeProjects、includeSubprojects、includeFullProjectFields;无category(前端shared-resources.ts的category=1在后端未使用,若要做「我的项目/协作项目」需前后端对齐)。- 项目资源列表接口:分页、按类型/标签/搜索过滤,返回的是
items[],不是「树节点 + children」。
2. 方案对比
方案 A:改造 /api/v1/folders/tree
- 做法:增加参数(如
includeProjectResources=true),当为 true 时对每个项目查询其 character/scene/prop,挂到该项目的children下。 - 优点:一次请求拿到「文件夹 + 项目 + 项目内资源」整棵树,前端实现简单。
- 缺点:
- 树规模大时(多文件夹 × 多项目 × 每项目多资源)响应体大、耗时长。
folders/tree同时服务「选文件夹/选项目」和「选共享资源」两种场景,职责混合,后续扩展(如仅要统计、懒加载)不便。- 与现有「项目节点 children 仅子项目」的语义不一致,易造成复用方误解。
结论:仅适合「树规模很小且确定不会膨胀」的场景;一般不推荐作为唯一方案。
方案 B:新增「项目资源树」专用接口
- 做法:新增例如
GET /api/v1/shared-resources/tree或GET /api/v1/projects/resources/tree,专门返回「可共享资源树」:- 结构:虚拟根(可选)→ 文件夹 → 项目 → 可选一层:项目下的 character/scene/prop。
- 可通过查询参数控制:是否包含资源层级、是否只返回资源统计(如
characterCount/sceneCount/propCount)、category(我的项目/协作项目)、最大深度等。
- 优点:
- 职责清晰,与「选文件夹」用的
folders/tree分离。 - 可单独做性能设计:例如先只返回「文件夹 + 项目 + 统计」,项目下明细按需懒加载或另接口分页。
- 前端
ResourceSelectorPanel与getShareableFoldersAndProjects的语义一致,便于对接。
- 职责清晰,与「选文件夹」用的
- 缺点:多一个接口需要维护、文档与测试。
结论:推荐,尤其当产品需要「一棵清晰的、可扩展的共享资源树」时。
方案 C:前端组合现有接口 + 懒加载
- 做法:
- 用现有
folders/tree(或对齐后的getShareableFoldersAndProjects)拉取「文件夹 + 项目」树。 - 项目节点展示时,可用「项目资源统计」接口(若存在)只显示数量;用户展开某项目时再请求
GET /api/v1/projects/{projectId}/resources,将结果转为树子节点挂到该节点下(懒加载)。
- 用现有
- 优点:不新增后端接口,首屏只加载文件夹+项目,体积小、响应快。
- 缺点:展开多个项目时会有多次请求;前端需维护「树节点 + 懒加载状态」逻辑。
结论:在不新增接口的前提下可作为过渡或长期方案;若已有或计划有「项目资源统计」接口,体验会更好。
3. 建议
-
资源内容(到 character/scene/prop)
- 不推荐仅通过改造
folders/tree把「项目下资源」塞进同一棵树并作为主方案(职责与性能考虑)。 - 推荐二选一或组合使用:
- 方案 B:新增「项目资源树」接口,专门服务「选择共享资源」场景,便于后续加统计、过滤、懒加载。
- 方案 C:沿用
folders/tree+ 按项目懒加载projects/{id}/resources,首屏轻量、不增新接口。
- 不推荐仅通过改造
-
若选方案 B
- 建议接口设计时考虑:
- 是否先只返回「文件夹 + 项目 + 每项目资源统计」,明细(character/scene/prop 列表)通过原
projects/{id}/resources按需加载,以控制首包体积。
- 是否先只返回「文件夹 + 项目 + 每项目资源统计」,明细(character/scene/prop 列表)通过原
- 前端
ResourceSelectorPanel中已注释的getShareableFoldersAndProjects可改为调用新树接口(或先接folders/tree+ 统计/明细按需请求)。
- 建议接口设计时考虑:
-
若选方案 C
- 前端需要:
- 用
folders/tree(或带 category 的等价能力)拿 文件夹+项目; - 项目节点展开时请求
getProjectResources(projectId)(及可选getProjectResourceStats)并挂到节点; - 统一成
ResourceSelectorPanel所需的树形与SharedResource类型。
- 用
- 前端需要:
-
与 CreateProjectModal 的衔接
- 无论 B 或 C,提交时仍将选中项整理为
sharedResources: [{ id, type }]传给创建/更新项目 API(当前代码中 TODO 部分),后端需有对应字段与校验。
- 无论 B 或 C,提交时仍将选中项整理为
4. 涉及文件(参考)
- 前端:
client/src/components/features/project/CreateProjectModal.tsx、ResourceSelectorPanel.tsx、shared-resources.ts、types/shared-resource.ts - 后端:
server/app/api/v1/folders.py(/tree)、server/app/services/folder_service.py、server/app/repositories/folder_repository.py、server/app/api/v1/project_resources.py(/projects/{id}/resources)