# 分镜资源服务实现 > **变更日期**:2026-02-03 > **变更类型**:功能实现 > **影响范围**:后端 - 分镜资源管理 --- ## 变更概述 完成分镜资源服务(Storyboard Resource Service)的完整实现,包括分镜图片、视频、对白、配音的管理功能。 ## 实现内容 ### 1. Service 层补充 **文件**:`server/app/services/storyboard_resource_service.py` 新增方法: #### 1.1 对白重新排序 ```python async def reorder_dialogues( self, user_id: str, storyboard_id: str, dialogue_orders: dict ) -> List[StoryboardDialogue]: """重新排序对白""" ``` **功能**: - 批量更新对白的 `sequence_order` - 验证用户权限 - 自动更新 `updated_at` 时间戳 - 返回排序后的对白列表 #### 1.2 视频删除 ```python async def delete_video( self, user_id: str, video_id: str ) -> None: """删除分镜视频""" ``` **功能**: - 验证视频存在性和用户权限 - 禁止删除激活的视频 - 删除数据库记录 - 减少文件引用计数(通过 FileStorageService) #### 1.3 配音删除 ```python async def delete_voiceover( self, user_id: str, voiceover_id: str ) -> None: """删除配音""" ``` **功能**: - 验证配音存在性和用户权限 - 禁止删除激活的配音 - 删除数据库记录 - 减少文件引用计数 ### 2. API 路由补充 **文件**:`server/app/api/v1/storyboard_resources.py` 新增路由: #### 2.1 对白重新排序 ```http POST /api/v1/storyboards/{storyboard_id}/dialogues/reorder ``` **请求体**: ```json { "dialogue_orders": { "019d1234-5678-7abc-def0-333333333333": 1, "019d1234-5678-7abc-def0-555555555555": 2 } } ``` **响应**: ```json { "success": true, "code": 200, "message": "对白排序已更新", "data": [ { "dialogue_id": "...", "sequence_order": 1, ... } ] } ``` #### 2.2 视频删除 ```http DELETE /api/v1/storyboard-videos/{video_id} ``` **响应**: ```json { "success": true, "code": 200, "message": "分镜视频已删除", "data": null } ``` **错误场景**: - 视频不存在:404 Not Found - 无权限:403 Forbidden - 删除激活视频:400 Bad Request #### 2.3 配音删除 ```http DELETE /api/v1/voiceovers/{voiceover_id} ``` **响应**: ```json { "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 数据库注释 所有表和列都添加了中文注释,便于理解: ```sql 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}` - 删除配音 ## 数据库迁移执行 ```bash # 在 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. 场景测试 - 多版本生成和切换 - 激活版本约束验证 - 文件去重机制验证 - 引用计数正确性 ## 相关文档 - [分镜资源服务需求文档](../../requirements/backend/04-services/project/storyboard-resource-service.md) - [Jointo 技术栈规范](../../architecture/tech-stack.md) - [数据库迁移最佳实践](../../architecture/adrs/007-database-migration-best-practices.md) - [日志使用规范](../../architecture/tech-stack.md#logging) ## 后续工作 ### 1. 测试覆盖 - [ ] 编写单元测试 - [ ] 编写集成测试 - [ ] 编写 API 测试 ### 2. 性能优化 - [ ] 批量操作优化 - [ ] 查询性能测试 - [ ] 索引效果验证 ### 3. 功能扩展 - [ ] 批量删除功能 - [ ] 批量激活功能 - [ ] 资源统计功能 --- **变更人**:Kiro AI **审核人**:待审核 **变更日期**:2026-02-03