import 'dart:convert'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:uuid/uuid.dart'; import 'package:vitalapp/architecture/utils/prompt_box.dart'; import 'package:vitalapp/components/alert_dialog.dart'; import 'package:vitalapp/database/db.dart'; import 'package:vitalapp/database/entities/defines.dart'; import 'package:vitalapp/database/entities/diagnosis.dart'; import 'package:vitalapp/global.dart'; import 'package:vitalapp/managers/interfaces/patient.dart'; import 'package:vitalapp/managers/interfaces/record_data_cache.dart'; import 'package:vnote_device_plugin/consts/types.dart'; import 'package:vitalapp/architecture/defines.dart'; import 'package:vitalapp/architecture/storage/text_storage.dart'; import 'package:vitalapp/managers/interfaces/cachedRecord.dart'; import 'package:vitalapp/managers/interfaces/device.dart'; import 'package:vitalapp/managers/interfaces/diagnosis.dart'; import 'package:vitalapp/managers/interfaces/models/device.dart'; import 'package:vitalapp/pages/medical/models/item.dart'; import 'package:vitalapp/pages/medical/state.dart'; import 'package:vitalapp/store/store.dart'; import 'package:vnote_device_plugin/events/event_type.dart'; import 'package:fis_common/logger/logger.dart'; class MedicalController extends FControllerBase { String patientCode = ''; Map diagnosisDataValue = {}; final _patientManager = Get.find(); String appDataId = ""; final state = MedicalState(); final recordDataCacheManager = Get.find(); static final typeConvertMap = { DeviceTypes.TEMP: "Temp", DeviceTypes.WEIGHT: "BMI", DeviceTypes.SPO2: "SpO2", DeviceTypes.NIBP: "NIBP", DeviceTypes.SUGAR: "GLU", DeviceTypes.URINE: "Urine", DeviceTypes.IC_READER: "ICReader", DeviceTypes.HEART: "HEART", }; final changePatient = FEventHandler(); final _diagnosisManager = Get.find(); final _cachedRecordManager = Get.find(); final _deviceManager = Get.find(); final _medicalMenus = [ MedicalItem(key: DeviceTypes.TEMP, diagnosticItem: '体温'), MedicalItem(key: DeviceTypes.SUGAR, diagnosticItem: '血糖'), MedicalItem(key: DeviceTypes.NIBP, diagnosticItem: '血压'), MedicalItem(key: DeviceTypes.SPO2, diagnosticItem: '血氧'), MedicalItem(key: DeviceTypes.WEIGHT, diagnosticItem: 'BMI'), MedicalItem(key: DeviceTypes.URINE, diagnosticItem: '尿常规'), MedicalItem(key: DeviceTypes.HEART, diagnosticItem: '心电'), ]; @override void onInit() async { setBusy('Loading...'); await initData(); await getAccessTypes(); state.currentTab = DeviceTypes.TEMP; //等数据加载完成之后在切换到体温页面 busy = false; logger.i('MedicalController init end'); super.onInit(); } Future initData() async { patientCode = Store.user.currentSelectPatientInfo?.code ?? ''; if (patientCode.isNotEmpty) { logger.i( 'MedicalController initData patientName:${Store.user.currentSelectPatientInfo?.patientName} patientCode:${Store.user.currentSelectPatientInfo?.code}'); var cachedAppDataId = await readCachedAppDataId(); if (cachedAppDataId != null) { appDataId = cachedAppDataId; } else { await saveCachedAppDataId(); } await initReadCached(); } } Future getAccessTypes() async { List medicalItemList = []; List accessTypes = await _deviceManager.getAccessTypes(); for (var element in _medicalMenus) { if (accessTypes.contains(element.key)) { medicalItemList.add(element); } } state.medicalMenuList = medicalItemList; } Future getDevice(String type) async { List devices = await _deviceManager.getDeviceList(); return devices.firstWhereOrNull((element) => element.type == type); } Future initReadCached() async { if (patientCode.isNotEmpty) { TextStorage cachedRecord = TextStorage( fileName: 'JKJC', directory: "patient/$patientCode", ); String? value = await cachedRecord.read(); if (value == null) { diagnosisDataValue = {}; Store.resident.handleSaveMedicalData(jsonEncode(diagnosisDataValue)); return; } Store.resident.handleSaveMedicalData(value); diagnosisDataValue = jsonDecode(value); } } Future saveCachedAppDataId() async { appDataId = const Uuid().v4().replaceAll('-', ''); TextStorage cachedRecord = TextStorage( fileName: 'appDataId', directory: "patient/$patientCode", ); Get.back(); return cachedRecord.save(appDataId); } Future readCachedAppDataId() async { TextStorage cachedRecord = TextStorage( fileName: 'appDataId', directory: "patient/$patientCode", ); return cachedRecord.read(); } Future saveCachedRecord() async { Store.resident.handleSaveMedicalData(jsonEncode(diagnosisDataValue)); TextStorage cachedRecord = TextStorage( fileName: 'JKJC', directory: "patient/$patientCode", ); return cachedRecord.save(jsonEncode(diagnosisDataValue)); } Future deleteDirectory() async { TextStorage cachedRecord = TextStorage( fileName: 'JKJC', directory: "patient/$patientCode", ); return cachedRecord.deleteDirectory(); } Future submitDiagnosis( Map submitDiagnosisDataValue, ) async { try { List diagnosisItems = await recordDataCacheManager .convertDiagnosisDataToList(submitDiagnosisDataValue); state.currentTab = '-1'; await recordDataCacheManager.saveRecordData( appDataId, patientCode, submitDiagnosisDataValue, ); if (kIsOnline) { SubmitDiagnosisRequest submitDiagnosisRequest = SubmitDiagnosisRequest( appDataId: appDataId, patientCode: patientCode, diagnosisItems: diagnosisItems, diagnosisTime: DateTime.now().toUtc(), ); print(submitDiagnosisRequest.toJson()); busy = true; bool result; if (kIsOnline) { result = await _diagnosisManager.syncPatientAndDiagnosisData( SyncPatientAndDiagnosisDataRequest( patientCode: patientCode, patientName: Store.user.currentSelectPatientInfo?.patientName ?? '', patientAddress: Store.user.currentSelectPatientInfo?.patientAddress ?? '', patientGender: Store.user.currentSelectPatientInfo?.patientGender ?? GenderEnum.Unknown, permanentResidenceAddress: Store .user.currentSelectPatientInfo?.permanentResidenceAddress, phone: Store.user.currentSelectPatientInfo?.phone, cardNo: Store.user.currentSelectPatientInfo?.cardNo, nationality: Store.user.currentSelectPatientInfo?.nationality, birthday: Store.user.currentSelectPatientInfo?.birthday, crowdLabels: Store.user.currentSelectPatientInfo?.crowdLabels, cardType: Store.user.currentSelectPatientInfo?.cardType ?? CardTypeEnum.Identity, contractedDoctor: Store.user.currentSelectPatientInfo?.contractedDoctor, appDataId: appDataId, diagnosisTime: DateTime.now(), token: Store.user.token, diagnosisItems: diagnosisItems, ), ); if (result) { //如果在线,则提交历史数据 var submitSuccess = await _submitHistory(); if (submitSuccess) { logger.i('当前数据提交成功,且历史记录:$patientCode 提交成功'); } } } else { result = await _diagnosisManager .submitDiagnosisAsync(submitDiagnosisRequest); } if (result) { busy = false; recordDataCacheManager.recordSyncStateChange(appDataId); PromptBox.toast('提交成功'); await saveCachedAppDataId(); await deleteDirectory(); await initReadCached(); ///提交之后,测试结果清空 diagnosisDataValue.clear(); Future.delayed(const Duration(milliseconds: 10), () { state.currentTab = state.medicalMenuList[0].key; }); } else { PromptBox.toast('提交失败'); logger.i('提交失败:$patientCode'); } if (busy) { busy = false; } } else { Future.delayed(const Duration(milliseconds: 10), () { state.currentTab = state.medicalMenuList[0].key; }); PromptBox.toast("已缓存至本地"); logger.i('已缓存至本地:$patientCode'); await saveCachedAppDataId(); await deleteDirectory(); await initReadCached(); ///提交之后,测试结果清空 diagnosisDataValue.clear(); Get.back(); } } catch (err) { state.currentTab = state.medicalMenuList[0].key; logger.e('submitDiagnosis error: ${err.toString()}'); } } Future createDiagnosis() async { busy = true; try { if (Store.user.teamName.isEmpty) { PromptBox.toast('未设置团队无法提交检测数据'); return; } if (patientCode.isEmpty || patientCode != Store.user.currentSelectPatientInfo?.code) { initData(); } Map submitDiagnosisDataValue = Map.from(diagnosisDataValue); //确定提交值不会发生变更 List diagnosisItems = await recordDataCacheManager .convertDiagnosisDataToList(submitDiagnosisDataValue); logger.i('submitDiagnosis diagnosisItems.leng:${diagnosisItems.length}'); if (diagnosisItems.isEmpty) { if (patientCode.isNotEmpty && kIsOnline) { bool submitHistory = await _submitHistory(); if (submitHistory) { PromptBox.toast('提交成功'); return; } } PromptBox.toast('不能提交空数据'); return; } if (state.medicalMenuList.length > submitDiagnosisDataValue.length) { logger.i( 'state.medicalMenuList.length:${state.medicalMenuList.length},copiedDiagnosisDataValue.length:${diagnosisDataValue.length}'); Get.dialog( VAlertDialog( title: '提示', content: Container( margin: const EdgeInsets.only(bottom: 20), child: const Text( '当前检测项目未完成,请确定是否提交本次检测', style: TextStyle(fontSize: 20), textAlign: TextAlign.center, ), ), showCancel: true, onConfirm: () { submitDiagnosis(submitDiagnosisDataValue); }, onCanceled: () {}, ), ); return; } else { ///如果已完成所有检查,则直接提交 submitDiagnosis(submitDiagnosisDataValue); } } catch (e) { logger.e('MedicalController createDiagnosis ex:', e); } finally { busy = false; } } @override void dispose() { print('MedicalController dispose'); super.dispose(); } ///提交历史记录 Future _submitHistory() async { var existDatas = await recordDataCacheManager.getNoSubmitRecords(patientCode); var historyDatas = existDatas.where((element) => element.code != appDataId); if (historyDatas.isEmpty) { return false; } for (DiagnosisEntity data in historyDatas) { try { Map jsonData = jsonDecode(data.dataJson); var diagnosisItems = await recordDataCacheManager.convertDiagnosisDataToList(jsonData); SubmitDiagnosisRequest submitDiagnosisRequest = SubmitDiagnosisRequest( appDataId: data.code, patientCode: data.patientCode, diagnosisItems: diagnosisItems, diagnosisTime: data.updateTime ?? data.createTime, ); bool submitResult; if (kIsOnline) { PatientDTO? patientInfo = await _patientManager.getDetail( data.patientCode, ); if (patientInfo == null) { ///如果Server没有,则从本地读取 var patientEntity = await db.repositories.patient .singleByCode(data.patientCode, Store.user.userCode!); if (patientEntity != null) { patientInfo = PatientDTO.fromJson(jsonDecode(patientEntity.dataJson)); } } submitResult = await _diagnosisManager.syncPatientAndDiagnosisData( SyncPatientAndDiagnosisDataRequest( token: Store.user.token, patientCode: data.patientCode, patientName: patientInfo?.patientName ?? '', patientAddress: patientInfo?.patientAddress ?? '', patientGender: patientInfo?.patientGender ?? GenderEnum.Unknown, permanentResidenceAddress: patientInfo?.permanentResidenceAddress, phone: patientInfo?.phone, cardNo: patientInfo?.cardNo, nationality: patientInfo?.nationality, birthday: patientInfo?.birthday, crowdLabels: patientInfo?.crowdLabels, cardType: patientInfo?.cardType ?? CardTypeEnum.Identity, contractedDoctor: patientInfo?.contractedDoctor, appDataId: data.code, diagnosisTime: data.updateTime ?? data.createTime, diagnosisItems: diagnosisItems, ), ); } else { submitResult = await _diagnosisManager .submitDiagnosisAsync(submitDiagnosisRequest); } OfflineDataSyncState state; if (submitResult) { state = OfflineDataSyncState.success; logger.i('提交历史记录:$patientCode 成功'); } else { state = OfflineDataSyncState.fail; logger.i('提交历史记录:$patientCode 失败'); } recordDataCacheManager.recordSyncStateChange(data.code, state: state); } catch (e) { logger.e('MedicalController _submitHistory ex:', e); } } return true; } }