import 'dart:convert'; import 'package:fis_common/index.dart'; import 'package:fis_common/logger/logger.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:excel/excel.dart'; import 'package:intl/intl.dart'; import 'package:vitalapp/rpc.dart'; import 'package:vitalapp/store/store.dart'; import 'interfaces/excelData.dart'; import 'interfaces/models/exce_keys.dart'; import 'interfaces/models/excel_data.dart'; import 'interfaces/template.dart'; class ExcelDataManager implements IExcelDataManager { final List _bloodRoutineKeys = [ "Blood_Hgb", "Blood_Wbc", "ALC", "AMC", "ANC", "AEC", "Blood_NeutrophilRatio", "Blood_LymphocyteRatio", "Blood_MonocyteRatio", "EOS", "RBC", "Blood_Mchc", "Urea", "Blood_Hematocrit", "Blood_McV", "Blood_Mch", "Blood_Rlt", "Blood_MeanPlateletVolume", "Blood_PlateletDW", "Blood_PlateletPct" ]; final List _biochemicalKeys = [ "Liver_Alt", "Liver_Ast", "Total_Protein", "Liver_Alb", "Liver_Tbil", "directBili", "GGT", "Renal_Cr", "UricAcid", "Urea", "BCH_Glu", "Lipid_Cho", "Lipid_Tg", "Lipid_Ldl", "Lipid_Hdl", "AGratio", "ALP", "UB", "Globulin", ]; final List biochemicalValues_CQZYKeys = [ "Liver_Alt", "Liver_Ast", "Liver_Tbil", "Liver_Dbil", "Liver_Alb", "Urea", "Lipid_Cho", "Lipid_Tg", "Lipid_Ldl", "Lipid_Hdl", "BCH_Glu", "Renal_Cr", ]; ///将csv中的数据解析成结构化数据 @override Future> CsvDataConvert( List> datas, String key) async { List keys = []; if (key.contains("BiochemicalValues_CQZY")) { keys = biochemicalValues_CQZYKeys; } else if (key.contains("Biochemical")) {} String json = ''; json = await Get.find().getTemplateByKey(key); if (kDebugMode) { // String path = "assets/BiochemicalValues_CQZY.json"; // json = await rootBundle.loadString(path); } List csvRevords = []; List items = []; items = jsonDecode(json); if (kDebugMode) { // items = jsonDecode(json)["Content"]; } List>> result = _splitIntoChunks(datas); for (List> chunkDatas in result) { List csvDatas = []; for (var item in items) { try { if (item is Map) { int row = item["row"]; int column = item["column"]; String key = item["key"]; String des = item["des"]; String identifier = item["identifier"]; String referenceRange = item["referenceRange"]; String unit = item["unit"]; String value = ""; if (chunkDatas.length >= row + 1) { var rowValue = chunkDatas[row]; if (rowValue.length >= column + 1) { value = chunkDatas[row][column].toString().trim(); } else { continue; } } else { continue; } ///过滤不需要展示的数据 if (keys.contains(key) || key == "sampleBarcode" || key == "patientName" || key == "samplingTime") { csvDatas.add(ExcelDataItem( key: key, value: value, des: des, unit: unit, identifier: identifier, referenceRange: referenceRange, )); } } } catch (e) { logger.e("CsvDataManager csvDataConvert ex:", e); } } csvRevords.add(ExcelDataRecord(csvDatas)); } return csvRevords; } @override Future> ExcelDataConvert( List> rows, String templateKey) async { ///首行是标题 rows.removeAt(0); List records = []; var json = await Get.find().getTemplateByKey(templateKey); List items = jsonDecode(json); List keys = []; if (templateKey.contains("BloodRoutine")) { keys = _bloodRoutineKeys; } else if (templateKey.contains("Biochemical")) { keys = _biochemicalKeys; } for (List rowData in rows) { List csvDatas = []; for (var item in items) { try { if (item is Map) { String key = item["key"]; ///过滤不需要展示的数据 if (keys.contains(key) || key == "sampleBarcode" || key == "patientName" || key == "samplingTime") { int column = item["column"]; String des = item["des"]; String unit = item["unit"]; String identifier = item["identifier"]; String referenceRange = item["referenceRange"]; String value = ""; if (key == "Blood_Wbc") { print("sampleBarcode"); } if (rowData.length >= column + 1) { Data? data = rowData[column]; if (data == null) { continue; } else { value = data.value.toString(); } csvDatas.add(ExcelDataItem( key: key, value: value, des: des, unit: unit, identifier: identifier, referenceRange: referenceRange, )); } } } } catch (e) { logger.e("CsvDataManager ExcelDataConvert ex:", e); } } records.add(ExcelDataRecord(csvDatas)); } return records; } @override Future uploadDatas( List datas, String templateKey) async { try { List keys = []; if (templateKey.contains("BiochemicalValues_CQZY")) { keys = biochemicalValues_CQZYKeys; } else if (templateKey.contains("BloodRoutine")) { keys = _bloodRoutineKeys; } else if (templateKey.contains("Biochemical")) { keys = _biochemicalKeys; } if (ExcelTemplateKeys.AllBiochemicalKeys.contains(templateKey)) { templateKey = "HEIBiochemical"; } else if (ExcelTemplateKeys.AllBloodRoutineKeys.contains(templateKey)) { templateKey = "HEIBloodRoutine"; } List examInfos = []; for (ExcelDataRecord data in datas) { List items = data.excelDatas; var physicalExamNumber = items.firstWhere((element) => element.key == "sampleBarcode").value; String examTimeStr = items.firstWhere((element) => element.key == "samplingTime").value; // 使用DateFormat格式化日期,去除时间部分 DateFormat dateOnlyFormat = DateFormat('yyyy-MM-dd'); DateTime dateOnlyDateTime = dateOnlyFormat.parse(examTimeStr); var examDTO = AddExamDTO( key: templateKey, examNumber: physicalExamNumber, examTime: dateOnlyDateTime, examData: data.toJson(keys), ); examInfos.add(examDTO); } if (examInfos.length <= 200) { await rpc.vitalExam.batchAddExamAsync(BatchAddExamRequest( examInfos: examInfos, token: Store.user.token, )); } else { // 计算需要拆分成多少个小组 int groupCount = (examInfos.length / 200).ceil(); // 遍历并拆分列表 for (int i = 0; i < groupCount; i++) { // 计算当前小组的起始索引和结束索引 int startIndex = i * 200; int endIndex = (i + 1) * 200; // 如果已经到达列表的末尾,设置结束索引为列表的长度 if (endIndex > examInfos.length) { endIndex = examInfos.length; } // 使用 getRange 方法获取当前小组的数据 List group = examInfos.getRange(startIndex, endIndex).toList(); await rpc.vitalExam.batchAddExamAsync(BatchAddExamRequest( examInfos: group, token: Store.user.token, )); } } } catch (e) { logger.e("ExcelDataManager uploadDatas ex:", e); return false; } return true; } List>> _splitIntoChunks(List> datas) { List>> records = []; List> currentRecord = []; for (int i = 0; i < datas.length; i++) { // Check if the current element and the next one are empty lists if ((datas[i].length == 1 && datas[i][0].isEmpty) && i + 1 < datas.length && (datas[i + 1].length == 1 && datas[i + 1][0].isEmpty)) { // Skip the next empty list as it is part of the separator i++; // Add the current record to records if it is not empty if (currentRecord.isNotEmpty) { records.add(List.from(currentRecord)); currentRecord.clear(); } } else { // Add the current data to the current record currentRecord.add(datas[i]); } } // Add the last record if it's not empty (case when no trailing empty lists) if (currentRecord.isNotEmpty) { records.add(currentRecord); } return records; } }