feat: 完善API文档系统和Swagger集成

- 集成Swagger文档生成和UI界面
- 为所有API端点添加详细的文档注解
- 添加统一的响应装饰器和DTO类型定义
- 优化API路由结构和全局验证配置
- 新增文档生成和服务脚本命令
This commit is contained in:
imeepos
2025-09-04 18:11:43 +08:00
parent 4dd37c7ce2
commit 21a2865e43
13 changed files with 4846 additions and 84 deletions

View File

@@ -11,21 +11,35 @@ import {
HttpException,
HttpStatus,
} from '@nestjs/common';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiParam,
ApiQuery,
ApiBody,
} from '@nestjs/swagger';
import { N8nTemplateFactoryService } from '../services/n8n-template-factory.service';
import {
N8nTemplateEntity,
TemplateType,
} from '../entities/n8n-template.entity';
import { CreateTemplateDto, UpdateTemplateDto } from '../dto/template.dto';
import {
CreateTemplateDto,
UpdateTemplateDto,
TemplateExecuteDto,
TemplateExecuteResponseDto,
TemplateListDto,
BatchExecuteDto,
} from '../dto/template.dto';
import { TemplateExecutionEntity } from '../entities/template-execution.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ApiCommonResponses } from '../decorators/api-common-responses.decorator';
/**
* 模板控制器
* 提供模板相关的API接口支持混合式架构的动态模板管理
*/
@ApiTags('AI模板系统')
@Controller('templates')
@ApiCommonResponses()
export class TemplateController {
constructor(
private readonly templateFactory: N8nTemplateFactoryService,
@@ -35,13 +49,29 @@ export class TemplateController {
private readonly executionRepository: Repository<TemplateExecutionEntity>,
) {}
/**
* 执行模板 - 通过模板ID
* @param templateId 模板ID
* @param body 请求体包含imageUrl
* @returns 执行结果
*/
@Post(':templateId/execute')
@ApiOperation({
summary: '执行模板生成',
description: '根据模板ID执行AI生成任务支持图片和视频生成',
})
@ApiParam({ name: 'templateId', description: '模板ID', example: 1 })
@ApiBody({ type: TemplateExecuteDto })
@ApiResponse({
status: 200,
description: '执行成功',
type: TemplateExecuteResponseDto,
})
@ApiResponse({
status: 400,
description: '参数错误',
schema: {
example: {
code: 400,
message: 'imageUrl is required',
data: null
}
}
})
async executeTemplateById(
@Param('templateId', ParseIntPipe) templateId: number,
@Body() body: { imageUrl: string },
@@ -76,13 +106,18 @@ export class TemplateController {
}
}
/**
* 执行模板 - 通过模板代码
* @param code 模板代码
* @param body 请求体包含imageUrl
* @returns 执行结果
*/
@Post('code/:code/execute')
@ApiOperation({
summary: '通过代码执行模板',
description: '根据模板代码执行AI生成任务支持图片和视频生成',
})
@ApiParam({ name: 'code', description: '模板代码', example: 'character_figurine_v1' })
@ApiBody({ type: TemplateExecuteDto })
@ApiResponse({
status: 200,
description: '执行成功',
type: TemplateExecuteResponseDto,
})
async executeTemplateByCode(
@Param('code') code: string,
@Body() body: { imageUrl: string },
@@ -116,13 +151,30 @@ export class TemplateController {
}
}
/**
* 批量执行模板
* @param templateId 模板ID
* @param body 包含多个imageUrl的数组
* @returns 批量执行结果
*/
@Post(':templateId/batch-execute')
@ApiOperation({
summary: '批量执行模板',
description: '批量执行模板生成任务,支持多张图片同时处理',
})
@ApiParam({ name: 'templateId', description: '模板ID', example: 1 })
@ApiBody({ type: BatchExecuteDto })
@ApiResponse({
status: 200,
description: '批量执行成功',
schema: {
example: {
success: true,
data: {
templateId: 1,
totalCount: 2,
results: [
{ inputUrl: 'image1.jpg', outputUrl: 'output1.jpg' },
{ inputUrl: 'image2.jpg', outputUrl: 'output2.jpg' }
]
}
}
}
})
async batchExecuteTemplate(
@Param('templateId', ParseIntPipe) templateId: number,
@Body() body: { imageUrls: string[] },
@@ -161,11 +213,16 @@ export class TemplateController {
}
}
/**
* 获取所有模板列表
* @returns 模板配置列表
*/
@Get()
@ApiOperation({
summary: '获取所有模板列表',
description: '获取所有可用的AI生成模板支持按类型筛选',
})
@ApiResponse({
status: 200,
description: '获取成功',
type: [TemplateListDto],
})
async getAllTemplates() {
try {
const templates = await this.templateFactory.getAllTemplates();
@@ -197,11 +254,16 @@ export class TemplateController {
}
}
/**
* 获取图片类型模板
* @returns 图片模板列表
*/
@Get('image')
@ApiOperation({
summary: '获取图片模板列表',
description: '获取所有图片类型的AI生成模板',
})
@ApiResponse({
status: 200,
description: '获取成功',
type: [TemplateListDto],
})
async getImageTemplates() {
try {
const templates = await this.templateFactory.getImageTemplates();
@@ -217,11 +279,16 @@ export class TemplateController {
}
}
/**
* 获取视频类型模板
* @returns 视频模板列表
*/
@Get('video')
@ApiOperation({
summary: '获取视频模板列表',
description: '获取所有视频类型的AI生成模板',
})
@ApiResponse({
status: 200,
description: '获取成功',
type: [TemplateListDto],
})
async getVideoTemplates() {
try {
const templates = await this.templateFactory.getVideoTemplates();
@@ -237,13 +304,26 @@ export class TemplateController {
}
}
/**
* 根据用户偏好推荐模板
* @param tags 用户偏好标签,逗号分隔
* @param limit 推荐数量
* @returns 推荐模板列表
*/
@Get('recommend')
@ApiOperation({
summary: '推荐模板',
description: '根据用户偏好标签推荐适合的模板',
})
@ApiQuery({ name: 'tags', required: false, description: '用户偏好标签,逗号分隔', example: '人物,手办' })
@ApiQuery({ name: 'limit', required: false, description: '推荐数量', example: 5 })
@ApiResponse({
status: 200,
description: '推荐成功',
schema: {
example: {
success: true,
data: {
userTags: ['人物', '手办'],
recommendedTemplates: []
}
}
}
})
async recommendTemplates(
@Query('tags') tags?: string,
@Query('limit') limit: number = 5,
@@ -270,12 +350,21 @@ export class TemplateController {
}
}
/**
* 获取特定模板详情
* @param templateId 模板ID
* @returns 模板详细信息
*/
@Get(':templateId')
@ApiOperation({
summary: '获取模板详情',
description: '根据模板ID获取详细信息',
})
@ApiParam({ name: 'templateId', description: '模板ID', example: 1 })
@ApiResponse({
status: 200,
description: '获取成功',
type: TemplateListDto,
})
@ApiResponse({
status: 404,
description: '模板不存在',
})
async getTemplateById(@Param('templateId', ParseIntPipe) templateId: number) {
try {
const template = await this.templateFactory.createTemplate(templateId);
@@ -411,12 +500,30 @@ export class TemplateController {
}
}
/**
* 创建新模板
* @param createTemplateDto 创建模板的数据传输对象
* @returns 创建的模板信息
*/
@Post()
@ApiOperation({
summary: '创建新模板',
description: '创建一个新的AI生成模板',
})
@ApiBody({ type: CreateTemplateDto })
@ApiResponse({
status: 200,
description: '创建成功',
schema: {
example: {
success: true,
data: {
id: 1,
code: 'new_template_v1',
name: '新模板'
}
}
}
})
@ApiResponse({
status: 409,
description: '模板代码已存在',
})
async createTemplate(@Body() createTemplateDto: CreateTemplateDto) {
try {
const existingTemplate = await this.templateRepository.findOne({
@@ -448,13 +555,26 @@ export class TemplateController {
}
}
/**
* 更新模板
* @param templateId 模板ID
* @param updateTemplateDto 更新模板的数据传输对象
* @returns 更新后的模板信息
*/
@Put(':templateId')
@ApiOperation({
summary: '更新模板',
description: '更新指定模板的配置信息',
})
@ApiParam({ name: 'templateId', description: '模板ID', example: 1 })
@ApiBody({ type: UpdateTemplateDto })
@ApiResponse({
status: 200,
description: '更新成功',
type: TemplateListDto,
})
@ApiResponse({
status: 404,
description: '模板不存在',
})
@ApiResponse({
status: 409,
description: '模板代码已存在',
})
async updateTemplate(
@Param('templateId', ParseIntPipe) templateId: number,
@Body() updateTemplateDto: UpdateTemplateDto,