CmdKsonToJson.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. using System.Text;
  2. namespace etoy
  3. {
  4. class CmdKsonToJson : Command
  5. {
  6. public override string Description => "将Kson数据转成Json";
  7. List<Exception> _errors = new List<Exception>();
  8. int _total;
  9. int _done;
  10. protected override void OnProcess()
  11. {
  12. _total = Context.Blackboard.Tables.Count;
  13. Task.Factory.StartNew(OnThread);
  14. Task.Factory.StartNew(() =>
  15. {
  16. while (_done < _total)
  17. Thread.Sleep(1);
  18. if (_errors.Count > 0)
  19. SetException(new Exception(string.Join('\n', (from e in _errors select $"## ERROR: {e.Message}").ToArray())));
  20. else
  21. Completed();
  22. });
  23. }
  24. private void OnThread()
  25. {
  26. var tables = Context.Blackboard.Tables;
  27. for (int i = 0; i < _total; i++)
  28. {
  29. var table = tables[i];
  30. SingleTable(table);
  31. SetProgress(++_done / (float)_total);
  32. }
  33. }
  34. void SingleTable(Table table)
  35. {
  36. for (int i = 0, rowCount = table.Rows.Count; i < rowCount; i++)
  37. {
  38. var row = table.Rows[i];
  39. for (int j = 0, colCount = row.Cells.Count; j < colCount; j++)
  40. {
  41. var cell = row.Cells[j];
  42. if (Context.Blackboard.TryGetMetadata(cell.FieldInfo.FieldType, out var metadata) && metadata.StructType == MetadataStructType.Struct)
  43. {
  44. if (cell.Value.IsKsonString())
  45. {
  46. string json;
  47. string repeated = cell.FieldInfo.IsRepeated ? "[]" : string.Empty;
  48. try
  49. {
  50. json = FromKsonToJson(cell.Value, metadata, cell.FieldInfo.IsRepeated);
  51. }
  52. catch (Exception e)
  53. {
  54. _errors.Add(new Exception($"Kson解析失败, {e.Message}。 类型: {cell.FieldInfo.FieldType}{repeated}\n配置表: {table.Name}, 字段: {cell.FieldInfo.FieldName}, kson: {cell.Value}\n"));
  55. continue;
  56. }
  57. if (!json.IsJsonString())
  58. {
  59. _errors.Add(new Exception($"kson转出来的json不合法, kson: {cell.Value}, json: {json}, Table: {table.Name}, Field: {cell.FieldInfo.FieldName}, FieldType: {cell.FieldInfo.FieldType}{repeated}"));
  60. continue;
  61. }
  62. // 正确才改值
  63. cell.Value = json;
  64. }
  65. }
  66. }
  67. }
  68. }
  69. string FromKsonToJson(string kson, MetadataStruct metadata, bool isRepeated)
  70. {
  71. StringBuilder sb = new StringBuilder();
  72. KsonObject ksonObject = new KsonObject(kson);
  73. if (ksonObject.IsArray != isRepeated || ksonObject.IsObject == isRepeated)
  74. throw new Exception("Kson配置错误");
  75. if (ksonObject.IsObject)
  76. {
  77. ToObjectJson(sb, ksonObject, metadata, string.Empty);
  78. }
  79. else
  80. {
  81. sb.Append("[");
  82. for (int i = 0, length = ksonObject.ArrayObjects.Count; i < length; i++)
  83. {
  84. var list = ksonObject.ArrayObjects[i];
  85. for (int j = 0, count = list.Count; j < count; j++)
  86. {
  87. ToObjectJson(sb, list[j], metadata, string.Empty);
  88. if (j < count - 1)
  89. sb.Append(",");
  90. }
  91. if (i < length - 1)
  92. sb.Append(",");
  93. }
  94. sb.Append("]");
  95. }
  96. return sb.ToString();
  97. }
  98. void ToObjectJson(StringBuilder sb, KsonObject ksonObject, MetadataStruct metadata, string key)
  99. {
  100. key = string.IsNullOrEmpty(key) ? "{" : $"\"{key}\":{{";
  101. sb.Append(key);
  102. // 0允许, 即{}. 非0且数量不相等便是策划配置字段数量有误
  103. int fieldCount = ksonObject.FieldCount;
  104. if (fieldCount != 0 && fieldCount != metadata.Fields.Length)
  105. throw new Exception("字段数量不一致");
  106. for (int i = 0; i < fieldCount; i++)
  107. {
  108. var field = metadata.Fields[i];
  109. var fieldName = field.Name;
  110. var fieldType = field.FieldType;
  111. if (Context.Blackboard.TryGetMetadata(fieldType, out var fieldMetadata))
  112. {
  113. if (ksonObject.KsonObjects.TryGetValue(i, out var obj))
  114. {
  115. ToObjectJson(sb, obj, fieldMetadata, fieldName);
  116. }
  117. else if (ksonObject.ArrayObjects.TryGetValue(i, out var array))
  118. {
  119. sb.Append($"\"{fieldName}\":[");
  120. for (int j = 0, arrayCount = array.Count; j < arrayCount; j++)
  121. {
  122. ToObjectJson(sb, array[j], fieldMetadata, string.Empty);
  123. if (j < arrayCount - 1)
  124. sb.Append(",");
  125. }
  126. sb.Append("]");
  127. }
  128. }
  129. else if (ksonObject.StringValues.TryGetValue(i, out var stringValue))
  130. {
  131. switch (fieldType)
  132. {
  133. case FieldTypeDefine.Boolean:
  134. case FieldTypeDefine.Int:
  135. case FieldTypeDefine.Long:
  136. case FieldTypeDefine.Float:
  137. case FieldTypeDefine.Double:
  138. sb.Append($"\"{fieldName}\":{stringValue}");
  139. break;
  140. default:
  141. sb.Append($"\"{fieldName}\":\"{stringValue}\"");
  142. break;
  143. }
  144. }
  145. else if (ksonObject.ArrayObjects.TryGetValue(i, out var array))
  146. {
  147. sb.Append($"\"{fieldName}\":[");
  148. for (int j = 0, arrayCount = array.Count; j < arrayCount; j++)
  149. {
  150. var item = array[j];
  151. switch (fieldType)
  152. {
  153. case FieldTypeDefine.Boolean:
  154. case FieldTypeDefine.Int:
  155. case FieldTypeDefine.Long:
  156. case FieldTypeDefine.Float:
  157. case FieldTypeDefine.Double:
  158. sb.Append(item.RawKson);
  159. break;
  160. default:
  161. sb.Append($"\"{item.RawKson}\"");
  162. break;
  163. }
  164. if (j < arrayCount - 1)
  165. sb.Append(",");
  166. }
  167. sb.Append("]");
  168. }
  169. if (i < fieldCount - 1)
  170. sb.Append(",");
  171. }
  172. sb.Append("}");
  173. }
  174. }
  175. }