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.
 

6.0 KiB

RFC 135: 时间轴元素进度状态系统

状态: 已实施
创建时间: 2026-01-28
实施时间: 2026-01-28

背景

时间轴元素块需要通过颜色直观地传递制作进度信息,帮助用户快速识别哪些内容已完成、哪些正在进行、哪些尚未开始。

需求

功能需求

  1. 进度状态定义

    • 未开始 (pending): bg-fill-default(与资源轨道块背景色一致)
    • 部分完成 (partial): 黄色 #f59e0b
    • 已完成 (completed): 绿色 #10b981
  2. 轨道类型状态规则

轨道类型 状态来源 计算规则
分镜轨道 storyboard.isFinalized 未定稿=蓝色,已定稿=绿色
资源轨道 关联资源的 isFinalized 全部完成=绿色,部分完成=黄色,未开始=灰色
视频轨道 video.isFinalized 已定稿=绿色,未定稿=灰色
音效轨道 soundEffect.isFinalized 已定稿=绿色,未定稿=灰色
字幕轨道 subtitle.isFinalized 已定稿=绿色,未定稿=灰色
配音轨道 voiceover.isFinalized 已定稿=绿色,未定稿=灰色
  1. 部分完成示例
    • 资源轨道块关联了角色A和场景A
    • 角色A已定稿,场景A未定稿
    • 显示黄色表示部分完成

技术方案

1. 类型定义扩展

在相关类型中添加 isFinalized?: boolean 字段:

// types/storyboard.ts
export interface Storyboard {
  // ... 其他字段
  isFinalized?: boolean; // 是否已定稿
}

// types/resource.ts
export interface Resource {
  // ... 其他字段
  isFinalized?: boolean; // 是否已定稿
}

export interface Video {
  // ... 其他字段
  isFinalized?: boolean;
}

export interface SoundEffect {
  // ... 其他字段
  isFinalized?: boolean;
}

export interface Subtitle {
  // ... 其他字段
  isFinalized?: boolean;
}

export interface Voiceover {
  // ... 其他字段
  isFinalized?: boolean;
}

2. 状态计算工具

创建 utils/timeline-status.ts 提供状态计算函数:

export type ElementStatus = 'pending' | 'partial' | 'completed';

export const statusColors: Record<ElementStatus, string> = {
  pending: 'bg-fill-default',   // 与资源轨道块背景色一致
  partial: 'bg-[#f59e0b]',   // 黄色
  completed: 'bg-[#10b981]', // 绿色
};

// 分镜状态:未定稿=pending,已定稿=completed
export function getStoryboardStatus(storyboard?: StoryboardWithUI): ElementStatus;

// 资源轨道状态:根据关联资源的定稿状态计算
export function getResourceTrackStatus(
  storyboard?: StoryboardWithUI,
  resources?: Resource[]
): ElementStatus;

// 其他轨道状态:未定稿=pending,已定稿=completed
export function getVideoStatus(video?: Video): ElementStatus;
export function getSoundEffectStatus(soundEffect?: SoundEffect): ElementStatus;
export function getSubtitleStatus(subtitle?: Subtitle): ElementStatus;
export function getVoiceoverStatus(voiceover?: Voiceover): ElementStatus;

// 统一颜色计算入口
export function getTimelineItemColor(
  trackType: string,
  storyboard?: StoryboardWithUI,
  resources?: Resource[],
  video?: Video,
  soundEffect?: SoundEffect,
  subtitle?: Subtitle,
  voiceover?: Voiceover
): string;

3. 组件更新

TimelineTrack.tsx:

import { getTimelineItemColor } from '@/utils/timeline-status';

// 计算元素颜色
const itemColor = getTimelineItemColor(
  track.type,
  relatedStoryboard,
  resources,
  undefined, // video
  undefined, // soundEffect
  undefined, // subtitle
  undefined  // voiceover
);

<TimelineItem
  color={itemColor}
  // ... 其他 props
/>

4. Mock 数据更新

在 mock 数据中添加定稿状态示例:

// mocks/storyboards.ts
createStoryboardWithCompat({
  // ... 其他字段
  isFinalized: true, // 已定稿
})

// mocks/project-resources.ts
{
  // ... 其他字段
  isFinalized: true, // 已定稿
}

实施步骤

  • 扩展类型定义(Storyboard, Resource, Video, SoundEffect, Subtitle, Voiceover)
  • 创建状态计算工具 utils/timeline-status.ts
  • 更新 TimelineTrack 组件使用状态颜色
  • 更新 mock 数据添加定稿状态示例
  • 更新 CSS 添加状态颜色变量

测试场景

场景 1: 分镜轨道

  • 分镜1: isFinalized: true → 显示绿色
  • 分镜2: isFinalized: false → 显示蓝色(默认)
  • 分镜3: 无 isFinalized 字段 → 显示蓝色(默认)

场景 2: 资源轨道

  • 关联角色A(已定稿)+ 场景A(未定稿)→ 显示黄色(部分完成)
  • 关联角色A(已定稿)+ 场景B(已定稿)→ 显示绿色(全部完成)
  • 关联角色A(未定稿)+ 场景A(未定稿)→ 显示 bg-fill-default(未开始)

场景 3: 其他轨道

  • 视频/音效/字幕/配音: isFinalized: true → 显示绿色
  • 视频/音效/字幕/配音: isFinalized: false → 显示 bg-fill-default

后续优化

  1. UI 交互

    • 添加右键菜单"标记为已完成"
    • 添加批量操作功能
  2. 状态指示器

    • 在元素块上添加状态图标
    • 悬停显示详细状态信息
  3. 进度统计

    • 在项目面板显示整体完成度
    • 按轨道类型统计完成率
  4. 后端集成

    • 实现 PATCH /api/v1/storyboards/{id} 更新 isFinalized
    • 实现 PATCH /api/v1/resources/{id} 更新 isFinalized
    • 实现批量更新接口

影响范围

新增文件

  • client/src/utils/timeline-status.ts

修改文件

  • client/src/types/storyboard.ts
  • client/src/types/resource.ts
  • client/src/components/features/timeline/TimelineTrack.tsx
  • client/src/components/features/timeline/TimelineItem.tsx
  • client/src/mocks/storyboards.ts
  • client/src/mocks/project-resources.ts
  • client/src/styles/globals.css

不影响

  • 现有 API 接口(字段为可选)
  • 其他组件逻辑
  • 数据库结构(暂时仅前端实现)

参考