CmdExportJsonDatabase.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using Newtonsoft.Json;
  2. namespace etoy
  3. {
  4. internal class CmdExportJsonDatabase : Command
  5. {
  6. /// <summary>
  7. /// 默认: Server
  8. /// </summary>
  9. public TableTag TableTag { get; set; } = TableTag.Server;
  10. public override string Description => "导出数据库-JSON";
  11. protected virtual TableTag AllowedTableTag => TableTag;
  12. protected virtual KeyValueTag AllowedKeyValueTag
  13. {
  14. get
  15. {
  16. return TableTag switch
  17. {
  18. TableTag.Client => KeyValueTag.Client,
  19. TableTag.Server => KeyValueTag.Server,
  20. _ => KeyValueTag.All,
  21. };
  22. }
  23. }
  24. protected virtual string DatabaseOutput => TableTag == TableTag.Server ? Context.Option.ServerDatabaseOutput : Context.Option.ClientDatabaseOutput;
  25. private readonly string TableExt = ".json";
  26. private readonly List<Exception> _errors = new List<Exception>();
  27. protected override void OnProcess()
  28. {
  29. var outputPath = DatabaseOutput.ToPath();
  30. if (Directory.Exists(outputPath))
  31. Directory.Delete(outputPath, true);
  32. Directory.CreateDirectory(outputPath);
  33. SetProgress(0.1f);
  34. ExportTables(Context, outputPath);
  35. if (_errors.Count > 0)
  36. {
  37. SetException(new Exception(string.Join('\n', (from e in _errors select $"## ERROR: {e.Message}").ToArray())));
  38. }
  39. else
  40. {
  41. Completed();
  42. }
  43. }
  44. private void ExportTables(Context context, string outputPath)
  45. {
  46. foreach (var table in Context.Blackboard.Tables)
  47. {
  48. if (HasTableFlag(table.TableTag))
  49. {
  50. try
  51. {
  52. ExportTable(context, outputPath, table);
  53. }
  54. catch (Exception ex)
  55. {
  56. _errors.Add(ex);
  57. }
  58. }
  59. }
  60. }
  61. private void ExportTable(Context context, string outputPath, Table table)
  62. {
  63. var fileName = table.Name + TableExt;
  64. var filePath = Path.Combine(outputPath, fileName);
  65. //var serializables = new List<ISerializable>();
  66. using var jsonWriter = new JsonWriter(true);
  67. jsonWriter.ArrayBracket().Indent().NewLine();
  68. for (int i = 0, rowCount = table.Rows.Count; i < rowCount; i++)
  69. {
  70. var row = table.Rows[i];
  71. jsonWriter.Bracket();
  72. //var fieldGroup = new SerializableFieldGroup();
  73. var isFieldFirst = true;
  74. for (int j = 0, colCount = row.Cells.Count; j < colCount; j++)
  75. {
  76. var cell = row.Cells[j];
  77. var fieldInfo = cell.FieldInfo;
  78. if (HasTableFlag(fieldInfo.OutputTag) == false)
  79. {
  80. continue;
  81. }
  82. if (isFieldFirst)
  83. { // 第一个属性前面不用加逗号
  84. isFieldFirst = false;
  85. }
  86. else
  87. {
  88. jsonWriter.Dot();
  89. }
  90. if (context.Blackboard.TryGetMetadata(fieldInfo.FieldType, out var metadata))
  91. { // 是自定义属性
  92. var cellVal = cell.Value;
  93. if (metadata.StructType == MetadataStructType.Enum)
  94. {// 枚举
  95. cellVal = SerializeEnum(fieldInfo.FieldType, fieldInfo.FieldName, fieldInfo.IsRepeated, cell.Value, metadata);
  96. }
  97. //else
  98. //{ // 数据结构
  99. // // 自定义的结构体的cell.Value已经是json字符串,直接写入
  100. //}
  101. jsonWriter.AppendKey(fieldInfo.FieldName).AppendForce(cellVal);
  102. }
  103. else
  104. { // 普通字段
  105. jsonWriter.AppendKey(fieldInfo.FieldName);
  106. if (fieldInfo.IsRepeated || fieldInfo.FieldType != FieldTypeDefine.String)
  107. {
  108. jsonWriter.AppendForce(cell.Value);
  109. }
  110. else
  111. {
  112. jsonWriter.Append(cell.Value);
  113. }
  114. }
  115. }
  116. jsonWriter.EndBracket();
  117. if (i < rowCount - 1)
  118. { // 最后一行后面不用加逗号
  119. jsonWriter.Dot().NewLine();
  120. }
  121. else
  122. {
  123. jsonWriter.Dedent().NewLine();
  124. }
  125. }
  126. jsonWriter.EndArrayBracket();
  127. File.WriteAllText(filePath, jsonWriter.Json);
  128. }
  129. /// <summary>
  130. /// 序列化枚举的值
  131. /// 转成int或者int[]对应的json字符串
  132. /// </summary>
  133. /// <param name="fieldType"></param>
  134. /// <param name="fieldName"></param>
  135. /// <param name="isRepeated"></param>
  136. /// <param name="value"></param>
  137. /// <param name="meta"></param>
  138. /// <returns></returns>
  139. private string SerializeEnum(string fieldType, string fieldName, bool isRepeated, string value, MetadataStruct meta)
  140. {
  141. if (isRepeated)
  142. {
  143. int[] enumIntVals = null;
  144. try
  145. {
  146. enumIntVals = JsonConvert.DeserializeObject<int[]>(value);
  147. }
  148. catch (Exception ex)
  149. {
  150. Console.WriteLine($"枚举数组转int[]失败 Type:{fieldType} Name:{fieldName} Value:{value} Message:{ex.Message}");
  151. }
  152. if (enumIntVals == null)
  153. {
  154. var enumVals = JsonConvert.DeserializeObject<string[]>(value);
  155. var count = enumVals?.Length ?? 0;
  156. enumIntVals = new int[count];
  157. for (int i = 0; i < count; i++)
  158. {
  159. if (!int.TryParse(enumVals[i], out var intVal))
  160. { // 存的是枚举的名字
  161. var field = meta.Fields.First(a => a.Name.Equals(enumVals[i], StringComparison.OrdinalIgnoreCase));
  162. intVal = field?.EnumIntVal ?? 0;
  163. }
  164. enumIntVals[i] = intVal;
  165. }
  166. }
  167. return JsonConvert.SerializeObject(enumIntVals);
  168. }
  169. else
  170. {
  171. if (!int.TryParse(value, out var intVal))
  172. { // value存的是枚举的名字
  173. var field = meta.Fields.First(a => a.Name.Equals(value, StringComparison.OrdinalIgnoreCase));
  174. intVal = field?.EnumIntVal ?? 0;
  175. }
  176. return intVal.ToString();
  177. }
  178. }
  179. private bool HasTableFlag(TableTag tag)
  180. {
  181. return AllowedTableTag == TableTag.All || tag.HasFlag(AllowedTableTag);
  182. }
  183. //private bool HasKeyValueFlag(KeyValueTag tag)
  184. //{
  185. // return AllowedKeyValueTag == KeyValueTag.All || tag.HasFlag(AllowedKeyValueTag);
  186. //}
  187. }
  188. }