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