const axios = require('axios').default const fs = require('fs') const Path = require('path') function mkdirsSync(dirname) { if (fs.existsSync(dirname)) { return true } else { if (mkdirsSync(Path.dirname(dirname))) { fs.mkdirSync(dirname) return true } } } const fileTemplate = `/** * 该文件由插件根据doc.html在启动项目时自动生成,请勿修改(修改了也会被覆盖 */ import request from '@/utils/request' ` const functionCodeGener = function(meta) { const functionParams = [] if (Array.isArray(meta.params) && meta.params.length > 0) { functionParams.push('params') } if (Array.isArray(meta.data) && meta.data.length > 0) { functionParams.push('data') } if (Array.isArray(meta.formData) && meta.formData.length > 0) { functionParams.push('formData') } return ` /** * ${meta.comment} */ export function ${meta.name}(${functionParams.join(', ')}) { return request({ method: '${meta.method}', url: '${meta.url}'${meta.requestType ? ',\n requestType: \'' + meta.requestType + '\'' : ''}${functionParams.includes('params') ? ',\n params' : ''}${functionParams.includes('data') || functionParams.includes('formData') ? ',\n data' + (functionParams.includes('formData') ? ': formData' : '') : ''} }) } ` } module.exports = class Genapi { constructor(apiUrl, output = 'build') { this.apiUrl = apiUrl[apiUrl.length - 1] === '/' ? apiUrl.slice(0, apiUrl.length - 1) : apiUrl this.output = output } apply(compiler) { compiler.hooks.environment.tap('Genapi', async(compilation, callback) => { const projectPath = Path.join(__dirname, '../') const apiPath = Path.join(projectPath, 'src/api/', this.output) axios({ url: this.apiUrl + '/swagger-resources', method: 'get' }).then(({ data }) => { const resultFile = {} Promise.all(data.map((apiScope) => { return axios({ url: this.apiUrl + '/v2/api-docs', params: { group: apiScope.name }, method: 'get' }).then(({ data }) => { const { basePath, paths } = data for (const _path in paths) { const path = _path.replace(new RegExp('^' + basePath, 'g'), '') const pathSplit = path.split('/').slice('/') const apiName = pathSplit[pathSplit.length - 1] const fileName = pathSplit.length > 2 ? pathSplit[pathSplit.length - 2] : '' const mkdirPath = pathSplit.slice(0, pathSplit.length - 2).join('/') || '/' const fileApiSet = new Set() const filePath = Path.join(mkdirPath, fileName) if (!resultFile[filePath]) { resultFile[filePath] = fileTemplate } for (const method in paths[_path]) { const apiMeta = paths[_path][method] const parameters = apiMeta.parameters || [] const formData = parameters.filter((item) => { return item.in === 'formData' }) const data = parameters.filter((item) => { return item.in === 'body' }) const params = parameters.filter((item) => { return item.in === 'query' }) resultFile[filePath] += functionCodeGener({ name: (() => { const filterApiName = apiName.replace(/\.do$/g, '') let result = Object.keys(paths[_path]).length > 1 ? `${method}_${filterApiName}` : filterApiName if (fileApiSet.has(result)) { let i = 1 while (fileApiSet.has(`${result}_${i}`)) { i++ } result = `${result}_${i}` } return result })(), method, url: path, comment: apiMeta.summary, data, params, formData, requestType: (() => { if (method !== 'get') { if (formData.length > 0) { return 'formdata' } else { return 'json' } } })() }) } } }).catch((e) => { console.warn(`无法读取api文档: ${apiScope.name}`) console.warn(e.message) }) })).then(() => { for (const path in resultFile) { mkdirsSync(Path.join(apiPath, path)) const filepath = Path.join(apiPath, path, 'index.js') if (fs.existsSync(filepath) && fs.readFileSync(filepath).toString() !== resultFile[path]) { fs.writeFileSync(filepath, resultFile[path]) } } }) }).catch((e) => { }) }) } }