# 默认形象系统设计 > **日期**:2026-01-21 > **类型**:功能设计 > **状态**:待实施 > **相关文档**:[剧本元素标签管理服务](../../requirements/backend/04-services/project/screenplay-tag-service.md#默认形象设置) --- ## 概述 为剧本标签系统添加"默认形象"功能,解决角色、场景、道具有多个标签时的默认显示问题。 ## 业务场景 当元素有多个标签时(如角色的不同年龄段、场景的不同时代),需要设置一个默认形象用于: 1. **时间轴拖拽**:用户拖入角色时显示默认形象 2. **快速预览**:在列表中快速显示元素的主要形象 3. **AI 生成**:作为 AI 生成的参考形象 ### 示例 ``` 角色"张三" ├── 少年(13-17岁)- 5张素材 ├── 青年(18-30岁)✓ 默认标签 │ ├── 素材1.jpg ✓ 默认素材 │ ├── 素材2.jpg │ └── 素材3.jpg └── 老年(51岁以上)- 2张素材 ``` 用户拖入"张三"时,显示"青年"标签的"素材1.jpg"。 ## 设计方案 ### 两级默认机制 1. **元素级别**:`default_tag_id` - 指定元素的默认标签 2. **标签级别**:`is_default` - 指定标签的默认素材 ### 数据库变更 #### 1. 剧本元素表(3个表) ```sql -- screenplay_characters 表 ALTER TABLE screenplay_characters ADD COLUMN default_tag_id UUID REFERENCES screenplay_element_tags(tag_id) ON DELETE SET NULL; CREATE INDEX idx_characters_default_tag ON screenplay_characters(default_tag_id) WHERE default_tag_id IS NOT NULL; -- screenplay_scenes 表 ALTER TABLE screenplay_scenes ADD COLUMN default_tag_id UUID REFERENCES screenplay_element_tags(tag_id) ON DELETE SET NULL; CREATE INDEX idx_scenes_default_tag ON screenplay_scenes(default_tag_id) WHERE default_tag_id IS NOT NULL; -- screenplay_props 表 ALTER TABLE screenplay_props ADD COLUMN default_tag_id UUID REFERENCES screenplay_element_tags(tag_id) ON DELETE SET NULL; CREATE INDEX idx_props_default_tag ON screenplay_props(default_tag_id) WHERE default_tag_id IS NOT NULL; ``` #### 2. 素材表 ```sql -- 添加默认标识字段 ALTER TABLE project_resources ADD COLUMN is_default BOOLEAN NOT NULL DEFAULT false; -- 唯一约束:同一标签下只能有一个默认素材 CREATE UNIQUE INDEX idx_resources_default_per_tag ON project_resources(element_tag_id) WHERE is_default = true AND element_tag_id IS NOT NULL; -- 查询优化索引 CREATE INDEX idx_resources_default ON project_resources(element_tag_id, is_default) WHERE is_default = true; ``` ## 业务逻辑 ### 自动设置 - 创建第一个标签时,自动设为 `default_tag_id` - 上传第一个素材时,自动设为 `is_default = true` ### 删除处理 - 删除默认标签时,自动切换到下一个标签(按 `order_index`) - 删除默认素材时,自动切换到下一个素材(按 `created_at`) ### 切换默认 - 提供 API 让用户手动设置默认标签 - 提供 API 让用户手动设置默认素材 ## API 接口 ### 1. 获取默认形象 ```http GET /api/v1/characters/{character_id}/default-image GET /api/v1/scenes/{scene_id}/default-image GET /api/v1/props/{prop_id}/default-image ``` ### 2. 设置默认标签 ```http PUT /api/v1/characters/{character_id}/default-tag PUT /api/v1/scenes/{scene_id}/default-tag PUT /api/v1/props/{prop_id}/default-tag ``` ### 3. 设置默认素材 ```http PUT /api/v1/resources/{resource_id}/set-default ``` ### 4. 批量获取默认形象 ```http POST /api/v1/elements/default-images ``` 用于时间轴加载时批量获取所有元素的默认形象。 ## 边界情况 | 情况 | 处理方案 | |------|---------| | 元素没有标签 | `default_tag_id = NULL`,UI 显示占位图 | | 元素有标签但未设置默认 | 自动选择第一个标签 | | 标签没有素材 | 查询返回 NULL,UI 显示占位图 | | 标签有素材但未设置默认 | 自动选择第一个素材 | | 删除默认标签 | 自动切换到下一个标签 | | 删除默认素材 | 自动切换到下一个素材 | ## 性能优化 ### 1. 单次查询 使用 JOIN 一次性查询元素的默认形象: ```sql SELECT c.character_id, c.name, t.tag_id, t.tag_label, r.id AS resource_id, r.file_url, r.thumbnail_url FROM screenplay_characters c LEFT JOIN screenplay_element_tags t ON c.default_tag_id = t.tag_id LEFT JOIN project_resources r ON r.element_tag_id = t.tag_id AND r.is_default = true WHERE c.character_id = ?; ``` ### 2. 缓存策略 ```python @cache(ttl=300, key="default_image:{element_type}:{element_id}") async def get_default_image(...): # 缓存 5 分钟 pass ``` ### 3. 批量查询 提供批量查询接口,避免 N+1 查询问题。 ## 前端 UI ### 标签列表 ``` ┌─────────────────────────────────────────────┐ │ 角色:张三 │ ├─────────────────────────────────────────────┤ │ ⭐ 青年 (默认) [设为默认] │ │ 素材: 3个 │ │ ┌────┬────┬────┐ │ │ │ ✓ │ │ │ ← ✓ 表示默认素材 │ │ └────┴────┴────┘ │ │ │ │ 少年 [设为默认] │ │ 素材: 5个 │ └─────────────────────────────────────────────┘ ``` ### 时间轴 素材库中显示元素的默认形象,拖拽到时间轴后可在属性面板切换标签和素材。 ## 实施清单 - [ ] 数据库迁移脚本(`006_default_image_system.py`) - [ ] Repository 层方法实现 - [ ] `count_element_tags()` - [ ] `get_first_tag()` - [ ] `count_tag_resources()` - [ ] `get_first_resource()` - [ ] `clear_default_resources()` - [ ] `get_default_image()` - [ ] Service 层业务逻辑 - [ ] 自动设置默认值 - [ ] 删除处理 - [ ] 切换默认值 - [ ] API 接口实现 - [ ] `GET /default-image` - [ ] `PUT /default-tag` - [ ] `PUT /set-default` - [ ] `POST /default-images` - [ ] 单元测试 - [ ] 集成测试 - [ ] 前端 UI 实现 - [ ] 文档更新 ## 优势 ✅ **清晰的两级结构**:元素级 + 标签级 ✅ **自动化处理**:首个标签/素材自动设为默认 ✅ **智能降级**:删除默认项时自动切换 ✅ **统一设计**:角色、场景、道具使用相同机制 ✅ **性能优化**:单次 JOIN 查询 + 缓存策略 ✅ **用户友好**:提供一键切换默认的 UI ## 相关文档 - [剧本元素标签管理服务](../../requirements/backend/04-services/project/screenplay-tag-service.md) - [项目素材管理服务](../../requirements/backend/04-services/project/project-resource-service.md) - [剧本管理服务](../../requirements/backend/04-services/project/screenplay-service.md)