ai_service/API_文档.md

598 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AI海报生成系统 API 文档
## 🎯 API概览
AI海报生成系统提供统一的REST API接口一键生成Vue组件代码和PSD文件。
**基础URL**: `http://localhost:8000`
**主要特性**:
- 🚀 一键生成Vue代码和PSD文件
- 🎨 集成多个AI模型DeepSeek + Kimi + ComfyUI
- 📁 会话管理和文件下载
- 🔄 自动图片生成和合成
## 📋 API端点总览
| 端点 | 方法 | 描述 | 状态 |
|------|------|------|------|
| `/` | GET | 获取API信息 | ✅ |
| `/health` | GET | 健康检查 | ✅ |
| `/api/generate-poster` | POST | **主要接口** - 生成海报 | ✅ |
| `/api/download/{file_type}` | GET | 下载文件 | ✅ |
| `/api/status/{session_id}` | GET | 获取会话状态 | ✅ |
## 🔧 主要接口详情
### 1. 生成海报(核心接口)
**POST** `/api/generate-poster`
这是唯一需要的主要接口,一次调用完成所有生成任务。
**请求示例**:
```json
{
"user_input": "端午节海报,传统风格,包含荷花和龙舟",
"session_id": "可选 - 用于跟踪会话"
}
```
**完整响应示例**:
```json
{
"status": "success",
"message": "海报生成完成",
"data": {
"vue_code": "完整的Vue 3组件代码",
"suggestions": {
"layer5_logo_content": {
"text": "主办方",
"color": "#000000"
},
"layer6_title_content": {
"content": "端午节安康",
"font_name": "SimHei",
"color": "#7E0C6E"
},
"layer7_subtitle_content": {
"content": "粽叶飘香,龙舟竞渡,共庆端午佳节",
"font_name": "Microsoft YaHei",
"color": "#000000"
}
},
"analysis_result": {
"analyzed_prompt": "端午节海报,传统风格",
"main_theme": "端午节祝福",
"style_preference": "传统",
"width": 1080,
"height": 1920,
"keywords": ["端午节", "传统", "荷花", "龙舟"]
},
"psd_file_path": "/path/to/session_xxx/final_poster.psd",
"file_size_mb": 5.93,
"generated_images": 2,
"files": {
"vue_file": "/path/to/generated_code.vue",
"psd_file": "/path/to/final_poster.psd"
}
},
"session_id": "uuid-generated-session-id"
}
```
### 2. 文件下载
**GET** `/api/download/{file_type}?session_id={session_id}`
**参数**:
- `file_type`: 文件类型
- `vue` - Vue组件文件
- `psd` - PSD文件
- `json` - 文案建议JSON文件
- `session_id`: 会话ID必需
**响应**: 直接返回文件流,浏览器会自动下载
### 3. 健康检查
**GET** `/health`
**响应**:
```json
{
"status": "healthy",
"timestamp": "2025-01-02T20:30:00.123456"
}
```
### 4. 会话状态查询
**GET** `/api/status/{session_id}`
**响应**:
```json
{
"status": "success",
"message": "状态获取成功",
"data": {
"user_input": "端午节海报,传统风格",
"analysis_result": "...",
"suggestions": "...",
"vue_path": "/path/to/vue/file",
"psd_path": "/path/to/psd/file",
"created_at": "2025-01-02T20:30:00"
},
"session_id": "session-id"
}
```
## 🛠️ 前端集成指南
### JavaScript ES6+ 示例
```javascript
class PosterGenerator {
constructor(baseUrl = 'http://localhost:8000') {
this.baseUrl = baseUrl;
}
// 主要方法:生成海报
async generatePoster(userInput) {
try {
const response = await fetch(`${this.baseUrl}/api/generate-poster`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_input: userInput
})
});
const result = await response.json();
if (result.status === 'success') {
console.log('✅ 海报生成成功');
console.log('Vue代码长度:', result.data.vue_code.length);
console.log('PSD文件大小:', result.data.file_size_mb, 'MB');
console.log('生成的图片数量:', result.data.generated_images);
return result;
} else {
throw new Error(result.message || '生成失败');
}
} catch (error) {
console.error('❌ 海报生成失败:', error);
throw error;
}
}
// 下载文件
downloadFile(sessionId, fileType) {
const url = `${this.baseUrl}/api/download/${fileType}?session_id=${sessionId}`;
const a = document.createElement('a');
a.href = url;
a.download = '';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
// 获取会话状态
async getSessionStatus(sessionId) {
const response = await fetch(`${this.baseUrl}/api/status/${sessionId}`);
return await response.json();
}
}
// 使用示例
const generator = new PosterGenerator();
async function createPoster() {
try {
// 生成海报
const result = await generator.generatePoster("春节海报,红色背景,现代风格");
// 显示Vue代码
document.getElementById('vue-code').textContent = result.data.vue_code;
// 显示文案建议
document.getElementById('suggestions').textContent =
JSON.stringify(result.data.suggestions, null, 2);
// 设置下载按钮
document.getElementById('download-vue').onclick = () =>
generator.downloadFile(result.session_id, 'vue');
document.getElementById('download-psd').onclick = () =>
generator.downloadFile(result.session_id, 'psd');
} catch (error) {
alert('生成失败: ' + error.message);
}
}
```
### Vue.js 组件示例
```vue
<template>
<div class="poster-generator">
<div class="input-section">
<h2>AI海报生成器</h2>
<div class="form-group">
<label>海报需求描述</label>
<textarea
v-model="userInput"
placeholder="请描述您的海报需求,例如:端午节海报,传统风格,包含荷花和龙舟"
rows="4"
></textarea>
</div>
<button
@click="generatePoster"
:disabled="loading || !userInput.trim()"
:class="{ loading: loading }"
>
{{ loading ? '生成中...' : '生成海报' }}
</button>
</div>
<div v-if="result" class="result-section">
<div class="tabs">
<button
@click="activeTab = 'vue'"
:class="{ active: activeTab === 'vue' }"
>
Vue代码
</button>
<button
@click="activeTab = 'suggestions'"
:class="{ active: activeTab === 'suggestions' }"
>
文案建议
</button>
<button
@click="activeTab = 'info'"
:class="{ active: activeTab === 'info' }"
>
生成信息
</button>
</div>
<div class="tab-content">
<div v-if="activeTab === 'vue'" class="vue-code">
<h3>Vue组件代码</h3>
<pre><code>{{ result.data.vue_code }}</code></pre>
</div>
<div v-if="activeTab === 'suggestions'" class="suggestions">
<h3>文案建议</h3>
<div class="suggestion-item" v-for="(item, key) in result.data.suggestions" :key="key">
<h4>{{ getSuggestionTitle(key) }}</h4>
<p><strong>内容:</strong> {{ item.content || item.text }}</p>
<p><strong>字体:</strong> {{ item.font_name || '未指定' }}</p>
<p><strong>颜色:</strong> <span :style="{ color: item.color }">{{ item.color }}</span></p>
</div>
</div>
<div v-if="activeTab === 'info'" class="info">
<h3>生成信息</h3>
<p><strong>主题:</strong> {{ result.data.analysis_result.main_theme }}</p>
<p><strong>风格:</strong> {{ result.data.analysis_result.style_preference }}</p>
<p><strong>PSD文件大小:</strong> {{ result.data.file_size_mb }} MB</p>
<p><strong>生成图片数量:</strong> {{ result.data.generated_images }}</p>
</div>
</div>
<div class="download-section">
<h3>下载文件</h3>
<button @click="downloadFile('vue')" class="download-btn">
📄 下载Vue文件
</button>
<button @click="downloadFile('psd')" class="download-btn">
🎨 下载PSD文件
</button>
<button @click="downloadFile('json')" class="download-btn">
📋 下载文案JSON
</button>
</div>
</div>
<div v-if="error" class="error">
<h3>错误信息</h3>
<p>{{ error }}</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const userInput = ref('')
const loading = ref(false)
const result = ref(null)
const error = ref('')
const activeTab = ref('vue')
const generatePoster = async () => {
loading.value = true
error.value = ''
try {
const response = await fetch('http://localhost:8000/api/generate-poster', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_input: userInput.value
})
})
const data = await response.json()
if (data.status === 'success') {
result.value = data
} else {
error.value = data.message || '生成失败'
}
} catch (err) {
error.value = '网络错误: ' + err.message
} finally {
loading.value = false
}
}
const downloadFile = (fileType) => {
if (!result.value) return
const url = `http://localhost:8000/api/download/${fileType}?session_id=${result.value.session_id}`
const a = document.createElement('a')
a.href = url
a.download = ''
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
const getSuggestionTitle = (key) => {
const titles = {
layer5_logo_content: 'Logo文字',
layer6_title_content: '主标题',
layer7_subtitle_content: '副标题'
}
return titles[key] || key
}
</script>
<style scoped>
.poster-generator {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.input-section {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
button.loading {
background: #ffc107;
}
.result-section {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.tabs {
display: flex;
background: #f8f9fa;
border-bottom: 1px solid #ddd;
}
.tabs button {
flex: 1;
padding: 15px;
background: transparent;
color: #666;
border: none;
border-radius: 0;
}
.tabs button.active {
background: white;
color: #007bff;
border-bottom: 2px solid #007bff;
}
.tab-content {
padding: 20px;
min-height: 400px;
}
.vue-code pre {
background: #f8f9fa;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
white-space: pre-wrap;
}
.suggestion-item {
background: #f8f9fa;
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
}
.download-section {
padding: 20px;
background: #f8f9fa;
border-top: 1px solid #ddd;
}
.download-btn {
margin-right: 10px;
margin-bottom: 10px;
}
.error {
background: #f8d7da;
color: #721c24;
padding: 15px;
border-radius: 4px;
margin-top: 20px;
}
</style>
```
## ⚡ 快速开始
### 1. 启动服务器
```bash
cd E:\砚\ai_service\scripts
python run_pipeline.py
# 选择: 2 (API服务器模式)
```
### 2. 测试API
```bash
# 健康检查
curl http://localhost:8000/health
# 生成海报
curl -X POST http://localhost:8000/api/generate-poster \
-H "Content-Type: application/json" \
-d '{"user_input": "春节海报,红色背景,现代风格"}'
```
### 3. 前端调用
```javascript
// 最简单的调用方式
fetch('http://localhost:8000/api/generate-poster', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_input: '端午节海报,传统风格' })
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
console.log('Vue代码:', data.data.vue_code);
// 下载PSD文件
window.open(`http://localhost:8000/api/download/psd?session_id=${data.session_id}`);
}
});
```
## 🔧 错误处理
### 错误响应格式
```json
{
"detail": "具体错误信息"
}
```
### 常见错误
- **400 Bad Request**: 请求参数错误
- **404 Not Found**: 会话不存在或文件不存在
- **500 Internal Server Error**: 服务器内部错误
### 错误处理示例
```javascript
try {
const response = await fetch('/api/generate-poster', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_input: 'test' })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || '请求失败');
}
const result = await response.json();
// 处理成功结果
} catch (error) {
console.error('API调用失败:', error.message);
// 显示错误给用户
}
```
## 🚀 部署配置
### 开发环境
```bash
# 启动开发服务器
python run_pipeline.py
# 访问: http://localhost:8000
```
### 生产环境
```bash
# 使用uvicorn直接运行
uvicorn run_pipeline:app --host 0.0.0.0 --port 8000
# 或使用PM2管理
pm2 start "uvicorn run_pipeline:app --host 0.0.0.0 --port 8000" --name poster-api
```
### Docker部署
```dockerfile
FROM python:3.11
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["uvicorn", "scripts.run_pipeline:app", "--host", "0.0.0.0", "--port", "8000"]
```
## 📝 更新日志
### v1.0.0 (2025-01-02)
- ✅ 统一API接口设计
- ✅ 集成DeepSeek + Kimi + ComfyUI
- ✅ 支持Vue组件和PSD文件生成
- ✅ 会话管理和文件下载
- ✅ 完整的错误处理和文档