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.8 KiB
8.8 KiB
分镜服务完整实现
日期:2026-02-04
类型:Feature Implementation
影响范围:后端 - 分镜管理模块
概述
完整实现分镜管理服务(Storyboard Service),包括分镜 CRUD、排序管理、元素关联、筛选搜索等核心功能。
实现内容
1. 数据模型层
新建文件:server/app/models/storyboard.py
- ✅
Storyboard模型:分镜主表 - ✅
StoryboardItem模型:分镜元素关联表 - ✅
ShotSizeType枚举:8种景别类型 - ✅
CameraMovementType枚举:9种运镜类型 - ✅
ItemType枚举:元素类型(剧本元素标签/项目素材)
技术栈符合度:
- ✅ UUID v7 应用层生成(
generate_uuid_v7()) - ✅ 枚举类型使用 SMALLINT + IntEnum
- ✅ 时间戳使用 TIMESTAMPTZ
- ✅ 无物理外键约束
- ✅ CHECK 约束和 UNIQUE 约束
2. Schema 层
新建文件:server/app/schemas/storyboard.py
- ✅
StoryboardCreate:创建分镜请求 - ✅
StoryboardUpdate:更新分镜请求 - ✅
StoryboardResponse:分镜响应 - ✅
StoryboardReorder:重新排序请求 - ✅
StoryboardItemCreate:添加元素请求 - ✅
StoryboardItemUpdate:更新元素请求 - ✅
StoryboardItemResponse:元素响应 - ✅
StoryboardListResponse:分镜列表响应 - ✅
StoryboardDurationStats:时长统计响应
3. 仓储层
新建文件:server/app/repositories/storyboard_repository.py
实现功能:
- ✅ 分镜 CRUD 操作
- ✅ 排序管理(获取最大 order_index、批量更新顺序)
- ✅ 筛选查询(按景别、运镜筛选)
- ✅ 全文搜索(标题、描述、拍摄描述)
- ✅ 时长统计(总时长、平均时长、方差)
- ✅ 分镜元素关联 CRUD
- ✅ 批量操作(批量检查存在性)
技术栈符合度:
- ✅ 使用
async/await异步编程 - ✅ 使用
flush()而非commit()(Repository 职责) - ✅ 日志使用 %-formatting 格式化
4. 服务层
新建文件:server/app/services/storyboard_service.py
实现功能:
- ✅ 分镜 CRUD(创建、查询、更新、删除)
- ✅ 排序管理(重新排序、删除后自动重排)
- ✅ 元素关联管理(添加、移除、更新属性、批量调整顺序)
- ✅ 筛选和搜索(按景别/运镜筛选、全文搜索)
- ✅ 时长统计(项目总时长、平均时长、方差)
- ✅ 权限检查(应用层验证项目权限)
技术栈符合度:
- ✅ 使用
commit()提交事务(Service 职责) - ✅ 日志记录关键操作
- ✅ 异常日志使用
exc_info=True - ✅ 应用层验证引用完整性
5. API 路由层
新建文件:server/app/api/v1/storyboards.py
实现端点(13个):
- ✅
GET /storyboards- 获取分镜列表 - ✅
POST /storyboards- 创建分镜 - ✅
GET /storyboards/{id}- 获取分镜详情 - ✅
PUT /storyboards/{id}- 更新分镜 - ✅
DELETE /storyboards/{id}- 删除分镜 - ✅
POST /storyboards/reorder- 重新排序分镜 - ✅
POST /storyboards/{id}/items- 添加元素到分镜 - ✅
GET /storyboards/{id}/items- 获取分镜的所有关联元素 - ✅
PATCH /storyboards/items/{id}- 更新元素的关联属性 - ✅
DELETE /storyboards/items/{id}- 从分镜移除元素 - ✅
POST /storyboards/{id}/items/reorder- 批量调整元素顺序 - ✅
GET /storyboards/filter- 按景别和运镜筛选分镜 - ✅
GET /storyboards/search- 全文搜索分镜 - ✅
GET /storyboards/statistics/duration- 获取项目时长统计
技术栈符合度:
- ✅ 使用
ApiResponse统一响应格式 - ✅ 依赖注入模式
- ✅ 日志记录 API 调用
6. 数据库迁移
新建文件:server/alembic/versions/20260204_1600_create_storyboards_tables.py
迁移内容:
- ✅ 创建
storyboards表 - ✅ 创建
storyboard_items表 - ✅ 创建索引(B-tree、GIN、部分索引)
- ✅ 创建全文搜索索引(pg_trgm)
- ✅ 创建触发器(自动更新 updated_at)
- ✅ 添加表和列注释
索引策略:
- B-tree 索引:project_id, order_index
- 部分索引:shot_size, camera_movement(仅非空值)
- GIN 索引:metadata, 全文搜索(title, description, shooting_description)
7. 路由注册
修改文件:server/app/api/v1/__init__.py
- ✅ 导入
storyboards模块 - ✅ 注册路由:
/storyboards
核心设计
1. 镜号管理
- 设计:使用
order_index作为镜号(1, 2, 3...) - 创建时:自动分配下一个序号
- 删除时:后续分镜的
order_index自动 -1 - 排序时:批量更新
order_index - 优势:极简设计,无需单独维护镜号字段
2. 影视专业字段
- 景别(shot_size):SMALLINT 存储(1-8),代码层使用 IntEnum
- 8种标准景别:大远景、远景、全景、中景、中近景、特写、大特写、过肩
- 运镜(camera_movement):SMALLINT 存储(1-9),代码层使用 IntEnum
- 9种标准运镜:固定、摇镜、俯仰、推拉、变焦、跟踪、环绕、升降、手持
- 拍摄描述(shooting_description):TEXT 类型,支持全文搜索
3. 元素关联设计
统一关联表:storyboard_items
- 两种关联类型:
item_type=1:剧本元素标签(角色/场景/道具的变体)item_type=2:项目素材(实拍素材、音频、视频等)
- 关联字段:
element_tag_id:指向screenplay_element_tags.tag_idresource_id:指向project_resources.project_resource_id
- 冗余字段:
element_name,tag_label,cover_url避免 JOIN - 关联属性:
action_description(动作)、spatial_position(位置)、is_visible(可见性) - 排序与层级:
display_order(显示顺序)、z_index(视觉层级)
4. 时间轴管理
- start_time/end_time:用于视频编辑时间轴定位
- estimated_duration/actual_duration:预估时长 vs 实际时长
- 时间范围查询:支持 GiST 索引(未来扩展)
技术栈符合度检查
✅ 数据库设计
- UUID v7 应用层生成(
generate_uuid_v7()) - 枚举类型使用 SMALLINT + IntEnum
- 时间戳使用 TIMESTAMPTZ(ADR 006)
- 无物理外键约束,应用层验证引用完整性
- 索引策略完整(B-tree、GIN、部分索引)
✅ 后端代码
- 异步编程(async/await)
- Repository 使用
flush(),Service 使用commit() - 日志使用 %-formatting 格式化
- 异常日志使用
exc_info=True - API 响应使用
ApiResponse统一格式 - 依赖注入模式
✅ 文档规范
- Changelog 文档创建
- 文件路径符合规范:
docs/server/changelogs/ - 日期格式:YYYY-MM-DD
后续工作
阶段 3:分镜看板服务(未实现)
- 创建
StoryboardBoardService - 实现六种轨道(分镜、资源、视频、音效、对白、配音)
- 实时计算时间轴数据
- 创建 API 路由
阶段 4:项目素材关联(未实现)
- 扩展
ProjectResource模型(添加usage_count字段) - 创建数据库迁移脚本
- 扩展
ProjectResourceService(引用计数维护) - 实现删除保护逻辑
测试建议
单元测试
test_storyboard_repository.py:仓储层测试test_storyboard_service.py:服务层测试
集成测试
test_storyboard_api.py:API 端点测试
测试场景
- 创建分镜并自动分配 order_index
- 删除分镜后自动重排序
- 批量调整分镜顺序
- 添加/移除元素到分镜
- 按景别/运镜筛选分镜
- 全文搜索分镜
- 获取项目时长统计
数据库迁移
执行迁移
# 在 Docker 容器内执行
docker exec jointo-server-app python scripts/db_migrate.py upgrade
验证迁移
# 检查当前迁移版本
docker exec jointo-server-app alembic current
# 查看表结构
docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\d storyboards"
docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\d storyboard_items"
相关文档
实现者:Kiro AI
审核状态:待审核
部署状态:待部署