分析api-docs
目前公司不同BU的swagger文档格式大致如下
详细规范可参考:
mock/next.js
module.exports = {
"swagger": "2.0",
"info": {
"description": "xxxx swagger Application.",
"version": "1.0.0",
"title": "xxxx swagger Application",
"termsOfService": "TERMS OF SERVICE URL",
"contact": {
"name": "xxxx",
"url": "http://xxxx.com/",
"email": "xxxx.com"
},
"license": {
"name": "MIT License",
"url": "LICENSE URL"
}
},
"host": "xxxx",
"basePath": "xxx",
"tags": [
{
"name": "product",
"description": "Product Controller"
}
],
"paths": {
"/product/createOrUpdate": {
"post": {
"tags": [
"product"
],
"summary": "创建或编辑商品",
"operationId": "createOrUpdateUsingPOST",
"consumes": [
"application/json"
],
"produces": [
"*/*"
],
"parameters": [
{
"in": "body",
"name": "vo",
"description": "vo",
"required": true,
"schema": {
"originalRef": "CreateOrUpdateProductVo",
"$ref": "#/definitions/CreateOrUpdateProductVo"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"originalRef": "SimpleResponse«boolean»",
"$ref": "#/definitions/SimpleResponse«boolean»"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"deprecated": false
}
}
},
"definitions": {
"CreateOrUpdateProductVo": {
"type": "object",
"properties": {
"displayOriginalPrice": {
"type": "string",
"description": "原价(单位:元)"
},
"firstImageUrl": {
"type": "string",
"description": "商品头图url"
},
"firstOrderPrice": {
"type": "string",
"description": "首单优惠价(单位:元),可不传"
},
"id": {
"type": "integer",
"format": "int64",
"description": "商品id,创建时传入0",
"minimum": 0.0,
"exclusiveMinimum": false
},
"imageUrls": {
"type": "array",
"description": "商品详情图片url列表,最多5张",
"items": {
"type": "string"
}
},
"limitAmount": {
"type": "integer",
"format": "int32",
"description": "限购数量",
"minimum": 1.0,
"exclusiveMinimum": false
},
"orderNumber": {
"type": "integer",
"format": "int32",
"description": "排序号",
"minimum": 1.0,
"exclusiveMinimum": false
},
"productName": {
"type": "string",
"description": "商品名称,最长20字符"
},
"productState": {
"type": "string",
"description": "商品状态,1-下架,2-上架",
"enum": [
"UN_KNOWN",
"UN_SALE",
"SALE_ING"
]
},
"unitPrice": {
"type": "string",
"description": "单位(单位:元)"
}
},
"title": "CreateOrUpdateProductVo"
},
"SimpleResponse«boolean»": {
"type": "object",
"properties": {
"data": {
"type": "boolean"
},
"errorCode": {
"type": "integer",
"format": "int32"
},
"errorMessage": {
"type": "string"
},
"status": {
"type": "boolean"
}
},
"title": "SimpleResponse«boolean»"
},
"enumDto": {
"type": "object",
"properties": {
"key": {
"type": "integer",
"format": "int32"
},
"value": {
"type": "string"
}
},
"title": "enumDto"
},
"WhitelistEnumsDto": {
"type": "object",
"properties": {
"applyStateEnums": {
"type": "array",
"items": {
"originalRef": "enumDto",
"$ref": "#/definitions/enumDto"
}
}
},
"title": "WhitelistEnumsDto"
}
}
}
几个主要的对象:
- tags
- paths
- definitions
实现步骤
- 实现可配置apiconfigJSON,生成存放api的文件夹
- 提取接口相关json
- 提取接口相关type以及enum
- 输出type 以及 enum 文件,输出接口文件
实现功能
1.配置apiconfig 创建api文件夹
在项目中创建config/apis/api-config.js文件
const next = require('./next')
module.exports = {
serviceTemplate: `import http from "./../../http"
import { AxiosPromise, AxiosRequestConfig } from 'axios';
`,//新增serviceTemplate,用于后续生成的api文件内部引入
outputDir: '/src/common/api',
apiList: [
{
//swaggerUrl: next, //演示地址
swaggerUrl: 'http://xxxx/api-docs', //实际地址
outputDir: '/src/common/api/next',
isCreate: true,
},
],
}
- outputDir:生成的输入文件夹路径
- apiList(可配置多个):
-
- swaggerUrl:api doc地址(需免登),本项目演示用本地json代替
- outputDir :该api 对应输出文件夹路径
- isCreate: 用于开启或关闭检索生成
在项目config/apis文件夹中创建auto-port.js
const apiConfig = require('./api-config')
const fs = require('fs')
const path = require('path')
/**
* 创建文件
* @param {*} dirname
* @returns
*/
const mkdir = (dirname) => {
if (fs.existsSync(dirname)) {
return true
}
else {
// 去掉文件名,返回目录 path.dirname ,当存在目录开始进行mkdirSync
if (mkdir(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
}
/**
* mkdirSync 创建目录要一层一层创建
*/
const checkOutputDirExit = () => {
mkdir(path.resolve(process.cwd() + apiConfig.outputDir))
}
/**
* 自动生成api
*/
const createApi = () => {
checkOutputDirExit()
}
createApi()
配置package.json
"scripts": {
"prettier": "prettier --write "src/**/**/*.{js,jsx,vue,tsx,json,css,scss,less,md}"",
"api": "node ./config/apis/auto-port.js && npm run prettier "
},
运行命令 yarn api ,此时生成src/common/api的目录,后续用于存放自动生成的api文件
2.解析接口JSON(将paths转为JSON)
原始json
分析下swagger paths的结构
"paths": {
"/aggregatedCreditPayment/switchAvailableState": {
"post": {
"tags": [
"riskMerchant"
],
"summary": "xxxxxxxxxx",
"operationId": "switchAvailableStateUsingPOST",
"consumes": [
"application/json"
],
"produces": [
"*/*"
],
"parameters": [
{
"in": "body",
"name": "vo",
"description": "vo",
"required": true,
"schema": {
"originalRef": "MerchantCreditPayLimitVo",
"$ref": "#/definitions/MerchantCreditPayLimitVo"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"originalRef": "SimpleResponse«boolean»",
"$ref": "#/definitions/SimpleResponse«boolean»"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"deprecated": false
}
}
},
- tags 该接口对应模块
- post/get 该接口对应请求方式
- summary 注释
- parameters - in params类型
-
- formData
- query
- body
- responses 返回结果
- schema 源数据对象
-
- originalRef 原始数据类型
- $ref 数据类型
- type 类型
希望的得到的结构
{
"product": [
{
"name": "createOrUpdate",
"method": "post",
"url": "/product/createOrUpdate",
"summary": "创建或编辑商品",
"params": [
{
"name": "vo",
"desc": "vo",
"type": "CreateOrUpdateProductVo",
"originType": {
"originalRef": "CreateOrUpdateProductVo",
"$ref": "#/definitions/CreateOrUpdateProductVo"
},
"required": true,
"simpleType": false
}
],
"returnData": {
"type": "SimpleResponse«boolean»",
"originType": {
"originalRef": "SimpleResponse«boolean»",
"$ref": "#/definitions/SimpleResponse«boolean»"
},
"simpleType": false
}
}
]
}
2.1 处理paths对象,生成基本机构JSON
在自动生成api方法中提取swaggerJSON
/**
* 自动生成api
*/
const createApi = () => {
checkOutputDirExit()
apiConfig.apiList.forEach(async api => {
if (api.isCreate) {
//真实请求swaggerUrl地址
const result = await axios.get(api.swaggerUrl)
const data = result.data
// const data = api.swaggerUrl // 当前项目本地文件演示
parseData(data, api.outputDir)
}
})
}
/**
* 解析swagger
* @param {*} swaggerJson
* @param {*} dirname
*/
const parseData = (swaggerJson, dirname) => {
const paths = handlePath(swaggerJson.paths)
console.log('paths', JSON.stringify(paths))
}
- 实现json基本机构
/**
* 处理paths对象
* @param {*} path
*/
const handlePath = (path) => {
let apiOptions = {};
const apiPaths = Object.keys(path)
apiPaths && apiPaths.forEach(apiItem => {
const apiInfo = {
name: apiItem.split('/').pop(),
method: path[apiItem].get ? 'get' : 'post',
url: apiItem,
summary: '',
params: '',
returnData: {
type: '',
originType: '',
simpleType: true,
},
}
const apiInfoBody = path[apiItem][apiInfo.method]
apiInfo.summary = apiInfoBody.summary
//分模块
const belongModule = getBelong(apiInfoBody.tags)
if (!apiOptions[belongModule]) {
apiOptions[belongModule] = []
}
apiOptions[belongModule].push(apiInfo)
})
return apiOptions
}
/** 获取所属模块名 */
const getBelong = (str) => {
if (str.length === 0) {
throw new Error('无所属模块')
} else {
return str[0]
}
}
此时得到的json数据结果如下
{
"riskMerchant": [
{
"name": "switchAvailableState",
"method": "post",
"url": "/aggregatedCreditPayment/switchAvailableState",
"summary": "xxxxxx",
"params": "",
"returnData": {
"type": "",
"originType": "",
"simpleType": true
}
}
]
}
但是此时该方法的params以及returnData中的数据未做处理
- 通过解析parameters字段,实现getParams方法
//handlePath中添加
apiInfo.params = apiInfoBody.parameters ? getParams(apiInfoBody.parameters) : []
/**
* 获取api params
* @param {*} params
*/
const getParams = (params) => {
const arr = []
params.forEach(paramsItem => {
if (['formData', 'query', 'body'].includes(paramsItem.in)) {
const _item = {
name: paramsItem.name,
desc: paramsItem.description || '描述缺失',
type: null, //类型
originType:null, //源类型
required: paramsItem.schema ? true : paramsItem.required, //是否必须
simpleType: paramsItem.schema ? false : true, //是否基础类型
}
//处理paths中
if (paramsItem.schema) {
const _schema = paramsItem.schema
_schema.$ref = _schema.$ref && splitRealType(_schema.$ref)
_schema.originType = _schema.originType && splitRealType(_schema.originType)
_item.originType = _schema || paramsItem.type
}
_item.type = paramsItem.schema
? getRealType(paramsItem.schema)
: paramsItem.format == 'int64'
? 'string'
: toTypescriptType(paramsItem.type)
arr.push(_item)
}
})
return arr
}
- 解析responses字段,实现returnData
//handlePath中添加
apiInfo.returnData = getResponses(apiInfoBody.responses)
const getResponses = (responses) => {
const res = responses['200']
if (res.schema) {
const _item = {
type: null,
originType: res.schema,
simpleType: false,
}
_item.type = getRealType(res.schema)
return _item
} else {
return {
type: res.type,
originType: res.type,
simpleType: false,
}
}
}
/**
*
* @param {*} schema
*/
const getRealType = (schema) => {
if (schema) {
return splitRealType(schema.originalRef || schema.$ref?.split('#/definitions/')[1])
} else {
return 'any'
}
}
/**
* const _name = name.split("«")[0]// 处理类 SimpleResponse«List«ChannelFeeConfigDto»» => ChannelFeeConfigDto【tip:2022118调整】
* @param {*} name
* @returns
*/
const splitRealType = (name) => {
if (!name) {
return ''
}
return name?.split('«').join('»').split('»').filter(item => item).at(-1)
}
// /**
// * const _name = name.split("«")[0]//
// 处理类 SimpleResponse«List«ChannelFeeConfigDto»» => SimpleResponseListChannelFeeConfigDto
// * @param {*} name
// * @returns
// */
// const splitRealType = (name) => {
// if (!name) {
// return ''
// }
// return name?.split('«').join('').split('»').reduce((a, b) => { return `${a}${b}` })
// }
此刻运行 yarn api方法,就能得到目标json对象
2.2 处理 definitions,提取typeMap
/**
* 处理definitions
* @param {*} definitions
*/
const handleDefinitions = (definitions) => {
let typeMap = {};
const _enumMap = []
const apiDefinitions = Object.keys(definitions)
apiDefinitions.map(definitionsKey => {
const definitionsItem = definitions[definitionsKey]
const { title, type, description, properties } = definitionsItem
typeMap[title] = {
name: title,
type: type,
description: description || '缺少注释',
property: properties
}
})
return typeMap
}
得到下面结果的typaMap json
{
"CreateOrUpdateProductVo": {
"name": "CreateOrUpdateProductVo",
"type": "object",
"description": "缺少注释",
"property": {
"displayOriginalPrice": {
"type": "string",
"description": "原价(单位:元)"
},
"firstImageUrl": {
"type": "string",
"description": "商品头图url"
},
"firstOrderPrice": {
"type": "string",
"description": "首单优惠价(单位:元),可不传"
},
"id": {
"type": "integer",
"format": "int64",
"description": "商品id,创建时传入0",
"minimum": 0,
"exclusiveMinimum": false
},
"imageUrls": {
"type": "array",
"description": "商品详情图片url列表,最多5张",
"items": {
"type": "string"
}
},
"limitAmount": {
"type": "integer",
"format": "int32",
"description": "限购数量",
"minimum": 1,
"exclusiveMinimum": false
},
"orderNumber": {
"type": "integer",
"format": "int32",
"description": "排序号",
"minimum": 1,
"exclusiveMinimum": false
},
"productName": {
"type": "string",
"description": "商品名称,最长20字符"
},
"productState": {
"type": "string",
"description": "商品状态,1-下架,2-上架",
"enum": [
"UN_KNOWN",
"UN_SALE",
"SALE_ING"
]
},
"unitPrice": {
"type": "string",
"description": "单位(单位:元)"
}
}
},
"SimpleResponse«boolean»": {
"name": "SimpleResponse«boolean»",
"type": "object",
"description": "缺少注释",
"property": {
"data": {
"type": "boolean"
},
"errorCode": {
"type": "integer",
"format": "int32"
},
"errorMessage": {
"type": "string"
},
"status": {
"type": "boolean"
}
}
},
"enumDto": {
"name": "enumDto",
"type": "object",
"description": "缺少注释",
"property": {
"key": {
"type": "integer",
"format": "int32"
},
"value": {
"type": "string"
}
}
},
"WhitelistEnumsDto": {
"name": "WhitelistEnumsDto",
"type": "object",
"description": "缺少注释",
"property": {
"applyStateEnums": {
"type": "array",
"items": {
"originalRef": "enumDto",
"$ref": "#/definitions/enumDto"
}
}
}
}
}
但是现在还是存在一些问题,提取并且处理enum,property中仍是一个对象,存在大量的参数,仍需要单独提取出来方便后续处理
处理property和enum
/**
* 处理获取typeMap中的properties 和枚举Info
* @param {*} properties
* @returns
*/
const getPropertyAndEnumInfo = (properties) => {
const propertyArr = []
let enumInfo = {}
const propertyInfo = Object.keys(properties)
propertyInfo.forEach(propertyKey => {
const _item = properties[propertyKey]
const { type, format, description, items } = _item;
const propertyItem = {
name: propertyKey,
type: format == 'int64'
? 'string'
: toTypescriptType(type),
description: description || '注释丢失',
}
propertyArr.push(propertyItem)
if (_item.enum) {
enumInfo[`${propertyKey}Enum`] = _item.enum
}
})
return { propertyArr, enumInfo }
}
修改handleDefinitions方法
/**
* 处理definitions
* @param {*} definitions
*/
const handleDefinitions = (definitions) => {
const typeMap = {}
const apiDefinitions = Object.keys(definitions)
const _enumMap = []
apiDefinitions.map(definitionsKey => {
const definitionsItem = definitions[definitionsKey]
const { title, type, description, properties } = definitionsItem
if (properties) {
const { propertyArr, enumInfo } = getPropertyAndEnumInfo(properties)
typeMap[title] = {
name: title,
type: type,
description: description || '缺少注释',
property: properties ? propertyArr : []
}
if (isEmptyObj(enumInfo)) {
// 重复枚举去重
const check = _enumMap.every(item => Object.keys(item)[0] !== Object.keys(enumInfo)[0])
if (check) {
_enumMap.push(enumInfo)
}
}
}
})
return { typeMap, _enumMap }
}
/**
* 判断是否空对象
* @param {*} obj
* @returns
*/
const isEmptyObj = (obj) => {
for (let item in obj) {
return true
}
return false
}
此时运行yarn api,得到预期的机构如下:
//typeMap
{
"CreateOrUpdateProductVo": {
"name": "CreateOrUpdateProductVo",
"type": "object",
"description": "缺少注释",
"property": [
{
"name": "displayOriginalPrice",
"type": "string",
"description": "原价(单位:元)"
},
{
"name": "firstImageUrl",
"type": "string",
"description": "商品头图url"
},
{
"name": "firstOrderPrice",
"type": "string",
"description": "首单优惠价(单位:元),可不传"
},
{
"name": "id",
"type": "string",
"description": "商品id,创建时传入0"
},
{
"name": "imageUrls",
"description": "商品详情图片url列表,最多5张"
},
{
"name": "limitAmount",
"type": "number",
"description": "限购数量"
},
{
"name": "orderNumber",
"type": "number",
"description": "排序号"
},
{
"name": "productName",
"type": "string",
"description": "商品名称,最长20字符"
},
{
"name": "productState",
"type": "string",
"description": "商品状态,1-下架,2-上架"
},
{
"name": "unitPrice",
"type": "string",
"description": "单位(单位:元)"
}
]
},
"SimpleResponse«boolean»": {
"name": "SimpleResponse«boolean»",
"type": "object",
"description": "缺少注释",
"property": [
{
"name": "data",
"type": "boolean",
"description": "注释丢失"
},
{
"name": "errorCode",
"type": "number",
"description": "注释丢失"
},
{
"name": "errorMessage",
"type": "string",
"description": "注释丢失"
},
{
"name": "status",
"type": "boolean",
"description": "注释丢失"
}
]
},
"enumDto": {
"name": "enumDto",
"type": "object",
"description": "缺少注释",
"property": [
{
"name": "key",
"type": "number",
"description": "注释丢失"
},
{
"name": "value",
"type": "string",
"description": "注释丢失"
}
]
},
"WhitelistEnumsDto": {
"name": "WhitelistEnumsDto",
"type": "object",
"description": "缺少注释",
"property": [
{
"name": "applyStateEnums",
"type": "enumDto",
"description": "注释丢失"
}
]
}
}
//enumMap
[
{
"productStateENUM": [
"UN_KNOWN",
"UN_SALE",
"SALE_ING"
]
}
]
2.3 处理提取的typeMap以及enumMap
2.3.1处理输出enumMap.ts
/**
* 生成EnumCode
* @param {*} enumMap
*/
const generateEnumCode = (enumMap) => {
const enumCodeArr = []
enumMap.forEach(enumItem => {
const key = Object.keys(enumItem)[0]
enumCodeArr.push(` export enum ${key} {
${enumItem[key].join(',\n')}
}`)
})
return enumCodeArr.join('\n')
}
/**
* 写入文件
* @param {*} name
* @param {*} data
* @param {*} dirname
*/
const writeFile = (name, data, dirname) => {
const _path = process.cwd() + dirname
mkdir(_path)
const filePath = path.resolve(_path, `${name}.ts`)
fs.writeFileSync(filePath, data)
}
const enumCode = generateEnumCode(enumMap)
if (enumCode) {
writeFile('enum', enumCode, dirname)
}
此时得到文件以及对应枚举结构
export enum productStateEnum {
UN_KNOWN,
UN_SALE,
SALE_ING,
}
2.3.2处理输出typeMap.ts 并引入enum.ts
const typeCode = generateTypeCode(typeMap, enumMap)
if (typeCode) {
writeFile('type', typeCode, dirname)
}
/**
* 生成typeCode 引入enum.ts
* @param {*} typeCode
* @param {*} enumMap
* @returns
*/
const generateTypeCode = (typeCode, enumMap) => {
const typeCodeArr = []
const typeCodeData = Object.keys(typeCode)
typeCodeData.forEach(typeCodeDataKey => {
const _item = typeCode[typeCodeDataKey]
const { property, description, name } = _item
const _name = splitRealType(name)
typeCodeArr.push(`/** ${description} **/
export interface ${_name} {
${property.map(propertyItem => {
const { name, type, description } = propertyItem
let _type = type
// 替换枚举类型
const check = enumMap.find(enumMapItem => Object.keys(enumMapItem)[0] === `${name}Enum`)
if (check) {
_type = `${name}Enum`
}
return `${name}:${_type}, //${description}`
}).join('\n')}
}`)
})
// 引入enum.ts文件
const usedEnum = []
enumMap.forEach(enumMapItem => {
const type = Object.keys(enumMapItem)[0]
if (!usedEnum.includes(type)) {
usedEnum.push(type)
}
})
if (usedEnum.length) {
typeCodeArr.unshift(`
import {${usedEnum.join(',')}} from './enum'
`)
}
return typeCodeArr.join('\n')
}
此时就能正确输出type.ts文件并按需引入enum
import { productStateEnum } from "./enum";
/** 缺少注释 **/
export interface CreateOrUpdateProductVo {
displayOriginalPrice: string; //原价(单位:元)
firstImageUrl: string; //商品头图url
firstOrderPrice: string; //首单优惠价(单位:元),可不传
id: string; //商品id,创建时传入0
imageUrls: []; //商品详情图片url列表,最多5张
limitAmount: number; //限购数量
orderNumber: number; //排序号
productName: string; //商品名称,最长20字符
productState: productStateEnum; //商品状态,1-下架,2-上架
unitPrice: string; //单位(单位:元)
}
/** 缺少注释 **/
export interface SimpleResponseboolean {
data: boolean; //注释丢失
errorCode: number; //注释丢失
errorMessage: string; //注释丢失
status: boolean; //注释丢失
}
/** 缺少注释 **/
export interface enumDto {
key: number; //注释丢失
value: string; //注释丢失
}
/** 缺少注释 **/
export interface WhitelistEnumsDto {
applyStateEnums: []; //注释丢失
}
2.4 整合type.ts以及enum.ts到接口中,生成接口文件
最后需要整合ype.ts以及enum.ts到接口文件中,需要实现一个generateApiType的方法
const codes = generateApiType(paths, typeMap, enumMap)
Object.keys(codes).forEach(key => {
writeFile(key, codes[key], dirname)
})
2.4.1实现基本的接口格式
/**
* 生成API文件
* @param {*} paths
* @param {*} typeMap
* @param {*} enumMap
*/
const generateApiType = (paths, typeMap, enumMap) => {
const apiCodes = {}
Object.keys(paths).forEach(path => {
const apiText = []
const usedType = []
const moduleApiData = paths[path]
moduleApiData.forEach(api => {
const { summary, name, method, url, returnData, params } = api
const endParam = [...api.params]
endParam.push({
name: 'options',
type: 'AxiosRequestConfig | undefined',
required: false,
desc: '',
originType: '',
simpleType: false,
})
let paramToken = ''
paramToken = `${params
.map(paramsItem => {
return paramsItem.name
})
.join(',')}`
if (method === 'get') {
if (paramToken) {
paramToken = `,{params:{${paramToken}},...options}`
} else {
paramToken = `,{...options}`
}
}
else if (method === 'post') {
if (params.length === 1) {
paramToken = params[0].simpleType ? `,{${params[0].name},options}` : `,${params[0].name},options`
} else {
paramToken = `,{${paramToken}},options`
}
}
// const _name = /^.*[A-Z]+.*/.test(name) ? name : url.split('/').reduce((pre, next) => `${pre}${titleCase(next)}`) //存在同名的,一般是单个单词的
// apiText.push(`
// /** ${summary} */
// export const ${_name} =(${endParam
// .map(a => `${a.name}${a.name == 'options' ? '?' : ''}:${a.type}`)
// .join(',')}): AxiosPromise<${returnData.type || null}> => {
// return http.${method}('${url}'${paramToken})
// }`)
// 处理/dataImport/importTransactionAddress/{sign} 20221118修改
const _name = /^.*[A-Z]+.*/.test(name) ? name : url.split('/{')[0].split('/').reduce((pre, next) => `${pre}${titleCase(next)}`) //存在同名的,一般是单个单词的
apiText.push(`
/** ${summary} */
export const ${_name} =(params:{
${endParam
.map(a => `${a.name}${(a.require === 'options' || !a.require) ? '?' : ''}:${a.type}`) //补充require判断是否必填
.join(',')}
}): AxiosPromise<${returnData.type || null}> => {
return axios.${method}('${url}',{params})
}`)
})
}
apiText.unshift(apiConfig.serviceTemplate)
apiCodes[path] = apiText.join('\n')
})
return apiCodes
}
此时生成的接口文件没有对应参数的type类型
2.4.2 引入接口的参数对应的type以及返回参数对应的type
在 generateApiType方法中添加以下逻辑
//api.params.forEach中添加
if (!param?.simpleType) {
usedType.push(param.type)
}
})
if (!returnData?.simpleType) {
usedType.push(returnData.type)
}
// moduleApiData.forEach中添加
const _usedType = []
usedType.forEach(usedTypeItem => {
if (!_usedType.includes(usedTypeItem) && !!usedTypeItem) {
_usedType.push(usedTypeItem)
}
})
if (_usedType.length) {
apiText.unshift(`
import {${_usedType.join(',')}} from './type'
`)
}
此时再次运行yarn api,得到期待的结果