# Changelog: 剧本资源引用关系创建 **日期**: 2026-02-11 **类型**: 功能补充 **影响范围**: 后端 - 剧本解析服务 **关联文档**: [ADR-01: 项目级资源归属](../adrs/01-project-level-resource-ownership.md) --- ## 变更概述 在剧本解析流程中补充创建 `screenplay_element_refs` 表的关联数据,记录剧本引用的所有项目资源(角色/场景/道具)。 ## 问题背景 根据流程图和 ADR 文档设计,剧本解析后应该创建两种关联关系: 1. ✅ **已实现**: `storyboard_items` - 分镜实际使用的资源(实际) 2. ❌ **缺失**: `screenplay_element_refs` - 剧本提到的所有资源(计划) 缺少 `screenplay_element_refs` 导致: - 无法快速查询"这个剧本需要哪些资源"(需要多表 JOIN) - 无法追踪项目完成度(计划 vs 实际) - 业务逻辑不完整 ## 技术实现 ### 修改文件 - `server/app/services/screenplay_service.py` ### 核心变更 在 `ScreenplayService.store_parsed_elements()` 方法中,创建完项目资源后立即创建引用关系: ```python # 6. 创建剧本资源引用关系(screenplay_element_refs) from app.repositories.screenplay_element_ref_repository import ScreenplayElementRefRepository from app.models.screenplay_element_ref import ElementType ref_repo = ScreenplayElementRefRepository(self.db) refs_created = 0 # 6.1 创建角色引用 for idx, (char_name, char_id) in enumerate(character_id_map.items()): if not await ref_repo.exists(screenplay_id, ElementType.CHARACTER, char_id): await ref_repo.create_ref( screenplay_id=screenplay_id, element_type=ElementType.CHARACTER, element_id=char_id, order_index=idx ) refs_created += 1 # 6.2 创建场景引用(同上) # 6.3 创建道具引用(同上) ``` ### 数据流 ``` AI 解析剧本 ↓ 创建项目资源 (project_characters/locations/props) ↓ ✨ 创建剧本引用 (screenplay_element_refs) ← 新增 ↓ 创建项目标签 (project_element_tags) ↓ 创建分镜 (storyboards + storyboard_items) ``` ### 关联关系 ``` screenplay_element_refs ├─ screenplay_id → screenplays.screenplay_id ├─ element_type (1=角色, 2=场景, 3=道具) └─ element_id → project_characters/locations/props ``` ## 业务价值 ### 1. 资源准备清单 ```sql -- 快速查询剧本需要的所有资源 SELECT * FROM screenplay_element_refs WHERE screenplay_id = '剧本ID'; ``` ### 2. 完成度追踪 ```sql -- 对比计划 vs 实际 SELECT (SELECT COUNT(*) FROM screenplay_element_refs WHERE screenplay_id = 'xxx') AS planned, (SELECT COUNT(DISTINCT element_id) FROM storyboard_items JOIN storyboards ON ... WHERE screenplay_id = 'xxx') AS actual; ``` ### 3. 性能优化 - 单表查询,避免多表 JOIN - 支持按 `order_index` 排序(AI 解析顺序) ## 测试验证 ### 验证步骤 1. 解析一个剧本(包含角色/场景/道具) 2. 检查 `screenplay_element_refs` 表是否创建了对应记录 3. 验证 `element_type` 和 `element_id` 正确关联到项目资源 ### 预期结果 ```sql -- 示例数据 SELECT * FROM screenplay_element_refs WHERE screenplay_id = 'xxx'; ref_id | screenplay_id | element_type | element_id | order_index -------|---------------|--------------|------------|------------ uuid-1 | screenplay-A | 1 | char-001 | 0 uuid-2 | screenplay-A | 2 | loc-001 | 0 uuid-3 | screenplay-A | 3 | prop-001 | 0 ``` ## 日志输出 新增日志: ``` 剧本资源引用创建完成: screenplay_id=xxx, refs_created=15 (角色=5, 场景=8, 道具=2) ``` 返回结果新增字段: ```json { "refs_created": 15 } ``` ## 向后兼容性 ✅ **完全兼容** - 仅新增数据,不影响现有功能 ## 注意事项 1. **去重逻辑**: 使用 `ref_repo.exists()` 避免重复创建 2. **事务一致性**: 与其他数据创建在同一事务中 3. **排序索引**: 按 AI 解析顺序记录 `order_index` ## 后续优化 - [ ] 添加 API 端点查询剧本资源引用 - [ ] 前端展示"资源准备清单" - [ ] 完成度追踪仪表板 --- **变更人**: AI Assistant **审核人**: 待审核 **状态**: ✅ 已实施