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.6 KiB
3.6 KiB
资源轨道分镜预览修复
日期: 2026-02-04
类型: Bug Fix
影响范围: 分镜看板 - 资源轨道点击交互
问题描述
点击资源轨道的元素时,只有前3个分镜能够正确显示分镜资源预览(StoryboardResourcesPreview),其他分镜的资源轨道块点击后无反应。
根本原因
数据层与渲染层的不一致:
-
渲染层(StoryboardBoardTrack 组件):
- 为每个分镜生成
itemsToRender,包含占位项 - 占位项用于没有真实数据的分镜,ID 格式为
resource-${storyboardId}
- 为每个分镜生成
-
数据层(useStoryboardBoardLogic):
handleSelectItem查找时使用原始tracks[].items(来自 API)- 原始数据不包含占位项
-
问题表现:
- 前3个分镜在 API 返回的
trackItems中有真实数据 → 能找到 → 正常工作 - 后面的分镜只有占位项(仅存在于渲染层)→ 找不到 →
isResourceTrackItem = false→ 无反应
- 前3个分镜在 API 返回的
解决方案
在 handleSelectItem 中添加 fallback 逻辑,处理占位项:
// Fallback: 处理资源轨道占位项(不在 trackItems 中,仅存在于渲染层)
if (!clickedItem && !isResourceTrackItem && id.startsWith('resource-')) {
console.log('[handleSelectItem] 未找到资源轨道项,尝试 fallback 处理占位项');
const storyboardId = id.replace(/^resource-/, '');
const storyboardTrack = typedTracks.find((t) => t.type === 'storyboard');
const storyboard = storyboardTrack?.items.find((i) => i.id.toString() === storyboardId);
if (storyboard) {
console.log('[handleSelectItem] Fallback 成功:找到对应分镜', storyboard);
isResourceTrackItem = true;
clickedItem = {
id: id,
storyboardId: storyboardId,
startTime: storyboard.startTime,
endTime: storyboard.endTime,
trackId: '',
projectId: '',
content: '',
} as StoryboardBoardItemType;
} else {
console.warn('[handleSelectItem] Fallback 失败:未找到对应分镜', storyboardId);
}
}
修复逻辑
- 检测占位项:当找不到
clickedItem且 ID 是resource-格式时 - 提取分镜 ID:从
resource-${storyboardId}中提取storyboardId - 查找分镜:在分镜轨道中查找对应的分镜
- 构造虚拟 item:如果找到分镜,构造一个虚拟的
clickedItem - 标记为资源轨道项:设置
isResourceTrackItem = true
改进点
- 不影响现有逻辑:有真实数据的分镜仍然走原有查找逻辑
- 兼容占位项:为占位项提供 fallback 处理
- 详细的日志:便于调试和追踪问题
- 健壮的错误处理:当找不到分镜时输出警告
测试验证
修复后,所有资源轨道块(包括占位块)点击时都应该:
- ✅ 打开资源面板
- ✅ 显示对应分镜的资源总览(StoryboardResourcesPreview)
- ✅ 清除具体资源选中状态
- ✅ 输出详细的调试日志
影响文件
client/src/hooks/useStoryboardBoardLogic.ts- 在handleSelectItem函数中添加占位项 fallback 逻辑
相关组件
StoryboardBoardPanel- 分镜看板面板StoryboardBoardTrack- 分镜看板轨道(生成占位项)PreviewPanel- 预览面板StoryboardResourcesPreview- 分镜资源总览组件
技术细节
为什么不在数据层添加占位项?
- 占位项是 UI 层的概念,用于填充视觉空白
- 数据层应该保持纯净,只包含真实数据
- Fallback 方案更简单,不需要修改数据结构
- 避免在多个地方维护占位项逻辑