# 插入新分镜功能实现 ## 问题描述 分镜描述面板中的"插入新分镜"按钮点击后无法正常工作,存在以下问题: 1. 数据结构不匹配(order vs orderIndex) 2. API接口缺少projectId字段 3. 插入逻辑不完整,未处理后续分镜重新排序 4. 缓存更新逻辑有误 ## 修复内容 ### 1. 类型定义修正 **文件**: `client/src/types/storyboard.ts` - 为`CreateStoryboardDto`添加`projectId: number`字段 - 确保类型定义与API接口匹配 ### 2. API方法修复 **文件**: `client/src/services/mockApi.ts` #### 修复create方法 - 支持在指定`orderIndex`位置插入新分镜 - 自动为后续分镜的`orderIndex`+1 - 修正ID生成逻辑,使用数字类型 - 添加默认的`startTime`和`endTime`计算 #### 统一字段引用 - 所有方法统一使用`orderIndex`字段(替代`order`) - 修正ID类型处理(string ↔ number转换) - 更新排序逻辑使用`orderIndex` #### 数据转换逻辑 - 添加`convertToStandardStoryboard`函数 - 将mock数据转换为标准Storyboard格式 - 确保数据结构一致性 ### 3. 缓存逻辑更新 **文件**: `client/src/hooks/api/useStoryboards.ts` - 修正所有缓存更新中的字段引用 - 统一使用`orderIndex`进行排序 - 修正projectId的类型转换 ### 4. 组件逻辑完善 **文件**: `client/src/components/features/storyboard/StoryboardDescPanel.tsx` #### handleInsertStoryboard函数 - 传递正确的`projectId`(转换为number类型) - 计算正确的`orderIndex` - 确保新分镜插入到指定位置 #### handleCreateStoryboard函数 - 添加`projectId`参数传递 - 保持原有的末尾添加逻辑 ## 技术细节 ### 插入逻辑 ```typescript // 如果指定了orderIndex,需要为后续分镜重新排序 let targetOrderIndex = data.orderIndex; if (targetOrderIndex === undefined) { // 添加到末尾 const maxOrderIndex = Math.max( 0, ...projectStoryboards.map((s) => s.orderIndex) ); targetOrderIndex = maxOrderIndex + 1; } else { // 将指定位置及之后的分镜orderIndex都+1 projectStoryboards .filter((s) => s.orderIndex >= targetOrderIndex!) .forEach((s) => { s.orderIndex += 1; s.updatedAt = new Date().toISOString(); }); } ``` ### 数据转换 ```typescript const convertToStandardStoryboard = (mockStoryboard: any): Storyboard => ({ id: mockStoryboard.id, projectId: mockStoryboard.projectId, // ... 其他字段映射 orderIndex: mockStoryboard.orderIndex, // ... }); ``` ## 修复结果 - ✅ 点击插入按钮能在指定位置创建新分镜 - ✅ 后续分镜的orderIndex自动递增 - ✅ 新分镜自动选中 - ✅ UI立即更新显示新分镜 - ✅ 数据结构统一,类型安全 ## 修复时间 2026-01-12