# 资源轨道选中状态修复记录 **日期**: 2026-02-08 **类型**: Bug 修复 **影响范围**: 分镜看板资源轨道交互 **严重程度**: 中(影响用户体验) ## 问题描述 用户报告资源轨道存在以下问题: 1. **资源轨道元素不高亮**:点击资源轨道元素块后,元素没有显示高亮效果 2. **选中状态冲突**:点击资源轨道元素时,需要同时选中对应的分镜(用于资源面板显示),但不应该影响资源轨道元素的选中状态 ## 问题根本原因 ### 1. 选中状态覆盖问题 **问题代码** (`client/src/hooks/useStoryboardBoardLogic.ts:739`): ```typescript // 点击资源轨道元素时 selectStoryboard(cleanSbId); // ❌ 这会覆盖 selectedStoryboardBoardItems ``` **问题分析**: - `selectStoryboard` 方法会同时更新 `selectedStoryboardId` 和 `selectedStoryboardBoardItems` - 当点击资源轨道元素时: 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` **新增方法**: ```typescript selectStoryboardOnly: (id) => set({ selectedStoryboardId: id, selectedResourceId: null, // 不更新 selectedStoryboardBoardItems,保持看板选中状态 }), ``` **作用**: - 只更新 `selectedStoryboardId`,不影响 `selectedStoryboardBoardItems` - 用于资源轨道点击时选中对应分镜,但保持资源轨道元素的高亮状态 #### 2. 修改资源轨道点击逻辑 **文件**: `client/src/hooks/useStoryboardBoardLogic.ts` **修改位置**: 第 756 行 **修改前**: ```typescript selectStoryboard(cleanSbId); ``` **修改后**: ```typescript // 使用 selectStoryboardOnly 而不是 selectStoryboard // 这样可以保持资源轨道元素的选中状态,不会被覆盖 selectStoryboardOnly(cleanSbId); ``` #### 3. 保持分镜列表同步逻辑 **文件**: `client/src/stores/editorStore.ts` **修改位置**: `selectStoryboard` 方法 **修改后**: ```typescript 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. **状态分离**:`selectedStoryboardId` 和 `selectedStoryboardBoardItems` 独立管理 2. **职责清晰**: - `selectStoryboard`:用于分镜列表和分镜轨道的选中,同步更新看板状态 - `selectStoryboardOnly`:用于资源轨道的选中,只更新分镜 ID,不影响看板状态 3. **易于维护**:逻辑清晰,不同场景使用不同方法 ### 注意事项 1. **方法选择**: - 点击分镜列表或分镜轨道 → 使用 `selectStoryboard` - 点击资源轨道 → 使用 `selectStoryboardOnly` 2. **状态同步**:`selectStoryboard` 会同步更新看板选中状态,确保一致性 3. **向后兼容**:现有功能不受影响,只是新增了一个方法