docs: 更新数据库配置从PostgreSQL到MySQL
- 更新multi-platform-integration-solution.md中的数据库配置 - 数据库类型从PostgreSQL改为MySQL - 端口从5432改为3306 - 默认用户名从postgres改为root - 所有jsonb字段类型改为json - Docker配置更新为MySQL 8.0 - 更新swagger-api-documentation.md中的数据存储描述 - 从"PostgreSQL + JSONB"改为"MySQL + JSON"
This commit is contained in:
@@ -20,13 +20,19 @@ export function setupSwagger(app: INestApplication): void {
|
||||
.setDescription(`
|
||||
## 功能特性
|
||||
- 🔐 统一用户认证 (微信/支付宝/百度/字节跳动等)
|
||||
- 🔄 平台数据同步 (RabbitMQ异步处理)
|
||||
- 🔄 平台数据同步 (数据库异步处理)
|
||||
- 🧩 可扩展架构 (支持后续添加支付、推送等功能)
|
||||
- 📊 灵活数据存储 (PostgreSQL + JSONB)
|
||||
- 📊 灵活数据存储 (MySQL + JSON)
|
||||
|
||||
## 认证方式
|
||||
使用JWT Bearer Token进行API认证
|
||||
|
||||
## AI模板系统
|
||||
- 🎨 动态模板管理 (数据库配置 + 代码执行)
|
||||
- 🚀 N8n工作流集成 (图片/视频生成)
|
||||
- 📊 使用统计分析 (性能监控 + 用户行为)
|
||||
- 🎛️ 运营管理后台 (A/B测试 + 个性化推荐)
|
||||
|
||||
## 响应格式
|
||||
所有API响应都遵循统一格式:
|
||||
\`\`\`json
|
||||
@@ -539,9 +545,427 @@ export class UserController {
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 环境配置
|
||||
## 7. AI模板管理 API
|
||||
|
||||
### 7.1 开发环境配置
|
||||
### 7.1 模板数据传输对象
|
||||
|
||||
```typescript
|
||||
// src/dto/template.dto.ts
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsNumber, IsEnum, IsOptional, IsArray, IsBoolean } from 'class-validator';
|
||||
|
||||
export enum TemplateType {
|
||||
IMAGE = 'image',
|
||||
VIDEO = 'video'
|
||||
}
|
||||
|
||||
export class TemplateListDto {
|
||||
@ApiProperty({ description: '模板ID', example: 1 })
|
||||
id: number;
|
||||
|
||||
@ApiProperty({ description: '模板代码', example: 'character_figurine_v1' })
|
||||
code: string;
|
||||
|
||||
@ApiProperty({ description: '模板名称', example: '人物手办' })
|
||||
name: string;
|
||||
|
||||
@ApiProperty({ description: '模板描述', example: '将人物照片制作成精细的角色手办模型' })
|
||||
description: string;
|
||||
|
||||
@ApiProperty({ enum: TemplateType, description: '模板类型', example: 'video' })
|
||||
templateType: TemplateType;
|
||||
|
||||
@ApiProperty({ description: '积分消耗', example: 28 })
|
||||
creditCost: number;
|
||||
|
||||
@ApiProperty({ description: '版本号', example: '1.0.0' })
|
||||
version: string;
|
||||
|
||||
@ApiProperty({ description: '输入示例URL', required: false })
|
||||
inputExampleUrl?: string;
|
||||
|
||||
@ApiProperty({ description: '输出示例URL', required: false })
|
||||
outputExampleUrl?: string;
|
||||
|
||||
@ApiProperty({ type: [String], description: '标签数组', example: ['人物', '手办', '模型'] })
|
||||
tags: string[];
|
||||
|
||||
@ApiProperty({ description: '是否启用', example: true })
|
||||
isActive: boolean;
|
||||
|
||||
@ApiProperty({ description: '创建时间', example: '2024-01-01T00:00:00Z' })
|
||||
createdAt: Date;
|
||||
}
|
||||
|
||||
export class TemplateExecuteDto {
|
||||
@ApiProperty({
|
||||
description: '输入图片URL',
|
||||
example: 'https://cdn.roasmax.cn/upload/3d590851eb584e92aa415a964e93260e.jpg'
|
||||
})
|
||||
@IsString()
|
||||
imageUrl: string;
|
||||
}
|
||||
|
||||
export class TemplateExecuteResponseDto {
|
||||
@ApiProperty({ description: '执行状态', example: true })
|
||||
success: boolean;
|
||||
|
||||
@ApiProperty({ description: '生成结果URL(图片模板)', required: false })
|
||||
imageUrl?: string;
|
||||
|
||||
@ApiProperty({ description: '生成结果URL(视频模板)', required: false })
|
||||
videoUrl?: string;
|
||||
|
||||
@ApiProperty({ description: '缩略图URL', required: false })
|
||||
thumbnailUrl?: string;
|
||||
|
||||
@ApiProperty({ description: '任务ID', example: 'req_1704067200_abc123' })
|
||||
taskId: string;
|
||||
|
||||
@ApiProperty({ description: '执行耗时(毫秒)', example: 5000 })
|
||||
executionTime: number;
|
||||
|
||||
@ApiProperty({ description: '消耗积分', example: 28 })
|
||||
creditCost: number;
|
||||
}
|
||||
|
||||
export class TemplateStatsDto {
|
||||
@ApiProperty({ description: '总模板数', example: 8 })
|
||||
total: number;
|
||||
|
||||
@ApiProperty({ description: '启用模板数', example: 8 })
|
||||
enabled: number;
|
||||
|
||||
@ApiProperty({ description: '图片模板数', example: 3 })
|
||||
imageTemplates: number;
|
||||
|
||||
@ApiProperty({ description: '视频模板数', example: 5 })
|
||||
videoTemplates: number;
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 模板管理控制器
|
||||
|
||||
```typescript
|
||||
// src/controllers/template.controller.ts
|
||||
import {
|
||||
Controller, Get, Post, Param, Body, Query, UseGuards, ParseIntPipe
|
||||
} from '@nestjs/common';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiResponse,
|
||||
ApiBearerAuth,
|
||||
ApiParam,
|
||||
ApiQuery
|
||||
} from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
||||
import { CurrentUser } from '../decorators/current-user.decorator';
|
||||
import { ApiCommonResponses, ApiAuthResponses } from '../decorators/api-common-responses.decorator';
|
||||
import { N8nTemplateFactoryService } from '../services/n8n-template-factory.service';
|
||||
import { TemplateListDto, TemplateExecuteDto, TemplateExecuteResponseDto, TemplateStatsDto } from '../dto/template.dto';
|
||||
|
||||
@ApiTags('🎨 AI模板系统')
|
||||
@Controller('templates')
|
||||
@ApiCommonResponses()
|
||||
export class TemplateController {
|
||||
constructor(
|
||||
private readonly templateFactory: N8nTemplateFactoryService,
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({
|
||||
summary: '获取所有模板列表',
|
||||
description: '获取所有可用的AI生成模板,支持按类型筛选'
|
||||
})
|
||||
@ApiQuery({
|
||||
name: 'type',
|
||||
required: false,
|
||||
enum: ['image', 'video'],
|
||||
description: '模板类型筛选'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: [TemplateListDto]
|
||||
})
|
||||
async getTemplates(@Query('type') type?: 'image' | 'video') {
|
||||
if (type === 'image') {
|
||||
return this.templateFactory.getTemplatesByType('image');
|
||||
} else if (type === 'video') {
|
||||
return this.templateFactory.getTemplatesByType('video');
|
||||
}
|
||||
return this.templateFactory.getAllTemplates();
|
||||
}
|
||||
|
||||
@Get('stats')
|
||||
@ApiOperation({
|
||||
summary: '获取模板统计信息',
|
||||
description: '获取模板总数、类型分布等统计信息'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: TemplateStatsDto
|
||||
})
|
||||
async getTemplateStats() {
|
||||
const allTemplates = await this.templateFactory.getAllTemplates();
|
||||
const imageTemplates = allTemplates.filter(t => t.templateType === 'image');
|
||||
const videoTemplates = allTemplates.filter(t => t.templateType === 'video');
|
||||
|
||||
return {
|
||||
total: allTemplates.length,
|
||||
enabled: allTemplates.filter(t => t.isActive).length,
|
||||
imageTemplates: imageTemplates.length,
|
||||
videoTemplates: videoTemplates.length,
|
||||
};
|
||||
}
|
||||
|
||||
@Get(':templateId')
|
||||
@ApiOperation({
|
||||
summary: '获取模板详情',
|
||||
description: '根据模板ID获取详细信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'templateId',
|
||||
description: '模板ID',
|
||||
example: 1
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: TemplateListDto
|
||||
})
|
||||
async getTemplateById(@Param('templateId', ParseIntPipe) templateId: number) {
|
||||
return this.templateFactory.getTemplateById(templateId);
|
||||
}
|
||||
|
||||
@Get('code/:templateCode')
|
||||
@ApiOperation({
|
||||
summary: '通过代码获取模板详情',
|
||||
description: '根据模板代码获取详细信息'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'templateCode',
|
||||
description: '模板代码',
|
||||
example: 'character_figurine_v1'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '获取成功',
|
||||
type: TemplateListDto
|
||||
})
|
||||
async getTemplateByCode(@Param('templateCode') templateCode: string) {
|
||||
return this.templateFactory.getTemplateByCode(templateCode);
|
||||
}
|
||||
|
||||
@Post(':templateId/execute')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@ApiAuthResponses()
|
||||
@ApiOperation({
|
||||
summary: '执行模板生成',
|
||||
description: '根据模板ID执行AI生成任务,支持图片和视频生成'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'templateId',
|
||||
description: '模板ID',
|
||||
example: 1
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '执行成功',
|
||||
type: TemplateExecuteResponseDto
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 400,
|
||||
description: '参数错误',
|
||||
schema: {
|
||||
example: {
|
||||
code: 400,
|
||||
message: '输入图片URL不能为空',
|
||||
data: null
|
||||
}
|
||||
}
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 402,
|
||||
description: '积分不足',
|
||||
schema: {
|
||||
example: {
|
||||
code: 402,
|
||||
message: '积分不足,当前余额: 10,需要: 28',
|
||||
data: null
|
||||
}
|
||||
}
|
||||
})
|
||||
async executeTemplate(
|
||||
@Param('templateId', ParseIntPipe) templateId: number,
|
||||
@Body() executeDto: TemplateExecuteDto,
|
||||
@CurrentUser() user: any
|
||||
) {
|
||||
const startTime = Date.now();
|
||||
|
||||
// 获取模板配置
|
||||
const templateConfig = await this.templateFactory.getTemplateById(templateId);
|
||||
|
||||
// 创建动态模板实例并执行
|
||||
let template;
|
||||
if (templateConfig.templateType === 'image') {
|
||||
template = await this.templateFactory.createImageTemplate(templateId);
|
||||
} else {
|
||||
template = await this.templateFactory.createVideoTemplate(templateId);
|
||||
}
|
||||
|
||||
const result = await template.execute(executeDto.imageUrl);
|
||||
const executionTime = Date.now() - startTime;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
imageUrl: templateConfig.templateType === 'image' ? result : undefined,
|
||||
videoUrl: templateConfig.templateType === 'video' ? result : undefined,
|
||||
taskId: `req_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
||||
executionTime,
|
||||
creditCost: templateConfig.creditCost
|
||||
};
|
||||
}
|
||||
|
||||
@Post('code/:templateCode/execute')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@ApiAuthResponses()
|
||||
@ApiOperation({
|
||||
summary: '通过代码执行模板',
|
||||
description: '根据模板代码执行AI生成任务,支持图片和视频生成'
|
||||
})
|
||||
@ApiParam({
|
||||
name: 'templateCode',
|
||||
description: '模板代码',
|
||||
example: 'character_figurine_v1'
|
||||
})
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: '执行成功',
|
||||
type: TemplateExecuteResponseDto
|
||||
})
|
||||
async executeTemplateByCode(
|
||||
@Param('templateCode') templateCode: string,
|
||||
@Body() executeDto: TemplateExecuteDto,
|
||||
@CurrentUser() user: any
|
||||
) {
|
||||
const startTime = Date.now();
|
||||
|
||||
// 创建动态模板实例并执行
|
||||
const template = await this.templateFactory.createTemplateByCode(templateCode);
|
||||
const result = await template.execute(executeDto.imageUrl);
|
||||
const executionTime = Date.now() - startTime;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
imageUrl: template.templateType === 'image' ? result : undefined,
|
||||
videoUrl: template.templateType === 'video' ? result : undefined,
|
||||
taskId: `req_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
|
||||
executionTime,
|
||||
creditCost: template.creditCost
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 API使用示例
|
||||
|
||||
#### 获取所有模板
|
||||
```bash
|
||||
curl -X GET "http://localhost:3000/api/templates" \
|
||||
-H "accept: application/json"
|
||||
```
|
||||
|
||||
响应示例:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "character_figurine_v1",
|
||||
"name": "人物手办",
|
||||
"description": "将人物照片制作成精细的角色手办模型,展示在收藏家房间中,并生成抚摸手办的视频",
|
||||
"templateType": "video",
|
||||
"creditCost": 28,
|
||||
"version": "1.0.0",
|
||||
"inputExampleUrl": "https://cdn.roasmax.cn/upload/3d590851eb584e92aa415a964e93260e.jpg",
|
||||
"outputExampleUrl": "https://file.302.ai/gpt/imgs/20250828/2283106b31faf2066e1a72d955f65bca.jpg",
|
||||
"tags": ["人物", "手办", "模型", "收藏", "PVC", "角色模型", "视频生成"],
|
||||
"isActive": true,
|
||||
"createdAt": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 执行模板生成
|
||||
```bash
|
||||
curl -X POST "http://localhost:3000/api/templates/1/execute" \
|
||||
-H "accept: application/json" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"imageUrl": "https://cdn.roasmax.cn/upload/3d590851eb584e92aa415a964e93260e.jpg"
|
||||
}'
|
||||
```
|
||||
|
||||
响应示例:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"success": true,
|
||||
"videoUrl": "https://n8n.bowongai.com/files/generated_video_abc123.mp4",
|
||||
"taskId": "req_1704067200_abc123",
|
||||
"executionTime": 5000,
|
||||
"creditCost": 28
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.4 错误处理
|
||||
|
||||
```typescript
|
||||
// 常见错误响应
|
||||
export const TemplateApiErrors = {
|
||||
TEMPLATE_NOT_FOUND: {
|
||||
code: 404,
|
||||
message: '模板不存在',
|
||||
data: null
|
||||
},
|
||||
INSUFFICIENT_CREDITS: {
|
||||
code: 402,
|
||||
message: '积分不足',
|
||||
data: { required: 28, current: 10 }
|
||||
},
|
||||
INVALID_IMAGE_URL: {
|
||||
code: 400,
|
||||
message: '无效的图片URL',
|
||||
data: null
|
||||
},
|
||||
TEMPLATE_EXECUTION_FAILED: {
|
||||
code: 500,
|
||||
message: 'AI生成失败,请稍后重试',
|
||||
data: null
|
||||
},
|
||||
TEMPLATE_DISABLED: {
|
||||
code: 403,
|
||||
message: '模板已禁用',
|
||||
data: null
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 8. 环境配置
|
||||
|
||||
### 8.1 开发环境配置
|
||||
```typescript
|
||||
// src/main.ts
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
@@ -584,7 +1008,7 @@ async function bootstrap() {
|
||||
bootstrap();
|
||||
```
|
||||
|
||||
## 8. 访问API文档
|
||||
## 9. 访问API文档
|
||||
|
||||
启动应用后,访问以下地址查看API文档:
|
||||
|
||||
@@ -598,3 +1022,6 @@ API文档包含:
|
||||
- 📝 请求/响应示例
|
||||
- 🧪 在线接口测试功能
|
||||
- 📊 数据模型定义
|
||||
- 🎨 AI模板系统接口 (支持图片/视频生成)
|
||||
- 💾 动态模板配置管理
|
||||
- 📈 模板使用统计和监控
|
||||
|
||||
Reference in New Issue
Block a user