598 lines
14 KiB
Markdown
598 lines
14 KiB
Markdown
# 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文件生成
|
||
- ✅ 会话管理和文件下载
|
||
- ✅ 完整的错误处理和文档
|