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

资源轨道选中状态修复记录

日期: 2026-02-08 类型: Bug 修复 影响范围: 分镜看板资源轨道交互 严重程度: 中(影响用户体验)

问题描述

用户报告资源轨道存在以下问题:

  1. 资源轨道元素不高亮:点击资源轨道元素块后,元素没有显示高亮效果
  2. 选中状态冲突:点击资源轨道元素时,需要同时选中对应的分镜(用于资源面板显示),但不应该影响资源轨道元素的选中状态

问题根本原因

1. 选中状态覆盖问题

问题代码 (client/src/hooks/useStoryboardBoardLogic.ts:739):

// 点击资源轨道元素时
selectStoryboard(cleanSbId); // ❌ 这会覆盖 selectedStoryboardBoardItems

问题分析

  • selectStoryboard 方法会同时更新 selectedStoryboardIdselectedStoryboardBoardItems
  • 当点击资源轨道元素时:
    1. 先调用 selectStoryboardBoardItems([id]) 选中资源轨道元素
    2. 然后调用 selectStoryboard(cleanSbId) 选中对应分镜
    3. selectStoryboard 会将 selectedStoryboardBoardItems 覆盖为 [cleanSbId]
    4. 导致资源轨道元素的选中状态丢失

2. 数据流示意图

修复前的数据流

用户点击资源轨道元素 (resource-xxx)
    ↓
selectStoryboardBoardItems(['resource-xxx'])  // 选中资源轨道元素
    ↓
selectedStoryboardBoardItems = ['resource-xxx']  // ✅ 正确
    ↓
selectStoryboard(storyboardId)  // 选中分镜
    ↓
selectedStoryboardBoardItems = [storyboardId]  // ❌ 覆盖了资源轨道选中状态
    ↓
资源轨道元素失去高亮

解决方案

核心原则

引入 双重选中状态管理

  1. selectedStoryboardId:用于资源面板显示对应分镜的资源
  2. selectedStoryboardBoardItems:用于看板元素的高亮显示
  3. 两个状态独立管理,互不干扰

修改内容

1. 添加 selectStoryboardOnly 方法

文件: client/src/stores/editorStore.ts

新增方法:

selectStoryboardOnly: (id) =>
  set({
    selectedStoryboardId: id,
    selectedResourceId: null,
    // 不更新 selectedStoryboardBoardItems,保持看板选中状态
  }),

作用

  • 只更新 selectedStoryboardId,不影响 selectedStoryboardBoardItems
  • 用于资源轨道点击时选中对应分镜,但保持资源轨道元素的高亮状态

2. 修改资源轨道点击逻辑

文件: client/src/hooks/useStoryboardBoardLogic.ts

修改位置: 第 756 行

修改前:

selectStoryboard(cleanSbId);

修改后:

// 使用 selectStoryboardOnly 而不是 selectStoryboard
// 这样可以保持资源轨道元素的选中状态,不会被覆盖
selectStoryboardOnly(cleanSbId);

3. 保持分镜列表同步逻辑

文件: client/src/stores/editorStore.ts

修改位置: selectStoryboard 方法

修改后:

selectStoryboard: (id) =>
  set({
    selectedStoryboardId: id,
    selectedResourceId: null,
    // 同步更新分镜看板的选中状态
    selectedStoryboardBoardItems: id ? [id] : [],
  }),

作用

  • 点击分镜列表或分镜轨道元素时,同步更新看板选中状态
  • 确保分镜列表和分镜看板的选中状态保持一致

修复后的数据流

用户点击资源轨道元素 (resource-xxx)
    ↓
selectStoryboardBoardItems(['resource-xxx'])  // 选中资源轨道元素
    ↓
selectedStoryboardBoardItems = ['resource-xxx']  // ✅ 正确
    ↓
selectStoryboardOnly(storyboardId)  // 选中分镜(仅更新 selectedStoryboardId)
    ↓
selectedStoryboardId = storyboardId  // ✅ 正确
selectedStoryboardBoardItems = ['resource-xxx']  // ✅ 保持不变
    ↓
资源轨道元素保持高亮 ✅
资源面板显示对应分镜的资源 ✅

测试建议

1. 基础功能测试

  • 点击资源轨道元素,验证元素是否高亮
  • 验证资源面板是否打开并显示对应分镜的资源
  • 验证分镜轨道的分镜块是否不会被选中
  • 点击分镜列表中的分镜,验证分镜看板中的分镜块是否同步选中

2. 交互测试

  • 点击资源轨道元素 A,然后点击资源轨道元素 B,验证选中状态切换
  • 点击资源轨道元素,然后点击分镜轨道元素,验证选中状态切换
  • 点击分镜列表,然后点击资源轨道元素,验证选中状态切换

3. 边界情况测试

  • 点击空白区域,验证选中状态是否清除
  • 连续快速点击多个资源轨道元素,验证选中状态是否正确
  • 拖拽分镜后,点击资源轨道元素,验证功能是否正常

相关文件

前端

  • client/src/stores/editorStore.ts - 状态管理(新增 selectStoryboardOnly 方法)
  • client/src/hooks/useStoryboardBoardLogic.ts - 点击逻辑修改
  • client/src/components/features/storyboard-board/StoryboardBoardTrack.tsx - 渲染逻辑
  • client/src/components/features/storyboard-board/StoryboardBoardItem.tsx - 高亮样式

总结

修复效果

通过引入 selectStoryboardOnly 方法,实现了:

  1. 资源轨道元素正确高亮:点击后元素显示白色边框高亮效果
  2. 资源面板正确显示:自动打开并显示对应分镜的资源总览
  3. 分镜轨道不受影响:分镜轨道的分镜块不会被误选中
  4. 分镜列表同步正常:点击分镜列表时,分镜看板同步选中

架构优势

  1. 状态分离selectedStoryboardIdselectedStoryboardBoardItems 独立管理
  2. 职责清晰
    • selectStoryboard:用于分镜列表和分镜轨道的选中,同步更新看板状态
    • selectStoryboardOnly:用于资源轨道的选中,只更新分镜 ID,不影响看板状态
  3. 易于维护:逻辑清晰,不同场景使用不同方法

注意事项

  1. 方法选择
    • 点击分镜列表或分镜轨道 → 使用 selectStoryboard
    • 点击资源轨道 → 使用 selectStoryboardOnly
  2. 状态同步selectStoryboard 会同步更新看板选中状态,确保一致性
  3. 向后兼容:现有功能不受影响,只是新增了一个方法