report_info.dart 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. import 'package:fis_lib_report/converts/event_type.dart';
  2. import 'package:fis_lib_report/report/element_type.dart';
  3. import 'package:fis_lib_report/report/interfaces/block_element.dart';
  4. import 'package:fis_lib_report/report/interfaces/element.dart';
  5. import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
  6. import 'package:fis_lib_report/report_info/element_info.dart';
  7. import 'package:fis_lib_report/report_info/element_tag_names.dart';
  8. import 'package:fis_lib_report/report_info/input_image_info.dart';
  9. import 'package:fis_lib_report/report_info/input_image_list_info.dart';
  10. import 'package:fis_lib_report/report_info/input_text_info.dart';
  11. import 'package:fis_lib_report/report_info/multi_selected_info.dart';
  12. import 'package:fis_lib_report/report_info/paragraph_info.dart';
  13. import 'package:fis_lib_report/report_info/report_base_info.dart';
  14. import 'package:fis_lib_report/report_info/report_event_args.dart';
  15. import 'package:fis_lib_report/report_info/rt_table_info.dart';
  16. import 'package:fis_lib_report/report_info/single_selected_info.dart';
  17. import 'package:flutter/cupertino.dart';
  18. class ReportInfo extends ReportBaseInfo {
  19. static ReportInfo? _reportInfo;
  20. ReportInfo._internal();
  21. ///选择词条按钮点击时触发
  22. FEventHandler<String> onDiagnosticTap = FEventHandler();
  23. ///ReportInfo全局单例
  24. static ReportInfo get instance {
  25. _reportInfo ??= ReportInfo._internal();
  26. return _reportInfo!;
  27. }
  28. ///从Json中加载数据
  29. void fromJson(Map<String, dynamic> json) {
  30. List<dynamic> jsonBlocks = json['BlockInfos'];
  31. if (jsonBlocks.isNotEmpty) {
  32. for (var block in jsonBlocks) {
  33. _blockElementInfoFromJson(block);
  34. }
  35. }
  36. List<dynamic> jsonHeaders = json['HeadInfos'];
  37. if (jsonHeaders.isNotEmpty) {
  38. for (var block in jsonHeaders) {
  39. _blockElementInfoFromJson(block);
  40. }
  41. }
  42. List<dynamic> jsonFooters = json['FooterInfos'];
  43. if (jsonFooters.isNotEmpty) {
  44. for (var block in jsonFooters) {
  45. _blockElementInfoFromJson(block);
  46. }
  47. }
  48. }
  49. ///插入报告描述&超声提示
  50. void insertDiagnostic(String desc, String tips) {
  51. try {
  52. if (desc.isNotEmpty) {
  53. final descInfo =
  54. getElementInfoByTagName(TagNames.REPORTDES) as InputTextInfo;
  55. if (descInfo.text.isEmpty) {
  56. descInfo.text = desc;
  57. } else {
  58. descInfo.text = descInfo.text + '\r\n' + desc;
  59. }
  60. }
  61. if (tips.isNotEmpty) {
  62. final tipsInfo =
  63. getElementInfoByTagName(TagNames.REPORTSUMARY) as InputTextInfo;
  64. if (tipsInfo.text.isEmpty) {
  65. tipsInfo.text = tips;
  66. } else {
  67. tipsInfo.text = tipsInfo.text + '\r\n' + tips;
  68. }
  69. }
  70. } catch (e) {
  71. print(e);
  72. }
  73. }
  74. ///ReportInfo转为Json,用于报告存储至Server
  75. Map<String, dynamic> toJson() {
  76. final map = <String, dynamic>{};
  77. try {
  78. final headInfos = [];
  79. for (var element in headers) {
  80. headInfos.add(_getElementInfo(element));
  81. }
  82. map['HeadInfos'] = headInfos;
  83. final blockInfos = [];
  84. for (var block in blocks) {
  85. blockInfos.add(_getElementInfo(block));
  86. }
  87. map['BlockInfos'] = blockInfos;
  88. final footerInfos = [];
  89. for (var block in footers) {
  90. footerInfos.add(_getElementInfo(block));
  91. }
  92. map['FooterInfos'] = footerInfos;
  93. } catch (e) {
  94. print(e);
  95. }
  96. return map;
  97. }
  98. ///重新渲染UI&重构reportInfo
  99. void reload(String reporter, DateTime reportDate, String jsonStr,
  100. FEventHandler<String> onSelect) {
  101. _reportInfo = null;
  102. onReload.emit(
  103. this, ReportEventArgs(reportDate, reporter, jsonStr, onSelect));
  104. }
  105. ///获取二级ElementInfo(布局组件,非最基础的组件)
  106. IBlockElementInfo? getBlockElement(IBlockElement block) {
  107. final id = block.id;
  108. for (var element in headers) {
  109. if (element.id == id) {
  110. return element;
  111. }
  112. }
  113. for (var element in blocks) {
  114. if (element.id == id) {
  115. return element;
  116. }
  117. }
  118. for (var element in footers) {
  119. if (element.id == id) {
  120. return element;
  121. }
  122. }
  123. }
  124. ///获取报告模板中当前处于选中状态的图像输入框
  125. void selectedInputImage(String imageUrl) {
  126. for (var element in headers) {
  127. if (_checkImageisSelected(element, imageUrl)) {
  128. return;
  129. }
  130. }
  131. for (var element in blocks) {
  132. if (_checkImageisSelected(element, imageUrl)) {
  133. return;
  134. }
  135. }
  136. for (var element in footers) {
  137. if (_checkImageisSelected(element, imageUrl)) {
  138. return;
  139. }
  140. }
  141. }
  142. ///跟据UI组件获取ReportInfo中的组件
  143. ElementInfo? getElementInfo(IElement element) {
  144. try {
  145. for (var e in headers) {
  146. final elementInfo = _getBaseElementInfo(e, element);
  147. if (elementInfo != null) {
  148. return elementInfo;
  149. }
  150. }
  151. for (var e in blocks) {
  152. final elementInfo = _getBaseElementInfo(e, element);
  153. if (elementInfo != null) {
  154. return elementInfo;
  155. }
  156. }
  157. for (var e in footers) {
  158. final elementInfo = _getBaseElementInfo(e, element);
  159. if (elementInfo != null) {
  160. return elementInfo;
  161. }
  162. }
  163. } catch (e) {
  164. print(e);
  165. }
  166. return null;
  167. }
  168. void _blockElementInfoFromJson(Map<String, dynamic> block) {
  169. final type = block['ElementType'];
  170. final jsonType = ElementType.fromJson(type);
  171. final name = jsonType.name;
  172. if (name == ElementType.paragraph.name) {
  173. final paragraphInfo = block as Map<String, dynamic>;
  174. _paragraphInfoFromJson(paragraphInfo);
  175. } else if (name == ElementType.rtTable.name) {
  176. final tableInfo = block as Map<String, dynamic>;
  177. List<dynamic> jsonElements = tableInfo['Cells'];
  178. int index = 0;
  179. for (var map in jsonElements) {
  180. //TODO(Loki):此处可优化Json的结构,无需区分奇偶
  181. if (index.isOdd) {
  182. final jsonType = map['ElementType'];
  183. final type = ElementType.fromJson(jsonType);
  184. if (type.name == ElementType.rtCell.name) {
  185. final cellMap = map as Map<String, dynamic>;
  186. final jsonBlocks = cellMap['Blocks'] as Map<String, dynamic>;
  187. _paragraphInfoFromJson(jsonBlocks);
  188. }
  189. }
  190. index++;
  191. }
  192. } else if (name == ElementType.imageList.name) {
  193. final imageList = block as Map<String, dynamic>;
  194. final id = imageList['Id'];
  195. final imagesInfo = getElementInfoById(id) as InputImageListInfo;
  196. final images = imageList['SelectedImages'];
  197. List<String> targetImages = [];
  198. for (var i in images) {
  199. targetImages.add(i.toString());
  200. }
  201. imagesInfo.selectedImages = targetImages;
  202. }
  203. }
  204. void _paragraphInfoFromJson(Map<String, dynamic> paragraphInfo) {
  205. List<dynamic> jsonElements = paragraphInfo['ElementInfos'];
  206. if (jsonElements.isEmpty) {
  207. return;
  208. }
  209. for (var map in jsonElements) {
  210. final jsonType = ElementType.fromJson(map['ElementType']);
  211. final id = map['Id'];
  212. if (jsonType.name == ElementType.inputText.name) {
  213. final info = getElementInfoById(id);
  214. if (info != null) {
  215. final inputInfo = info as InputTextInfo;
  216. inputInfo.text = map['Text'];
  217. }
  218. } else if (jsonType.name == ElementType.singleSelected.name) {
  219. final info = getElementInfoById(id);
  220. if (info != null) {
  221. final inputInfo = info as SingleSelectedInfo;
  222. inputInfo.selectedItem = map['SelectedItem'];
  223. }
  224. } else if (jsonType.name == ElementType.multiSelected.name) {
  225. final info = getElementInfoById(id);
  226. if (info != null) {
  227. final inputInfo = info as MulitiSelectedInfo;
  228. List<String> list = [];
  229. final items = map['SelectedItems'];
  230. for (var i in items) {
  231. list.add(i.toString());
  232. }
  233. inputInfo.selectedItems = list;
  234. }
  235. }
  236. }
  237. }
  238. bool _checkImageisSelected(IBlockElementInfo block, String url) {
  239. if (block is InputImageListInfo) {
  240. final inputImage = block;
  241. if (inputImage.isSelected ?? false) {
  242. inputImage.addImage(url);
  243. return true;
  244. }
  245. } else if (block is ParagraphInfo) {
  246. for (var el in block.elementInfos!) {
  247. if (el is InputImageInfo) {
  248. final image = el;
  249. if (image.isSelected!) {
  250. image.addImage(url);
  251. return true;
  252. }
  253. }
  254. }
  255. }
  256. return false;
  257. }
  258. ///获取基础组件信息
  259. ElementInfo? _getBaseElementInfo(IBlockElementInfo block, IElement element) {
  260. ElementInfo? result;
  261. final type = block.elementType;
  262. if (type!.name == ElementType.paragraph.name) {
  263. final paragraph = block as ParagraphInfo;
  264. for (var el in paragraph.elementInfos!) {
  265. if (el.id == element.id) {
  266. result = el;
  267. break;
  268. }
  269. }
  270. }
  271. if (result == null) {
  272. if (type.name == ElementType.rtTable.name) {
  273. final table = block as RTTableInfo;
  274. final cells = table.cells!;
  275. for (var cell in cells.values) {
  276. for (var b in cell.blocks!) {
  277. final info = _getBaseElementInfo(b, element);
  278. if (info != null) {
  279. result = info;
  280. break;
  281. }
  282. }
  283. }
  284. }
  285. }
  286. return result;
  287. }
  288. Map<String, dynamic> _getElementInfo(IBlockElementInfo element) {
  289. final _type = element.elementType!;
  290. if (_type.name == ElementType.rtTable.name) {
  291. final table = element as RTTableInfo;
  292. return table.toJson();
  293. } else if (_type.name == ElementType.paragraph.name) {
  294. final paragraph = element as ParagraphInfo;
  295. return paragraph.toJson();
  296. } else {
  297. final inputImageList = element as InputImageListInfo;
  298. return inputImageList.toJson();
  299. }
  300. }
  301. }