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.1 KiB

默认形象系统设计

日期:2026-01-21
类型:功能设计
状态:待实施
相关文档剧本元素标签管理服务


概述

为剧本标签系统添加"默认形象"功能,解决角色、场景、道具有多个标签时的默认显示问题。

业务场景

当元素有多个标签时(如角色的不同年龄段、场景的不同时代),需要设置一个默认形象用于:

  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个表)

-- 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. 素材表

-- 添加默认标识字段
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. 获取默认形象

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. 设置默认标签

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. 设置默认素材

PUT /api/v1/resources/{resource_id}/set-default

4. 批量获取默认形象

POST /api/v1/elements/default-images

用于时间轴加载时批量获取所有元素的默认形象。

边界情况

情况 处理方案
元素没有标签 default_tag_id = NULL,UI 显示占位图
元素有标签但未设置默认 自动选择第一个标签
标签没有素材 查询返回 NULL,UI 显示占位图
标签有素材但未设置默认 自动选择第一个素材
删除默认标签 自动切换到下一个标签
删除默认素材 自动切换到下一个素材

性能优化

1. 单次查询

使用 JOIN 一次性查询元素的默认形象:

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. 缓存策略

@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

相关文档