前端根据接口数据自动生成api文件-v2

601 阅读25分钟

版本升级说明

之前chenms_auto_create_file这个插件v1版本的时候,有一些掘友私信说apifox这个接口工具里面如果有嵌套多次文件夹,使用chenms_auto_create_file这个插件自动生成会把所有的接口都统一生成到以根目录命名的文件夹里,例如下图这个文件夹分布

想看v1版本的可以直接点下面的链接 juejin.cn/post/729816…

image.png

使用v1版本生成的api文件是这样的

image.png

他们希望生成的api文件是这样的

image.png

接口工具有多少层文件夹,生成出来的也嵌套几层,后面我就利用了几个周末放假时间彻底重构了之前v1版本的逻辑,相比于v1版本,v2版本提供了更多的属性配置,同时也增加了React的zustand配置

获取接口数据的url

yapi

  1. 登录yapi切换到设置栏然后点击生成 ts services
  2. 拿到下面json里的remoteUrl字段

image.png 这个字段的值主要是用来生成所有的接口数据的

apifox

  1. 下载桌面端apifox

image.png

  1. 打开自己的接口目录如下图,点击加号小图标右边的三个点小图标调出项目预览

image.png

  1. 在项目预览页面点击立即生成按钮,如下图

image.png 4.如下图,画红框的地址就是生成接口数据的url image.png

自动代码生成的页面展示

该插件提供了createApiTs、createApiJs、createInterface、 createStoreTs、createStoreJs、createZustandTs、createZustandJs等方法

  • createApiJs根据数据生成对应的接口的js文件及代码

生成的文件如下 image.png

  • createApiTs根据数据生成对应的接口的ts文件及代码

生成的文件如下 image.png

  • createInterface根据数据生成对应的接口返回数据的ts类型文件及代码

生成的文件如下 image.png

  • createStoreJs根据数据生成对应的pinia的js文件及代码

生成的文件如下 image.png

  • createStoreTs根据数据生成对应的pinia的ts文件及代码

生成的文件如下 image.png

  • createZustandJs根据数据生成对应的zustand的js文件及代码 image.png

  • createZustandTs根据数据生成对应的zustand的ts文件及代码 image.png

使用

  1. 安装
npm i chenms_auto_create_file_plus
  1. 参数介绍

备注:hostname、port、path这三个参数主要由接口工具那边获取,上面有介绍怎么拿到接口的url

例如:

yapi

接口的url为:

http://39.106.196.57:3000/api/open/plugin/export-full?type=json&pid=150&status=all&token=9e5b30f82c324b31b4826cd54593a608a7301326e0e65e8948b313cc02808980

那么

apifox

接口的url为

http://127.0.0.1:4523/export/openapi?projectId=3440180&specialPurpose=openapi-generator

那么

具体参数

参数说明类型默认值例子
hostname获取接口数据的hoststring-39.106.196.57
port获取接口数据的端口号string-4523
path获取接口数据的pathstring-/export/openapi?projectId=3440180&specialPurpose=openapi-generator
interfaceType自动生成文件的工具,目前只支持apifox跟yapistring-apifox
createPath生成文件要放置的目录string-path.resolve(__dirname, '../src/api')
apiPrefix导入api目录的前缀string-@/api
interfacePrefix导入interface目录的前缀string-@/interface
topTemplate头部需要引入的string-import request from '@/service/index'
excludeList不自动生成接口的url,这个字段主要用来过滤不想生成接口的urlstring[]['/time/list']

具体回调事件

formatePathCb
  • 对path进行处理的回调(如果有其他特殊符号要记得自己处理下)
  • 这个要处理成什么样子完全由自己决定
  • 不设置的话会默认返回小驼峰, 如:参数path为 /my/list/detailed的接口 会默认返回 myListDetailed

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
  2. 如果直接返回pathTitle也会返回默认设置
// pathTitle是接口的url
// methods该接口的请求方式
// json该接口的完整信息
 formatePathCb: (pathTitle, methods, json) => {
    return pathTitle.replace(/\/|\-|\_|\{|\}/g, '')
}

如下图,上面回调设置会生成对应的函数名称,也就是函数名称是根据上面pathTitle写的正则规则去生成的名字,上面写什么样的规则就会生成什么样的名称 image.png

特别提醒

后端给我们接口中有可能会返回post跟get都是同一个请求,那个这个时候我们就可以回调里的第二个或者第三个参数做区分,如下图

image.png

formatePathCb这个回调我是这样设置,反正很灵活具体看自己要做什么样的逻辑判断都行

image.png

源码截图

image.png


formateFileNameCb
  • 对生成的文件名称进行处理
  • 不设置的话会默认返回 ${folderTitle}名称
apifox的folderTitle是

image.png

yapi的folderTitle是

image.png 如果yapi的备注为空的话会默认取分类名作为folderTitle

image.png 生成出来的文件列表如下图

image.png

image.png

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
  2. 如果直接返回folderTitle也会返回默认设置
// folderTitle 是各个文件夹的名称
formateFileNameCb: (folderTitle) => {
  return folderTitle.split('--')[1]
}

如下图是apifox文件名称包含有中文跟英文,通过上面的回调设置可以把中文跟英文以'--'分割开,然后取后面那个当作文件名,这个到时候具体看后端文件名称怎么命名的,可以通过这个回调去自定义文件名称

image.png

生成的文件名称

image.png

源码截图

image.png

image.png


formateApiBodyCb
  • 对生成的api里的body进行处理
  • 返回值必须是字符串类型
  • 生成api文件才会用到的回调
  • 不填或者返回空的话会默认填入 request.${methods.toLowerCase()}("${url}", data)
  // methods 接口请求的方式
  // url 接口的url
  // interfaceType ts的interface类型,生成ts文件时会用到这个参数
 formateApiBodyCb: function (methods, url, interfaceType) {
    return `hyRequest.${methods.toLowerCase()}<${interfaceType}>("${url}", data);`
 }

如下图,上面回调设置会生成对应的接口请求 image.png

源码截图

image.png


formateActionBodyCb
  • 对生成的action里的body进行处理(action里的各个函数完全由自己定义,非常灵活)

注意:

  1. 返回值必须是字符串类型
  2. 不填或者返回空的话会默认填入如下图

image.png

备注:

setFeildFormateFnStr(config.formateActionCb, pathTitle, 'action')formateActionCb回调返回的结果,下面代码

const res = await ${pathTitle}(data)
this.${setFeildFormateFnStr(config.formateStateCb, pathTitle, 'state')} = res
 return res

是默认的返回体

// pathTitle 接口的url(formatePathCb回调处理过的)
// actionName action里各个函数的名称(formateActionCb回调处理过的)
// stateName state里各个data的名称(formateStateCb回调处理过的)
// interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
// mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
// annotationDesName 是api interface state mutation action等类型的注释标记
// summary 该接口的名称
function formateActionBodyCb (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return ` 
      async ${actionName}(data:any){
        try {
            const res = await ${pathTitle}(data)
            this.${stateName} = res
            return res
        } catch(err) {
            console.log(err)
        }
      },
    `
  }

如下图,上面回调设置会生成对应的接口请求

image.png

如果使用了自定义注释的话,如下代码

// pathTitle 接口的url(formatePathCb回调处理过的)
// actionName action里各个函数的名称(formateActionCb回调处理过的)
// stateName state里各个data的名称(formateStateCb回调处理过的)
// interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
// mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
// annotationDesName 是api interface state mutation action等类型的注释标记
// summary 该接口的名称
function formateActionBodyCb (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return ` 
      /**
       * @${annotationDesName} ${actionName}
       * @title ${summary}666
       */
      async ${actionName}(data:any){
        try {
            const res = await ${pathTitle}(data)
            this.${stateName} = res
            return res
        } catch(err) {
            console.log(err)
        }
      },
    `
  }

则会生成如下图的样子

image.png

特别注意

上面代码中里的注释 @${annotationDesName} ${actionName}一定要写,写这个的目的是生成完之后,如果后续有新增接口的话,我是根据@${annotationDesName} ${actionName}这个标记来判断的,所以生成之后也不要乱改,更不要删除,如果自定义的注释没有加@${annotationDesName} ${actionName}的话,则会生成如下效果

// pathTitle 接口的url(formatePathCb回调处理过的)
// actionName action里各个函数的名称(formateActionCb回调处理过的)
// stateName state里各个data的名称(formateStateCb回调处理过的)
// interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
// mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
// annotationDesName 是api interface state mutation action等类型的注释标记
// summary 该接口的名称
function formateActionBodyCb (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return ` 
      /**
       * @title ${summary}66688
       */
      async ${actionName}(data:any){
        try {
            const res = await ${pathTitle}(data)
            this.${stateName} = res
            return res
        } catch(err) {
            console.log(err)
        }
      },
    `
  }

image.png

源码截图

image.png

formateMutationsBodyCb(同formateActionBodyCb这个回调的注意点一样的)
  • 对生成的action里的body进行处理(mutations里的各个函数完全由自己定义,非常灵活)

注意:

  1. 返回值必须是字符串类型
  2. 不填或者返回空的话会默认如下图

image.png

备注:

setFeildFormateFnStr(config.formateMutationsCb, pathTitle, 'mutations')formateMutationsCb回调返回的结果,(data${typeStr}) => { set({ data }) }是默认的返回体,因为目前只有zustand有mustations,所以就返回zustand相关的返回体

// pathTitle 接口的url(formatePathCb回调处理过的)
// actionName action里各个函数的名称(formateActionCb回调处理过的)
// stateName state里各个data的名称(formateStateCb回调处理过的)
// interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
// mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
// annotationDesName 是api interface state mutation action等类型的注释标记
// summary 该接口的名称
formateMutationsBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return ` 
      /**
       * @${annotationDesName} ${mutationsName}
       * @title ${summary}1122
       */
      ${mutationsName}: (data?: any, aaab?: any) => {
        set({ data })
      },
    `
  }

如下图,上面回调设置会生成对应的接口请求

image.png

源码部分同formateActionBodyCb这个回调一样


formateStateBodyCb(同formateActionBodyCb这个回调的注意点一样的)
  • 对生成的state进行处理(state里的各个属性完全由自己定义,非常灵活)

注意:

  1. 返回值必须是字符串类型
  2. 不填或者返回空的话会默认填入如下图

image.png

备注:

setFeildFormateFnStr(config.formateStateCb, pathTitle, 'state')formateStateCb回调返回的结果,{}是默认的返回体

// pathTitle 接口的url(formatePathCb回调处理过的)
// actionName action里各个函数的名称(formateActionCb回调处理过的)
// stateName state里各个data的名称(formateStateCb回调处理过的)
// interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
// mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
// annotationDesName 是api interface state mutation action等类型的注释标记
// summary 该接口的名称
formateMutationsBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return ` 
      /**
       * @${annotationDesName} ${stateName}
       * @title ${summary}6699
       */
      ${stateName}: {},
    `
  }

如下图,上面回调设置会生成对应的接口请求

image.png

源码部分同formateActionBodyCb这个回调一样


formateInterfaceCb
  • 对interface进行处理
  • 不设置的话会默认返回 I${pathTitle} 也就是处理后的pathTitle前面加I

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
  2. 如果直接返回pathTitle也会返回默认设置
// pathTitle 接口的url(formatePathCb回调处理过的)
formateInterfaceCb: (pathTitle) => {
  return `I${pathTitle}11234`
}

如下图,上面回调设置会生成对应的interface的ts接口名称 image.png

源码截图

image.png

image.png


formateActionCb
  • 对action里的数据字段进行处理
  • 不设置的话会默认返回 ${pathTitle}Api 也就是处理后的pathTitle前面加Api

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
  2. 如果直接返回pathTitle也会返回默认设置
// pathTitle 接口的url(formatePathCb回调处理过的)
 formateActionCb: (pathTitle) => {
   return `${pathTitle}Api1`
}

如下图,上面回调设置会生成对应的action函数名称

image.png

源码截图

image.png

image.png


formateStateCb
  • 对state里的数据字段进行处理
  • 不设置的话会默认返回 ${pathTitle}Data 也就是处理后的pathTitle前面加Data

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
  2. 如果直接返回pathTitle也会返回默认设置
 formateStateCb: (pathTitle) => {
    return `${pathTitle}Data1113`
 }

如下图,上面回调设置会生成对应的state属性名称

image.png

源码截图

image.png

image.png

formateMutationsCb
  • 对state里的数据字段进行处理
  • 不设置的话会默认返回 set${pathTitle}Func 也就是处理后的pathTitle前面加set后面加Func

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
  2. 如果直接返回pathTitle也会返回默认设置
formateMutationsCb: function (pathTitle) {
  return `set1${pathTitle}Func123`
}

如下图,上面回调设置会生成对应的mutations函数名称

image.png

源码截图

image.png

image.png

formateInterfaceActionCb
  • 对zustand里interface接口的action设置
  • 不设置的话会默认返回 (data?: any) => void

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
formateInterfaceActionCb: function () {
  return '(dataa?:any) => void'
}

如下图,上面回调设置会生成对应的interface的action接口名称

image.png

源码截图

image.png

image.png

formateInterfaceMutationsCb
  • 对zustand里interface接口的mutations设置
  • 不设置的话会默认返回 (data?: any) => void

注意:

  1. 这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
formateInterfaceMutationsCb: function () {
   return '(datab?:any) => void'
}

如下图,上面回调设置会生成对应的interface的mutations名称

image.png

源码截图

image.png

image.png

项目中使用

  1. 在根目录下创建一个文件夹,如expand,然后在文件夹里创建文件,如createJs.js

如果项目是用js写的,可以编写如下配置

使用vue3用此配置:

const path = require('path')
const { createApiJs, createStoreJs } = require('chenms_auto_create_file_plus')
const commonJson = {
  hostname: 你的hostname,
  port: 你的port,
  path: 你的path,

  //   hostname: 你的hostname,
  //   port: 你的port,
  //   path: 你的path,
  /**
   * 自动生成文件的工具,目前只支持apifox跟yapi
   */
  interfaceType: 'apifox',
  //   interfaceType: 'yapi',
  /**
   * 不自动生成接口的url,这个字段主要用来过滤不想生成接口的url
   */
  excludeList: ['/send/sms'],
  /**
   * 对path进行处理的回调(如果有其他特殊符号要记得自己处理下)
   * 这个要处理成什么样子完全由自己决定
   * 不设置的话会默认返回小驼峰, 如:参数path为 /my/list/detailed的接口 会默认返回 myListDetailed
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   */
  formatePathCb: function (pathTitle, methods, json) {
    return pathTitle.replace(/\/|\-|\_|\{|\}/g, '') + methods
  },
  /**
   * 对生成的文件名称进行处理
   * 不设置的话会默认返回 `${folderTitle}`名称
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回folderTitle也会返回默认设置
   */
  formateFileNameCb: function (folderTitle) {
    return folderTitle.split('--')[1]
  }
}
createApiJs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/api'),
  /**
   * 头部需要引入的插件
   */
  topTemplate: `import hyRequest from "@/service/index"`,

  /**
   * 对生成的api里的body进行处理(必填)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入 request.${methods.toLowerCase()}("${url}", data)
   * @author chenms
   * @param {String} methods 接口的请求方式
   * @param {String} url 接口的url
   */
  formateApiBodyCb: function (methods, url) {
    return `hyRequest.${methods.toLowerCase()}("${url}", data);`
  }
})

createStoreJs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/store'),
  /**
   * 导入api目录的前缀
   */
  apiPrefix: '@/api',
  /**
   * 对生成的action里的body进行处理(action里的各个函数完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   *  const res = await ${pathTitle}(data)
   *  this.${stateName} = res
   *  return res
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称
   *  @param {String} stateName state里各个data的名称
   *  @param {String} interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   *  @param {String} mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
   *  @param {String} annotationDesName 是api interface state mutation action等类型的注释标记
   *  @param {String} summary 该接口的名称
   */
  formateActionBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return `
        /**
         * @${annotationDesName} ${actionName}
         * @title ${summary}888
         */
        async ${actionName}(data){
          try {
              const res = await ${pathTitle}(data)
              this.${stateName} = res
              return res
          } catch(err) {
              console.log(err)
          }
        },
      `
  },
  /**
   * 对生成的state里的body进行处理(state里的各个属性完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   * ${stateName}: {}
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称
   *  @param {String} stateName state里各个data的名称
   *  @param {String} interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   *  @param {String} mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
   *  @param {String} annotationDesName 是api interface state mutation action等类型的注释标记
   *  @param {String} summary 该接口的名称
   */
  formateStateBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return `
      /**
       * @${annotationDesName} ${stateName}
       * @title ${summary}999
       */
      ${stateName}333: {},
    `
  },
  /**
   * 对pinia的action里的数据字段进行处理
   * 不设置的话会默认返回 `${pathTitle}Api` 也就是处理后的path前面加Api
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateActionCb: function (pathTitle) {
    return `${pathTitle}Apiiii`
  },
  /**
   * 对pinia的state里的数据字段进行处理
   * 不设置的话会默认返回 `${pathTitle}Data` 也就是处理后的path前面加Data
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateStateCb: function (pathTitle) {
    return `${pathTitle}Databbb`
  }
})

使用react用此配置

const path = require('path')
const { createApiJs, createZustandJs } = require('chenms_auto_create_file_plus')
const commonJson = {
  hostname: 你的hostname,
  port: 你的port,
  path: 你的path,

  //   hostname: 你的hostname,
  //   port: 你的port,
  //   path: 你的path,
  /**
   * 自动生成文件的工具,目前只支持apifox跟yapi
   */
  interfaceType: 'apifox',
  //   interfaceType: 'yapi',
  /**
   * 不自动生成接口的url,这个字段主要用来过滤不想生成接口的url
   */
  excludeList: ['/send/sms'],
  /**
   * 对path进行处理的回调(如果有其他特殊符号要记得自己处理下)
   * 这个要处理成什么样子完全由自己决定
   * 不设置的话会默认返回小驼峰, 如:参数path为 /my/list/detailed的接口 会默认返回 myListDetailed
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url
   */
  formatePathCb: function (pathTitle, methods, json) {
    return pathTitle.replace(/\/|\-|\_|\{|\}/g, '') + 'abc' + methods
  },
  /**
   * 对生成的文件名称进行处理
   * 不设置的话会默认返回 `${pathTitle}`名称
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   */
  formateFileNameCb: function (pathTitle) {
    return pathTitle.split('--')[1]
  }
}
createApiJs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/api'),
  /**
   * 头部需要引入的插件
   */
  topTemplate: `import hyRequest from "@/service/index"`,

  /**
   * 对生成的api里的body进行处理(必填)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入 request.${methods.toLowerCase()}("${url}", data)
   * @author chenms
   * @param {String} methods 接口的请求方式
   * @param {String} url 接口的url
   */
  formateApiBodyCb: function (methods, url) {
    return `hyRequest.${methods.toLowerCase()}("${url}", data);`
  }
})

createZustandJs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/zustand'),
  /**
   * 导入api目录的前缀
   */
  apiPrefix: '@/api'
})

如果项目是用ts写的,可以编写如下配置(使用vue3用此配置)

使用vue3用此配置


const path = require('path')
const { createApiTs, createInterface, createStoreTs } = require('chenms_auto_create_file_plus')
const commonJson = {
  hostname: 你的hostname,
  port: 你的port,
  path: 你的path,

  //   hostname: 你的hostname,
  //   port: 你的port,
  //   path: 你的path,
  /**
   * 自动生成文件的工具,目前只支持apifox跟yapi
   */
  interfaceType: 'apifox',
  //   interfaceType: 'yapi',
  /**
   * 不自动生成接口的url,这个字段主要用来过滤不想生成接口的url
   */
  excludeList: ['/send/sms'],
  /**
   * 导入api目录的前缀
   */
  apiPrefix: '@/api',
  /**
   * 导入interface目录的前缀
   */
  interfacePrefix: '@/interface',
  /**
   * 对path进行处理的回调
   * 不设置的话会默认返回小驼峰, 如:参数path为 /my/list/detailed的接口 会默认返回 myListDetailed
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url
   */
  formatePathCb: function (pathTitle, methods, json) {
    return pathTitle.replace(/\/|\-|\_|\{|\}/g, '') + methods
  },
  /**
   * 对interface进行处理
   * 不设置的话会默认返回 `I${pathTitle}` 也就是处理后的path前面加I
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateInterfaceCb: function (pathTitle) {
    return `I${pathTitle}11234`
  },
  /**
   * 对生成的文件名称进行处理
   * 不设置的话会默认返回 `${pathTitle}`名称
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   */
  formateFileNameCb: function (pathTitle) {
    return pathTitle.split('--')[1]
  }
}

createInterface({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/interface')
})

createApiTs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/api'),

  /**
   * 头部需要引入的插件
   */
  topTemplate: `import hyRequest from "@/service/home"`,

  /**
   * 对生成的api里的body进行处理(必填)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入 request.${methods.toLowerCase()}("${url}", data)
   * @author chenms
   * @param {String} methods 接口的请求方式
   * @param {String} url 接口的url
   */
  formateApiBodyCb: function (methods, url, interfaceType) {
    return `hyRequest.${methods.toLowerCase()}<${interfaceType}>("${url}", data);`
  }
})

createStoreTs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/store'),
  /**
   * 对生成的action里的body进行处理(action里的各个函数完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   *  const res = await ${pathTitle}(data)
   *  this.${stateName} = res
   *  return res
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称
   *  @param {String} stateName state里各个data的名称
   *  @param {String} interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   *  @param {String} mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
   *  @param {String} annotationDesName 是api interface state mutation action等类型的注释标记
   *  @param {String} summary 该接口的名称
   */
  formateActionBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return `
      /**
       * @${annotationDesName} ${actionName}
       * @title ${summary}666
       */
      async ${actionName}(data:any){
        try {
            const res = await ${pathTitle}(data)
            this.${stateName} = res
            return res
        } catch(errr) {
            console.log(errr)
        }
      },
    `
  },
  /**
   * 对action里的数据字段进行处理
   * 不设置的话会默认返回 `${pathTitle}Api` 也就是处理后的path前面加Api
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateActionCb: function (pathTitle) {
    return `${pathTitle}Apiaa`
  },
  /**
   * 对state里的数据字段进行处理
   * 不设置的话会默认返回 `${pathTitle}Data` 也就是处理后的path前面加Data
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateStateCb: function (pathTitle) {
    return `${pathTitle}Dataccc`
  },
  /**
   * 对生成的state里的body进行处理(state里的各个属性完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   * ${stateName}: {}
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称
   *  @param {String} stateName state里各个data的名称
   *  @param {String} interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   *  @param {String} mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
   *  @param {String} annotationDesName 是api interface state mutation action等类型的注释标记
   *  @param {String} summary 该接口的名称
   */
  formateStateBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return `
      /**
       * @${annotationDesName} ${stateName}
       * @title ${summary}999
       */
      ${stateName}: {},
    `
  }
})


使用react用此配置


const path = require('path')
const {
  createApiTs,
  createInterface,
  createZustandTs
} = require('chenms_auto_create_file_plus')
const commonJson = {
  hostname: 你的hostname,
  port: 你的port,
  path: 你的path,

  //   hostname: 你的hostname,
  //   port: 你的port,
  //   path: 你的path,
  /**
   * 自动生成文件的工具,目前只支持apifox跟yapi
   */
  interfaceType: 'apifox',
  //   interfaceType: 'yapi',
  /**
   * 不自动生成接口的url,这个字段主要用来过滤不想生成接口的url
   */
  excludeList: ['/send/sms'],
  /**
   * 导入api目录的前缀
   */
  apiPrefix: '@/api',
  /**
   * 导入interface目录的前缀
   */
  interfacePrefix: '@/interface',
  /**
   * 对path进行处理的回调
   * 不设置的话会默认返回小驼峰, 如:参数path为 /my/list/detailed的接口 会默认返回 myListDetailed
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url
   */
  formatePathCb: function (pathTitle, methods, json) {
    return pathTitle.replace(/\/|\-|\_|\{|\}/g, '') + methods
  },
  /**
   * 对interface进行处理
   * 不设置的话会默认返回 `I${pathTitle}` 也就是处理后的path前面加I
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateInterfaceCb: function (pathTitle) {
    return `I${pathTitle}11234`
  },
  /**
   * 对生成的文件名称进行处理
   * 不设置的话会默认返回 `${pathTitle}`名称
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   */
  formateFileNameCb: function (pathTitle) {
    return pathTitle.split('--')[1]
  }
}

createInterface({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/interface')
})

createApiTs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/api'),

  /**
   * 头部需要引入的插件
   */
  topTemplate: `import hyRequest from "@/service/home"`,

  /**
   * 对生成的api里的body进行处理(必填)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入 request.${methods.toLowerCase()}("${url}", data)
   * @author chenms
   * @param {String} methods 接口的请求方式
   * @param {String} url 接口的url
   */
  formateApiBodyCb: function (methods, url, interfaceType) {
    return `hyRequest.${methods.toLowerCase()}<${interfaceType}>("${url}", data);`
  }
})

createZustandTs({
  ...commonJson,
  /**
   * 生成文件的根目录名称路径
   */
  createPath: path.resolve(__dirname, '../src/zustand'),
  /**
   * 导入api目录的前缀
   */
  apiPrefix: '@/api',
  /**
   * 对state里的数据字段进行处理
   * 不设置的话会默认返回 `${pathTitle}Data` 也就是处理后的path前面加Data
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateStateCb: function (pathTitle) {
    return `${pathTitle}Dataccc`
  },
  /**
   * 对action里的数据字段进行处理
   * 不设置的话会默认返回 `${pathTitle}Api` 也就是处理后的path前面加Api
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateActionCb: function (pathTitle) {
    return `${pathTitle}Apiaa`
  },
  /**
   * 对生成的action里的body进行处理(action里的各个函数完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   *  const res = await ${pathTitle}(data)
   *  this.${stateName} = res
   *  return res
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称
   *  @param {String} stateName state里各个data的名称
   *  @param {String} interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   *  @param {String} mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
   *  @param {String} annotationDesName 是api interface state mutation action等类型的注释标记
   *  @param {String} summary 该接口的名称
   */
  formateActionBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return `
      /**
       * @${annotationDesName} ${actionName}
       * @title ${summary}666
       */
      ${actionName}: async (data1234?: any) => {
        const res = await ${pathTitle}(data1234)
        set({ ${stateName}: res })
      },
    `
  },
  /**
   * 对生成的state里的body进行处理(state里的各个属性完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   * ${stateName}: {}
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称
   *  @param {String} stateName state里各个data的名称
   *  @param {String} interfaceName interface里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   *  @param {String} mutationsName mutations里各个data对应的mutations名称(formateMutationsCb回调处理过的)
   *  @param {String} annotationDesName 是api interface state mutation action等类型的注释标记
   *  @param {String} summary 该接口的名称
   */
  formateStateBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName,
    summary
  ) {
    return `
    /**
     * @${annotationDesName} ${stateName}
     * @title ${summary}999
     */
    ${stateName}: {},
  `
  },
  /**
   * 对生成的mutations里的body进行处理(mutations里的各个函数完成由自己定义,非常灵活)
   * 返回值必须是字符串类型
   * 不填或者返回空的话会默认填入
   *  @author chenms
   *  @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   *  @param {String} actionName action里各个函数的名称(formateActionCb回调处理过的)
   *  @param {String} stateName state里各个data的名称(formateStateCb回调处理过的)
   *  @param {String} interfaceName state里各个data对应的interface名称(formateInterfaceCb回调处理过的)
   */
  formateMutationsBodyCb: function (
    pathTitle,
    actionName,
    stateName,
    interfaceName,
    mutationsName,
    annotationDesName
  ) {
    return ` 
      /**
       * @${annotationDesName} ${mutationsName}
       * @params 
       */
      ${mutationsName}: (data?: any, aaab?: any) => {
        set({ data })
      },
    `
  },
  /**
   * 对mutations里的数据字段进行处理
   * 不设置的话会默认返回 `set${pathTitle}Func`
   * 注意:1.这个function的返回值只能是字符串,如果返回其他类型的则会返回默认设置
   *      2.如果直接返回pathTitle也会返回默认设置
   * @author chenms
   * @param {String} pathTitle 接口的url(formatePathCb回调处理过的)
   */
  formateMutationsCb: function (pathTitle) {
    return `set1${pathTitle}Func123`
  },
  /**
   * 对生成的action里的interface进行处理
   */
  formateInterfaceActionCb: function () {
    return '(dataaa?:any) => void'
  },
  /**
   * 对生成的mutations里的interface进行处理
   */
  formateInterfaceMutationsCb: function () {
    return '(databb?:any) => void'
  }
})


两个文件如下图所示

image.png

  1. 在根目录的package.json中的scripts添加如下代码
"scripts": {
   "apijs": "node expand/createJs.js && prettier --write .",
   "apits": "node expand/createTs.js && prettier --write ."
}

image.png 项目中有配置prettier的可以加&&后面的代码,这样生成的文件就会根据prettier规则自动格式化

  1. 在控制台运行对应的命令
npm run apits
npm run apijs
  1. 上面的配置生成的文件夹及文件目录如下

image.png

接口测试数据

可以到

gitee.com/chenmiaoson… 或者 gitee.com/chenmiaoson…

测试项目的中json文件夹里拿

image.png

导入对应数据

yapi

image.png

apifox

image.png

示例项目地址(可以把它下载下来运行看看自动生成文件的效果)

vue3

gitee.com/chenmiaoson…

react

gitee.com/chenmiaoson…

npm地址

www.npmjs.com/package/che…

注意点

  1. 如果interfaceType参数设置为apifox执行自动生成文件的命令的时候出现problem with request: connect ECONNREFUSED 127.0.0.1:4523那说明是因为没有打开客户端apifox,打开即可

image.png

  1. 根据接口返回的数据自动生成interface文件,这一步我们是有跟后端商量把接口返回的示例数据放在备注里,如下图

yapi image.png apifox

image.png

然后再拿到数据根据后端写的示例自动生成接口文件,生成的文件如下图

image.png

所以使用要使用此插件去生成interface文件的话,你们也要跟你们的后端先商量好把接口返回的数据放在备注里面,不然可能会报错

  1. 因为生成(pinia/zustand)相关文件之后,再次生成的话并不会直接把新的覆盖到旧的去,只会比较新旧差异,然后再把有差异的添加到旧的文件里,所以这个设置完之后尽量不要再修改了,除非(pinia/zustand)文件还未生成,不然很多参数设置都跟(pinia/zustand)生成的文件内容相关联,如果重新再设置其他规则的话就很有可能会对不上

  2. 因为使用apifox接口工具生成的代码的文件夹及文件名称是通过拿到x-apifox-folder然后再通过"/"分割拿到的,所以接口名称及分组名称不要带有"/"的特殊字符,否则的话可能会因为分割不正确导致无法生成对应的文件及代码

image.png

源码部分

image.png

  1. formateActionBodyCb、formateStateBodyCb、formateMutationsBodyCb这几个回调是可以完全自定义要生成的action、state、mutations里的内容的,但由于生成ts文件的时候需要和interface对应上,所以生成的时候尽量保持原来action、state、mutations名称,否则可能因为跟interface对应不上而报错

image.png

image.png

image.png

错误案列截图

image.png

image.png

  1. store文件里对比有没有新的接口进来是根据@actionName、@stateInterfaceName、@stateName这几个标识来进行判断,所以这几个标识不要删除也不要修改,不然可能会造成生成的文件内容不正确

image.png

image.png

image.png