chore: src/modules/swagger/builder.ts

This commit is contained in:
2026-07-01 17:57:18 +08:00
parent 6a24f42f79
commit c96ac73dcf
+316
View File
@@ -0,0 +1,316 @@
import { CoolEps } from '@cool-midway/core';
import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
import * as _ from 'lodash';
/**
* 构建文档
*/
@Provide()
@Scope(ScopeEnum.Singleton)
export class SwaggerBuilder {
@Config('module.swagger.base')
swaggerBase;
@Inject()
eps: CoolEps;
json = {};
@Config('cool.eps')
epsConfig: boolean;
/**
* 初始化
*/
async init() {
if (this.epsConfig) {
this.build();
}
}
/**
* 构建文档
*/
async build() {
const epsData = {
app: this.eps.app || [],
admin: this.eps.admin || [],
module: this.eps.module || {},
};
this.json = this.convertToSwagger(epsData);
}
/**
* Epss转换为Swagger
* @param dataJson
* @returns
*/
convertToSwagger(dataJson) {
const swagger = {
...this.swaggerBase,
paths: {},
tags: Object.keys(dataJson.module)
.filter(item => item != 'swagger')
.map(moduleKey => {
return {
key: moduleKey,
name: dataJson.module[moduleKey].name || '',
description: dataJson.module[moduleKey].description || '',
};
}),
};
// 添加组件
function addComponentSchemas(data) {
if (_.isEmpty(data.name)) return;
const schema = {
type: 'object',
properties: {},
required: [],
};
data.columns.forEach(column => {
const swaggerType = mapTypeToSwagger(column.type);
schema.properties[column.propertyName] = {
type: swaggerType,
description: column.comment,
};
if (!column.nullable) {
schema.required.push(column.propertyName);
}
});
swagger.components.schemas[data.name] = schema;
return data.name;
}
// 转换类型
function mapTypeToSwagger(type) {
const typeMapping = {
string: 'string',
number: 'number',
bigint: 'integer',
datetime: 'string', // assuming datetime is formatted as ISO8601 string
};
return typeMapping[type] || 'string';
}
// 添加请求体
function addRequest(path, schemas, data) {
if (path == '/info' || path == '/list' || path == '/page') {
if (path == '/info') {
data.parameters = [
{
name: 'id',
in: 'query',
description: 'ID',
required: true,
schema: {
type: 'integer',
},
},
];
} else {
data.requestBody = {
description: '动态请求体',
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties:
path == '/page'
? {
page: {
type: 'integer',
description: '第几页',
default: 1,
},
size: {
type: 'integer',
description: '每页大小',
default: 20,
},
}
: {},
},
},
},
};
}
data.responses = {
'200': {
description: '成功响应',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
code: {
type: 'integer',
description: '状态码',
},
message: {
type: 'string',
description: '响应消息',
},
data: {
$ref: `#/components/schemas/${schemas}`,
},
},
},
},
},
},
};
}
if (path == '/add' || path == '/update') {
data.requestBody = {
description: schemas,
required: true,
content: {
'application/json': {
schema: {
$ref: `#/components/schemas/${schemas}`,
},
},
},
};
data.responses = {
'200': {
description: '成功响应',
content: {
'application/json': {
example: {
code: 1000,
message: 'success',
data: {
id: 6,
},
},
},
},
},
};
}
if (path == '/delete') {
data.requestBody = {
description: schemas,
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
ids: {
type: 'array',
description: 'ID数组',
items: {
type: 'integer',
},
},
},
},
},
},
};
data.responses = {
'200': {
description: '成功响应',
content: {
'application/json': {
example: {
code: 1000,
message: 'success',
},
},
},
},
};
}
}
// 处理每个模块下的API接口
function processModuleApis(moduleApis, moduleName) {
moduleApis.forEach(module => {
const schemas = addComponentSchemas({
name: module.name,
columns: module.columns,
});
if (Array.isArray(module.api)) {
module.api.forEach(api => {
const fullPath = `${api.prefix == '/' ? '' : api.prefix}${
api.path
}`;
const method = api.method.toLowerCase();
if (!swagger.paths[fullPath]) {
swagger.paths[fullPath] = {};
}
swagger.paths[fullPath][method] = {
summary:
`${module.info.type.description || module.info.type.name}` +
api.summary || '',
security: api.ignoreToken
? []
: [
{
ApiKeyAuth: [],
},
],
tags: [moduleName || '其他'],
requestBody:
method == 'post'
? {
description: '请求体',
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {},
},
},
},
}
: {},
responses: schemas
? {
'200': {
description: 'Success response',
content: {
'application/json': {
schema: {
$ref: `#/components/schemas/${schemas}`,
},
},
},
},
}
: {},
};
addRequest(api.path, schemas, swagger.paths[fullPath][method]);
});
}
});
}
// 遍历app和admin中的所有模块
Object.keys(dataJson.app).forEach(moduleKey => {
if (Array.isArray(dataJson.app[moduleKey])) {
processModuleApis(
dataJson.app[moduleKey],
dataJson.module[moduleKey]?.name
);
}
});
Object.keys(dataJson.admin).forEach(moduleKey => {
if (Array.isArray(dataJson.admin[moduleKey])) {
processModuleApis(
dataJson.admin[moduleKey],
dataJson.module[moduleKey]?.name
);
}
});
return swagger;
}
}