前端根据swagger,生成 .ts 映射接口文件
新建 generator.js 文件,写入以下代码
const fs = require('fs')
const path = require('path')
const parse = require('swagger-parser')
const beautify = require('js-beautify').js_beautify
const swaggerUrl = 'http://localhost:7170/swagger/v1/swagger.json'
// api接口方法存放目录
const API_PATH = path.resolve(__dirname, './src/api')
// 判断目录是否存在
const isExist = (lastPath = '') => {
const privatePath = `${lastPath ? API_PATH + '/' + lastPath : API_PATH}`
const stat = fs.existsSync(privatePath)
if (!stat) {
fs.mkdirSync(privatePath)
}
}
// 模块名称整理
const moduleName = (operationId) => {
return operationId.replace(/Using|_/g, '')
}
// 数据类型
const dataType = (key) => {
const type = {
string: 'string',
integer: 'number',
int: 'number',
long: 'string',
Array: 'array',
file: 'Blob',
boolean: 'boolean',
}
return type[key] ? type[key] : 'any'
}
// 整理出相同模块路径
const getModules = (map) => {
let moduleList = []
map.forEach((value, key) => {
const module = writeFileApi(key, value)
moduleList = [...moduleList, ...module]
})
return moduleList
}
// 参数模板参数数组
const interfaceParamsList = (params) => {
let str = ''
params.forEach((item) => {
str = `${str}
/** ${item.description ? item.description : ''} **/
${item.name}${item.required ? '?' : ''}: ${dataType(item.type)};
`
})
return str
}
// 参数模板
const interfaceParamsTpl = (params, interfaceName) => {
if (!params || params.length === 0) {
return ''
} else {
return `export interface ${interfaceName} {
${interfaceParamsList(params)}
}`
}
}
// 写入模板
const tplInsertApi = (apiInfo) => {
const keys = Object.keys(apiInfo)
const method = keys[0]
const methodParams = apiInfo[method]
const parameters = methodParams.parameters
const operationId = methodParams.operationId
const allPath = apiInfo.allPath
const requestName = moduleName(operationId)
let interfaceName = 'any'
let interfaceParams = 'data?:any'
let parametersType = 'data'
if (parameters && parameters.length > 0) {
interfaceName = `${requestName}Ife`
interfaceParams = `data: ${interfaceName}`
}
if (method.toLocaleLowerCase() === 'get') {
parametersType = 'params'
interfaceParams = `params: ${interfaceName}`
}
return `/**
* @description ${methodParams.summary}
*/
${interfaceParamsTpl(parameters, interfaceName)}
export async function ${requestName}(${interfaceParams}) {
return Request('${allPath}', {
${parametersType},
method: '${method}'
});
}
`
}
// 模板名
const getModulesName = (apiInfo) => {
const keys = Object.keys(apiInfo)
const method = keys[0]
const methodParams = apiInfo[method]
const operationId = methodParams.operationId
return operationId
}
// 写入tsx
const writeFileApi = (fileName, apiData) => {
let indexStr = ''
// index.tsx
let tplIndex = `import Request from '@/http/request';`
const apiDataLen = apiData.length
let moduleList = []
for (let i = 0; i < apiDataLen; i++) {
const item = apiData[i]
tplIndex = `${tplIndex}\n${tplInsertApi(item)}\n`
moduleList.push(getModulesName(item))
}
tplIndex = beautify(tplIndex, { indent_size: 2, max_preserve_newlines: 2 })
fs.writeFileSync(`${API_PATH}/${fileName}/index.ts`, tplIndex)
return moduleList
}
//导出总文件
const downIndexts = (fileName,indexStr) => {
let str = ''
console.log('正在导出文件/src/api/index.ts')
indexStr.forEach((item) => {
str += `import * as ${item} from '@/api/${item}/index'`
})
str += 'export {'
indexStr.forEach((item) => {
str += `${item},`
})
str += '}'
str = beautify(str, { indent_size: 2, max_preserve_newlines: 2 })
fs.writeFileSync(`${API_PATH}/index.ts`, str)
console.log('导出成功')
}
const gen = async () => {
isExist()
try {
// 解析url 获得
const parsed = await parse.parse(swaggerUrl)
const paths = parsed.paths
const pathsKeys = Object.keys(paths) // 获取url路径
const pathsKeysLen = pathsKeys.length
const modulesMap = new Map()
//总的文件
let indexStr = []
for (let i = 0; i < pathsKeysLen; i++) {
const item = pathsKeys[i]
const itemAry = item.split('/')
const pathsItem = paths[item]
let fileName = itemAry[2]
console.log('正在生成', fileName)
//最后导出总文件
if (indexStr.findIndex((r) => r === fileName.toLowerCase()) == -1) {
indexStr.push(fileName.toLowerCase())
}
if (!fileName) continue
fileName = fileName.toLowerCase()
// 创建模块目录
isExist(fileName)
// 完整路径
pathsItem.allPath = item
if (modulesMap.has(fileName)) {
const fileNameAry = modulesMap.get(fileName)
fileNameAry.push(pathsItem)
modulesMap.set(fileName, fileNameAry)
} else {
modulesMap.set(fileName, [pathsItem])
}
}
downIndexts('index.ts',indexStr)
getModules(modulesMap)
console.log('生成完毕')
} catch (e) {
console.log('生成失败', e)
}
}
gen()
我的api文件结构是 "/api/模块/接口名"
1 | http: //localhost:7170/swagger/v1/swagger.json 换成实际swagger文件地址<br>执行命令: node generator.js |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步