diff --git a/docs/multi-platform-integration-solution.md b/docs/multi-platform-integration-solution.md index cdb76df..754da57 100644 --- a/docs/multi-platform-integration-solution.md +++ b/docs/multi-platform-integration-solution.md @@ -53,7 +53,7 @@ ┌─────────────────────────────────────────────────────────────┐ │ 数据存储层 (Data Layer) │ ├─────────────────────────────────────────────────────────────┤ -│ PostgreSQL │ Redis │ 文件存储 │ RabbitMQ │ 对象存储 │ +│ MySQL │ 文件存储 │ 对象存储 │ └─────────────────────────────────────────────────────────────┘ ``` @@ -89,9 +89,8 @@ ### 后端技术栈 - **框架**: NestJS (已选择) -- **数据库**: PostgreSQL (主数据库) + Redis (缓存) +- **数据库**: MySQL (主数据库) - **ORM**: TypeORM (数据库操作) -- **消息队列**: RabbitMQ ### 开发工具 - **API文档**: Swagger/OpenAPI @@ -158,88 +157,40 @@ interface ExtensionServiceInterface { - **平台适配层**: 每个服务都有对应的平台适配器 - **配置驱动**: 通过配置文件控制服务的启用和禁用 -### 3. 消息队列服务 (RabbitMQ) +### 3. 异步任务处理服务 -#### 3.1 业务队列配置 +#### 3.1 数据库异步处理 +- **功能**: 使用数据库任务队列替代消息队列 +- **实现方式**: 通过数据库表存储待处理任务,定时处理器执行 + +#### 3.2 业务异步处理 ```typescript -interface QueueConfig { - // 用户相关队列 - USER_REGISTRATION: 'user.registration'; - USER_LOGIN: 'user.login'; - USER_UPDATE: 'user.update'; - - // AI生成相关队列 - AI_GENERATION_TASK: 'ai.generation.task'; - AI_GENERATION_COMPLETED: 'ai.generation.completed'; - AI_GENERATION_FAILED: 'ai.generation.failed'; - - // 积分系统队列 - CREDIT_REWARD: 'credit.reward'; - CREDIT_CONSUME: 'credit.consume'; - - // 广告系统队列 - AD_WATCH_COMPLETED: 'ad.watch.completed'; - AD_REWARD_GRANTED: 'ad.reward.granted'; - - // 订阅系统队列 - SUBSCRIPTION_ACTIVATED: 'subscription.activated'; - SUBSCRIPTION_EXPIRED: 'subscription.expired'; - - // 注意: 模板系统采用面向对象设计,通过AI_GENERATION_*队列处理 - - // 平台同步队列 - PLATFORM_SYNC: 'platform.sync'; - PLATFORM_DATA_SYNC: 'platform.data.sync'; -} -``` - -#### 3.2 业务消息处理 -```typescript -// 用户注册消息处理 -@RabbitSubscribe({ - exchange: 'user.exchange', - routingKey: 'user.registration', - queue: 'user.registration.queue', -}) -async handleUserRegistration(message: UserRegistrationMessage) { +// 用户注册异步处理 +async processUserRegistration(userId: string, platform: string) { // 用户数据处理 - await this.userService.processRegistration(message.userId); + await this.userService.processRegistration(userId); // 发放新用户积分奖励 - await this.creditService.grantNewUserBonus(message.userId, message.platform); + await this.creditService.grantNewUserBonus(userId, platform); // 同步到各平台 - await this.platformService.syncUserData(message); + await this.platformService.syncUserData({ userId, platform }); } -// AI生成任务处理 -@RabbitSubscribe({ - exchange: 'ai.exchange', - routingKey: 'ai.generation.task', - queue: 'ai.generation.task.queue', -}) -async handleAIGenerationTask(message: AIGenerationTaskMessage) { +// AI生成任务异步处理 +async processAIGenerationTask(taskId: string) { // 处理AI生成任务 - await this.generationService.processGenerationTask(message.taskId); + await this.generationService.processGenerationTask(taskId); } -// 广告观看完成处理 -@RabbitSubscribe({ - exchange: 'ad.exchange', - routingKey: 'ad.watch.completed', - queue: 'ad.watch.completed.queue', -}) -async handleAdWatchCompleted(message: AdWatchCompletedMessage) { +// 广告观看完成异步处理 +async processAdWatchCompleted(adWatchId: string, watchDuration: number, adData: any) { // 发放广告观看奖励 - await this.adService.completeAdWatch( - message.adWatchId, - message.watchDuration, - message.adData - ); + await this.adService.completeAdWatch(adWatchId, watchDuration, adData); } ``` -## 数据库设计 (PostgreSQL + TypeORM) +## 数据库设计 (MySQL + TypeORM) ### 1. 用户实体 (User Entity) ```typescript @@ -339,7 +290,7 @@ export class PlatformUser { @Column({ length: 100 }) platformUserId: string; - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) platformData: any; @Column({ length: 500, nullable: true }) @@ -390,10 +341,10 @@ export class ExtensionData { @Column({ length: 100, nullable: true }) referenceId: string; // 外部引用ID - @Column({ type: 'jsonb' }) + @Column({ type: 'json' }) data: any; // 灵活的JSON数据存储 - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) metadata: any; // 元数据 @Column({ length: 20, default: 'active' }) @@ -469,7 +420,7 @@ export class UserCredit { @Column({ length: 100, nullable: true }) referenceId: string; // 关联的业务ID(如广告ID、任务ID等) - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) metadata: any; @CreateDateColumn() @@ -548,7 +499,7 @@ export class GenerationTask { @Column({ length: 100, nullable: true }) aiModelId: string; // 使用的AI模型ID - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) parameters: any; // 生成参数 @Column({ type: 'text', nullable: true }) @@ -633,7 +584,7 @@ export class UserSubscription { @Column({ length: 100, nullable: true }) paymentId: string; // 支付订单ID - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) features: any; // 订阅特权 @Column({ type: 'boolean', default: true }) @@ -709,7 +660,7 @@ export class AdWatch { @Column({ type: 'integer', nullable: true }) rewardCredits: number; // 奖励积分 - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) adData: any; // 广告相关数据 @CreateDateColumn() @@ -740,10 +691,10 @@ export class AdWatch { export class GenerationTask { // ... 其他字段 - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) parameters: any; // 存储模板执行参数 - @Column({ type: 'jsonb', nullable: true }) + @Column({ type: 'json', nullable: true }) metadata: any; // 存储模板代码、版本等信息 } @@ -764,10 +715,10 @@ import { TypeOrmModuleOptions } from '@nestjs/typeorm'; import { ConfigService } from '@nestjs/config'; export const getDatabaseConfig = (configService: ConfigService): TypeOrmModuleOptions => ({ - type: 'postgres', + type: 'mysql', host: configService.get('DB_HOST', 'localhost'), - port: configService.get('DB_PORT', 5432), - username: configService.get('DB_USERNAME', 'postgres'), + port: configService.get('DB_PORT', 3306), + username: configService.get('DB_USERNAME', 'root'), password: configService.get('DB_PASSWORD', 'password'), database: configService.get('DB_DATABASE', 'mini_app_platform'), entities: [__dirname + '/../**/*.entity{.ts,.js}'], @@ -823,7 +774,7 @@ export class CreateInitialTables1703001000000 implements MigrationInterface { "userId" uuid NOT NULL, "platform" "platform_type" NOT NULL, "platformUserId" character varying(100) NOT NULL, - "platformData" jsonb, + "platformData" json, "accessToken" character varying(500), "refreshToken" character varying(500), "expiresAt" TIMESTAMP, @@ -843,8 +794,8 @@ export class CreateInitialTables1703001000000 implements MigrationInterface { "platform" "platform_type" NOT NULL, "dataType" character varying(50) NOT NULL, "referenceId" character varying(100), - "data" jsonb NOT NULL, - "metadata" jsonb, + "data" json NOT NULL, + "metadata" json, "status" character varying(20) NOT NULL DEFAULT 'active', "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), @@ -873,7 +824,7 @@ export class CreateInitialTables1703001000000 implements MigrationInterface { "balance" integer NOT NULL, "description" character varying(200), "referenceId" character varying(100), - "metadata" jsonb, + "metadata" json, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_user_credits_id" PRIMARY KEY ("id"), @@ -903,7 +854,7 @@ export class CreateInitialTables1703001000000 implements MigrationInterface { "status" "task_status" NOT NULL DEFAULT 'pending', "creditCost" integer NOT NULL, "aiModelId" character varying(100), - "parameters" jsonb, + "parameters" json, "errorMessage" text, "processingTime" integer, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), @@ -935,7 +886,7 @@ export class CreateInitialTables1703001000000 implements MigrationInterface { "currency" character varying(10) NOT NULL DEFAULT 'CNY', "monthlyCredits" integer NOT NULL, "paymentId" character varying(100), - "features" jsonb, + "features" json, "autoRenew" boolean NOT NULL DEFAULT true, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), @@ -964,7 +915,7 @@ export class CreateInitialTables1703001000000 implements MigrationInterface { "status" "ad_status" NOT NULL, "watchDuration" integer, "rewardCredits" integer, - "adData" jsonb, + "adData" json, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_ad_watches_id" PRIMARY KEY ("id"), @@ -1172,49 +1123,28 @@ services: build: . environment: - NODE_ENV=production - - DB_HOST=postgres - - DB_PORT=5432 - - DB_USERNAME=${POSTGRES_USER} - - DB_PASSWORD=${POSTGRES_PASSWORD} - - DB_DATABASE=${POSTGRES_DB} - - REDIS_HOST=redis - - REDIS_PORT=6379 - - RABBITMQ_URL=amqp://rabbitmq:5672 + - DB_HOST=mysql + - DB_PORT=3306 + - DB_USERNAME=${MYSQL_USER} + - DB_PASSWORD=${MYSQL_PASSWORD} + - DB_DATABASE=${MYSQL_DB} depends_on: - - postgres - - redis - - rabbitmq + - mysql - postgres: - image: postgres:15-alpine + mysql: + image: mysql:8.0 environment: - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - POSTGRES_DB: ${POSTGRES_DB} + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DB} volumes: - - postgres_data:/var/lib/postgresql/data + - mysql_data:/var/lib/mysql ports: - - "5432:5432" - - redis: - image: redis:alpine - ports: - - "6379:6379" - - rabbitmq: - image: rabbitmq:3-management-alpine - environment: - RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER} - RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD} - ports: - - "5672:5672" - - "15672:15672" # 管理界面 - volumes: - - rabbitmq_data:/var/lib/rabbitmq + - "3306:3306" volumes: - postgres_data: - rabbitmq_data: + mysql_data: ``` ### 2. 负载均衡配置 @@ -1222,75 +1152,6 @@ volumes: - 支持多实例部署 - 健康检查和自动故障转移 -## RabbitMQ 配置与管理 - -### 1. 交换机配置 -```typescript -// src/config/rabbitmq.config.ts -export const RabbitMQConfig = { - exchanges: [ - { - name: 'user.exchange', - type: 'topic', - options: { durable: true } - }, - { - name: 'payment.exchange', - type: 'topic', - options: { durable: true } - }, - { - name: 'push.exchange', - type: 'topic', - options: { durable: true } - }, - { - name: 'platform.exchange', - type: 'topic', - options: { durable: true } - } - ], - queues: [ - { - name: 'user.registration.queue', - options: { durable: true } - }, - { - name: 'payment.success.queue', - options: { durable: true } - }, - { - name: 'push.message.queue', - options: { durable: true } - } - ] -}; -``` - -### 2. 消息生产者示例 -```typescript -// src/services/message-producer.service.ts -@Injectable() -export class MessageProducerService { - constructor( - @Inject('RABBITMQ_CONNECTION') - private readonly connection: Connection, - ) {} - - async publishPaymentSuccess(paymentData: PaymentSuccessMessage) { - const channel = await this.connection.createChannel(); - - await channel.publish( - 'payment.exchange', - 'payment.success', - Buffer.from(JSON.stringify(paymentData)), - { persistent: true } - ); - - await channel.close(); - } -} -``` ## API文档配置 (Swagger/OpenAPI) @@ -1675,7 +1536,6 @@ bootstrap(); - [ ] 广告服务集成 (观看验证、奖励发放) - [ ] AI生成服务开发 (任务管理、模型调用) - [ ] 文件存储服务 (图片上传、结果存储) -- [ ] RabbitMQ消息队列集成 ### Phase 3: 高级功能开发 (6周) - [ ] 订阅服务开发 (包月付费、会员权益) @@ -1730,8 +1590,8 @@ bootstrap(); 1. **统一性**: 抹平8大平台API差异和AI模型调用差异,统一的开发体验 2. **可扩展性**: 模块化架构,支持快速添加新功能、平台和AI模型 3. **模板化**: 通过模板系统标准化AI调用,简化前端集成 -4. **高性能**: PostgreSQL + Redis + RabbitMQ,支持高并发处理 +4. **高性能**: PostgreSQL 数据库,支持高并发处理 5. **数据安全**: JSONB灵活存储,完整的数据备份和恢复机制 -6. **异步处理**: 基于消息队列的异步任务处理,提升用户体验 +6. **异步处理**: 基于数据库任务队列的异步处理,提升用户体验 7. **类型安全**: TypeScript + TypeORM,编译时错误检查 8. **智能缓存**: 活跃模板缓存,提升模板执行性能 diff --git a/docs/swagger-api-documentation.md b/docs/swagger-api-documentation.md index 1602526..e00588d 100644 --- a/docs/swagger-api-documentation.md +++ b/docs/swagger-api-documentation.md @@ -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模板系统接口 (支持图片/视频生成) +- 💾 动态模板配置管理 +- 📈 模板使用统计和监控