# 资源添加到错误分镜的问题修复 **日期**: 2026-02-04 **类型**: Critical Bug Fix **影响范围**: 分镜资源管理 - 资源添加功能 ## 问题描述 用户点击分镜5的资源轨道块,打开资源预览面板后添加角色,但角色被错误地添加到了分镜1,而不是分镜5。 ## 问题复现步骤 1. 点击分镜5的资源轨道块 2. 资源预览面板正确显示分镜5的资源 3. 点击"添加角色",选择一个角色 4. 角色被添加到分镜1,而不是分镜5 ## 根本原因 **状态管理冲突**: ```typescript // editorStore.ts selectResource: (id) => set({ selectedResourceId: id, selectedStoryboardId: null // ❌ 清空了 selectedStoryboardId! }), ``` **问题链条**: 1. 用户点击分镜5的资源轨道块 2. `handleSelectItem` 调用 `selectStoryboard('分镜5ID')` 3. `selectedStoryboardId` = 分镜5ID ✅ 4. `currentStoryboard` 计算为分镜5 ✅ 5. `StoryboardResourcesPreview` 显示分镜5的资源 ✅ 6. 用户点击添加角色 7. `handleAddResource(分镜5ID, 角色ID, ...)` 被调用 ✅ 8. **关键问题**:资源添加成功后,调用 `handleResourceSelect(resourceId)` 9. `handleResourceSelect` → `selectResource(resourceId)` 10. `selectResource` 执行:`set({ selectedResourceId: id, selectedStoryboardId: null })` 11. `selectedStoryboardId` 被清空!❌ 12. `currentStoryboard` 重新计算,变成第一个分镜或 null ❌ 13. 如果用户再次添加资源,使用的是错误的 `storyboard.id` ❌ ## 解决方案 移除 `handleAddResource` 中的 `handleResourceSelect(resourceId)` 调用: **修改前**: ```typescript try { await updateStoryboardMutation.mutateAsync({ id: storyboardId, data: { resources: updatedResources, }, }); console.log('[useStoryboardBoardLogic] 资源添加成功'); // 选中该资源以提供视觉反馈 handleResourceSelect(resourceId); // ❌ 这会清空 selectedStoryboardId } catch (error) { console.error('[useStoryboardBoardLogic] 资源添加失败:', error); } ``` **修改后**: ```typescript try { await updateStoryboardMutation.mutateAsync({ id: storyboardId, data: { resources: updatedResources, }, }); console.log('[useStoryboardBoardLogic] 资源添加成功,分镜ID:', storyboardId); } catch (error) { console.error('[useStoryboardBoardLogic] 资源添加失败:', error); } ``` ## 为什么移除 handleResourceSelect? 1. **上下文不匹配**:在资源总览界面(StoryboardResourcesPreview)添加资源后,不需要切换到单个资源的详细视图 2. **状态冲突**:`selectResource` 会清空 `selectedStoryboardId`,破坏当前的分镜上下文 3. **用户体验**:用户在分镜资源总览中添加资源,期望停留在总览界面,而不是跳转到资源详情 ## 修复效果 修复后: 1. ✅ 点击任意分镜的资源轨道块,打开资源预览 2. ✅ 添加资源时,资源被正确添加到当前选中的分镜 3. ✅ `selectedStoryboardId` 保持不变 4. ✅ 可以连续添加多个资源到同一个分镜 5. ✅ 不会意外切换到其他分镜 ## 影响文件 - `client/src/hooks/useStoryboardBoardLogic.ts` - 移除 `handleAddResource` 中的 `handleResourceSelect` 调用 ## 相关问题 这个问题暴露了状态管理的设计缺陷: **当前设计**: ```typescript selectStoryboard: (id) => set({ selectedStoryboardId: id, selectedResourceId: null }), selectResource: (id) => set({ selectedResourceId: id, selectedStoryboardId: null }), ``` 这种互斥设计假设用户不能同时选中分镜和资源,但在资源总览界面,用户需要: - 选中一个分镜(查看其资源总览) - 同时可能需要高亮某个资源 **未来优化建议**: 考虑允许同时选中分镜和资源,或者引入更细粒度的状态管理: ```typescript // 可能的改进方案 selectStoryboard: (id) => set({ selectedStoryboardId: id }), selectResource: (id) => set({ selectedResourceId: id }), clearStoryboardSelection: () => set({ selectedStoryboardId: null }), clearResourceSelection: () => set({ selectedResourceId: null }), ``` ## 测试验证 请验证以下场景: 1. 点击分镜5的资源轨道块 2. 添加一个角色 3. 检查角色是否被添加到分镜5(而不是分镜1) 4. 继续添加更多资源 5. 验证所有资源都被添加到分镜5