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.
 

8.9 KiB

分镜资源服务实现

变更日期:2026-02-03
变更类型:功能实现
影响范围:后端 - 分镜资源管理


变更概述

完成分镜资源服务(Storyboard Resource Service)的完整实现,包括分镜图片、视频、对白、配音的管理功能。

实现内容

1. Service 层补充

文件server/app/services/storyboard_resource_service.py

新增方法:

1.1 对白重新排序

async def reorder_dialogues(
    self,
    user_id: str,
    storyboard_id: str,
    dialogue_orders: dict
) -> List[StoryboardDialogue]:
    """重新排序对白"""

功能

  • 批量更新对白的 sequence_order
  • 验证用户权限
  • 自动更新 updated_at 时间戳
  • 返回排序后的对白列表

1.2 视频删除

async def delete_video(
    self, 
    user_id: str, 
    video_id: str
) -> None:
    """删除分镜视频"""

功能

  • 验证视频存在性和用户权限
  • 禁止删除激活的视频
  • 删除数据库记录
  • 减少文件引用计数(通过 FileStorageService)

1.3 配音删除

async def delete_voiceover(
    self, 
    user_id: str, 
    voiceover_id: str
) -> None:
    """删除配音"""

功能

  • 验证配音存在性和用户权限
  • 禁止删除激活的配音
  • 删除数据库记录
  • 减少文件引用计数

2. API 路由补充

文件server/app/api/v1/storyboard_resources.py

新增路由:

2.1 对白重新排序

POST /api/v1/storyboards/{storyboard_id}/dialogues/reorder

请求体

{
  "dialogue_orders": {
    "019d1234-5678-7abc-def0-333333333333": 1,
    "019d1234-5678-7abc-def0-555555555555": 2
  }
}

响应

{
  "success": true,
  "code": 200,
  "message": "对白排序已更新",
  "data": [
    {
      "dialogue_id": "...",
      "sequence_order": 1,
      ...
    }
  ]
}

2.2 视频删除

DELETE /api/v1/storyboard-videos/{video_id}

响应

{
  "success": true,
  "code": 200,
  "message": "分镜视频已删除",
  "data": null
}

错误场景

  • 视频不存在:404 Not Found
  • 无权限:403 Forbidden
  • 删除激活视频:400 Bad Request

2.3 配音删除

DELETE /api/v1/voiceovers/{voiceover_id}

响应

{
  "success": true,
  "code": 200,
  "message": "配音已删除",
  "data": null
}

错误场景

  • 配音不存在:404 Not Found
  • 无权限:403 Forbidden
  • 删除激活配音:400 Bad Request

3. 数据库迁移

文件server/alembic/versions/20260203_1600_add_storyboard_resources.py

创建表:

  • storyboard_images - 分镜图片表
  • storyboard_videos - 分镜视频表
  • storyboard_dialogues - 分镜对白表
  • storyboard_voiceovers - 分镜配音表

3.1 表结构特性

storyboard_images

  • 主键:image_id (UUID)
  • 版本管理:version 字段递增
  • 激活约束:UNIQUE (storyboard_id, is_active) WHERE is_active = true
  • 状态枚举:status (SMALLINT: 0=pending, 1=processing, 2=completed, 3=failed)
  • 文件去重:checksum 字段关联 file_checksums

storyboard_videos

  • 主键:video_id (UUID)
  • 版本管理:version 字段递增
  • 激活约束:UNIQUE (storyboard_id, is_active) WHERE is_active = true
  • 视频元数据:duration, resolution, frame_rate
  • 生成时间:started_at, completed_at

storyboard_dialogues

  • 主键:dialogue_id (UUID)
  • 顺序约束:UNIQUE (storyboard_id, sequence_order)
  • 对白类型:dialogue_type (SMALLINT: 1=normal, 2=inner_monologue, 3=narration)
  • 时间信息:start_time, duration
  • 自动更新:updated_at 字段

storyboard_voiceovers

  • 主键:voiceover_id (UUID)
  • 双重关联:dialogue_id + storyboard_id(冗余,便于查询)
  • 激活约束:UNIQUE (dialogue_id, is_active) WHERE is_active = true
  • TTS 参数:voice_id, speed, volume, pitch
  • 音频元数据:duration, file_size, format

3.2 索引设计

性能索引

  • idx_storyboard_images_storyboard_id - 按分镜查询图片
  • idx_storyboard_images_status - 按状态查询
  • idx_storyboard_images_checksum - 文件去重查询
  • idx_storyboard_images_ai_prompt_id - AI 提示词关联(条件索引)

条件索引

  • idx_storyboard_dialogues_character_id WHERE character_id IS NOT NULL
  • idx_storyboard_dialogues_type WHERE dialogue_type != 1

3.3 数据库注释

所有表和列都添加了中文注释,便于理解:

COMMENT ON TABLE storyboard_images IS '分镜图片表 - 存储AI生成的分镜画面,支持多版本管理';
COMMENT ON COLUMN storyboard_images.status IS '生成状态: 0=pending, 1=processing, 2=completed, 3=failed';

技术规范遵循

1. UUID v7 生成

  • 应用层生成(使用 generate_uuid()
  • 数据库不使用 DEFAULT

2. 日志规范

  • 使用 %-formatting 格式化
  • 异常日志添加 exc_info=True
  • 中文日志消息

3. 时间戳规范

  • 所有时间字段使用 TIMESTAMPTZ
  • 事件时间戳符合 ADR 006

4. 枚举类型

  • 数据库使用 SMALLINT
  • 代码使用 IntEnum(ResourceStatus, DialogueType

5. API 响应格式

  • 统一使用 SuccessResponse 包装
  • 符合 api-design.md 规范

6. 文件存储集成

  • 通过 checksum 实现去重
  • 引用计数管理
  • 自动清理未引用文件

完整功能列表

分镜图片管理

  • 创建图片(AI 生成后调用)
  • 获取所有图片版本
  • 获取激活图片
  • 设置激活图片(切换版本)
  • 删除图片(不能删除激活的)

分镜视频管理

  • 创建视频(AI 生成后调用)
  • 获取所有视频版本
  • 获取激活视频
  • 设置激活视频(切换版本)
  • 删除视频(不能删除激活的)

对白管理

  • 创建对白
  • 获取所有对白
  • 更新对白
  • 删除对白
  • 重新排序对白

配音管理

  • 创建配音(TTS 生成后调用)
  • 获取所有配音版本
  • 获取激活配音
  • 设置激活配音(切换版本)
  • 删除配音(不能删除激活的)

API 端点总览

分镜图片

  • GET /api/v1/storyboards/{storyboard_id}/images - 获取所有图片版本
  • GET /api/v1/storyboards/{storyboard_id}/images/active - 获取激活图片
  • POST /api/v1/storyboards/{storyboard_id}/images - 创建图片
  • POST /api/v1/storyboard-images/{image_id}/activate - 设置激活图片
  • DELETE /api/v1/storyboard-images/{image_id} - 删除图片

分镜视频

  • GET /api/v1/storyboards/{storyboard_id}/videos - 获取所有视频版本
  • GET /api/v1/storyboards/{storyboard_id}/videos/active - 获取激活视频
  • POST /api/v1/storyboards/{storyboard_id}/videos - 创建视频
  • POST /api/v1/storyboard-videos/{video_id}/activate - 设置激活视频
  • DELETE /api/v1/storyboard-videos/{video_id} - 删除视频

对白

  • GET /api/v1/storyboards/{storyboard_id}/dialogues - 获取所有对白
  • POST /api/v1/storyboards/{storyboard_id}/dialogues - 创建对白
  • PATCH /api/v1/dialogues/{dialogue_id} - 更新对白
  • DELETE /api/v1/dialogues/{dialogue_id} - 删除对白
  • POST /api/v1/storyboards/{storyboard_id}/dialogues/reorder - 重新排序对白

配音

  • GET /api/v1/dialogues/{dialogue_id}/voiceovers - 获取所有配音版本
  • GET /api/v1/dialogues/{dialogue_id}/voiceovers/active - 获取激活配音
  • POST /api/v1/dialogues/{dialogue_id}/voiceovers - 创建配音
  • POST /api/v1/voiceovers/{voiceover_id}/activate - 设置激活配音
  • DELETE /api/v1/voiceovers/{voiceover_id} - 删除配音

数据库迁移执行

# 在 Docker 容器中执行迁移
docker exec jointo-server-app python scripts/db_migrate.py upgrade

# 验证迁移
docker exec jointo-server-app alembic current

测试建议

1. 单元测试

  • Service 层方法测试
  • Repository 层 CRUD 测试
  • 权限验证测试

2. 集成测试

  • API 端点测试
  • 文件存储集成测试
  • 版本管理测试

3. 场景测试

  • 多版本生成和切换
  • 激活版本约束验证
  • 文件去重机制验证
  • 引用计数正确性

相关文档

后续工作

1. 测试覆盖

  • 编写单元测试
  • 编写集成测试
  • 编写 API 测试

2. 性能优化

  • 批量操作优化
  • 查询性能测试
  • 索引效果验证

3. 功能扩展

  • 批量删除功能
  • 批量激活功能
  • 资源统计功能

变更人:Kiro AI
审核人:待审核
变更日期:2026-02-03