excel_data_manager.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import 'dart:convert';
  2. import 'package:fis_common/logger/logger.dart';
  3. import 'package:fis_jsonrpc/rpc.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:get/get.dart';
  6. import 'package:excel/excel.dart';
  7. import 'package:vitalapp/rpc.dart';
  8. import 'package:vitalapp/store/store.dart';
  9. import 'interfaces/excelData.dart';
  10. import 'interfaces/models/excel_data.dart';
  11. import 'interfaces/template.dart';
  12. class ExcelDataManager implements IExcelDataManager {
  13. final List<String> _bloodRoutineKeys = [
  14. "Blood_Hgb",
  15. "Blood_Wbc",
  16. "ALC",
  17. "AMC",
  18. "ANC",
  19. "AEC",
  20. "Blood_Neutrophils",
  21. "Blood_LymphocyteRatio",
  22. "Blood_MonocyteRatio",
  23. "EOS%",
  24. "Urea",
  25. "Blood_Hematocrit",
  26. "Blood_McV",
  27. "Blood_Mch",
  28. "Blood_Rlt",
  29. "Blood_MeanPlateletVolume",
  30. "Blood_PlateletDW",
  31. "Blood_PlateletPct"
  32. ];
  33. final List<String> _biochemicalKeys = [
  34. "Liver_Alt",
  35. "Liver_Ast",
  36. "Total_Protein",
  37. "Liver_Alb",
  38. "Liver_Tbil",
  39. "directBili",
  40. "GGT",
  41. "Renal_Cr",
  42. "UricAcid",
  43. "Urea",
  44. "BCH_Glu",
  45. "Lipid_Cho",
  46. "Lipid_Tg",
  47. "Lipid_Ldl",
  48. "Lipid_Hdl",
  49. "AGratio",
  50. "ALP",
  51. "UB",
  52. "Globulin",
  53. ];
  54. ///将csv中的数据解析成结构化数据
  55. @override
  56. Future<List<ExcelDataRecord>> CsvDataConvert(
  57. List<List<dynamic>> datas, String key) async {
  58. var json = await Get.find<ITemplateManager>()
  59. .getTemplateByKey("BiochemicalValues");
  60. List<ExcelDataRecord> csvRevords = [];
  61. List<dynamic> items = jsonDecode(json);
  62. List<List<List<dynamic>>> result = _splitIntoChunks(datas);
  63. for (List<List<dynamic>> chunkDatas in result) {
  64. List<ExcelDataItem> csvDatas = [];
  65. for (var item in items) {
  66. try {
  67. if (item is Map) {
  68. int row = item["row"];
  69. int column = item["column"];
  70. String key = item["key"];
  71. String des = item["des"];
  72. String identifier = item["identifier"];
  73. String referenceRange = item["referenceRange"];
  74. String unit = item["unit"];
  75. String value = "";
  76. if (chunkDatas.length >= row + 1) {
  77. var rowValue = chunkDatas[row];
  78. if (rowValue.length >= column + 1) {
  79. value = chunkDatas[row][column].toString().trim();
  80. } else {
  81. continue;
  82. }
  83. } else {
  84. continue;
  85. }
  86. csvDatas.add(ExcelDataItem(
  87. key: key,
  88. value: value,
  89. des: des,
  90. unit: unit,
  91. identifier: identifier,
  92. referenceRange: referenceRange,
  93. ));
  94. }
  95. } catch (e) {
  96. logger.e("CsvDataManager csvDataConvert ex:", e);
  97. }
  98. }
  99. csvRevords.add(ExcelDataRecord(csvDatas));
  100. }
  101. return csvRevords;
  102. }
  103. @override
  104. Future<List<ExcelDataRecord>> ExcelDataConvert(
  105. List<List<Data?>> rows, String key) async {
  106. ///首行是标题
  107. rows.removeAt(0);
  108. List<ExcelDataRecord> records = [];
  109. var json = await Get.find<ITemplateManager>().getTemplateByKey(key);
  110. List<dynamic> items = jsonDecode(json);
  111. for (List<Data?> rowData in rows) {
  112. List<ExcelDataItem> csvDatas = [];
  113. for (var item in items) {
  114. try {
  115. if (item is Map) {
  116. int column = item["column"];
  117. String key = item["key"];
  118. String des = item["des"];
  119. String unit = item["unit"];
  120. String identifier = item["identifier"];
  121. String referenceRange = item["referenceRange"];
  122. String value = "";
  123. if (key == "sampleBarcode") {
  124. print("sampleBarcode");
  125. }
  126. if (rowData.length >= column + 1) {
  127. Data? data = rowData[column];
  128. if (data == null) {
  129. continue;
  130. } else {
  131. value = data.value.toString();
  132. }
  133. csvDatas.add(ExcelDataItem(
  134. key: key,
  135. value: value,
  136. des: des,
  137. unit: unit,
  138. identifier: identifier,
  139. referenceRange: referenceRange,
  140. ));
  141. }
  142. }
  143. } catch (e) {
  144. logger.e("CsvDataManager ExcelDataConvert ex:", e);
  145. }
  146. }
  147. records.add(ExcelDataRecord(csvDatas));
  148. }
  149. return records;
  150. }
  151. @override
  152. Future<bool> uploadDatas(
  153. List<ExcelDataRecord> datas, String templateKey) async {
  154. try {
  155. List<AddExamDTO> examInfos = [];
  156. for (ExcelDataRecord data in datas) {
  157. List<ExcelDataItem> items = data.excelDatas;
  158. var physicalExamNumber =
  159. items.firstWhere((element) => element.key == "sampleBarcode").value;
  160. List<String> keys = [];
  161. if (templateKey.contains("BloodRoutine")) {
  162. keys = _bloodRoutineKeys;
  163. } else if (templateKey.contains("Biochemical")) {
  164. keys = _biochemicalKeys;
  165. }
  166. var examDTO = AddExamDTO(
  167. key: templateKey,
  168. physicalExamNumber: physicalExamNumber,
  169. examData: data.toJson(keys),
  170. );
  171. examInfos.add(examDTO);
  172. }
  173. if (examInfos.length <= 200) {
  174. await rpc.vitalExam.batchAddExamAsync(BatchAddExamRequest(
  175. examInfos: examInfos,
  176. token: Store.user.token,
  177. ));
  178. } else {
  179. // 计算需要拆分成多少个小组
  180. int groupCount = (examInfos.length / 200).ceil();
  181. // 遍历并拆分列表
  182. for (int i = 0; i < groupCount; i++) {
  183. // 计算当前小组的起始索引和结束索引
  184. int startIndex = i * 200;
  185. int endIndex = (i + 1) * 200;
  186. // 如果已经到达列表的末尾,设置结束索引为列表的长度
  187. if (endIndex > examInfos.length) {
  188. endIndex = examInfos.length;
  189. }
  190. // 使用 getRange 方法获取当前小组的数据
  191. List<AddExamDTO> group =
  192. examInfos.getRange(startIndex, endIndex).toList();
  193. await rpc.vitalExam.batchAddExamAsync(BatchAddExamRequest(
  194. examInfos: group,
  195. token: Store.user.token,
  196. ));
  197. }
  198. }
  199. } catch (e) {
  200. logger.e("ExcelDataManager uploadDatas ex:", e);
  201. return false;
  202. }
  203. return true;
  204. }
  205. List<List<List<dynamic>>> _splitIntoChunks(List<List<dynamic>> datas) {
  206. List<List<List<dynamic>>> records = [];
  207. List<List<dynamic>> currentRecord = [];
  208. for (int i = 0; i < datas.length; i++) {
  209. // Check if the current element and the next one are empty lists
  210. if ((datas[i].length == 1 && datas[i][0].isEmpty) &&
  211. i + 1 < datas.length &&
  212. (datas[i + 1].length == 1 && datas[i + 1][0].isEmpty)) {
  213. // Skip the next empty list as it is part of the separator
  214. i++;
  215. // Add the current record to records if it is not empty
  216. if (currentRecord.isNotEmpty) {
  217. records.add(List.from(currentRecord));
  218. currentRecord.clear();
  219. }
  220. } else {
  221. // Add the current data to the current record
  222. currentRecord.add(datas[i]);
  223. }
  224. }
  225. // Add the last record if it's not empty (case when no trailing empty lists)
  226. if (currentRecord.isNotEmpty) {
  227. records.add(currentRecord);
  228. }
  229. return records;
  230. }
  231. }