feat: 按模块拆分 Knife4j 接口文档
This commit is contained in:
parent
7a93e49af6
commit
8ae097e44d
@ -17,7 +17,7 @@ import { AdminAuthService } from './admin-auth.service';
|
|||||||
import { JwtAuthGuard } from './jwt-auth.guard';
|
import { JwtAuthGuard } from './jwt-auth.guard';
|
||||||
import { WordpressService } from '@/wordpress/wordpress.service';
|
import { WordpressService } from '@/wordpress/wordpress.service';
|
||||||
|
|
||||||
@ApiTags('admin-auth')
|
@ApiTags('Admin - 认证')
|
||||||
@Controller()
|
@Controller()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminAuthController {
|
export class AdminAuthController {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ class CompPageDto
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Controller('component')
|
@Controller('component')
|
||||||
@ApiTags('component')
|
@ApiTags('Admin - 组件管理')
|
||||||
@ApiExtraModels(PaginatedDto)
|
@ApiExtraModels(PaginatedDto)
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class ComponentController {
|
export class ComponentController {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
|||||||
import { AdminDept } from './admin-dept.entity';
|
import { AdminDept } from './admin-dept.entity';
|
||||||
import { AdminDeptService } from './admin-dept.service';
|
import { AdminDeptService } from './admin-dept.service';
|
||||||
|
|
||||||
@ApiTags('admin-dept')
|
@ApiTags('Admin - 部门管理')
|
||||||
@Controller('system/dept')
|
@Controller('system/dept')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminDeptController {
|
export class AdminDeptController {
|
||||||
|
|||||||
@ -35,7 +35,7 @@ const chartDictExample = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ApiTags('dict')
|
@ApiTags('Admin - 字典管理')
|
||||||
@Controller('dict')
|
@Controller('dict')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class DictController {
|
export class DictController {
|
||||||
|
|||||||
@ -66,7 +66,7 @@ const DEMO_ROWS: DemoTableRow[] = Array.from({ length: 100 }, (_, index) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ApiTags('admin-example')
|
@ApiTags('Admin - 示例')
|
||||||
@Controller()
|
@Controller()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminExampleController {
|
export class AdminExampleController {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import { AdminUser } from '../user/admin-user.entity';
|
|||||||
import { AdminMenu } from './admin-menu.entity';
|
import { AdminMenu } from './admin-menu.entity';
|
||||||
import { AdminMenuService } from './admin-menu.service';
|
import { AdminMenuService } from './admin-menu.service';
|
||||||
|
|
||||||
@ApiTags('admin-menu')
|
@ApiTags('Admin - 菜单管理')
|
||||||
@Controller()
|
@Controller()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminMenuController {
|
export class AdminMenuController {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { vbenPage, vbenSuccess } from '@/common';
|
|||||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||||
import { AdminRoleService } from './admin-role.service';
|
import { AdminRoleService } from './admin-role.service';
|
||||||
|
|
||||||
@ApiTags('admin-role')
|
@ApiTags('Admin - 角色管理')
|
||||||
@Controller('system/role')
|
@Controller('system/role')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminRoleController {
|
export class AdminRoleController {
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const TIMEZONE_OPTIONS = [
|
|||||||
{ label: 'Asia/Seoul (GMT+9)', value: 'Asia/Seoul' },
|
{ label: 'Asia/Seoul (GMT+9)', value: 'Asia/Seoul' },
|
||||||
];
|
];
|
||||||
|
|
||||||
@ApiTags('admin-timezone')
|
@ApiTags('Admin - 时区')
|
||||||
@Controller('timezone')
|
@Controller('timezone')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminTimezoneController {
|
export class AdminTimezoneController {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
|||||||
import { AdminUser } from './admin-user.entity';
|
import { AdminUser } from './admin-user.entity';
|
||||||
import { AdminUserService } from './admin-user.service';
|
import { AdminUserService } from './admin-user.service';
|
||||||
|
|
||||||
@ApiTags('admin-user')
|
@ApiTags('Admin - 用户管理')
|
||||||
@Controller('user')
|
@Controller('user')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class AdminUserController {
|
export class AdminUserController {
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
import { Controller, Get, Redirect } from '@nestjs/common';
|
import { Controller, Get, Redirect } from '@nestjs/common';
|
||||||
import { ApiMovedPermanentlyResponse, ApiOperation } from '@nestjs/swagger';
|
import {
|
||||||
|
ApiMovedPermanentlyResponse,
|
||||||
|
ApiOperation,
|
||||||
|
ApiTags,
|
||||||
|
} from '@nestjs/swagger';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
|
|
||||||
|
@ApiTags('基础能力 - 根入口')
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(private readonly appService: AppService) {}
|
constructor(private readonly appService: AppService) {}
|
||||||
|
|||||||
104
src/main.ts
104
src/main.ts
@ -1,8 +1,56 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||||
|
import type { OpenAPIObject } from '@nestjs/swagger';
|
||||||
import { urlencoded, json } from 'express';
|
import { urlencoded, json } from 'express';
|
||||||
import { knife4jSetup } from 'nestjs-knife4j-plus';
|
import { knife4jSetup } from 'nestjs-knife4j-plus';
|
||||||
|
import type { Service } from 'nestjs-knife4j-plus';
|
||||||
|
|
||||||
|
type SwaggerPathMatcher = (path: string) => boolean;
|
||||||
|
|
||||||
|
interface SwaggerDocumentGroup {
|
||||||
|
matcher: SwaggerPathMatcher;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const adminSwaggerPathPrefixes = [
|
||||||
|
'/auth',
|
||||||
|
'/component',
|
||||||
|
'/dict',
|
||||||
|
'/menu',
|
||||||
|
'/system',
|
||||||
|
'/timezone',
|
||||||
|
'/user',
|
||||||
|
'/demo',
|
||||||
|
'/status',
|
||||||
|
'/table',
|
||||||
|
'/test',
|
||||||
|
'/upload',
|
||||||
|
];
|
||||||
|
|
||||||
|
const swaggerGroups: SwaggerDocumentGroup[] = [
|
||||||
|
{
|
||||||
|
matcher: (path) => matchPathPrefixes(path, adminSwaggerPathPrefixes),
|
||||||
|
name: 'Admin 后台管理',
|
||||||
|
path: 'api/admin',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matcher: (path) => path.startsWith('/qqbot'),
|
||||||
|
name: 'QQBot 机器人',
|
||||||
|
path: 'api/qqbot',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matcher: (path) => path.startsWith('/wordpress'),
|
||||||
|
name: 'WordPress 博客',
|
||||||
|
path: 'api/wordpress',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matcher: (path) => path === '/' || path.startsWith('/minio'),
|
||||||
|
name: '基础能力',
|
||||||
|
path: 'api/basic',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
@ -15,15 +63,57 @@ async function bootstrap() {
|
|||||||
.build();
|
.build();
|
||||||
const document = SwaggerModule.createDocument(app, options);
|
const document = SwaggerModule.createDocument(app, options);
|
||||||
SwaggerModule.setup('api', app, document);
|
SwaggerModule.setup('api', app, document);
|
||||||
|
const services: Service[] = [
|
||||||
|
{
|
||||||
|
name: '全量接口',
|
||||||
|
url: '/api-json',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
swaggerGroups.forEach((group) => {
|
||||||
|
const groupDocument = filterSwaggerDocument(document, group.matcher);
|
||||||
|
SwaggerModule.setup(group.path, app, groupDocument);
|
||||||
|
services.push({
|
||||||
|
name: group.name,
|
||||||
|
url: `/${group.path}-json`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 启用knife4j增强(关键代码)
|
// 启用knife4j增强(关键代码)
|
||||||
knife4jSetup(app, [
|
knife4jSetup(app, services);
|
||||||
{
|
|
||||||
name: '1.0', // 文档版本名称
|
|
||||||
url: `/api-json`, // Swagger openapi JSON地址
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
await app.listen(48085);
|
await app.listen(48085);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterSwaggerDocument(
|
||||||
|
document: OpenAPIObject,
|
||||||
|
matcher: SwaggerPathMatcher,
|
||||||
|
): OpenAPIObject {
|
||||||
|
const paths = Object.fromEntries(
|
||||||
|
Object.entries(document.paths).filter(([path]) => matcher(path)),
|
||||||
|
) as OpenAPIObject['paths'];
|
||||||
|
const usedTags = new Set<string>();
|
||||||
|
|
||||||
|
Object.values(paths).forEach((pathItem) => {
|
||||||
|
Object.values(pathItem || {}).forEach((operation) => {
|
||||||
|
const tags = (operation as any)?.tags;
|
||||||
|
if (Array.isArray(tags)) {
|
||||||
|
tags.forEach((tag) => usedTags.add(tag));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...document,
|
||||||
|
paths,
|
||||||
|
tags: document.tags?.filter((tag) => usedTags.has(tag.name)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchPathPrefixes(path: string, prefixes: string[]) {
|
||||||
|
return prefixes.some(
|
||||||
|
(prefix) => path === prefix || path.startsWith(`${prefix}/`),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
|||||||
@ -50,7 +50,7 @@ const PROXY_RESOURCE_EXTENSION_RE =
|
|||||||
/\.(avif|bmp|css|eot|gif|ico|jpe?g|otf|png|svg|ttf|webp|woff2?)(?:[?#].*)?$/i;
|
/\.(avif|bmp|css|eot|gif|ico|jpe?g|otf|png|svg|ttf|webp|woff2?)(?:[?#].*)?$/i;
|
||||||
|
|
||||||
@Controller('minio')
|
@Controller('minio')
|
||||||
@ApiTags('minio')
|
@ApiTags('基础能力 - MinIO')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class MinioClientController {
|
export class MinioClientController {
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import { QqbotAccountService } from './qqbot-account.service';
|
|||||||
import { QqbotNapcatLoginService } from './qqbot-napcat-login.service';
|
import { QqbotNapcatLoginService } from './qqbot-napcat-login.service';
|
||||||
import { QqbotReverseWsService } from '../connection/qqbot-reverse-ws.service';
|
import { QqbotReverseWsService } from '../connection/qqbot-reverse-ws.service';
|
||||||
|
|
||||||
@ApiTags('qqbot-account')
|
@ApiTags('QQBot - 账号连接')
|
||||||
@Controller('qqbot/account')
|
@Controller('qqbot/account')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotAccountController {
|
export class QqbotAccountController {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import { QqbotCommandEngineService } from './qqbot-command-engine.service';
|
|||||||
import { QqbotCommandService } from './qqbot-command.service';
|
import { QqbotCommandService } from './qqbot-command.service';
|
||||||
import { normalizeBoolean } from '../qqbot.utils';
|
import { normalizeBoolean } from '../qqbot.utils';
|
||||||
|
|
||||||
@ApiTags('qqbot-command')
|
@ApiTags('QQBot - 在线命令')
|
||||||
@Controller('qqbot/command')
|
@Controller('qqbot/command')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotCommandController {
|
export class QqbotCommandController {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { JwtAuthGuard } from '@/admin/auth/jwt-auth.guard';
|
|||||||
import { vbenSuccess } from '@/common';
|
import { vbenSuccess } from '@/common';
|
||||||
import { QqbotDashboardService } from './qqbot-dashboard.service';
|
import { QqbotDashboardService } from './qqbot-dashboard.service';
|
||||||
|
|
||||||
@ApiTags('qqbot-dashboard')
|
@ApiTags('QQBot - 工作台')
|
||||||
@Controller('qqbot/dashboard')
|
@Controller('qqbot/dashboard')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotDashboardController {
|
export class QqbotDashboardController {
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import {
|
|||||||
} from './qqbot-message.dto';
|
} from './qqbot-message.dto';
|
||||||
import { QqbotMessageService } from './qqbot-message.service';
|
import { QqbotMessageService } from './qqbot-message.service';
|
||||||
|
|
||||||
@ApiTags('qqbot-message')
|
@ApiTags('QQBot - 会话与消息')
|
||||||
@Controller('qqbot')
|
@Controller('qqbot')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotMessageController {
|
export class QqbotMessageController {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
} from './qqbot-permission.dto';
|
} from './qqbot-permission.dto';
|
||||||
import { QqbotPermissionService } from './qqbot-permission.service';
|
import { QqbotPermissionService } from './qqbot-permission.service';
|
||||||
|
|
||||||
@ApiTags('qqbot-permission')
|
@ApiTags('QQBot - 权限名单')
|
||||||
@Controller('qqbot/permission')
|
@Controller('qqbot/permission')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotPermissionController {
|
export class QqbotPermissionController {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import { QqbotEventPluginRegistryService } from './qqbot-event-plugin-registry.s
|
|||||||
import { QqbotPluginRegistryService } from './qqbot-plugin-registry.service';
|
import { QqbotPluginRegistryService } from './qqbot-plugin-registry.service';
|
||||||
import type { QqbotPluginTriggerMode } from './qqbot-plugin.types';
|
import type { QqbotPluginTriggerMode } from './qqbot-plugin.types';
|
||||||
|
|
||||||
@ApiTags('qqbot-plugin')
|
@ApiTags('QQBot - 插件能力')
|
||||||
@Controller('qqbot/plugin')
|
@Controller('qqbot/plugin')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotPluginController {
|
export class QqbotPluginController {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
import { QqbotRuleService } from './qqbot-rule.service';
|
import { QqbotRuleService } from './qqbot-rule.service';
|
||||||
import { normalizeBoolean } from '../qqbot.utils';
|
import { normalizeBoolean } from '../qqbot.utils';
|
||||||
|
|
||||||
@ApiTags('qqbot-rule')
|
@ApiTags('QQBot - 自动回复规则')
|
||||||
@Controller('qqbot/rule')
|
@Controller('qqbot/rule')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotRuleController {
|
export class QqbotRuleController {
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import {
|
|||||||
} from './qqbot-send.dto';
|
} from './qqbot-send.dto';
|
||||||
import { QqbotSendService } from './qqbot-send.service';
|
import { QqbotSendService } from './qqbot-send.service';
|
||||||
|
|
||||||
@ApiTags('qqbot-send')
|
@ApiTags('QQBot - 发送日志')
|
||||||
@Controller('qqbot/send')
|
@Controller('qqbot/send')
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
export class QqbotSendController {
|
export class QqbotSendController {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import {
|
|||||||
} from './wordpress.dto';
|
} from './wordpress.dto';
|
||||||
import { WordpressService } from './wordpress.service';
|
import { WordpressService } from './wordpress.service';
|
||||||
|
|
||||||
@ApiTags('wordpress-article')
|
@ApiTags('WordPress - 文章')
|
||||||
@ApiHeader({
|
@ApiHeader({
|
||||||
name: 'X-WordPress-Authorization',
|
name: 'X-WordPress-Authorization',
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import { JwtAuthGuard } from '@/admin/auth/jwt-auth.guard';
|
|||||||
import { Public, vbenSuccess } from '@/common';
|
import { Public, vbenSuccess } from '@/common';
|
||||||
import { WordpressService } from './wordpress.service';
|
import { WordpressService } from './wordpress.service';
|
||||||
|
|
||||||
@ApiTags('wordpress-auth')
|
@ApiTags('WordPress - 认证')
|
||||||
@ApiHeader({
|
@ApiHeader({
|
||||||
name: 'X-WordPress-Authorization',
|
name: 'X-WordPress-Authorization',
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import {
|
|||||||
} from './wordpress.dto';
|
} from './wordpress.dto';
|
||||||
import { WordpressService } from './wordpress.service';
|
import { WordpressService } from './wordpress.service';
|
||||||
|
|
||||||
@ApiTags('wordpress-category')
|
@ApiTags('WordPress - 分类')
|
||||||
@ApiHeader({
|
@ApiHeader({
|
||||||
name: 'X-WordPress-Authorization',
|
name: 'X-WordPress-Authorization',
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import {
|
|||||||
} from './wordpress.dto';
|
} from './wordpress.dto';
|
||||||
import { WordpressService } from './wordpress.service';
|
import { WordpressService } from './wordpress.service';
|
||||||
|
|
||||||
@ApiTags('wordpress-tag')
|
@ApiTags('WordPress - 标签')
|
||||||
@ApiHeader({
|
@ApiHeader({
|
||||||
name: 'X-WordPress-Authorization',
|
name: 'X-WordPress-Authorization',
|
||||||
required: false,
|
required: false,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user