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.
 

2.7 KiB

插入新分镜功能实现

问题描述

分镜描述面板中的"插入新分镜"按钮点击后无法正常工作,存在以下问题:

  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生成逻辑,使用数字类型
  • 添加默认的startTimeendTime计算

统一字段引用

  • 所有方法统一使用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参数传递
  • 保持原有的末尾添加逻辑

技术细节

插入逻辑

// 如果指定了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();
    });
}

数据转换

const convertToStandardStoryboard = (mockStoryboard: any): Storyboard => ({
  id: mockStoryboard.id,
  projectId: mockStoryboard.projectId,
  // ... 其他字段映射
  orderIndex: mockStoryboard.orderIndex,
  // ...
});

修复结果

  • 点击插入按钮能在指定位置创建新分镜
  • 后续分镜的orderIndex自动递增
  • 新分镜自动选中
  • UI立即更新显示新分镜
  • 数据结构统一,类型安全

修复时间

2026-01-12