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.
 

18 KiB

前端影响分析:storyboard_resources 废弃

概述

本文档详细分析前端代码中受 storyboard_resources 废弃影响的所有文件。

受影响文件清单

📊 统计总览

类别 文件数 严重程度 说明
API 服务层 1 🔴 核心 API 调用失效
类型定义 1 🟡 类型定义过时
UI 组件 6 🔴 资源显示/操作失效
Hooks 2 🔴 业务逻辑失效
工具函数 1 🟡 状态计算不准确
Mock 数据 3 🟢 仅影响开发环境
总计 14 - -

详细分析

1. API 服务层(1 个文件)

📄 client/src/services/api/storyboards.ts

严重程度🔴

问题代码

// 第 91-112 行
const syncStoryboardResources = async (
  storyboardId: string, 
  resources: StoryboardResources
) => {
  const desiredIds = collectResourceIds(resources);
  
  // ❌ 调用废弃的 GET 端点
  const existing = (await apiClient.get(
    `/storyboards/${storyboardId}/resources`
  )) as ProjectResourceResponse[];
  
  const existingIds = new Set(existing.map((r) => r.projectResourceId));
  const toAdd = desiredIds.filter((id) => !existingIds.has(id));
  const toRemove = Array.from(existingIds).filter((id) => !desiredIds.includes(id));

  // ❌ 调用废弃的 POST 端点
  if (toAdd.length > 0) {
    await apiClient.post(`/storyboards/${storyboardId}/resources/batch`, {
      resource_ids: toAdd,
    });
  }

  // ❌ 调用废弃的 DELETE 端点
  if (toRemove.length > 0) {
    await apiClient.delete(`/storyboards/${storyboardId}/resources/batch`, {
      data: { resource_ids: toRemove },
    });
  }
};

// 第 194-196 行
async update(id: string, data: UpdateStoryboardDto): Promise<Storyboard | null> {
  // ...
  if (data.resources) {
    await syncStoryboardResources(id, data.resources);  // ❌ 调用失效
  }
  // ...
}

影响

  • 更新分镜时无法同步资源关联
  • 所有依赖此 API 的组件功能失效
  • 3 个废弃 API 端点调用:
    • GET /storyboards/{id}/resources
    • POST /storyboards/{id}/resources/batch
    • DELETE /storyboards/{id}/resources/batch

修复方案

  1. 删除 syncStoryboardResources 函数
  2. 使用 storyboard_items API 替代
  3. 修改 update 方法,移除 resources 同步逻辑

2. 类型定义(1 个文件)

📄 client/src/types/storyboard.ts

严重程度🟡

问题代码

// 第 14-20 行
export interface StoryboardResources {
  characters: StoryboardResourceItem[];
  locations: StoryboardResourceItem[];
  props: StoryboardResourceItem[];
  footages?: StoryboardResourceItem[];
}

// 第 21-26 行
export interface StoryboardResourceItem {
  resourceId: string;
  tagId?: string;
  tagLabel?: string;
  displayOrder: number;
}

// 第 48-52 行
export interface Storyboard {
  // ...
  /** 关联的资源(详情接口返回) */
  resources?: StoryboardResources;  // ❌ 废弃字段
  /** v3.0 统一关联表 - 分镜元素关联项 */
  items?: StoryboardItem[];  // ✅ 新字段
  // ...
}

影响

  • ⚠️ 类型定义过时,但不会导致编译错误
  • ⚠️ 开发者可能误用 resources 字段
  • ⚠️ 代码提示会显示废弃字段

修复方案

  1. 标记 resources 字段为 @deprecated
  2. 添加 JSDoc 注释说明迁移路径
  3. 最终删除 StoryboardResourcesStoryboardResourceItem 接口

3. UI 组件(6 个文件)

📄 3.1 client/src/components/features/preview/VideoGenerationPrecheck.tsx

严重程度🔴

问题代码

// 第 62-64 行
const storyboardCharacters = storyboard.resources?.characters || [];
storyboardCharacters.forEach((_sc) => {
  const resource = resources.find((r) => r.id === _sc.resourceId);
  // ...
});

// 第 79-81 行
const storyboardLocations = storyboard.resources?.locations || [];
storyboardLocations.forEach((sl) => {
  const resource = resources.find((r) => r.id === sl.resourceId);
  // ...
});

// 第 96-98 行
const storyboardProps = storyboard.resources?.props || [];
storyboardProps.forEach((sp) => {
  const resource = resources.find((r) => r.id === sp.resourceId);
  // ...
});

影响

  • 视频生成前的资源完整性检查失效
  • 无法检测缺失的角色/场景/道具资源
  • 可能导致视频生成失败

使用场景

  • 用户点击"生成视频"按钮前的预检查
  • 显示缺失资源的警告信息

修复方案

// 优先使用 items,降级到 resources
const resources = storyboard.items 
  ? getResourcesFromItems(storyboard.items)
  : storyboard.resources || { characters: [], locations: [], props: [] };

const storyboardCharacters = resources.characters || [];
const storyboardLocations = resources.locations || [];
const storyboardProps = resources.props || [];

📄 3.2 client/src/components/features/preview/StoryboardResourcesPreview.tsx

严重程度🔴

问题代码

// 第 189-193 行
if (storyboard.resources) {
  characters = getResourceWithTag(storyboard.resources.characters, 'character');
  locations = getResourceWithTag(storyboard.resources.locations, 'location');
  props = getResourceWithTag(storyboard.resources.props, 'prop');
  footages = getResourceWithTag(storyboard.resources.footages, 'footage');
}

// 第 452-469 行
{renderResourceSection(
  <User className="w-4 h-4" />,
  '角色',
  groupedResources.characters,
  'character'
)}
{renderResourceSection(
  <MapPin className="w-4 h-4" />,
  '场景',
  groupedResources.locations,
  'location'
)}
{renderResourceSection(
  <Package className="w-4 h-4" />,
  '道具',
  groupedResources.props,
  'prop'
)}

影响

  • 分镜资源预览面板显示为空
  • 无法查看分镜关联的角色/场景/道具
  • 添加/移除资源功能失效

使用场景

  • 分镜详情页的资源预览面板
  • 显示当前分镜使用的所有资源
  • 提供添加/移除资源的操作

修复方案

const groupedResources = useMemo(() => {
  if (storyboard.items) {
    return getResourcesFromItems(storyboard.items);
  }
  return storyboard.resources || { 
    characters: [], 
    locations: [], 
    props: [], 
    footages: [] 
  };
}, [storyboard]);

📄 3.3 client/src/components/features/storyboard/StoryboardList.tsx

严重程度🔴

问题代码

// 第 89-92 行
characters: getResourceNames(s.resources?.characters),
characterDialogues,
locations: getResourceNames(s.resources?.locations),
props: getResourceNames(s.resources?.props),

影响

  • 分镜列表中资源信息显示为空
  • 无法快速查看每个分镜使用的资源
  • 列表筛选功能可能失效

使用场景

  • 项目分镜列表页
  • 显示每个分镜的资源摘要
  • 支持按资源筛选分镜

修复方案

const resources = s.items 
  ? getResourcesFromItems(s.items)
  : s.resources || { characters: [], locations: [], props: [] };

characters: getResourceNames(resources.characters),
locations: getResourceNames(resources.locations),
props: getResourceNames(resources.props),

📄 3.4 client/src/components/features/storyboard/StoryboardEditForm.tsx

严重程度🔴

问题代码

// 第 19-22 行
interface ResourceSelectorProps {
  type: 'character' | 'location' | 'prop';
  icon: React.ReactNode;
  // ...
}

// 第 65-68 行
const ResourceSelector = ({
  type,
  // ...
}: ResourceSelectorProps) => {
  const typeMap: Record<string, number> = { character: 1, location: 2, prop: 3 };
  const numericType = typeMap[type];
  // ...
}

影响

  • ⚠️ 资源选择器组件本身可能正常工作
  • 但选择后的资源无法正确保存(依赖 syncStoryboardResources
  • 表单提交后资源关联失败

使用场景

  • 分镜编辑表单
  • 选择角色/场景/道具资源
  • 保存分镜时同步资源关联

修复方案

  • 修改表单提交逻辑
  • 使用 storyboard_items API 保存资源关联
  • 不再依赖 resources 字段

📄 3.5 client/src/components/features/storyboard/ParseFlowDialog.tsx

严重程度🔴

问题代码

// 第 1113-1125 行
const characters = item.resources?.characters
  ?.map((c) => resourceMap.get(c.resourceId) || '')
  .filter(Boolean) || [];

const allCharacters = Array.from(new Set([...characters, ...charNamesFromDialogues]));

const locations = item.resources?.locations
  ?.map((c) => resourceMap.get(c.resourceId) || '')
  .filter(Boolean) || [];

const props = item.resources?.props
  ?.map((c) => resourceMap.get(c.resourceId) || '')
  .filter(Boolean) || [];

影响

  • 剧本解析流程中资源映射失败
  • 无法将剧本中的角色/场景/道具映射到项目资源
  • 自动创建分镜时资源关联缺失

使用场景

  • 剧本解析流程
  • 自动识别剧本中的资源
  • 创建分镜时自动关联资源

修复方案

const resources = item.items 
  ? getResourcesFromItems(item.items)
  : item.resources || { characters: [], locations: [], props: [] };

const characters = resources.characters
  ?.map((c) => resourceMap.get(c.resourceId) || '')
  .filter(Boolean) || [];

const locations = resources.locations
  ?.map((c) => resourceMap.get(c.resourceId) || '')
  .filter(Boolean) || [];

const props = resources.props
  ?.map((c) => resourceMap.get(c.resourceId) || '')
  .filter(Boolean) || [];

📄 3.6 client/src/components/features/storyboard-board/StoryboardBoardItem.tsx

严重程度🔴

问题代码

// 第 464-468 行
processV2Items(storyboard.resources.characters);
processV2Items(storyboard.resources.locations);
processV2Items(storyboard.resources.props);
processV2Items(storyboard.resources.footages);

影响

  • 分镜看板项显示异常
  • 资源轨道显示为空
  • 时间轴上的资源标记缺失

使用场景

  • 分镜看板视图
  • 显示分镜在时间轴上的位置
  • 显示分镜关联的资源

修复方案

const resources = storyboard.items 
  ? getResourcesFromItems(storyboard.items)
  : storyboard.resources || { 
      characters: [], 
      locations: [], 
      props: [], 
      footages: [] 
    };

processV2Items(resources.characters);
processV2Items(resources.locations);
processV2Items(resources.props);
processV2Items(resources.footages);

4. Hooks(2 个文件)

📄 4.1 client/src/hooks/usePreviewActions.ts

严重程度🔴

问题代码

// 第 49-52 行
const existingResources = currentStoryboard.resources || {
  characters: [],
  locations: [],
  props: [],
  footages: []
};

// 第 96-98 行
if (!currentStoryboard || !currentStoryboard.resources) return;

const existingResources = currentStoryboard.resources;
const updatedResources = { ...existingResources };

影响

  • 预览页面的资源添加功能失效
  • 预览页面的资源移除功能失效
  • 资源操作后无法正确更新状态

使用场景

  • 分镜预览页面
  • 快速添加/移除资源
  • 实时更新资源列表

修复方案

const resources = currentStoryboard.items 
  ? getResourcesFromItems(currentStoryboard.items)
  : currentStoryboard.resources || {
      characters: [],
      locations: [],
      props: [],
      footages: []
    };

const existingResources = resources;

📄 4.2 client/src/hooks/useStoryboardBoardLogic.ts

严重程度🔴

问题代码

// 第 823 行
console.log('[useStoryboardBoardLogic] 当前分镜资源:', storyboard.resources);

// 第 837-839 行
const updatedResources = {
  ...(storyboard.resources || { 
    characters: [], 
    locations: [], 
    props: [], 
    footages: [] 
  }),
};

影响

  • 分镜看板逻辑中资源同步失败
  • 拖拽分镜时资源信息丢失
  • 看板状态计算不准确

使用场景

  • 分镜看板的核心业务逻辑
  • 处理分镜拖拽、排序、更新
  • 维护看板状态一致性

修复方案

const resources = storyboard.items 
  ? getResourcesFromItems(storyboard.items)
  : storyboard.resources || { 
      characters: [], 
      locations: [], 
      props: [], 
      footages: [] 
    };

console.log('[useStoryboardBoardLogic] 当前分镜资源:', resources);

const updatedResources = { ...resources };

5. 工具函数(1 个文件)

📄 client/src/utils/storyboard-board-status.ts

严重程度🟡

问题代码

// 第 44-50 行
if (storyboard.resources) {
  storyboard.resources.characters?.forEach((item) => 
    relatedResourceIds.add(item.resourceId)
  );
  storyboard.resources.locations?.forEach((item) => 
    relatedResourceIds.add(item.resourceId)
  );
  storyboard.resources.props?.forEach((item) => 
    relatedResourceIds.add(item.resourceId)
  );
  storyboard.resources.footages?.forEach((item) => 
    relatedResourceIds.add(item.resourceId)
  );
}

影响

  • ⚠️ 分镜状态计算不准确
  • ⚠️ 资源完整性判断失效
  • ⚠️ 看板状态指示器显示错误

使用场景

  • 计算分镜的完成状态
  • 判断资源是否完整
  • 显示状态指示器(如:缺失资源警告)

修复方案

if (storyboard.items) {
  storyboard.items.forEach(item => {
    if (item.resourceId) {
      relatedResourceIds.add(item.resourceId);
    }
  });
} else if (storyboard.resources) {
  // 降级方案
  storyboard.resources.characters?.forEach(item => 
    relatedResourceIds.add(item.resourceId)
  );
  storyboard.resources.locations?.forEach(item => 
    relatedResourceIds.add(item.resourceId)
  );
  storyboard.resources.props?.forEach(item => 
    relatedResourceIds.add(item.resourceId)
  );
  storyboard.resources.footages?.forEach(item => 
    relatedResourceIds.add(item.resourceId)
  );
}

6. Mock 数据(3 个文件)

📄 6.1 client/src/services/mockApi.ts

严重程度🟢

问题代码

// 第 55 行
resources: mockStoryboard.resources,

影响

  • ⚠️ 仅影响开发环境
  • ⚠️ Mock 数据结构与实际 API 不一致
  • ⚠️ 可能导致开发时的测试不准确

修复方案

resources: mockStoryboard.resources,  // 保留向后兼容
items: mockStoryboard.items,  // 添加新字段

📄 6.2 client/src/services/mock/storyboardApi.ts

严重程度🟢

问题代码

// 第 25 行
resources: mockStoryboard.resources,

影响:同 mockApi.ts

修复方案:同 mockApi.ts


📄 6.3 client/src/mocks/storyboard-board.ts

严重程度🟢

问题代码

// 第 7-8 行注释
* - 分镜看板数据实时从分镜及其关联表计算,无独立数据存储
* - 所有轨道数据都源自 storyboards 及其关联的 resources

影响

  • ⚠️ 注释过时,但不影响功能
  • ⚠️ 可能误导开发者

修复方案

* - 分镜看板数据实时从分镜及其关联表计算,无独立数据存储
* - 所有轨道数据都源自 storyboards 及其关联的 items (v3.0)  resources (v2.0)

修复优先级

🔴 P0 - 立即修复(核心功能失效)

  1. API 服务层

    • client/src/services/api/storyboards.ts
    • 影响:所有资源关联功能
  2. UI 组件 - 资源预览

    • client/src/components/features/preview/StoryboardResourcesPreview.tsx
    • 影响:分镜详情页核心功能
  3. UI 组件 - 视频生成

    • client/src/components/features/preview/VideoGenerationPrecheck.tsx
    • 影响:视频生成流程

🟡 P1 - 高优先级(影响用户体验)

  1. Hooks - 预览操作

    • client/src/hooks/usePreviewActions.ts
    • 影响:资源添加/移除功能
  2. Hooks - 看板逻辑

    • client/src/hooks/useStoryboardBoardLogic.ts
    • 影响:分镜看板功能
  3. UI 组件 - 分镜列表

    • client/src/components/features/storyboard/StoryboardList.tsx
    • 影响:列表显示
  4. UI 组件 - 看板项

    • client/src/components/features/storyboard-board/StoryboardBoardItem.tsx
    • 影响:看板显示

🟢 P2 - 中优先级(功能降级)

  1. UI 组件 - 编辑表单

    • client/src/components/features/storyboard/StoryboardEditForm.tsx
    • 影响:资源选择器
  2. UI 组件 - 剧本解析

    • client/src/components/features/storyboard/ParseFlowDialog.tsx
    • 影响:自动化流程
  3. 工具函数 - 状态计算

    • client/src/utils/storyboard-board-status.ts
    • 影响:状态指示器
  4. 类型定义

    • client/src/types/storyboard.ts
    • 影响:类型提示

P3 - 低优先级(开发环境)

  1. Mock 数据
    • client/src/services/mockApi.ts
    • client/src/services/mock/storyboardApi.ts
    • client/src/mocks/storyboard-board.ts
    • 影响:仅开发环境

修复策略

阶段 1:核心功能修复(P0)

目标:恢复基本的资源关联功能

步骤

  1. 修复 API 服务层
  2. 修复资源预览组件
  3. 修复视频生成预检查

预计工作量:2-3 天

阶段 2:用户体验修复(P1)

目标:恢复完整的用户交互功能

步骤

  1. 修复 Hooks
  2. 修复列表和看板显示

预计工作量:2-3 天

阶段 3:功能完善(P2)

目标:修复所有功能降级

步骤

  1. 修复编辑表单
  2. 修复剧本解析
  3. 修复工具函数
  4. 更新类型定义

预计工作量:1-2 天

阶段 4:清理优化(P3)

目标:清理开发环境代码

步骤

  1. 更新 Mock 数据
  2. 删除废弃代码
  3. 更新文档

预计工作量:1 天


总结

关键数据

  • 受影响文件总数:14 个
  • 核心功能失效:6 个组件 + 2 个 Hooks + 1 个 API 服务
  • 预计修复工作量:6-9 天
  • 风险等级🔴

核心问题

  1. API 调用失效:3 个废弃端点被调用
  2. 数据结构不匹配resources vs items
  3. 向后兼容缺失:没有降级方案
  4. 测试覆盖不足:缺少端到端测试

建议

  1. 立即行动:修复 P0 级别的文件
  2. 向后兼容:同时支持 resourcesitems
  3. 增加测试:编写端到端测试覆盖资源关联场景
  4. 分阶段部署:避免一次性破坏所有功能