forked from lxm_flutter/json2dart
Compare commits
11 Commits
v1.0.4
...
replace-fa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8f7b637a3 | ||
|
|
88a48be157 | ||
|
|
8bf4ebe233 | ||
|
|
103d92b610 | ||
|
|
6f007e8157 | ||
|
|
65cc06fe99 | ||
|
|
b507386ccc | ||
|
|
a0b0606c9d | ||
|
|
626512e475 | ||
|
|
bd858b22fb | ||
|
|
267425767a |
@@ -1,21 +1,39 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:json2dart_serialization/json_generator.dart';
|
||||
import 'package:json2dart_serialization/template.dart';
|
||||
|
||||
class Generator {
|
||||
String jsonString;
|
||||
String entityName;
|
||||
Version version;
|
||||
|
||||
Generator(this.jsonString, [this.entityName]);
|
||||
Generator(this.jsonString, [this.entityName, this.version = Version.v0]) {
|
||||
this.jsonString = convertJsonString(jsonString);
|
||||
}
|
||||
|
||||
List<DefaultTemplate> templateList = [];
|
||||
|
||||
String makeDartCode() {
|
||||
var entityName = this.entityName ?? "Entity";
|
||||
DefaultTemplate template = DefaultTemplate(srcJson: jsonString, className: entityName);
|
||||
DefaultTemplate template;
|
||||
if (version == Version.v1) {
|
||||
template = V1Template(srcJson: jsonString, className: entityName);
|
||||
} else {
|
||||
template = DefaultTemplate(srcJson: jsonString, className: entityName);
|
||||
}
|
||||
|
||||
StringBuffer resultSb = StringBuffer();
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
if (!template.isList) {
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
// return resultSb.toString();
|
||||
} else {
|
||||
var listTemplate = template.getListTemplate();
|
||||
templateList.add(listTemplate);
|
||||
|
||||
refreshTemplate(template);
|
||||
}
|
||||
|
||||
resultSb.writeln(header);
|
||||
templateList.forEach((template) {
|
||||
@@ -28,13 +46,18 @@ class Generator {
|
||||
var fieldList = template.fieldList;
|
||||
fieldList.forEach((filed) {
|
||||
if (filed is MapField) {
|
||||
// filed.typeString
|
||||
DefaultTemplate template = DefaultTemplate(srcJson: json.encode(filed.map), className: filed.typeString);
|
||||
if (version == Version.v1) {
|
||||
template = V1Template(srcJson: json.encode(filed.map), className: filed.typeString);
|
||||
}
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
} else if (filed is ListField) {
|
||||
if (filed.childIsObject) {
|
||||
DefaultTemplate template = DefaultTemplate(srcJson: json.encode(filed.list[0]), className: filed.typeName);
|
||||
if (version == Version.v1) {
|
||||
template = V1Template(srcJson: json.encode(filed.list[0]), className: filed.typeName);
|
||||
}
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
}
|
||||
@@ -60,3 +83,22 @@ String camelCase2UnderScoreCase(String name) {
|
||||
return "_" + str.toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
/// use the string replace's method the resolve the int and double problem.
|
||||
String convertJsonString(String jsonString) {
|
||||
var numberReg = RegExp(r"[0-9]\.[0-9]+");
|
||||
|
||||
//匹配小数数字正则
|
||||
var allMatch = numberReg.allMatches(jsonString).toList();
|
||||
|
||||
for (var i = 0; i < allMatch.length; i++) {
|
||||
//是一个小数数字
|
||||
var m = allMatch[i];
|
||||
var s = m.group(0);
|
||||
|
||||
// 应该是double,但由于js的原因被识别成了整数数,这里对这种数据进行处理,将这里的最后一位从0替换为5,以便于让该被js识别成小数 而非数字
|
||||
s = s.replaceRange(s.length - 1, s.length, "5");
|
||||
jsonString = jsonString.replaceRange(m.start, m.end, s);
|
||||
}
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@ import 'dart:convert';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:json2dart_serialization/generator.dart';
|
||||
import 'package:json2dart_serialization/storage.dart';
|
||||
|
||||
String entityName = null;
|
||||
|
||||
bool useJsonKey = true;
|
||||
|
||||
bool isCamelCase = true;
|
||||
bool isStaticMethod = true;
|
||||
|
||||
var downloadFileName = "";
|
||||
|
||||
@@ -22,28 +24,36 @@ var downloadFileName = "";
|
||||
// }""";
|
||||
const defaultValue = "";
|
||||
|
||||
enum Version { v0, v1 }
|
||||
|
||||
Version v = Version.v0;
|
||||
|
||||
void main() async {
|
||||
isChinese = await _isChinese();
|
||||
|
||||
var dataHelper = CookieHelper();
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
jsonInput.value = defaultValue;
|
||||
jsonInput.value = dataHelper.loadJsonString();
|
||||
|
||||
jsonInput.onInput.listen((event) {
|
||||
// print(jsonInput.value);
|
||||
dataHelper.saveJsonString(jsonInput.value);
|
||||
refreshData();
|
||||
});
|
||||
|
||||
InputElement entityNameEle = querySelector("#out_entity_name");
|
||||
entityNameEle.value = dataHelper.loadEntityName();
|
||||
entityName = entityNameEle.value;
|
||||
entityNameEle.onInput.listen((event) {
|
||||
entityName = entityNameEle.value;
|
||||
dataHelper.saveEntityName(entityName);
|
||||
refreshData();
|
||||
});
|
||||
|
||||
ButtonElement formatButton = querySelector("#format");
|
||||
formatButton.onClick.listen((click) {
|
||||
String pretty;
|
||||
pretty = convertJsonString(jsonInput.value);
|
||||
try {
|
||||
pretty = formatJson(jsonInput.value);
|
||||
pretty = formatJson(pretty);
|
||||
} on Exception {
|
||||
return;
|
||||
}
|
||||
@@ -52,7 +62,41 @@ void main() async {
|
||||
|
||||
InputElement eJsonKey = querySelector("#use_json_key");
|
||||
InputElement eCamelCase = querySelector("#camelCase");
|
||||
InputElement eUseStatic = querySelector("#use_static");
|
||||
TextAreaElement result = querySelector("#result");
|
||||
RadioButtonInputElement v0 = querySelector("#v0");
|
||||
RadioButtonInputElement v1 = querySelector("#v1");
|
||||
|
||||
void updateVersioin() {
|
||||
if (v1.checked) {
|
||||
v = Version.v1;
|
||||
} else {
|
||||
v = Version.v0;
|
||||
}
|
||||
|
||||
dataHelper.saveVersion(v);
|
||||
}
|
||||
|
||||
void updateVersionUI() {
|
||||
if (v == Version.v1) {
|
||||
v1.checked = true;
|
||||
} else {
|
||||
v1.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
v = dataHelper.loadVersion();
|
||||
|
||||
updateVersionUI();
|
||||
|
||||
v0.onInput.listen((event) {
|
||||
updateVersioin();
|
||||
refreshData();
|
||||
});
|
||||
v1.onInput.listen((event) {
|
||||
updateVersioin();
|
||||
refreshData();
|
||||
});
|
||||
|
||||
void onJsonKeyChange() {
|
||||
useJsonKey = eJsonKey.checked;
|
||||
@@ -83,6 +127,17 @@ void main() async {
|
||||
refreshData();
|
||||
});
|
||||
|
||||
eUseStatic.checked = isStaticMethod;
|
||||
eUseStatic.onInput.listen((event) {
|
||||
isStaticMethod = eUseStatic.checked;
|
||||
refreshData();
|
||||
});
|
||||
|
||||
querySelector("#useStaticLabel").onClick.listen((event) {
|
||||
eUseStatic.checked = !eUseStatic.checked;
|
||||
refreshData();
|
||||
});
|
||||
|
||||
refreshData();
|
||||
|
||||
querySelector("#copy").onClick.listen((event) {
|
||||
@@ -101,7 +156,8 @@ void main() async {
|
||||
// FileWriter fw = await fileEntry.createWriter();
|
||||
// fw.write(blob);
|
||||
// File file = await fileEntry.file();
|
||||
AnchorElement saveLink = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
|
||||
AnchorElement saveLink =
|
||||
document.createElementNS("http://www.w3.org/1999/xhtml", "a");
|
||||
saveLink.href = Url.createObjectUrlFromBlob(blob);
|
||||
// saveLink.type = "download";
|
||||
saveLink.download = downloadFileName;
|
||||
@@ -133,10 +189,10 @@ bool isChinese = false;
|
||||
void refreshData() async {
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
var string = jsonInput.value;
|
||||
String pretty;
|
||||
TextAreaElement result = querySelector("#result");
|
||||
|
||||
try {
|
||||
pretty = formatJson(string);
|
||||
formatJson(string);
|
||||
} on Exception {
|
||||
if (isChinese) {
|
||||
result.value = "不是一个正确的json";
|
||||
@@ -152,7 +208,7 @@ void refreshData() async {
|
||||
entityClassName = entityName;
|
||||
}
|
||||
|
||||
var generator = Generator(string, entityClassName);
|
||||
var generator = Generator(string, entityClassName, v);
|
||||
var dartCode = generator.makeDartCode();
|
||||
var dartFileName = ("${generator.fileName}.dart");
|
||||
downloadFileName = dartFileName;
|
||||
@@ -163,7 +219,7 @@ void refreshData() async {
|
||||
} else {
|
||||
filePrefix = "your dart file name is:";
|
||||
}
|
||||
print(filePrefix);
|
||||
// print(filePrefix);
|
||||
querySelector("#file_name").text = "$filePrefix $dartFileName";
|
||||
|
||||
result.value = dartCode;
|
||||
|
||||
44
lib/storage.dart
Normal file
44
lib/storage.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:json2dart_serialization/json_generator.dart';
|
||||
|
||||
const _entityKey = "entityKey";
|
||||
const _versionKey = "versionKey";
|
||||
|
||||
class CookieHelper {
|
||||
String loadJsonString() {
|
||||
var storage = window.localStorage;
|
||||
if (!storage.containsKey("json")) {
|
||||
return "";
|
||||
}
|
||||
return window.localStorage["json"];
|
||||
}
|
||||
|
||||
void saveJsonString(String jsonString) {
|
||||
window.localStorage.addAll({"json": jsonString});
|
||||
}
|
||||
|
||||
void saveEntityName(String entityName) {
|
||||
window.localStorage.addAll({_entityKey: entityName});
|
||||
}
|
||||
|
||||
String loadEntityName() {
|
||||
if (!window.localStorage.containsKey(_entityKey)) {
|
||||
return "";
|
||||
}
|
||||
return window.localStorage[_entityKey];
|
||||
}
|
||||
|
||||
void saveVersion(Version version) {
|
||||
var index = Version.values.indexOf(version);
|
||||
window.localStorage.addAll({_versionKey: index.toString()});
|
||||
}
|
||||
|
||||
Version loadVersion() {
|
||||
if (!window.localStorage.containsKey(_versionKey)) {
|
||||
return Version.v0;
|
||||
}
|
||||
|
||||
return Version.values[int.parse(window.localStorage[_versionKey])];
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,11 @@ class DefaultTemplate extends Template {
|
||||
@override
|
||||
String declare() {
|
||||
return """@JsonSerializable()
|
||||
class $className extends Object with _\$${className}SerializerMixin {""";
|
||||
class $className extends Object ${interface()}{""";
|
||||
}
|
||||
|
||||
String interface() {
|
||||
return "with _\$${className}SerializerMixin";
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -93,10 +97,91 @@ class $className extends Object with _\$${className}SerializerMixin {""";
|
||||
|
||||
@override
|
||||
String method() {
|
||||
if (main.isStaticMethod) {
|
||||
return " static $className fromJson(Map<String, dynamic> srcJson) => _\$${className}FromJson(srcJson);";
|
||||
}
|
||||
return " factory $className.fromJson(Map<String, dynamic> srcJson) => _\$${className}FromJson(srcJson);";
|
||||
}
|
||||
|
||||
List<Field> get fieldList => FieldHelper(srcJson).getFields();
|
||||
|
||||
bool get isList => json.decode(srcJson) is List;
|
||||
|
||||
ListTemplate getListTemplate() {
|
||||
if (this is ListTemplate) {
|
||||
return this;
|
||||
}
|
||||
return ListTemplate(
|
||||
srcJson: srcJson, className: className, delegateTemplate: this);
|
||||
}
|
||||
}
|
||||
|
||||
class ListTemplate extends DefaultTemplate {
|
||||
Template delegateTemplate;
|
||||
|
||||
ListTemplate(
|
||||
{String srcJson, String className = "Entity", this.delegateTemplate})
|
||||
: super(className: className, srcJson: srcJson);
|
||||
|
||||
@override
|
||||
String declare() {
|
||||
return _declareListMethod() + "\n" + delegateTemplate?.declare() ??
|
||||
super.declare();
|
||||
}
|
||||
|
||||
String _declareListMethod() {
|
||||
var listMethod =
|
||||
"""List<$className> get${className}List(List<dynamic> list){
|
||||
List<$className> result = [];
|
||||
list.forEach((item){
|
||||
result.add($className.fromJson(item));
|
||||
});
|
||||
return result;
|
||||
}""";
|
||||
return listMethod;
|
||||
}
|
||||
|
||||
@override
|
||||
String constructor() {
|
||||
return delegateTemplate?.constructor() ?? super.constructor();
|
||||
}
|
||||
|
||||
@override
|
||||
String field() {
|
||||
return delegateTemplate?.field() ?? super.field();
|
||||
}
|
||||
|
||||
@override
|
||||
String method() {
|
||||
return delegateTemplate?.method() ?? super.method();
|
||||
}
|
||||
|
||||
@override
|
||||
String end() {
|
||||
return delegateTemplate?.end() ?? super.end();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Field> get fieldList =>
|
||||
FieldHelper(json.encode(json.decode(srcJson)[0])).getFields();
|
||||
}
|
||||
|
||||
class V1Template extends DefaultTemplate {
|
||||
V1Template({String srcJson, String className = "Entity"})
|
||||
: super(className: className, srcJson: srcJson);
|
||||
|
||||
@override
|
||||
String interface() => "";
|
||||
|
||||
@override
|
||||
String method() {
|
||||
var result = StringBuffer();
|
||||
result.writeln(super.method());
|
||||
result.writeln();
|
||||
result.write(
|
||||
" Map<String, dynamic> toJson() => _\$${className}ToJson(this);");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class FieldHelper {
|
||||
@@ -104,26 +189,35 @@ class FieldHelper {
|
||||
|
||||
FieldHelper(this.srcJson);
|
||||
|
||||
List<Field> _getMapFiled(Map<String, dynamic> map) {
|
||||
List<Field> list = [];
|
||||
map.forEach((k, v) {
|
||||
if (v is List) {
|
||||
list.add(ListField(v, k));
|
||||
} else if (v is String) {
|
||||
list.add(SimpleField("String", k));
|
||||
} else if (v is int) {
|
||||
list.add(SimpleField("int", k));
|
||||
} else if (v is double) {
|
||||
list.add(SimpleField("double", k));
|
||||
} else if (v is bool) {
|
||||
list.add(SimpleField("bool", k));
|
||||
} else if (v is Map<String, dynamic>) {
|
||||
list.add(MapField(v, k));
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
List<Field> getFields() {
|
||||
var j = json.decode(srcJson);
|
||||
if (j is Map<String, dynamic>) {
|
||||
List<Field> list = [];
|
||||
j.forEach((k, v) {
|
||||
if (v is List) {
|
||||
list.add(ListField(v, k));
|
||||
} else if (v is String) {
|
||||
list.add(SimpleField("String", k));
|
||||
} else if (v is int) {
|
||||
list.add(SimpleField("int", k));
|
||||
} else if (v is double) {
|
||||
list.add(SimpleField("double", k));
|
||||
} else if (v is bool) {
|
||||
list.add(SimpleField("bool", k));
|
||||
} else if (v is Map<String, dynamic>) {
|
||||
list.add(MapField(v, k));
|
||||
}
|
||||
});
|
||||
return list;
|
||||
return _getMapFiled(j);
|
||||
} else if (j is List) {
|
||||
var item = j[0];
|
||||
if (item is Map<String, dynamic>) {
|
||||
return _getMapFiled(item);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
11
pubspec.yaml
11
pubspec.yaml
@@ -11,11 +11,10 @@ environment:
|
||||
# path: ^1.4.1
|
||||
dependencies:
|
||||
# Your other regular dependencies here
|
||||
json_annotation: ^0.2.3
|
||||
intl: ^0.15.7
|
||||
json_annotation: ^3.0.0
|
||||
intl: ^0.15.8
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^0.9.0
|
||||
build_web_compilers: ^0.4.0
|
||||
json_serializable: ^0.5.4
|
||||
build_runner: ^1.6.6
|
||||
build_web_compilers: ^2.2.3
|
||||
json_serializable: ^3.2.0
|
||||
@@ -21,42 +21,49 @@
|
||||
<img src="github_logo.jpg" width="50px" />
|
||||
</a>
|
||||
</div>
|
||||
<h1>simple use
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable" target="_blank">json_serializable</a>
|
||||
</h1>
|
||||
<div>
|
||||
<div class="title">
|
||||
<span class="half_span">copy your json to left textarea</span>
|
||||
<span class="half_span">
|
||||
<div class="result_title">
|
||||
dart class name
|
||||
<input id="out_entity_name" />
|
||||
<input type="checkbox" id="use_json_key" />
|
||||
<span id="check_label">jsonKey annotation</span>
|
||||
<input type="checkbox" id="camelCase" />
|
||||
<span id="camelCaseLabel">use camelCase</span>
|
||||
</div>
|
||||
<div id="file_name"></div>
|
||||
</span>
|
||||
<h1>simple use
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable" target="_blank">json_serializable</a>
|
||||
</h1>
|
||||
<div class="version">
|
||||
<input class="version" type="radio" value="0" name="version" id="v0" checked="true">v0.x.x</input>
|
||||
<input class="version" type="radio" value="1" name="version" id="v1">v1.x.x</input>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="half_span">
|
||||
<textarea id="json" title="json" class="content_area"></textarea>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<textarea id="result" title="result" class="content_area"></textarea>
|
||||
</span>
|
||||
<div>
|
||||
<div class="title">
|
||||
<span class="half_span">copy your json to left textarea</span>
|
||||
<span class="half_span">
|
||||
<div class="result_title">
|
||||
dart class name
|
||||
<input id="out_entity_name" />
|
||||
<input type="checkbox" id="use_json_key" />
|
||||
<span id="check_label">jsonKey annotation</span>
|
||||
<input type="checkbox" id="camelCase" />
|
||||
<span id="camelCaseLabel">use camelCase</span>
|
||||
<input type="checkbox" id="use_static" />
|
||||
<span id="useStaticLabel">use static</span>
|
||||
</div>
|
||||
<div id="file_name"></div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="half_span">
|
||||
<textarea id="json" title="json" class="content_area"></textarea>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<textarea id="result" title="result" class="content_area"></textarea>
|
||||
</span>
|
||||
</div>
|
||||
<div class="func">
|
||||
<span class="half_span">
|
||||
<button id="format">format</button>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<button id="copy">copy</button>
|
||||
<button id="save">download</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="func">
|
||||
<span class="half_span">
|
||||
<button id="format">format</button>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<button id="copy">copy</button>
|
||||
<button id="save">download</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -21,8 +21,15 @@
|
||||
<img src="github_logo.jpg" width="50px" />
|
||||
</a>
|
||||
</div>
|
||||
<h1>为了便利使用
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable">json_serializable</a>库</h1>
|
||||
<div>
|
||||
<h1>为了便利使用
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable">json_serializable</a>库
|
||||
</h1>
|
||||
<div class="version">
|
||||
<input class="version" type="radio" value="0" name="version" id="v0" checked="true">v0.x.x</input>
|
||||
<input class="version" type="radio" value="1" name="version" id="v1">v1.x.x</input>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="title">
|
||||
<span class="half_span">将json粘贴至左边</span>
|
||||
@@ -31,9 +38,11 @@
|
||||
类名称
|
||||
<input id="out_entity_name" />
|
||||
<input type="checkbox" id="use_json_key" />
|
||||
<span id="check_label">jsonKey annotation</span>
|
||||
<span id="check_label">使用 JsonKey 注解</span>
|
||||
<input type="checkbox" id="camelCase" />
|
||||
<span id="camelCaseLabel">use camelCase</span>
|
||||
<span id="camelCaseLabel">驼峰命名</span>
|
||||
<input type="checkbox" id="use_static" />
|
||||
<span id="useStaticLabel">使用静态方法</span>
|
||||
</div>
|
||||
<div id="file_name"></div>
|
||||
</span>
|
||||
|
||||
@@ -8,34 +8,6 @@ body {
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
}
|
||||
/*
|
||||
.top {
|
||||
height: 4vh;
|
||||
text-align: center;
|
||||
padding-top: 1vh;
|
||||
}
|
||||
|
||||
.result_title {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
width: 50%;
|
||||
height: 90%;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content_area {
|
||||
width: 80%;
|
||||
height: 90vh;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.out_entity_name {
|
||||
height: 40px;
|
||||
} */
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
@@ -86,3 +58,8 @@ a {
|
||||
a:hover {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user