当前位置: 首页 > news >正文

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

 

 

 

 

相关文章:

  • REACT (Web开发框架 : react)极速入门
  • 《云原生安全攻防》-- 容器环境下的攻击行为
  • 6月7号作业
  • Redis 双写一致原理篇
  • log4j日志打印导致OOM问题
  • 第十一周:学习总结
  • web前端电影简介标签:深度解析与创意应用
  • 初阶c++入门
  • 视频监控管理平台LntonCVS视频汇聚平台充电桩视频监控应用方案
  • JS笔记(自用)
  • 攻防演练之-动员大会
  • C/C++学习笔记 C语言中的\0以及查找字符串中字符出现的频率
  • Python爬取城市空气质量数据并写入mysql数据库
  • 细说NLP中的Embedding层
  • eclipse怎么导入python项目
  • [数据结构]链表的实现在PHP中
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • C++入门教程(10):for 语句
  • CAP理论的例子讲解
  • gitlab-ci配置详解(一)
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Just for fun——迅速写完快速排序
  • Puppeteer:浏览器控制器
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Quartz初级教程
  • Solarized Scheme
  • SpiderData 2019年2月16日 DApp数据排行榜
  • 翻译--Thinking in React
  • 跳前端坑前,先看看这个!!
  • 微服务框架lagom
  • 微信开源mars源码分析1—上层samples分析
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 详解NodeJs流之一
  • 7行Python代码的人脸识别
  • Android开发者必备:推荐一款助力开发的开源APP
  • FaaS 的简单实践
  • Hibernate主键生成策略及选择
  • Spring第一个helloWorld
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • (09)Hive——CTE 公共表达式
  • (1)(1.11) SiK Radio v2(一)
  • (70min)字节暑假实习二面(已挂)
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (办公)springboot配置aop处理请求.
  • (排序详解之 堆排序)
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (三)模仿学习-Action数据的模仿
  • (一)SvelteKit教程:hello world
  • (转) RFS+AutoItLibrary测试web对话框
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • ./configure、make、make install 命令
  • .htaccess配置常用技巧
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...