chore: src/modules/swagger/builder.ts
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user