7.6 KiB
分镜看板服务实现
日期:2026-02-04
类型:功能实现
影响范围:后端服务层、API 层
变更概述
实现分镜看板服务(StoryboardBoardService),提供多轨道视图展示分镜及其关联资源的可视化看板功能。
变更详情
1. 创建 Schema 定义
文件:server/app/schemas/storyboard_board.py
创建了 4 个 Schema 类:
StoryboardBoardItem- 分镜看板项StoryboardBoardTrack- 分镜看板轨道StoryboardBoardData- 完整分镜看板数据StoryboardReorder- 分镜重新排序请求
2. 创建 Service 层
文件:server/app/services/storyboard_board_service.py
实现了 StoryboardBoardService 类,提供以下功能:
核心方法
-
get_storyboard_board_data() - 获取项目的完整分镜看板数据
- 实时从分镜表计算,无独立数据存储
- 支持按轨道类型筛选
- 计算每个项的 start_time 和 end_time
- 计算项目总时长
-
reorder_storyboards() - 调整分镜顺序
- 直接更新分镜表的 order_index 字段
- 使用事务批量更新
- 应用层验证分镜存在性
- 返回更新后的看板数据
-
get_track_items() - 获取指定轨道的所有项
- 支持 6 种轨道类型:storyboard/resource/video/sound/subtitle/voice
- 验证轨道类型有效性
-
get_items_by_time_range() - 查询时间范围内的所有项
- 支持时间范围筛选
- 支持按轨道类型筛选
私有方法
_calculate_storyboard_board_tracks()- 实时计算分镜看板轨道数据_get_track_name()- 获取轨道显示名称
3. 创建 API 路由
文件:server/app/api/v1/storyboard_board.py
实现了 4 个 API 端点:
-
GET /projects/{project_id}/storyboard-board
- 获取项目分镜看板数据
- 查询参数:track_types(可选,逗号分隔)
-
POST /projects/{project_id}/storyboard-board/reorder
- 调整分镜顺序
- 请求体:storyboard_orders(分镜 ID 到新排序的映射)
-
GET /projects/{project_id}/storyboard-board/tracks/{track_type}
- 获取指定轨道的所有项
- 路径参数:track_type
-
GET /projects/{project_id}/storyboard-board/items/time-range
- 查询时间范围内的所有项
- 查询参数:start_time、end_time、track_types(可选)
4. 注册路由
文件:server/app/api/v1/__init__.py
- 导入
storyboard_board模块 - 注册路由:
api_router.include_router(storyboard_board.router, tags=["分镜看板"])
技术栈符合性
✅ 完全符合 jointo-tech-stack 规范:
-
日志系统
- 使用标准库
logging - 使用 %-formatting 格式化
- 异常日志使用
exc_info=True
- 使用标准库
-
异步编程
- 所有数据库操作使用
async/await - 使用
AsyncSession
- 所有数据库操作使用
-
无物理外键
- 应用层验证引用完整性
- 使用
batch_exists()批量检查分镜存在性
-
事务管理
- 批量更新使用
async with self.db.begin()
- 批量更新使用
-
统一响应格式
- 所有 API 使用
ApiResponse格式
- 所有 API 使用
-
权限检查
- 使用
ProjectRepository.check_user_permission() - 区分 viewer 和 editor 权限
- 使用
设计特点
1. 无独立数据存储
分镜看板服务不创建独立的数据表,所有数据实时从分镜表计算:
-
优点:
- 避免数据冗余
- 自动同步(分镜变化立即反映到看板)
- 简化维护(无需维护同步逻辑)
-
实现:
- 按 order_index 排序分镜
- 累积计算每个分镜的时间位置
- 实时组装轨道数据
2. 六种轨道类型
| 轨道类型 | 数据来源 | 说明 |
|---|---|---|
| storyboard | storyboards 表 | 分镜元素块 |
| resource | storyboard_items 表 | 项目素材(角色、场景、道具) |
| video | 待实现 | 分镜生成的视频 |
| sound | 待实现 | 分镜搭配的音效 |
| subtitle | 待实现 | 对白台词文本 |
| voice | 待实现 | 对白生成的配音音频 |
注意:当前实现仅包含 storyboard 轨道,其他轨道需要在后续实现中添加 Relationship 查询。
3. 时间计算逻辑
current_time = 0.0
for storyboard in storyboards:
start_time = current_time
duration = float(storyboard.actual_duration or storyboard.estimated_duration or 0)
end_time = current_time + duration
current_time = end_time
API 示例
1. 获取分镜看板数据
请求:
GET /api/v1/projects/019c0361-ea8e-7d43-bbcc-edd8eea06bb6/storyboard-board?track_types=storyboard,video
响应:
{
"success": true,
"code": 200,
"message": "分镜看板数据获取成功",
"data": {
"project_id": "019c0361-ea8e-7d43-bbcc-edd8eea06bb6",
"total_duration": 120.5,
"storyboard_count": 15,
"tracks": [
{
"type": "storyboard",
"name": "分镜轨道",
"items": [
{
"id": "019c0361-ea8e-7d43-bbcc-edd8eea06bb7",
"type": "storyboard",
"start_time": 0,
"end_time": 5.5,
"data": {
"id": "019c0361-ea8e-7d43-bbcc-edd8eea06bb7",
"title": "开场镜头",
"shot_size": 3,
"camera_movement": 1
}
}
]
}
]
},
"timestamp": "2026-02-04T10:00:00Z"
}
2. 调整分镜顺序
请求:
POST /api/v1/projects/019c0361-ea8e-7d43-bbcc-edd8eea06bb6/storyboard-board/reorder
Content-Type: application/json
{
"storyboard_orders": {
"019c0361-ea8e-7d43-bbcc-edd8eea06bb7": 0,
"019c0361-ea8e-7d43-bbcc-edd8eea06bb8": 1,
"019c0361-ea8e-7d43-bbcc-edd8eea06bb9": 2
}
}
响应:
{
"success": true,
"code": 200,
"message": "分镜顺序调整成功",
"data": {
"project_id": "019c0361-ea8e-7d43-bbcc-edd8eea06bb6",
"total_duration": 120.5,
"storyboard_count": 15,
"tracks": [...]
},
"timestamp": "2026-02-04T10:00:00Z"
}
后续优化建议
1. 性能优化
- 缓存策略:使用 Redis 缓存分镜看板数据(5 分钟)
- 分页加载:对于大型项目(100+ 分镜)实现分页
- 前端虚拟滚动:只渲染可见区域的轨道项
2. 功能扩展
- 实现其他轨道:resource、video、sound、subtitle、voice
- 添加 Relationship:在 Storyboard 模型中配置关联关系
- 预加载关联数据:使用
selectinload()减少 N+1 查询
3. 数据完整性
- 引用计数维护:在 StoryboardService 中维护 project_resources.usage_count
- 删除保护:usage_count > 0 的素材禁止删除
相关文档
测试建议
单元测试
test_get_storyboard_board_data()- 测试获取看板数据test_reorder_storyboards()- 测试调整分镜顺序test_get_track_items()- 测试获取轨道数据test_get_items_by_time_range()- 测试时间范围查询test_calculate_storyboard_board_tracks()- 测试轨道计算逻辑
集成测试
test_storyboard_board_api_get()- 测试 GET 端点test_storyboard_board_api_reorder()- 测试 POST 端点test_storyboard_board_api_tracks()- 测试轨道端点test_storyboard_board_api_time_range()- 测试时间范围端点
变更作者:Kiro AI
审核状态:待审核
部署状态:待部署