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.6 KiB

资源库数据集成 - 前端资源面板

日期: 2026-02-01
类型: 功能增强
影响范围: 前端资源面板数据源

变更概述

ProjectResourcePanel 的数据源从项目素材(project-resources)切换为资源库数据(resource-library),实现正确的业务逻辑:左侧面板显示角色/场景/道具档案,点击后在中间预览区域展示对应的标签和素材。

背景

之前的实现存在概念混淆:

  • 错误实现: 左侧面板直接显示项目素材文件(图片/视频)
  • 正确实现: 左侧面板显示资源库档案(角色/场景/道具),每个档案包含多个标签,每个标签下有多个素材

技术实现

1. 新增类型定义

文件: client/src/types/resource-library.ts

// 资源库核心类型
export interface ResourceLibraryCharacter { ... }
export interface ResourceLibraryLocation { ... }
export interface ResourceLibraryProp { ... }
export interface ResourceLibraryFootage { ... }
export interface ResourceLibraryTag { ... }

// 类型守卫和辅助函数
export function isCharacter(item: ResourceLibraryItem): item is ResourceLibraryCharacter
export function getResourceLibraryItemId(item: ResourceLibraryItem): string
export function getResourceLibraryItemThumbnail(item: ResourceLibraryItem): string | null

2. 新增资源库 API 服务

文件: client/src/services/mock/resourceLibraryApi.ts

export const resourceLibraryApi = {
  getCharacters(projectId, options): Promise<ResourceLibraryCharacter[]>
  getLocations(projectId, options): Promise<ResourceLibraryLocation[]>
  getProps(projectId, options): Promise<ResourceLibraryProp[]>
  getFootage(projectId, options): Promise<ResourceLibraryFootage[]>
  getByType(projectId, type, options): Promise<ResourceLibraryItem[]>
}

功能:

  • 支持按类型获取资源库数据
  • 支持搜索过滤
  • 支持分页(简化实现)

3. 修改 resourceApi 数据源

文件: client/src/services/mock/resourceApi.ts

核心变更:

// 旧实现:从 mockProjectResources 获取
let filteredResources = resources.filter((r) => r.projectId === projectId);

// 新实现:从资源库 API 获取
const items = await resourceLibraryApi.getByType(projectId, type, { search });
const convertedResources = items.map((item) => convertToResource(item, type));

数据转换逻辑:

  • 角色/场景/道具 → Resource 格式(显示默认缩略图)
  • 实拍素材 → 直接使用原始数据
  • metadata 中保存资源数量、标签信息等

4. 更新 ProjectResourcePanel 组件

文件: client/src/components/features/project/ProjectResourcePanel.tsx

变更点:

  1. 标题显示资源数量:

    const resourceCount = typeof item.data.metadata?.resourceCount === 'number'
      ? item.data.metadata.resourceCount : 0;
    const displayTitle = item.data.type !== RESOURCE_TYPES.FOOTAGE && resourceCount > 0
      ? `${item.data.name} (${resourceCount})`
      : item.data.name;
    
  2. 优化空状态提示:

    description={
      filterType === RESOURCE_TYPES.FOOTAGE
        ? '点击下方「上传实拍」按钮添加素材'
        : `点击下方「新增${categoryLabel}」按钮创建`
    }
    

Mock 数据示例

角色数据(带标签和资源)

{
  character_id: '018e1234-5678-7abc-8def-300000000001',
  name: '孙悟空',
  description: '主角,齐天大圣',
  role_type: 'main',
  has_tags: true,
  default_tag_id: 'tag_char_002', // 默认显示"青年"标签
  resource_count: 8, // 所有标签的资源总数
  default_thumbnail_url: 'https://...', // 青年标签的第一张图
  tags: [
    {
      tag_id: 'tag_char_001',
      tag_label: '少年',
      resource_count: 3,
      thumbnail_url: 'https://...'
    },
    {
      tag_id: 'tag_char_002',
      tag_label: '青年',
      resource_count: 5,
      thumbnail_url: 'https://...'
    }
  ]
}

业务流程

用户交互流程

  1. 左侧资源库面板: 显示角色列表(孙悟空、唐僧、猪八戒...)
  2. 点击"孙悟空": 中间预览区域显示该角色的标签(少年、青年)
  3. 切换标签: 预览区域显示对应标签下的素材图片
  4. 设为默认标签: 左侧面板的缩略图自动更新为新默认标签的第一张图

数据流

用户选择 tab (角色/场景/道具/实拍)
  ↓
useResources hook
  ↓
resourceApi.getByProjectId(projectId, { type })
  ↓
resourceLibraryApi.getByType(projectId, type)
  ↓
返回资源库数据 (带标签和资源统计)
  ↓
转换为 Resource 格式
  ↓
ProjectResourcePanel 渲染

文件清单

新增文件

  • client/src/types/resource-library.ts - 资源库类型定义
  • client/src/services/mock/resourceLibraryApi.ts - 资源库 API 服务

修改文件

  • client/src/types/index.ts - 导出资源库类型
  • client/src/services/mock/resourceApi.ts - 切换数据源
  • client/src/services/mock/index.ts - 导出资源库 API
  • client/src/components/features/project/ProjectResourcePanel.tsx - 显示资源数量

测试要点

功能测试

  • 切换 tab(角色/场景/道具/实拍)显示对应数据
  • 搜索功能正常工作
  • 显示资源数量(如"孙悟空 (8)")
  • 无资源的项显示正确(如"唐僧")
  • 实拍素材不显示资源数量

数据验证

  • 角色数据包含 has_tagsdefault_tag_idresource_count
  • 场景数据包含 location 字段
  • 道具数据包含完整的标签列表
  • 实拍素材包含 durationmetadata

UI 验证

  • 卡片显示默认缩略图
  • 标题显示资源数量
  • 空状态提示正确
  • 删除操作正常

后续工作

  1. 中间预览区域: 实现点击角色后显示标签和素材的预览面板
  2. 标签切换: 实现标签切换时更新素材列表
  3. 设为默认标签: 实现"设为默认标签"按钮功能
  4. 真实 API 对接: 替换 mock 数据为真实后端 API

相关文档

注意事项

  1. 类型安全: 使用类型守卫确保数据类型正确
  2. 向后兼容: 保留 mockProjectResources 用于上传功能
  3. 性能优化: 使用 useMemouseCallback 优化渲染
  4. 错误处理: 处理 metadata.resourceCount 可能为 null 的情况