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.
9.8 KiB
9.8 KiB
AI 对话生成业务流程总览
更新日期: 2026-02-13
版本: v2.0 (补齐业务表写入环节)
🎯 业务场景映射
目标类型(target_type)与存储关系
| target_type | 前端传值 | 业务场景 | 存储目标表 | 必传关联 ID | 资源类型 (type) |
|---|---|---|---|---|---|
| 1 | storyboard | 分镜生图 | storyboard_images |
storyboard_id |
- |
| 1 | storyboard | 分镜生视频 | storyboard_videos |
storyboard_id |
- |
| 2 | character | 角色生图 | project_resources |
project_id + element_tag_id |
1 (角色) |
| 3 | scene | 场景生图 | project_resources |
project_id + element_tag_id |
2 (场景) |
| 4 | prop | 道具生图 | project_resources |
project_id + element_tag_id |
3 (道具) |
注意: 音效和配音不通过对话生成,使用其他 API 接口处理。
🔄 完整业务流程
步骤 1: 创建对话会话
API: POST /api/v1/ai/conversations
请求示例 (角色生图):
{
"projectId": "019d1234-5678-7abc-def0-123456789abc",
"targetType": 2,
"targetId": "019d1234-5678-7abc-def0-character001",
"tagId": "019d1234-5678-7abc-def0-tag-young",
"mediaType": 1,
"title": "张三-少年版 - 图片生成"
}
数据库记录:
INSERT INTO ai_conversations (
conversation_id, user_id, project_id,
target_type, target_id, tag_id, media_type,
title, status
) VALUES (
'019d1234-...', '019d1234-...', '019d1234-...',
2, '019d1234-...', '019d1234-...', 1,
'张三-少年版 - 图片生成', 1
);
步骤 2: 发送消息 + 触发生成
API: POST /api/v1/ai/conversations/{conversation_id}/messages
请求示例 A (仅发送消息):
{
"content": "帮我生成一个日落场景"
}
请求示例 B (发送消息 + 自动触发生成):
{
"content": "生成一个日落场景,色调偏暖",
"generate": {
"generationType": "image",
"modelId": "dall-e-3",
"aiParams": {
"resolution": "1024",
"aspectRatio": "1:1"
}
}
}
内部流程:
- 创建用户消息 (
role=USER) - 保存到
ai_conversation_messages表 - 如果提供
generate对象 → 调用trigger_ai_generation() - 创建 AI 任务 →
ai_jobs表 (status=PENDING) - 投递 Celery 任务到队列
数据库记录:
-- 用户消息
INSERT INTO ai_conversation_messages (
message_id, conversation_id, user_id, role, content,
meta_data, order_index, ai_job_id
) VALUES (
'019d1234-...', '019d1234-...', '019d1234-...', 1, '生成一个日落场景',
'{"generate": {...}}', 0, '019d1234-job-001'
);
-- AI 任务
INSERT INTO ai_jobs (
ai_job_id, user_id, project_id, job_type, status,
input_data, model_name
) VALUES (
'019d1234-job-001', '019d1234-...', '019d1234-...', 1, 1,
'{"prompt": "生成一个日落场景", ...}', 'dall-e-3'
);
步骤 3: Celery 异步任务执行
任务: generate_image_task / generate_video_task
执行流程:
- 更新任务状态 →
PROCESSING - 调用 AI Provider (OpenAI, FLUX, Doubao, etc.)
- 下载生成的文件
- 上传到自有 OSS (MinIO)
- 更新任务状态 →
COMPLETED
数据库更新:
UPDATE ai_jobs SET
status = 3, -- COMPLETED
progress = 100,
output_data = '{
"file_url": "https://minio.example.com/ai-generated/images/019d1234.png",
"file_size": 2048576,
"width": 1024,
"height": 1024,
"checksum": "abc123...",
"storage_provider": "minio",
"storage_path": "/ai-generated/images/019d1234.png"
}',
completed_at = now()
WHERE ai_job_id = '019d1234-job-001';
步骤 4: 🆕 自动写入业务表
服务: AIGenerationResultService.save_generation_result()
执行逻辑:
- 通过
ai_job_id查询关联的消息 (ai_conversation_messages) - 获取对话上下文 (
ai_conversations) - 根据
target_type+media_type路由到对应的保存方法
场景 A: 分镜图片 (target_type=1, media_type=1)
INSERT INTO storyboard_images (
image_id, storyboard_id, name, url,
status, is_active, version,
width, height, file_size, format, checksum,
storage_provider, storage_path,
ai_model, ai_prompt, ai_params,
created_at, completed_at
) VALUES (
'019d1234-img-001', '019d1234-storyboard-001',
'AI生成图片 - 20260213_143022', 'https://minio.../019d1234.png',
2, true, 1,
1024, 1024, 2048576, 'png', 'abc123...',
'minio', '/ai-generated/images/019d1234.png',
'dall-e-3', '生成一个日落场景', '{"resolution": "1024", ...}',
now(), now()
);
场景 B: 角色/场景/道具 (target_type=2/3/4, media_type=1)
INSERT INTO project_resources (
project_resource_id, project_id, name, type,
file_url, file_size, mime_type, width, height, checksum,
element_tag_id, ai_job_id, meta_data,
created_by, created_at, updated_at
) VALUES (
'019d1234-res-001', '019d1234-proj-001', 'AI生成角色 - 20260213',
1, -- ResourceType.CHARACTER
'https://minio.../019d1234.png', 2048576, 'image/png', 1024, 1024, 'abc123...',
'019d1234-tag-young', '019d1234-job-001',
'{"conversation_id": "...", "prompt": "...", "ai_params": {...}}',
'019d1234-user-001', now(), now()
);
📊 数据流示意图
┌─────────────────┐
│ 前端创建会话 │
│ POST /conversations
└────────┬────────┘
↓
┌─────────────────┐
│ ai_conversations│ (记录 target_type, target_id, tag_id)
└────────┬────────┘
↓
┌─────────────────┐
│ 前端发送消息 │
│ POST /messages │
│ (附带 generate) │
└────────┬────────┘
↓
┌───────────────────────┐
│ ai_conversation_messages│ (记录 content, ai_job_id)
└────────┬──────────────┘
↓
┌─────────────────┐
│ 创建 AI 任务 │
└────────┬────────┘
↓
┌─────────────────┐
│ ai_jobs │ (status=PENDING)
└────────┬────────┘
↓
┌─────────────────┐
│ Celery Worker │
│ 调用 AI Provider│
│ 下载文件 │
│ 上传到 OSS │
└────────┬────────┘
↓
┌─────────────────┐
│ ai_jobs │ (status=COMPLETED, output_data)
└────────┬────────┘
↓
┌─────────────────────────┐
│ 🆕 自动写入业务表 │
│ AIGenerationResultService│
└────────┬────────────────┘
↓
┌──────┴──────┐
│ │
↓ ↓
┌─────────────┐ ┌─────────────┐
│storyboard_ │ │project_ │
│images/videos│ │resources │
└─────────────┘ └─────────────┘
🔑 关键字段说明
ai_conversations 表
target_type: 目标类型(1=分镜 2=角色 3=场景 4=道具 5=资源)target_id: 目标对象 ID(storyboard_id / character_id / scene_id / prop_id)tag_id: 标签 ID(用于区分变体,如"少年版"、"中年版")media_type: 媒体类型(1=图片 2=视频)
ai_conversation_messages 表
role: 消息角色(1=USER 用户消息, 2=ASSISTANT AI回复)content: 消息内容(用户提示词或 AI 回复)ai_job_id: 关联的 AI 任务 ID(如果触发了生成)meta_data: 扩展数据(包含 generate 配置、mentions、reference_images)
ai_jobs 表
job_type: 任务类型(1=图片 2=视频 3=音效 4=配音)status: 任务状态(1=等待 2=处理中 3=已完成 4=失败)output_data: 输出结果(file_url, file_size, width, height, checksum 等)
✅ 前端查询指南
查询角色生成的所有图片
SELECT * FROM project_resources
WHERE project_id = '019d1234-proj-001'
AND type = 1 -- CHARACTER
AND element_tag_id = '019d1234-tag-young'
AND deleted_at IS NULL
ORDER BY created_at DESC;
查询分镜的所有图片
SELECT * FROM storyboard_images
WHERE storyboard_id = '019d1234-storyboard-001'
AND is_active = true
ORDER BY version DESC, created_at DESC;
查询某个对话生成的资源
-- 1. 通过 conversation_id 查询所有消息
SELECT * FROM ai_conversation_messages
WHERE conversation_id = '019d1234-conv-001';
-- 2. 通过 ai_job_id 查询任务结果
SELECT * FROM ai_jobs
WHERE ai_job_id IN (
SELECT ai_job_id FROM ai_conversation_messages
WHERE conversation_id = '019d1234-conv-001'
);
-- 3. 通过 meta_data 查询资源(如果需要)
SELECT * FROM project_resources
WHERE meta_data->>'conversation_id' = '019d1234-conv-001';
🎉 完成标志
✅ 现在前端可以直接从业务表查询生成的资源,无需解析 ai_jobs.output_data!
优势:
- 统一数据结构:所有资源都在业务表中
- 支持版本管理:通过
version字段管理多版本 - 支持标签筛选:通过
element_tag_id精准查询 - 支持状态管理:通过
is_active控制激活状态