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.4 KiB
7.4 KiB
RFC 132: 剧本资源数据结构重构
状态: ✅ 已实施
创建时间: 2026-01-26
实施时间: 2026-01-26
背景
原有的 resources.ts Mock 数据混淆了两个不同的概念:
- 剧本元素档案:从剧本中提取的角色、场景、道具的基础信息(纯文字描述)
- 项目素材:实际的图片/视频文件,用于视觉呈现
这导致数据结构混乱,不符合后端架构设计。
问题分析
原有设计的问题
// ❌ 错误:resources.ts 混合了两种数据
export const mockResources: Resource[] = [
{
id: '001',
name: '孙悟空形象1',
type: 'character',
fileUrl: 'https://...', // 图片 URL
elementTagId: 'tag_char_002', // 关联到标签
// ... 这是项目素材,不是剧本元素档案
}
];
正确的数据架构
根据后端文档分析,应该有三层数据结构:
1. screenplay_characters/scenes/props (剧本元素档案)
↓ 从剧本中提取的基础信息,不包含具体形象
2. screenplay_element_tags (元素标签)
↓ 元素的不同状态/变体(如年龄段、时代)
3. project_resources (项目素材 - 图片/视频)
↓ 关联到标签的具体视觉素材
解决方案
1. 文件拆分
重命名:resources.ts → screenplay-resources.ts
- 存储:剧本元素档案(角色、场景、道具的文字信息)
- 不包含:图片、视频等视觉素材
新建:project-resources.ts
- 存储:实际的图片/视频素材
- 关联:通过
elementTagId关联到标签
2. 数据结构对比
screenplay-resources.ts(剧本元素档案)
export const mockScreenplayCharacters = [
{
character_id: '018e1234-5678-7abc-8def-300000000001',
screenplay_id: '018e1234-5678-7abc-8def-100000000001',
name: '孙悟空',
description: '主角,齐天大圣,从被压五行山到护送唐僧西天取经的成长故事',
role_type: 'main',
line_count: 150,
appearance_count: 45,
has_tags: true, // 标识该角色有多个标签
default_tag_id: 'tag_char_002', // 默认显示"青年"标签
metadata: {
gender: 'male',
species: '石猴',
personality: '桀骜不驯、勇敢正义',
abilities: ['七十二变', '筋斗云', '火眼金睛']
},
// ❌ 没有 fileUrl, thumbnailUrl 等字段
}
];
project-resources.ts(项目素材)
export const mockProjectResources: Resource[] = [
{
id: '018e1234-5678-7abc-8def-200000000001',
projectId: '018e1234-5678-7abc-8def-100000000001',
name: '孙悟空-青年形象1',
type: 'character',
fileUrl: 'https://images.unsplash.com/...',
thumbnailUrl: 'https://images.unsplash.com/...',
fileSize: 1024000,
mimeType: 'image/png',
width: 400,
height: 533,
elementTagId: 'tag_char_002', // 关联到"孙悟空-青年"标签
isDefault: true, // 该标签的默认素材
// ...
}
];
3. 数据关联关系
剧本元素档案 (screenplay-resources.ts)
└─ 孙悟空 (character_id: char_001)
├─ has_tags: true
└─ default_tag_id: tag_char_002
剧本元素标签 (screenplay-tags.ts)
├─ 孙悟空-少年 (tag_id: tag_char_001)
└─ 孙悟空-青年 (tag_id: tag_char_002) ← 默认标签
项目素材 (project-resources.ts)
├─ 孙悟空-少年形象1 (elementTagId: tag_char_001, isDefault: true)
├─ 孙悟空-少年形象2 (elementTagId: tag_char_001, isDefault: false)
├─ 孙悟空-青年形象1 (elementTagId: tag_char_002, isDefault: true)
└─ 孙悟空-青年形象2 (elementTagId: tag_char_002, isDefault: false)
实施步骤
1. 创建新文件
- ✅
client/src/mocks/screenplay-resources.ts - ✅
client/src/mocks/project-resources.ts
2. 更新导出
- ✅
client/src/mocks/index.ts
3. 更新引用
- ✅
client/src/services/mockApi.ts - ✅
client/src/services/mock/resourceApi.ts
4. 删除旧文件
- ✅
client/src/mocks/resources.ts
数据示例
剧本元素档案(screenplay-resources.ts)
// 角色档案
{
character_id: '018e1234-5678-7abc-8def-300000000001',
screenplay_id: '018e1234-5678-7abc-8def-100000000001',
name: '孙悟空',
description: '主角,齐天大圣',
role_type: 'main',
has_tags: true,
default_tag_id: 'tag_char_002',
metadata: { gender: 'male', species: '石猴' }
}
// 场景档案
{
scene_id: '018e1234-5678-7abc-8def-400000000001',
screenplay_id: '018e1234-5678-7abc-8def-100000000001',
scene_number: 1,
title: '花果山水帘洞',
location: '花果山',
time_of_day: 'morning',
description: '孙悟空的老家,瀑布后的洞府',
has_tags: true,
default_tag_id: 'tag_scene_001'
}
// 道具档案
{
prop_id: '018e1234-5678-7abc-8def-500000000001',
screenplay_id: '018e1234-5678-7abc-8def-100000000001',
name: '金箍棒',
description: '孙悟空的武器,可大可小',
category: '武器',
importance: 'key',
has_tags: true,
default_tag_id: 'tag_prop_001'
}
项目素材(project-resources.ts)
// 角色素材(关联到标签)
{
id: '018e1234-5678-7abc-8def-200000000001',
projectId: '018e1234-5678-7abc-8def-100000000001',
name: '孙悟空-青年形象1',
type: 'character',
fileUrl: 'https://...',
thumbnailUrl: 'https://...',
elementTagId: 'tag_char_002', // 关联到"孙悟空-青年"标签
isDefault: true // 该标签的默认素材
}
// 场景素材(关联到标签)
{
id: '018e1234-5678-7abc-8def-200000000006',
projectId: '018e1234-5678-7abc-8def-100000000001',
name: '花果山水帘洞-白天1',
type: 'scene',
fileUrl: 'https://...',
elementTagId: 'tag_scene_001', // 关联到"花果山-白天"标签
isDefault: true
}
// 通用素材(不关联标签)
{
id: '018e1234-5678-7abc-8def-200000000004',
projectId: '018e1234-5678-7abc-8def-100000000001',
name: '唐僧形象1',
type: 'character',
fileUrl: 'https://...',
elementTagId: undefined, // 未关联标签
isDefault: false
}
优势
1. 符合后端架构
- ✅ 与后端数据库设计一致
- ✅ 清晰的数据层级关系
- ✅ 便于后续 API 集成
2. 职责分离
- ✅ 剧本元素档案:纯文字信息,从剧本提取
- ✅ 项目素材:视觉资源,用户上传或 AI 生成
- ✅ 标签系统:连接档案和素材
3. 易于维护
- ✅ 数据结构清晰,不混淆
- ✅ 便于扩展新功能
- ✅ 便于理解和调试
后续工作
短期(本周)
- 更新所有引用
mockResources的组件 - 更新 TypeScript 类型定义(如需要)
- 测试数据关联是否正确
中期(下周)
- 实现剧本元素档案的 CRUD API
- 实现项目素材的上传和管理 API
- 集成标签系统
长期(未来)
- AI 自动提取剧本元素档案
- AI 生成项目素材
- 素材库功能
参考文档
变更记录
2026-01-26
- 创建 RFC
- 实施文件拆分和重构
- 更新所有引用
RFC 编号: 132
状态: ✅ 已实施
创建时间: 2026-01-26