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.
 

4.2 KiB

Changelog: 剧本资源引用关系创建

日期: 2026-02-11
类型: 功能补充
影响范围: 后端 - 剧本解析服务
关联文档: ADR-01: 项目级资源归属


变更概述

在剧本解析流程中补充创建 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() 方法中,创建完项目资源后立即创建引用关系:

# 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. 资源准备清单

-- 快速查询剧本需要的所有资源
SELECT * FROM screenplay_element_refs 
WHERE screenplay_id = '剧本ID';

2. 完成度追踪

-- 对比计划 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_typeelement_id 正确关联到项目资源

预期结果

-- 示例数据
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)

返回结果新增字段:

{
  "refs_created": 15
}

向后兼容性

完全兼容 - 仅新增数据,不影响现有功能

注意事项

  1. 去重逻辑: 使用 ref_repo.exists() 避免重复创建
  2. 事务一致性: 与其他数据创建在同一事务中
  3. 排序索引: 按 AI 解析顺序记录 order_index

后续优化

  • 添加 API 端点查询剧本资源引用
  • 前端展示"资源准备清单"
  • 完成度追踪仪表板

变更人: AI Assistant
审核人: 待审核
状态: 已实施