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.
7.8 KiB
7.8 KiB
Changelog: 项目资源自动关联实现
日期: 2026-02-08
类型: Feature / Enhancement
优先级: P1
关联文档:
📋 问题背景
核心问题(P1-01)
在 Phase 1 实现中,AI 拆解剧本后:
- ✅ 角色/场景/道具元素已存储
- ✅ 元素标签已创建(
screenplay_element_tags) - ✅ 分镜及分镜元素关联已创建(
storyboards、storyboard_items) - ❌
project_resources表未关联
业务影响
根据 ADR 01 的三层架构设计:
元素(Element)→ 标签(Tag)→ 资源(Resource)
screenplay_characters screenplay_element_tags project_resources
screenplay_locations → (统一标签表) → (图片/视频素材)
screenplay_props
缺失环节:
- 标签创建后,没有为其创建对应的
project_resources记录 - 用户无法通过 "素材管理" 界面查看 AI 拆解的元素
- AI 生成图片功能缺少目标资源记录
架构约束
根据 ADR 01:
- 资源归属于项目级(
project_id),而非剧本级 - 多集项目共享资源库
- 标签与资源是
1:N关系(一个标签可有多张图片)
✅ 解决方案
1. 新增 _sync_storyboard_resources 方法
文件: server/app/services/screenplay_service.py
功能: 为 AI 拆解的所有标签自动创建占位符资源
方法签名:
async def _sync_storyboard_resources(
self,
screenplay_id: UUID,
project_id: UUID,
tag_id_maps: Dict[str, Dict[str, UUID]]
) -> int:
"""为标签创建占位符项目资源记录
逻辑说明:
1. 遍历所有标签(角色/场景/道具标签)
2. 为每个标签创建一条 project_resources 记录(占位符)
3. 不创建实际文件,仅关联 element_tag_id
4. 后续由 AI 生成图片并更新 file_url
"""
关键特性:
- ✅ 占位符机制:
file_url = "placeholder://pending-ai-generation" - ✅ 去重逻辑: 检查
element_tag_id是否已有关联资源 - ✅ 元数据追踪: 标记
source: 'ai_screenplay_parsing',auto_generated: true - ✅ 冗余字段: 存储
element_name和tag_label便于查询 - ✅ 事务安全: 使用
flush()而非commit(),依赖外层事务
2. 集成到 AI 解析流程
调用时机: 在 store_parsed_elements 方法的分镜创建后
# 5. 存储分镜(如果启用)
storyboard_ids = await self._create_storyboards_from_ai(...)
# 6. 同步项目资源关联(新增)
await self._sync_storyboard_resources(
screenplay_id=screenplay_id,
project_id=screenplay.project_id,
tag_id_maps=tag_id_maps
)
3. 占位符资源示例
ProjectResource(
project_resource_id=UUID_v7,
project_id=project_id,
name="孙悟空 - 青年",
type=ResourceType.CHARACTER, # 1
description="AI 拆解剧本自动生成的 孙悟空 (青年) 占位符",
file_url="placeholder://pending-ai-generation", # 占位符
checksum="pending", # 占位符
element_tag_id=tag_id, # 关联标签
element_name="孙悟空", # 冗余字段
tag_label="青年", # 冗余字段
created_by=screenplay.created_by,
meta_data={
'source': 'ai_screenplay_parsing',
'screenplay_id': str(screenplay_id),
'element_type': 1, # CHARACTER
'element_id': str(character_id),
'status': 'pending', # pending → generating → completed
'auto_generated': True
}
)
🧪 测试验证
测试文件
server/tests/integration/test_data_integrity.py
新增验证:项目资源占位符
# 验证 7: 项目资源占位符(project_resources)
stmt = select(ProjectResource).where(
ProjectResource.project_id == subproject.id,
ProjectResource.deleted_at.is_(None)
)
result = await db_session.execute(stmt)
resources = result.scalars().all()
assert len(resources) == 9, f"应创建 9 个占位符资源"
测试结果
✅ 项目资源占位符验证通过
- 总资源数: 9 个
🎉 数据完整性测试通过!
📊 最终统计:
- 角色: 3 个
- 场景: 2 个
- 道具: 2 个
- 标签: 9 个
- 分镜: 3 个
- 元素关联: 9 个
- 项目资源: 9 个 ← 新增验证
验证指标: 100% 通过
- 创建资源数 = 标签数(9 个)
- 每个标签一个占位符资源
- 资源正确关联到
project_id
📊 技术影响分析
代码变更统计
| 文件 | 变更类型 | 行数 |
|---|---|---|
screenplay_service.py |
新增方法 | +130 |
screenplay_service.py |
集成调用 | +5 |
test_data_integrity.py |
新增验证 | +15 |
数据流程
AI 解析剧本
↓
创建元素(角色/场景/道具)
↓
创建标签(screenplay_element_tags)
↓
创建分镜(storyboards + storyboard_items)
↓
[新增] 创建占位符资源(project_resources)← 本次实现
↓
[未来] AI 生成图片并更新 file_url
关键技术点
-
避免 Lazy Loading
- 问题:
tag.element_name是@property,访问时触发 relationship 查询 - 解决:使用预先构建的
element_type_map字典
- 问题:
-
事务管理
- 使用
self.db.add()+await self.db.flush() - 不调用
commit(),依赖外层事务控制
- 使用
-
数据库约束
created_by不能为 NULL → 从screenplay.created_by获取
-
字段映射
ElementType.CHARACTER(1) →ResourceType.CHARACTER(1)ElementType.LOCATION(2) →ResourceType.SCENE(2)ElementType.PROP(3) →ResourceType.PROP(3)
🔗 关联问题
已解决
- ✅ P1-01:
project_resources表未关联(本次实现)
待解决(Phase 3)
- ⏳ P1-02: AI Prompt 文档与实际实现不一致(标签格式已修复)
- ⏳ 实现 AI 图片生成功能(更新
file_url)
📝 开发者注意事项
占位符资源查询
查询所有待生成资源:
stmt = select(ProjectResource).where(
ProjectResource.file_url == "placeholder://pending-ai-generation",
ProjectResource.deleted_at.is_(None)
)
按标签查询资源:
stmt = select(ProjectResource).where(
ProjectResource.element_tag_id == tag_id,
ProjectResource.deleted_at.is_(None)
)
AI 图片生成流程(待实现)
- 查询待生成资源: 筛选
status = 'pending' - 调用 AI 图片生成服务: 传入
element_name,tag_label,description - 上传图片到存储: 获取
file_url,checksum,width,height - 更新资源记录:
resource.file_url = uploaded_url resource.checksum = file_checksum resource.width = image_width resource.height = image_height resource.meta_data['status'] = 'completed'
用户界面影响
素材管理页面:
- 现在可以看到 AI 拆解的所有元素占位符
- 占位符资源显示为 "待生成" 状态
- 用户可以手动上传图片替换占位符
✨ 总结
本次实现完成了 项目资源自动关联功能,填补了 AI 拆解剧本与素材管理之间的数据链路。
核心价值:
- ✅ 打通了三层架构的完整数据流
- ✅ 为 AI 图片生成功能准备了目标记录
- ✅ 用户可在素材库中查看 AI 拆解的所有元素
- ✅ 支持多集项目的资源共享
下一步:
- Phase 3: 实现 AI 图片生成服务
- Phase 3: 完成
file_url更新逻辑 - Phase 3: 前端展示占位符资源状态
审核: Pending
部署: Pending
文档更新: ✅ 已完成