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

 

 

 

相关推荐

  1. flutter细节

    2024-06-06 10:22:07       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 10:22:07       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 10:22:07       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 10:22:07       82 阅读
  4. Python语言-面向对象

    2024-06-06 10:22:07       91 阅读

热门阅读

  1. 详解大模型微调数据集构建方法(持续更新)

    2024-06-06 10:22:07       31 阅读
  2. Flutter之旅:探索安卓与跨平台开发的无限可能

    2024-06-06 10:22:07       36 阅读
  3. Android Audio实战——音量默认值修改(一)

    2024-06-06 10:22:07       29 阅读
  4. 怎么用SU做分层轴测图?

    2024-06-06 10:22:07       27 阅读
  5. delphi Windows

    2024-06-06 10:22:07       24 阅读
  6. ubuntu蓝牙连接问题

    2024-06-06 10:22:07       34 阅读
  7. k8s使用yml文件部署

    2024-06-06 10:22:07       24 阅读
  8. debian常用命令

    2024-06-06 10:22:07       29 阅读
  9. Server did not offer supported security type!问题解决

    2024-06-06 10:22:07       31 阅读
  10. hnust 湖南科技大学 2022 软件测试报告+代码

    2024-06-06 10:22:07       28 阅读