将Knife4j所展示请求参数和响应参数转化为TS类型声明

目标:在浏览器控制台输入js代码,将读取页面所展示的请求参数和响应参数,将他们转化为TS的类型声明,并在控制台中输出出来。

将Knife4j所展示请求参数和响应参数转化为TS类型声明

  • 1 找到所需要的元素节点
  • 2 转化元素节点
  • 3 封装成函数
  • 4 全部代码
  • 5 代码压缩
  • 6 使用说明及成果

1 找到所需要的元素节点

根据图1、图2所示,分析页面结构找到对应的参数行节点
响应参数页面截图
图1 响应参数页面截图
在这里插入图片描述
图2 页面元素结构

let elements = null;
// 获取所有class为"api-title"的元素
document.getElementsByClassName("api-title").forEach((item) => {
  // 如果找到与传入参数title相匹配的元素
  if (item.innerText === title)
    // 将elements设置为该元素的下一个兄弟元素,这些元素包含"ant-table-row"类
    elements = item.nextSibling.getElementsByClassName("ant-table-row");
});

2 转化元素节点

现有的元素节点结构使用起来较为费劲,并且浪费性能,需要将其转化为我们需要的数据格式

先转化为列表

// 初始化一些变量,用于后续的数据结构构建
let minLevel = 0, // 初始化最小级别为100
  maxLevel = 0, // 初始化最大级别为0
  objectArray = [], // 创建一个空数组,用于存储对象
  load = { datas: [] }, // 创建一个对象,用于临时存储数据
  continuity = false, // 初始化连续性标志为false
  textLoad = ""; // 初始化文本承载字符串为空
// 根据传入的title参数,创建一个基础对象,并将其添加到objectArray数组中
objectArray.push({
  class: "-1",
  key: title === "请求参数" ? "request" : "response",
  title: title === "请求参数" ? "request" : "response",
  type: title === "请求参数" ? "request" : "response",
});
// 遍历elements数组中的每个元素
elements.forEach((item) => {
  // 获取当前元素的级别,并更新minLevel和maxLevel
  if (item.className.split("").at(-1) > maxLevel)
    maxLevel = item.className.split("").at(-1);
  if (item.className.split("").at(-1) < minLevel)
    minLevel = item.className.split("").at(-1);
  // 创建一个对象,包含当前元素的相关信息,并添加到objectArray数组中
  objectArray.push({
    class: item.className.split("").at(-1),
    key: item.children[0].innerText, // 参数名称
    title: item.children[1].innerText, // 参数说明
    type: item.children[title === "请求参数" ? 4 : 2].innerText, // 类型
    require: title === "请求参数" ? item.children[3].innerText : "", // 是否必须
  });
});

再定义两个函数便于将数据转换为字符串

// 定义generate函数,用于生成TypeScript接口代码
function generate(item, load) {
  // 构建接口的开始部分
  let temp = `export interface ${format(item.key)} { \n`;
  // 遍历load.datas数组中的每个数据项
  load.datas.forEach((value) => {
    // 获取数据项的类型,并根据类型构建TypeScript类型字符串
    let type = value.type;
    let tempType = "";
    if (type.indexOf("integer") >= 0) tempType = "number";
    else if (type.indexOf("number") >= 0) tempType = "number";
    else if (type.indexOf("string") >= 0) tempType = "string";
    else if (type.indexOf("boolean") >= 0) tempType = "boolean";
    else if (type.indexOf("分页返回") >= 0) tempType = `${format(value.key)}`;
    else if (type.indexOf("array") >= 0) tempType = `${format(value.key)}[]`;
    else tempType = "any";
    // 构建接口的属性定义,并添加到temp字符串中
    temp += `\t${value.key}${
      value.require === "false" ? "?" : ""
    }: ${tempType}; // ${value.title} \n`;
  });
  // 构建接口的结束部分,并将其添加到textLoad字符串中
  return temp += "}\n";
}
// 定义format函数,用于将字符串的首字母大写
function format(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
  }

最后将列表数据转化为树形结构,同时拼接字符串

// 从最大级别开始向下遍历,构建最终的数据结构
while (minLevel <= maxLevel) {
  for (let i = objectArray.length - 1; i >= 0; i--) {
    // 如果当前对象的级别不等于最大级别,设置连续性为false
    if (objectArray[i].class != maxLevel) continuity = false;
    // 如果当前对象的级别等于最大级别
    if (objectArray[i].class == maxLevel) {
      // 如果load.datas数组为空,设置load.end为当前索引
      if (load.datas.length == 0) load.end = i;
      // 设置连续性为true
      continuity = true;
      // 将当前对象添加到load.datas数组中
      load.datas.unshift(objectArray[i]);
    }
    // 如果load.datas数组不为空且连续性为false,执行数据处理
    if (load?.datas.length > 0 && !continuity) {
      // 设置load.start为当前索引+1
      load.start = i + 1;
      // 将load.datas数组中的数据作为当前对象的children属性
      objectArray[i].children = load.datas;
      // 调用generate函数,生成TypeScript接口代码
      textLoad = generate(objectArray[i], load) + textLoad;
      // 从objectArray数组中移除已处理的数据
      objectArray.splice(load.start, load.end - load.start + 1);
      // 重置load对象
      load = { datas: [] };
    }
  }
  // 减小最大级别,继续下一轮循环
  maxLevel--;
}

3 封装成函数

封装成函数便于调用

// 定义getText函数,接受一个参数title,表示要查找的标题
function getText(title) {
	// 上方的所有代码
	// 返回生成的TypeScript接口代码
  	return textLoad;
}
// 调用getText函数,打印生成的TypeScript接口代码
console.log(getText("请求参数") + "\n" + getText("响应参数"));

4 全部代码

// 这段代码的主要功能是将HTML中的表格数据转换为TypeScript接口定义,以便在TypeScript项目中使用。代码中使用了递归和循环来处理嵌套的数据结构,并且通过生成TypeScript代码的方式,使得数据结构更加清晰和易于维护。
// 定义getText函数,接受一个参数title,表示要查找的标题
function getText(title) {
  let elements = null;
  // 获取所有class为"api-title"的元素
  document.getElementsByClassName("api-title").forEach((item) => {
    // 如果找到与传入参数title相匹配的元素
    if (item.innerText === title)
      // 将elements设置为该元素的下一个兄弟元素,这些元素包含"ant-table-row"类
      elements = item.nextSibling.getElementsByClassName("ant-table-row");
  });
  // 初始化一些变量,用于后续的数据结构构建
  let minLevel = 0, // 初始化最小级别为100
    maxLevel = 0, // 初始化最大级别为0
    objectArray = [], // 创建一个空数组,用于存储对象
    load = { datas: [] }, // 创建一个对象,用于临时存储数据
    continuity = false, // 初始化连续性标志为false
    textLoad = ""; // 初始化文本承载字符串为空
  // 根据传入的title参数,创建一个基础对象,并将其添加到objectArray数组中
  objectArray.push({
    class: "-1",
    key: title === "请求参数" ? "request" : "response",
    title: title === "请求参数" ? "request" : "response",
    type: title === "请求参数" ? "request" : "response",
  });
  // 遍历elements数组中的每个元素
  elements.forEach((item) => {
    // 获取当前元素的级别,并更新minLevel和maxLevel
    if (item.className.split("").at(-1) > maxLevel)
      maxLevel = item.className.split("").at(-1);
    if (item.className.split("").at(-1) < minLevel)
      minLevel = item.className.split("").at(-1);
    // 创建一个对象,包含当前元素的相关信息,并添加到objectArray数组中
    objectArray.push({
      class: item.className.split("").at(-1),
      key: item.children[0].innerText, // 参数名称
      title: item.children[1].innerText, // 参数说明
      type: item.children[title === "请求参数" ? 4 : 2].innerText, // 类型
      require: title === "请求参数" ? item.children[3].innerText : "", // 是否必须
    });
  });
  // 从最大级别开始向下遍历,构建最终的数据结构
  while (minLevel <= maxLevel) {
    for (let i = objectArray.length - 1; i >= 0; i--) {
      // 如果当前对象的级别不等于最大级别,设置连续性为false
      if (objectArray[i].class != maxLevel) continuity = false;
      // 如果当前对象的级别等于最大级别
      if (objectArray[i].class == maxLevel) {
        // 如果load.datas数组为空,设置load.end为当前索引
        if (load.datas.length == 0) load.end = i;
        // 设置连续性为true
        continuity = true;
        // 将当前对象添加到load.datas数组中
        load.datas.unshift(objectArray[i]);
      }
      // 如果load.datas数组不为空且连续性为false,执行数据处理
      if (load?.datas.length > 0 && !continuity) {
        // 设置load.start为当前索引+1
        load.start = i + 1;
        // 将load.datas数组中的数据作为当前对象的children属性
        objectArray[i].children = load.datas;
        // 调用generate函数,生成TypeScript接口代码
        textLoad = generate(objectArray[i], load) + textLoad;
        // 从objectArray数组中移除已处理的数据
        objectArray.splice(load.start, load.end - load.start + 1);
        // 重置load对象
        load = { datas: [] };
      }
    }
    // 减小最大级别,继续下一轮循环
    maxLevel--;
  }
  // 定义generate函数,用于生成TypeScript接口代码
  function generate(item, load) {
    // 构建接口的开始部分
    let temp = `export interface ${format(item.key)} { \n`;
    // 遍历load.datas数组中的每个数据项
    load.datas.forEach((value) => {
      // 获取数据项的类型,并根据类型构建TypeScript类型字符串
      let type = value.type;
      let tempType = "";
      if (type.indexOf("integer") >= 0) tempType = "number";
      else if (type.indexOf("number") >= 0) tempType = "number";
      else if (type.indexOf("string") >= 0) tempType = "string";
      else if (type.indexOf("boolean") >= 0) tempType = "boolean";
      else if (type.indexOf("分页返回") >= 0) tempType = `${format(value.key)}`;
      else if (type.indexOf("array") >= 0) tempType = `${format(value.key)}[]`;
      else tempType = "any";
      // 构建接口的属性定义,并添加到temp字符串中
      temp += `\t${value.key}${
        value.require === "false" ? "?" : ""
      }: ${tempType}; // ${value.title} \n`;
    });
    // 构建接口的结束部分,并将其添加到textLoad字符串中
    return temp += "}\n";
  }
  // 定义format函数,用于将字符串的首字母大写
  function format(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
  }
  // 返回生成的TypeScript接口代码
  return textLoad;
}
// 调用getText函数,打印生成的TypeScript接口代码
console.log(getText("请求参数") + "\n" + getText("响应参数"));

5 代码压缩

内容太长了,复制和使用起来都很不便捷,为方便使用rollup将其压缩,压缩后代码如下方所示

function e(e){let t=null;document.getElementsByClassName("api-title").forEach((n=>{n.innerText===e&&(t=n.nextSibling.getElementsByClassName("ant-table-row"))}));let n=0,s=0,a=[],l={datas:[]},r=!1,i="";for(a.push({class:"-1",key:"请求参数"===e?"request":"response",title:"请求参数"===e?"request":"response",type:"请求参数"===e?"request":"response"}),t.forEach((t=>{t.className.split("").at(-1)>s&&(s=t.className.split("").at(-1)),t.className.split("").at(-1)<n&&(n=t.className.split("").at(-1)),a.push({class:t.className.split("").at(-1),key:t.children[0].innerText,title:t.children[1].innerText,type:t.children["请求参数"===e?4:2].innerText,require:"请求参数"===e?t.children[3].innerText:""})}));n<=s;){for(let e=a.length-1;e>=0;e--)a[e].class!=s&&(r=!1),a[e].class==s&&(0==l.datas.length&&(l.end=e),r=!0,l.datas.unshift(a[e])),l?.datas.length>0&&!r&&(l.start=e+1,a[e].children=l.datas,i=c(a[e],l)+i,a.splice(l.start,l.end-l.start+1),l={datas:[]});s--}function c(e,t){let n=`export interface ${o(e.key)} { \n`;return t.datas.forEach((e=>{let t=e.type,s="";s=t.indexOf("integer")>=0||t.indexOf("number")>=0?"number":t.indexOf("string")>=0?"string":t.indexOf("boolean")>=0?"boolean":t.indexOf("分页返回")>=0?`${o(e.key)}`:t.indexOf("array")>=0?`${o(e.key)}[]`:"any",n+=`\t${e.key}${"false"===e.require?"?":""}: ${s}; // ${e.title} \n`})),n+="}\n"}function o(e){return e.charAt(0).toUpperCase()+e.slice(1)}return i}console.log(e("请求参数")+"\n"+e("响应参数"));

6 使用说明及成果

将第五部分的代码复制到控制台,进行回车
成果截图
最后将控制台钟打印出来的TS类型声明复制到代码中就可以直接使用了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/499432.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地部署的stable diffusion 如何更新controlnet?

stable diffusion 未启动状态 点击“版本管理” 点击“扩展” 找到controlnet&#xff0c;点击右边的“更新”按钮 完成&#xff01;

【软考---系统架构设计师】特殊的操作系统介绍

目录 一、嵌入式系统&#xff08;EOS&#xff09; &#xff08;1&#xff09;嵌入式系统的特点 &#xff08;2&#xff09;硬件抽象层 &#xff08;3&#xff09;嵌入式系统的开发设计 二、实时操作系统&#xff08;RTOS&#xff09; &#xff08;1&#xff09;实时性能…

总结TCP各类知识点

前言 本篇博客博主将详细地介绍TCP有关知识点&#xff0c;坐好板凳发车啦~ 一.TCP特点 1.有连接 TCP传输的过程中类似于打电话的各个过程 2.可靠传输 通过TCP自身的多种机制来保证可靠传输 3.面向字节流 内容是以字节的方式来进行发送与接收 4.缓冲区 TCP有接收缓冲区…

网络安全接入认证-802.1X接入说明

介绍 802.1X是一个网络访问控制协议&#xff0c;它可以通过认证和授权来控制网络访问。它的基本原理是在网络交换机和认证服务器之间建立一个安全的通道&#xff0c;并要求客户端提供身份验证凭据。如果客户端提供的凭据是有效的&#xff0c;交换机将开启端口并允许访问。否则&…

服务器被挖矿了怎么办,实战清退

当我们发现服务器资源大量被占用的时候&#xff0c;疑似中招了怎么办 第一时间重启服务是不行的&#xff0c;这些挖矿木马一定是会伴随着你的重启而自动重启&#xff0c;一定时间内重新霸占你的服务器资源 第一步检查高占用进程 top -c ps -ef 要注意这里%CPU&#xff0c;如果…

1.8.1 摄像机

一、摄像机 OpenGL本身没有摄像机的概念&#xff0c;但是我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机&#xff0c;产生一种我们在移动的感觉&#xff0c;而不是场景在移动。 本节将会讨论如何在OpenGL中配置一个摄像机&#xff0c;让你能够在3D场景中…

Web APIs

文章目录 Web APIs1. DOM1.1 介绍DOM 树DOM 节点document 1.2 获取DOM对象1.3 操作元素内容1.4 操作元素属性常用属性修改控制样式属性操作表单元素属性自定义属性 1.5 间歇函数1.6 事件事件监听事件类型事件处理程序 1.7 事件类型鼠标事件键盘事件焦点事件文本框输入事件 1.8 …

【JavaScript】数组 ③ ( JavaScript 数组长度 | 修改数组长度 | 数组案例 )

文章目录 一、JavaScript 数组长度1、数组长度2、修改数组长度 二、数组案例1、求数组元素平均值2、求数组元素最大值 一、JavaScript 数组长度 1、数组长度 在 JavaScript 中 , 数组长度 可以通过 数组变量的 length 属性 获取 , 该属性 返回 数组中的元素数量 , 也就是 数组长…

【Java】ArrayList数组的扩容机制 jdk1.8

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 ArrayList和普通数组不同&#xff0c;ArrayList支持动态扩容&#xff0c;那么ArrayList到底是如何扩容的呢&#xff1f;你又是否知道ArrayList数组的初始长度是多少呢&#xff1f; 在开始介绍之前&#xff0c;我们要先介…

【IDEA+通义灵码插件】实现属于你的大模型编程助手

1、前言 大模型到底该以一种什么方式落地&#xff0c;从而嵌入我们的工作当中&#xff0c;助力我们工作效率的提升&#xff0c;其实最好的方式也许就是虚拟助手的方式&#xff0c;就像钢铁侠的"贾维斯"一样&#xff0c;随叫随到能回答问题&#xff0c;能自动的解决一…

python函数参数中独立星号*的作用

python函数中间有一个&#xff08;&#xff09;分隔&#xff0c;星号后面为*命名关键字参数&#xff0c;星号本身不是参数**。命名关键字参数&#xff0c;在函数调用时必须带参数名字进行调用。如下例子&#xff1a;

【Golang入门教程】Go语言变量的初始化

文章目录 强烈推荐引言举例多个变量同时赋值总结强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 推荐一个个人工作&#xff0c;日常中比较常…

深入剖析哈希表:以Java中的HashMap为例

哈希表是一种非常高效的数据结构&#xff0c;它允许我们以接近常数的时间复杂度进行插入、删除和查找操作。在Java中&#xff0c;HashMap类是实现哈希表的一个非常流行的工具。本文将深入探讨哈希表的工作原理&#xff0c;并通过Java代码来展示HashMap的使用和内部机制。 一、…

Linux 动静态库的制作,使用和加载

Linux 动静态库的制作,使用和加载 一.前置说明1.mylib.h2.mylib.c3.mymath.h mymath.c4.如何制作库 二.动静态库的制作1.静态库的制作1.制作2.使用一下静态库,验证是否成功打包 2.动态库的制作1.编译.c源文件文件生成.o目标文件2.打包生成动态库3.编写makefile文件,自动化制作动…

基于Springboot+vue的鲜花销售商城网站

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;鲜花销售商城当然也不能排除在外。鲜花销售商城是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#x…

多线程的学习1

多线程 线程是操作系统能够进入运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 进程&#xff1a;是程序的基本执行实体。 并发&#xff1a;在同一个时刻&#xff0c;有多个指令在单个CPU上交替执行。 并行&#xff1a;在同一时刻&#xff0c…

程序汪若依微服务华为云Linux部署保姆教程

若依官方有3个版本&#xff0c;程序汪以前已经出了对应的安装部署视频教程 单应用版本 前后分离版本 微服务版本 本视频是若依微服务版本&#xff0c;如果基础的环境软件都不会安装建议看下程序汪的单应用和前后端分离版本教程&#xff0c; 欢迎点击进入 &#xff08;单应…

全局UI方法-弹窗二-列表选择弹窗(ActionSheet)

1、描述 定义列表弹窗 2、接口 ActionSheet.show(value:{ title: string | Resource, message: string | Resource, autoCancel?: boolean, confrim?: {value: string | Resource, action: () > void }, cancel?: () > void, alignment?: DialogAlignment, …

Lightguide

Resolve Assembly Challenges with Projected AR Workflows The future of assembly is here. It’s not just about automation, it’s about empowering your workforce with the best possible digital toolset. LightGuide AR is a powerful addition to your Industry 4.…

基于单片机的便携式瓦斯检测仪系统设计

**单片机设计介绍&#xff0c;基于单片机的便携式瓦斯检测仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的便携式瓦斯检测仪系统设计是一个针对煤矿等工业环境中瓦斯气体浓度检测的重要项目。以下是该设计…