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
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}/resourcesPOST /storyboards/{id}/resources/batchDELETE /storyboards/{id}/resources/batch
修复方案:
- 删除
syncStoryboardResources函数 - 使用
storyboard_itemsAPI 替代 - 修改
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字段 - ⚠️ 代码提示会显示废弃字段
修复方案:
- 标记
resources字段为@deprecated - 添加 JSDoc 注释说明迁移路径
- 最终删除
StoryboardResources和StoryboardResourceItem接口
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_itemsAPI 保存资源关联 - 不再依赖
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 - 立即修复(核心功能失效)
-
API 服务层
client/src/services/api/storyboards.ts- 影响:所有资源关联功能
-
UI 组件 - 资源预览
client/src/components/features/preview/StoryboardResourcesPreview.tsx- 影响:分镜详情页核心功能
-
UI 组件 - 视频生成
client/src/components/features/preview/VideoGenerationPrecheck.tsx- 影响:视频生成流程
🟡 P1 - 高优先级(影响用户体验)
-
Hooks - 预览操作
client/src/hooks/usePreviewActions.ts- 影响:资源添加/移除功能
-
Hooks - 看板逻辑
client/src/hooks/useStoryboardBoardLogic.ts- 影响:分镜看板功能
-
UI 组件 - 分镜列表
client/src/components/features/storyboard/StoryboardList.tsx- 影响:列表显示
-
UI 组件 - 看板项
client/src/components/features/storyboard-board/StoryboardBoardItem.tsx- 影响:看板显示
🟢 P2 - 中优先级(功能降级)
-
UI 组件 - 编辑表单
client/src/components/features/storyboard/StoryboardEditForm.tsx- 影响:资源选择器
-
UI 组件 - 剧本解析
client/src/components/features/storyboard/ParseFlowDialog.tsx- 影响:自动化流程
-
工具函数 - 状态计算
client/src/utils/storyboard-board-status.ts- 影响:状态指示器
-
类型定义
client/src/types/storyboard.ts- 影响:类型提示
⚪ P3 - 低优先级(开发环境)
- Mock 数据
client/src/services/mockApi.tsclient/src/services/mock/storyboardApi.tsclient/src/mocks/storyboard-board.ts- 影响:仅开发环境
修复策略
阶段 1:核心功能修复(P0)
目标:恢复基本的资源关联功能
步骤:
- 修复 API 服务层
- 修复资源预览组件
- 修复视频生成预检查
预计工作量:2-3 天
阶段 2:用户体验修复(P1)
目标:恢复完整的用户交互功能
步骤:
- 修复 Hooks
- 修复列表和看板显示
预计工作量:2-3 天
阶段 3:功能完善(P2)
目标:修复所有功能降级
步骤:
- 修复编辑表单
- 修复剧本解析
- 修复工具函数
- 更新类型定义
预计工作量:1-2 天
阶段 4:清理优化(P3)
目标:清理开发环境代码
步骤:
- 更新 Mock 数据
- 删除废弃代码
- 更新文档
预计工作量:1 天
总结
关键数据
- 受影响文件总数:14 个
- 核心功能失效:6 个组件 + 2 个 Hooks + 1 个 API 服务
- 预计修复工作量:6-9 天
- 风险等级:🔴 高
核心问题
- API 调用失效:3 个废弃端点被调用
- 数据结构不匹配:
resourcesvsitems - 向后兼容缺失:没有降级方案
- 测试覆盖不足:缺少端到端测试
建议
- 立即行动:修复 P0 级别的文件
- 向后兼容:同时支持
resources和items - 增加测试:编写端到端测试覆盖资源关联场景
- 分阶段部署:避免一次性破坏所有功能