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

news2024/12/26 12:00:50

目的:

根据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();
}

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DVWA-File Upload

Low 后端代码没有对上传的文件做任何过滤&#xff0c;所以可以上传一句话木马。 <?phpif( isset( $_POST[ Upload ] ) ) {// Where are we going to be writing to?$target_path DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";$target_path . basename( $_F…

安装MongoDB单副本说明

参考&#xff1a;https://blog.csdn.net/weixin_43464076/article/details/126509254 https://driverzhang.github.io/post/mongo%E5%BC%80%E5%90%AF%E4%BA%8B%E5%8A%A1%E4%B9%8B%E5%89%AF%E6%9C%AC%E9%9B%86%E9%87%87%E5%9D%91/ https://dev.to/alexalvess/getting-started-wi…

【CMake系列】05-静态库与动态库编译

在各种项目类型中&#xff0c;可能我们的项目就是一个 库 项目&#xff0c;向其他人提供 我们开发好的 库 (windows下的 dll /lib &#xff1b; linux下的 .a / .so)&#xff1b;有时候在一个项目中&#xff0c;我们对部分功能 打包成 库&#xff0c;方便在不同地方进行调用 静…

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

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

pip(3) install,完美解决 externally-managed-environment

前言 现象 在 Manjaro 22、Ubuntu 23.04、Fedora 38 等最新的linux发行版中运行pip install时&#xff0c;通常会收到一个错误提示&#xff1a;error: externally-managed-environment&#xff0c;即“外部管理环境”错误&#xff0c;但这不是一个 bug。 如果您想阅读&#x…

ISSCC论文详解-ISSCC.34.1 适用于高精度 AI 应用的 28nm 83.23TFLOPS/W POSIT

0 前言 本文将对存内计算前沿论文——ISSCC 2024 34.1进行分享介绍&#xff0c;包括背景介绍、解决方案和架构、主要创新点、最终结果对比四部分内容。 1 背景介绍 题目&#xff1a;《A 28nm 83.23TFLOPS/W POSIT-Based Compute-in-Memory Macro for High-Accuracy AI Appli…

【UML用户指南】-08-对基本结构建模-图

目录 1、41视图 2、术语和概念 3、结构图 &#xff08;1&#xff09;类图&#xff08;class diagram&#xff09;&#xff1a; &#xff08;2&#xff09;构件图&#xff1a;&#xff08;component diagram&#xff09; &#xff08;3&#xff09;组合结构图&#xff1a;…

掌握ChatGPT的正确打开方式

引言 随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域取得了显著的突破。其中&#xff0c;聊天生成预训练变换器&#xff08;ChatGPT&#xff09;作为一种新型的对话式AI模型&#xff0c;引起了广泛关注。本文将详细介绍ChatGPT的正确使用…

更换 RT-DETR 主干网络为 【ResNet-18】【ResNet-34】| 已支持 18/34/50/101/152 全系列尺寸

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 之前这篇文章写过了添加【R…

ChatGPT基本原理详细解说

ChatGPT基本原理详细解说 引言 在人工智能领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;一直是研究的热点之一。随着技术的发展&#xff0c;我们见证了从简单的聊天机器人到复杂的语言模型的演变。其中&#xff0c;ChatGPT作为一项突破性技术&#xff0c;以其强大…

实战:Zig 编写高性能 Web 服务(2)

1.1 编写 HTTP server 我们从python -m http.server 8000启动得到灵感&#xff0c;先确定好目标&#xff1a; 编写一个HTTP/1.1 http serverzig version 0.12.0 使用zig init搭建项目的前置工作你先自行搭建好&#xff0c;不会的翻看前面铺垫的章节熟悉zig的项目结构。 关键…

小米用田忌赛马的方式,逼得苹果降价超2000元应对,确实厉害

苹果的iPhone15降价2300多元&#xff0c;成为618的大热门&#xff0c;之前不少人士认为迫使苹果如此大幅度降价的原因是因为另一家手机企业的竞争&#xff0c;而日前有人士认为是小米用田忌赛马的方式&#xff0c;迫使苹果降价应对。 小米这次大幅度降价的手机并非是最新款的小…

设计模式-策略模式(行为型)

行为型-策略模式 了解策略模式 策略模式是一种行为型设计模式&#xff0c;在策略模式中定义了一系列算法或者策略&#xff0c;并将这些策略封装到独立的类中&#xff0c;使得可以相互替换。在使用时&#xff0c;可以指定响应的策略使用。 角色 策略接口&#xff1a;对于某种…

【计算机网络】计算机网络的概念

计算机网络的概念 导读一、计算机网络的概念1.1 个人理解1.2 通信设备与线路1.2.1 集线器1.2.2 交换机1.2.3 路由器 1.3 计算机网络的进一步理解1.4 互联网1.5 网的不同含义 二、计算机网络的不同定义2.1 广义观点2.2 资源共享观点2.3 用户透明性观点 结语 导读 大家好&#x…

【机器学习】基于OpenCV和TensorFlow的MobileNetV2模型的物种识别与个体相似度分析

在计算机视觉领域&#xff0c;物种识别和图像相似度比较是两个重要的研究方向。本文通过结合深度学习和图像处理技术&#xff0c;基于OpenCV和TensorFlow的MobileNetV2的预训练模型模&#xff0c;实现物种识别和个体相似度分析。本文详细介绍该实验过程并提供相关代码。 一、名…

【Python】ERROR: Could not find a version that satisfies the requirement

成功解决“ERROR: Could not find a version that satisfies the requirement”错误的全面指南 一、引言 在Python开发中&#xff0c;经常需要通过pip工具来安装各种依赖包。然而&#xff0c;有时在尝试安装某个包时&#xff0c;可能会遇到“ERROR: Could not find a version …

批量提取 Word 文档中的全部图片

步骤 1、打开 WinRAR 任选一个现成的压缩包双击打开 WinRAR &#xff0c;或从开始菜单打开 WinRAR 2、直接把要提取图片的 Word 文档拖入 WinRAR 菜单区域 1 → 2 → 3&#xff0c;WinRAR 资源管理目录中的 media 就是该 Word 文档所要提取的全部图片所在文件夹 按住&#x…

python书上的动物是啥

Python的创始人为Guido van Rossum。1989年圣诞节期间&#xff0c;在阿姆斯特丹&#xff0c;Guido为了打发圣诞节的无趣&#xff0c;决心开发一个新的脚本解释程序&#xff0c;做为ABC语言的一种继承。之所以选中Python作为程序的名字&#xff0c;是因为他是一个叫Monty Python…

CATIA进阶操作——创成式曲面设计入门(1)线架设计,三维点、直线、平面、曲线

目录 引出三维空间点生成三维直线三维平面三维曲线总结异形弹簧新建几何体草图编辑&#xff0c;画一条样条线进行扫掠&#xff0c;圆心和半径画出曲面上的螺旋线再次选择扫掠&#xff0c;圆心和半径 其他自定义信号和槽1.自定义信号2.自定义槽3.建立连接4.进行触发 自定义信号重…

c++简略实现共享智能指针Shared_Ptr<T>

重点&#xff1a; 1.引用计数在堆上&#xff08;原本应为原子变量&#xff09; 2.引用计数增加减少需要加锁保证线程安全。 3.内部实现Release函数用于释放资源 4.未实现&#xff0c;增加自定义删除器可以将Release修改为模板函数&#xff0c;传入可调用参数。对于shared_p…