难道还要复制粘贴写接口api函数?

318 阅读2分钟

一个小功能,节省上千行代码:根据接口文档数据,生成接口函数代码。 没有多少技术含量,提供一个思路。

先上图说明

image.png

image.png

写接口文件的时候,需要重复复制、粘贴、复制、粘贴...... 如果项目很大,接口文件也是不少的代码量。
如果有大量重复的情况,一定存在更简单的解决方法。
本着这样的思路,仔细研究了接口文档返回的数据格式,我们目前使用的是RAP管理接口,返回数据很全面,包含请求地址,请求方法,请求参数。 那么接下来就是根据这些数据,自动生成接口函数代码。

  1. 添加import语句作为初始字符串。
  2. 获取地址,方法,参数,组装函数代码。遍历所有数据。函数名的生成规则是“方法+地址最后一个斜线后的的单词”。可能会存在重名,解决方法是如果存在重名函数,则追加前一个斜线后的单词。
  3. 字符串拼接,在打印台输出最后结果。

这样一个省时省力,减少出错的小功能就完成啦。生成一个模块的接口文件分四步走:

  1. 接口文档地址,network复制接口数据
  2. 粘贴到生成api文件的页面,点击生成代码
  3. 打开控制台,复制生成的代码
  4. 回到项目中,新建一个文件,粘贴,保存。

完整代码参考

<!---->

<template>
  <div>
    <SelForm v-model="data" :items="items"></SelForm>
    <el-button type="primary" @click="createApiCode">生成接口代码</el-button>
    <p>
      打开控制台查看打印信息,每个数组项是一个模块的文件,右键复制“字符串内容“到对应的api的ts文件中
    </p>

    <div style="margin-top: 50px">
      使用说明:Rap接口,查看network:repository/get的返回值,右键复制“复制object”
    </div>
    <div style="margin-top: 10px">
      生成的接口方法在每个模块中无重复命名,命名规则:方法类型+取url最后一个单词,如果有重复,方法类型+最后两个单词,以此类推。建议使用接口生成代码生成接口文件,不再次手动修改,以防修改内容被覆盖。如必须手动修改,另外新建文件重写单独引入
    </div>
    <div style="margin-top: 10px">接口传参统一为json格式</div>
  </div>
</template>

<script setup lang="ts">
import type { FormItem } from "@/config/types";

const data = ref({
  modules: "",
});

const items: FormItem[] = [
  {
    is: "el-input",
    label: "接口数据数组",
    prop: "modules",
    option: {
      type: "textarea",
      rows: 10,
    },
  },
];
///repository/get 接口网站,查询接口,复制modules

function createApiCode() {
  const { modules } = JSON.parse(data.value.modules);
  const strList = [];
  const allList: any = [];
  const nameArr: string[] = [];
  for (const item of modules) {
    const { name, interfaces } = item;
    const mudoleApi: any = { name, list: [] };

    let str = `/*${name}*/
  import request from "@/utils/request";
  `;

    for (const apiItem of interfaces) {
      if (!apiItem.url) continue;
      const { name: apiName, url, method } = apiItem;
      const _method = method.toLowerCase();
      const funcName = getFuncName(_method, url, nameArr);
      nameArr.push(funcName.toLowerCase());
      const _params = ["get", "delete"].includes(_method)
        ? "{params}"
        : "params";
      const _url = url.replace("{", "${params.");

      const _apiStr = `export function ${funcName}(params:{[index: string]: any }= {}) {
      return request.${_method}(\`${_url}\`, ${_params});
    }`;
      const apiStr = `/*${apiName}*/
    ${_apiStr}
    `;
      str += apiStr;

      mudoleApi.list.push(apiStr);
    }
    strList.push(str);
    allList.push(mudoleApi);
  }
  /**console打印代码,不可删除 */

  strList.forEach((item, index) => {
    console.log(index, item);
    console.log("\n\n");
  });
  // console.log("\n\n\n");

  // console.log("------------每个模块的单条数据列表-------------");

  // allList.forEach((item) => {
  //   console.log(`\n---${item.name}---`, item.list);
  // });
  ElMessage.success("已生成代码");
}

//防止重名
function getFuncName(_method: string, url: string, nameArr: string[]) {
  const urlSplitArr = url.replaceAll(/\/\{.*\}/g, "").split("/");
  const urlLastItem = urlSplitArr.pop();
  let funcName =
    _method + urlLastItem?.charAt(0).toUpperCase() + urlLastItem?.slice(1);
  if (nameArr.includes(funcName.toLowerCase())) {
    const lowerCaseName = funcName.replace(
      _method,
      _method + urlSplitArr[urlSplitArr.length - 2]
    );
    funcName = funcName.replace(
      _method,
      getFuncName(_method, urlSplitArr.join("/"), [...nameArr, lowerCaseName])
    );
  }
  return funcName;
}
</script>

<style scoped lang="scss"></style>