[flutter]一键将YAPI生成的api.json文件转为需要的Dart Model类的脚本

目的:

根据YAPI接口平台生成的api.json接口文件,将接口数据转化为model类,生成对应的接口值类型文件。

发现:

api.json文件导出:

YAPi是一个接口管理平台,登录账号打开项目后,在点击数据管理菜单,右侧导出按钮可以将接口数据全部导出在一份api.json文件中。

16ba829511d2451bb9f24e7dba9a3453.png

api.json文件分析:

4a1c7f4b964142ac89a00e69d17bb3f2.png

res_body与res_body_other的json解码后格式示例 :

b21fa289982d4841955bf365eae7edd0.png

dart文件模板

生成结果 

脚本源码: 

import 'dart:convert';
import 'dart:io';

const SRC = "json_model/api.json"; //来源JSON 文件
const DIST = "lib/models/"; //输出model目录
const TEMPLATE = "json_model/template.txt"; //dart文件模板

void run() {
  var list = json.decode(File(SRC).readAsStringSync());
  for (var apiClass in (list as List)) {
    apiClass["list"].forEach((api) {
      if (api["res_body"] != null) {
        var map = jsonDecode(api["res_body"]);
        processData(map, api["path"], "response");
      }
      if(api["method"]=="GET"){
        if (api["req_query"].length!=0) {
          processGetData(api["req_query"],api["path"]);
        }
      }else{
        if (api["req_body_other"] != null) {
          var map = jsonDecode(api["req_body_other"]);
          processData(map, api["path"], "query");
        }
      }
      
    });
  }
  debug("文件生成结束");
}

String processData(Map<String, dynamic> map, String path, String form, [String? keyName]) {
  var template = File(TEMPLATE).readAsStringSync(); /* dart文件模板 */
  var tempPath = path.split('/');
  tempPath.removeAt(0);
  var filename = tempPath.join("_");
  if (map['type'] == 'array') {
    var type = processData(map["items"], path, form, keyName);
    if (type.startsWith('%')) {
      /* 数组内容为对象 */
      var className = type.substring(1); /* Person */
      return '%[]$className';
    } else {
      return 'List<$type>';
    }
  } else if (map["type"] == 'object') {
    var setImport = <String>[];
    StringBuffer setKey = StringBuffer();
    (map["properties"] as Map<String, dynamic>).forEach((key, v) {
      /* 注释 */
      setKey.write("///");
      setKey.writeln((v["description"] as String).replaceAll("\n", " "));
      setKey.write("  ");
      bool ifRequired = map["required"] != null && (map["required"] as List).contains(key);
      if (ifRequired) {
        setKey.write("late ");
      }
      if (v["type"] == 'array') {
        var vType = processData(v, path, form, key);
        if (vType.startsWith('%[]')) {
          vType = vType.substring(3); /* Peason */
          var fileName = changeFirstChar(vType, false);
          setImport.add('import "$fileName.dart"');
          setKey.write('List<$vType>');
        } else {
          setKey.write(vType);
        }
      } else if (v["type"] == 'object') {
        var type = processData(v, path, form, key);
        var className = type.substring(1);
        var filename = changeFirstChar(className, false);
        setImport.add('import "$filename.dart"');
        setKey.write(className);
      } else {
        setKey.write(getType(v["type"]));
      }
      if (!ifRequired) {
        setKey.write("?");
      }
      setKey.write(" ");
      setKey.write(key);
      setKey.writeln(";"); /* writeln换行 */
      setKey.write("  ");
    });
    if (keyName != null) {
      filename += "_$keyName";
    }
    filename += "_$form";
    var tempImport = setImport.join(";\r\n");
    tempImport += tempImport.isEmpty ? "" : ";";
    String className = filename[0].toUpperCase() + filename.substring(1);
    var dist = template.replaceAll("%name", filename);
    dist = dist.replaceAll("%Name", className);
    dist = dist.replaceFirst("%i", tempImport);
    dist = dist.replaceFirst("%key", setKey.toString());
    var newFile = File("$DIST$filename.dart");
    if (!newFile.existsSync()) {
      newFile.createSync();
    }
    newFile.writeAsStringSync(dist);
    return '%$className'; /* %Person */
  }
  return getType(map["type"]);
}

String getType(String type) {
  // current = current.toLowerCase();
  switch (type) {
    case 'boolean':
      return "bool";
    case 'integer':
      return "num";
    case 'number':
      return "num";
    case 'string':
      return "String";
    default:
      return type;
  }
}

processGetData(List list, String path){
  var template = File(TEMPLATE).readAsStringSync(); /* dart文件模板 */
  var tempPath = path.split('/');
  tempPath.removeAt(0);
  var filename = tempPath.join("_");
  filename+="_query";
  StringBuffer setKey = StringBuffer();
  
  for (var element in list) { 
    setKey.write("///");
    setKey.writeln((element["desc"] as String).replaceAll("\n", " "));
    setKey.write("  ");
    if (element["required"]=="1") {
      setKey.write("late ");
    }
    setKey.write("String");
    if (element["required"]=="0") {
      setKey.write("?");
    }
    setKey.write(" ");
    setKey.write(element["name"]);
    setKey.writeln(";"); /* writeln换行 */
    setKey.write("  ");
  }
  String className = filename[0].toUpperCase() + filename.substring(1);
  var dist = template.replaceAll("%name", filename);
  dist = dist.replaceAll("%Name", className);
  dist = dist.replaceFirst("%i", "");
  dist = dist.replaceFirst("%key", setKey.toString());
  var newFile = File("$DIST$filename.dart");
  if (!newFile.existsSync()) {
    newFile.createSync();
  }
  newFile.writeAsStringSync(dist);
}

String changeFirstChar(String str, [bool upper = true]) {
  return (upper ? str[0].toUpperCase() : str[0].toLowerCase()) + str.substring(1);
}

/// 打印
void debug(String str) {
  DateTime now = DateTime.now();
  var value = now.toString();
  value += ": $str\n";
  File("json_model/debugLog.txt").writeAsBytesSync(const Utf8Encoder().convert(value), mode: FileMode.writeOnlyAppend);
}

void main() {
  run();
}

 

 

 

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

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

相关文章

AJAX 跨域

这里写目录标题 同源策略JSONPJSONP 是怎么工作的JSONP 的使用原生JSONP实践CORS 同源策略 同源&#xff1a; 协议、域名、端口号 必须完全相同、 当然网页的URL和AJAX请求的目标资源的URL两者之间的协议、域名、端口号必须完全相同。 AJAX是默认遵循同源策略的&#xff0c;不…

275 基于matlab的脉搏信号处理GUI界面编程

基于matlab的脉搏信号处理GUI界面编程&#xff0c;并实现滤波、去噪、实时回放、小波分析 计算脉率。采用低通滤波器&#xff0c;计算巴特沃斯数字滤波器的阶数N和截止频率Wn、使用coif4小波基计算信号的平稳小波分解完成降噪。程序已调通&#xff0c;可直接运行。 275 脉搏信号…

【面试笔记】嵌入式软件工程师,汽车电子软件相关

文章目录 1. C语言基础1.1 const1.2 static1.3 回调函数的用法1.4 宏定义1.5 编译、链接过程1.6 堆与栈的区别&#xff1f;1.7 简单的字符串算法题&#xff0c;C语言实现1.7.1 给定一个字符串&#xff0c;按顺序筛选出不重复的字符组成字符串&#xff0c;输出该字符串1.7.2 给定…

数据库(24)——外键约束

概念 外键用来让两张表的数据之间建立连接&#xff0c;从而保证数据的一致性和完整性。 具有外键的表称为子表&#xff0c;关联的表称为父表。 语法 添加外键 CREATE TABLE 表名( 字段名 数据类型, .. [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主…

优化家庭网络,路由器无线中继配置全攻略(中兴E1600无线中继设置/如何解决没有预埋有线网络接口的问题/使用闲置路由实现WIFI扩展)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 网络优化 📒📒 操作步骤 📒💡适用场景🚨 常见问题及解决方案⚓️ 相关链接 ⚓️📖 介绍 📖 在现代家庭生活中,WiFi已经渗透到我们生活的每一个角落,成为了日常生活中不可或缺的一部分。然而,不少用户常常遇到W…

Word忘记保存?请使用Word隐藏备份文件

大家用Word写材料时&#xff0c;如果忘记保存&#xff0c;可以使用Word隐藏备份文件找回未保存的文件。&#xff08;仅供参考&#xff09; Windows7、8、10、11系统的设置如下&#xff1a; 执行上述操作&#xff0c;可以在word文件菜单中信息项的自动保存中找到了。上述内容…

Python | mkvirtualenv命令改变虚拟环境存储位置

文章目录 1、问题引入2、解决方式 1、问题引入 使用mkvirtualenv 命令创建虚拟环境时&#xff0c;默认创建位置在C:\Users你的计算机名目录下&#xff0c;采用下面的方式可以修改虚拟环境存储位置&#xff0c;默认创建位置是Python内置写好的&#xff0c;默认是这样的。 2、解…

企业微信hook接口协议,ipad协议http,chatid转群id

chatid转群id 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","chatid":"wrO9o4EAAAeR_nSlmjeX1RWrKAKxN8jQ" } 返回示例 {&…

3072. 将元素分配到两个数组中 II Rust 线段树 + 离散化

题目 给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 现定义函数 greaterCount &#xff0c;使得 greaterCount(arr, val) 返回数组 arr 中 严格大于 val 的元素数量。 你需要使用 n 次操作&#xff0c;将 nums 的所有元素分配到两个数组 arr1 和 arr2 中。在第一次操…

docker 存储 网络 命令

文章目录 1 docker存储1.1 目录挂载2.1卷映射2.1.1卷映射和目录挂载的区别2.1.2卷映射的使用 2 docker网络2.1查看docker的默认网络2.2查看容器的IP2.3容器互通2.4自定义网络2.4.1 创建自定义网络2.4.2创建容器的时候加入到自定义的网络2.4.3使用域名进行容器之间的访问2.4.4re…

LeetCode-92. 反转链表 II【链表】

LeetCode-92. 反转链表 II【链表】 题目描述&#xff1a;解题思路一&#xff1a;简单的翻转链表操作背诵版&#xff1a;解题思路三&#xff1a;0 题目描述&#xff1a; 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 …

[Linux] 软链接使用绝对路径的重要性

文章目录 软链接使用绝对路径的重要性软链接路径复制软链接查看文件类型 软链接使用绝对路径的重要性 软链接路径 软链接必须指定绝对路径&#xff0c;否则复制软链接后&#xff0c;由于软链接的相对路径是从软链接所处位置开始解析的&#xff0c;因此使用相对路径的软链接可…

一次 K8s 故障诊断:从 CPU 高负载到存储挂载泄露根源揭示

一、背景 现代软件部署中&#xff0c;容器技术已成为不可或缺的一环&#xff0c;在云计算和微服务架构中发挥着核心作用。随着容器化应用的普及&#xff0c;确保容器环境的可靠性成为了一个至关重要的任务。这就是容器SRE&#xff08;Site Reliability Engineering&#xff0c…

2024首发!会声会影2024旗舰版,专业编辑新体验!

会声会影2024最新旗舰版是一款专业的视频编辑软件&#xff0c;它集成了多种高级功能&#xff0c;为用户带来极致的视频编辑体验。在这篇文章中&#xff0c;我们将详细介绍该软件的功能和特色&#xff0c;帮助用户更好地了解和使用它。 会声会影全版本绿色安装包获取链接&#…

HarmonyOS鸿蒙-DevEco Studio工具

一、官网下载DevEco Studio工具地址 文章内容: 1、下载工具 2、运行项目 3、安装启动器 https://developer.harmonyos.com/cn/develop/deveco-studio/https://developer.harmonyos.com/cn/develop/deveco-studio/ 下载不同平台工具目录 : 二、 安装DevEco Studio工具 安装的配置…

分布式架构与分布式理论

文章目录 分布式架构什么是分布式系统分布式系统特性分布式系统面临的问题 分布式理论数据一致性CAP理论BASE理论 分布式架构 什么是分布式系统 分布式系统是一个硬件或软件组件分布在不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进行通信和协调的系统。 所谓分…

html+CSS+js部分基础运用15

1、完成输入框内容的实时反向输出。 2、银行账户余额变动自动通知项目。 设计要求&#xff1a;单击按钮后&#xff0c;余额按照输入框的数额减少&#xff0c;同时将按钮式的提示信息&#xff08;金额&#xff09;同步改变。利用侦听属性实现余额发生变化时发出提示信息&#x…

LabVIEW减压阀和温控阀综合测试系统

在使用LabVIEW开发阀门测试软件时&#xff0c;特别是针对减压阀和温控阀&#xff0c;测试内容和注意事项包括以下方面&#xff1a; 测试内容 压力测试&#xff1a; 入口压力&#xff1a;测量阀门在不同入口压力下的表现。 出口压力&#xff1a;确保减压阀能够将出口压力控制在…

【一百零六】【算法分析与设计】并查集的实现,P3367 【模板】并查集,sizee集合的元素个数信息

并查集的实现 描述 给定一个没有重复值的整形数组arr&#xff0c;初始时认为arr中每一个数各自都是一个单独的集合。请设计一种叫UnionFind的结构&#xff0c;并提供以下两个操作。 boolean isSameSet(int a, int b): 查询a和b这两个数是否属于一个集合 void union(int a, int …

学习笔记——IP地址网络协议——VLSM-可变长子网掩码(子网划分)

四、VLSM-可变长子网掩码(子网划分) 1、为什么要子网划分 为什么要子网划分&#xff1a;有类IP地址规划的缺陷。IP地址空间只能按照默认的类别使用&#xff0c;例如一个B类地址&#xff0c;默认掩码为255.255.0.0&#xff0c;意味着这个地址空间里有2的16次方个IP&#xff0c;…