import 'dart:convert'; import 'package:fis_common/event/event_type.dart'; import 'package:fis_common/index.dart'; import 'package:fis_common/logger/logger.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:vitalapp/architecture/utils/prompt_box.dart'; import 'package:vitalapp/components/appbar.dart'; import 'package:vitalapp/components/button.dart'; import 'package:vitalapp/components/dialog_date.dart'; import 'package:vitalapp/components/dialog_input.dart'; import 'package:vitalapp/components/dialog_number.dart'; import 'package:vitalapp/components/dynamic_drawer.dart'; import 'package:vitalapp/managers/interfaces/cachedRecord.dart'; import 'package:vitalapp/managers/interfaces/patient.dart'; import 'package:vitalapp/managers/interfaces/registration.dart'; import 'package:vitalapp/managers/interfaces/template.dart'; import 'package:vitalapp/pages/check/models/form.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_ability_radio.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_abnormal.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_blood_pressure.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_blood_sugar.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_body_temperature.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_body_weight.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_boold_oxygen.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_check_box.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_check_guidance.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_checkbox_frequency.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_dentition.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_input.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_number_input.dart'; import 'dart:math' as math; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio_score.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_risk_factor_control.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_table.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_toxic_substance.dart'; import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_urinalys.dart'; import 'package:vitalapp/pages/check/widgets/exam_table/homecare_bed_history_from.dart'; import 'package:vitalapp/pages/check/widgets/exam_table/hospitalization_history_from.dart'; import 'package:vitalapp/pages/check/widgets/exam_table/inoculate_history_from.dart'; import 'package:vitalapp/pages/check/widgets/exam_table/main_medication_status_from.dart'; import 'package:vitalapp/pages/medical/controller.dart'; import 'package:vitalapp/store/store.dart'; class NewConfigurableCard extends StatefulWidget { final String cardKey; final Future Function(String, String, dynamic, bool) callBack; final Widget? followUpWidget; final String? patientCode; final String? examData; final FEventHandler? onChangeCurrentKeyEvent; final FEventHandler? onSubmitEvent; final String physicalExamNumber; final bool? isAllSelectZQCT; final Function(bool)? onAllSelectZQCTChange; const NewConfigurableCard({ super.key, required this.cardKey, required this.callBack, required this.physicalExamNumber, this.followUpWidget, this.patientCode, this.examData, this.onSubmitEvent, this.isAllSelectZQCT, this.onChangeCurrentKeyEvent, this.onAllSelectZQCTChange, }); @override State createState() => NewConfigurableFormState(); } class NewConfigurableFormState extends State { /// 当前最新的模板的键值对 Map templateRelation = {}; String templateCode = ''; /// 当前模板数据 List currentTemplate = []; /// 当前title的下标 // int currentTitleIndex = 0; Map formValue = {}; var scaffoldKey = GlobalKey(); final _templateManager = Get.find(); final _cachedRecordManager = Get.find(); final arrowHeight = math.tan(120 / 180) * 19; List deviceList = [ 'Temp', 'GLU', 'NIBP', 'SpO2', 'BMI', "Urinary_Pro", ]; Map deviceCached = {}; Map currentTable = {}; ScrollController _examScrollController = ScrollController(); ExamDTO? _currentExam; bool _isAllSelectZQCT = false; @override void initState() { print("formValue:$formValue"); _isAllSelectZQCT = widget.isAllSelectZQCT ?? false; initAddListener(); super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { if (mounted) { initTemplate(); } }); widget.onSubmitEvent?.addListener(submitEvent); _examScrollController.addListener(_scrollListener); } @override void dispose() { super.dispose(); widget.onSubmitEvent?.removeListener(submitEvent); _examScrollController.removeListener(_scrollListener); _examScrollController.dispose(); } void submitEvent(sender, e) { if (mounted) { if (formValue.isNotEmpty) { submit(e); } } } /// 是否有健康检测的页面权限 bool _hasHealthMonitor() { bool hasAuth = false; Store.user.menuPermissionList?.forEach((element) { if (element.code == "JKJC") { hasAuth = true; } }); return hasAuth; } /// 判断是否有健康检测的页面 void initAddListener() { if (_hasHealthMonitor()) { var medicalController = Get.find(); medicalController.setExamData.addListener(onSetExamDataEvent); } } void onSetExamDataEvent(sender, Map e) { try { Map examData = {}; Map blood = { "BloodPressure": { "left": "", "right": "", } }; e.forEach((key, value) { if (value is Map && value.isEmpty) { return; } if (key != "Urine") { /// 血压处理 if (value["Sbp_Left"] != null && value["Dbp_Left"] != null) { blood["BloodPressure"]["left"] = jsonEncode([value["Sbp_Left"], value["Dbp_Left"]]); } if (value["Sbp_Right"] != null && value["Dbp_Right"] != null) { blood["BloodPressure"]["right"] = jsonEncode([value["Sbp_Right"], value["Dbp_Right"]]); } if (blood["BloodPressure"]["left"] != null || blood["BloodPressure"]["right"] != null) { examData.addAll(blood); } examData.addAll(Map.from(value)); } else { examData.addAll({"Urinary_Pro": value}); } }); Map newMap = Map.from(examData); if (examData["sugar"]?.isNotEmpty ?? false) { newMap.remove("sugar"); // 将"sugar"的值作为"Fasting_Glucose_Mmol"键的值添加到新的Map中 newMap["Fasting_Glucose_Mmol"] = examData["sugar"] ?? ''; } formValue.addAll(newMap); submitExamData(); ///MedicalController => submitDiagnosis =》 initRecordDataState =》deleteDirectory if (mounted) { setState(() {}); } } catch (err) { logger.e("健康检测数据回填错误:$err"); } } Future submitExamData() async { Map normalItems = {}; Map urinaryItems = {}; Map organsItems = {}; formValue.forEach((key, value) { if (key == "Urinary_Pro" || key == "Fasting_Glucose_Mmol") { urinaryItems[key] = value; } else if (key == "HEART") { organsItems[key] = value; } else { normalItems[key] = value; } }); if (urinaryItems.isNotEmpty) { await widget.callBack( //辅助检查 "FZJC", templateCode, jsonEncode(urinaryItems), false, ); } if (normalItems.isNotEmpty) { await widget.callBack( //一般状况 "ZZYBZK", templateCode, jsonEncode(normalItems), false, ); } if (organsItems.isNotEmpty) { await widget.callBack( //脏器及查体 "ZQCT", templateCode, jsonEncode(organsItems), false, ); } } Future submit(bool isManual) async { await widget.callBack( widget.cardKey, templateCode, jsonEncode(formValue), isManual, ); } Future initTemplate() async { try { Store.app.busy = true; await fetchTemplateIndex(); await fetchTemplate(widget.cardKey); await fetchTemplateData(); if (widget.cardKey == "ZQCT") { var isAllSelectZQCT = CalculatesWhetherTheSelectAllButtonIsSelected(); _isAllSelectZQCT = isAllSelectZQCT; if (widget.onAllSelectZQCTChange != null) { widget.onAllSelectZQCTChange!(isAllSelectZQCT); } } Store.app.busy = false; setState(() {}); } catch (e) { Store.app.busy = false; print(e.toString()); logger.e("模版错误:" + e.toString()); } } /// 读取健康检测的缓存 Future readCachedRecord(String currentDevice) async { if (widget.patientCode == null) { return null; } String? value = await _cachedRecordManager.readCachedRecord( currentDevice, widget.patientCode!, //诊疗展示 'ZLZS', ); return value; } /// 读取体检的缓存 Future readCachedCheck() async { if (widget.patientCode == null) { return null; } String? value = await _cachedRecordManager.readCachedRecord( widget.cardKey, widget.patientCode!, 'exam', ); return value; } Future readCached() async { for (var element in deviceList) { String? value = await readCachedRecord(element); if (value?.isNotEmpty ?? false) { deviceCached.addAll(jsonDecode(value!)); } } } Future fetchTemplateIndex() async { try { /// 获取模板的键值对 String? templates; templates = await _templateManager.readTemplateRelation( 'templateRelation', ); templateRelation = jsonDecode(templates!); } catch (error) { print('发生错误: $error'); logger.e("发生错误" + error.toString()); } } Future setExamData() async { if (widget.physicalExamNumber.isNotEmpty) { List? examList = await Get.find() .getExamListByPhysicalExamNumberAsync( physicalExamNumber: widget.physicalExamNumber, ); ExamDTO? currentExam = examList?.firstWhereOrNull( (element) => element.key == widget.cardKey, ); _currentExam = currentExam; } else if (widget.cardKey == "YZJSZABCXX") { PatientExtensionDTO? patientExtensionDTO = await Get.find() .getPatientExtensionDetailByCodeAndKey( widget.cardKey, widget.patientCode ?? '', ); if (patientExtensionDTO != null) { String extensionData = patientExtensionDTO.extensionData ?? ''; _currentExam = ExamDTO( code: patientExtensionDTO.code, patientCode: patientExtensionDTO.patientCode, examData: extensionData, key: patientExtensionDTO.key, ); } } } Future fetchTemplateData() async { await setExamData(); if (_currentExam?.examData != null) { formValue = jsonDecode(_currentExam?.examData ?? ''); } else if (widget.examData != null) { formValue = jsonDecode(widget.examData ?? ''); } else { return; } formValue.forEach( (key, value) { if (value is List) { formValue[key] = List.from(formValue[key]); } else if (value is List) { formValue[key] = List.from(formValue[key]); } }, ); } Future loadJsonFromAssets(String filePath) async { String jsonString = await rootBundle.loadString(filePath); return jsonString; } Future fetchTemplate(String key) async { try { // String? templateContent = ""; // String? template = ""; // if (key == "YZJSZABCXX") { // templateContent = // await loadJsonFromAssets('assets/严重精神障碍患者个人信息补充表.json'); // } // if (templateRelation[key] == null && templateContent.isNullOrEmpty) { if (templateRelation[key] == null) { logger.i( "ConfigurableCard - fetchTemplate Template not exist key: $key."); currentTemplate = []; setState(() {}); if (!FPlatform.isWindows) { return; } } // if (templateContent.isNullOrEmpty) // template = await _templateManager.readTemplate(templateRelation[key]!); // if (templateContent.isNullOrEmpty) // templateContent = String? template; if (templateRelation.containsKey(key)) { templateCode = templateRelation[key]!; template = await _templateManager.readTemplate(templateCode); } List> list = []; if (template == null) { var json = await loadJsonFromAssets('assets/templates/${key}.json'); list = jsonDecode(json)["Content"].cast>(); } else { var templateContent = TemplateDTO.fromJson(jsonDecode(template)).templateContent!; list = jsonDecode(templateContent).cast>(); } for (var i in list) { if (i['children'] != null) { List currentChildren = []; for (var j in i['children']) { currentChildren.add(FormObject.fromJson(j)); } i['children'] = currentChildren; } var item = FormObject.fromJson(i); currentTemplate.add(item); } } catch (error) { print('发生错误: $error'); logger.e("发生错误: fetchTemplate" + error.toString()); } } @override Widget build(BuildContext context) { return Scaffold( key: scaffoldKey, appBar: widget.cardKey == "YZJSZABCXX" ? VAppBar( titleText: "精神障碍患者补充表", actions: [ TextButton( onPressed: () { widget.callBack( widget.cardKey, templateRelation[widget.cardKey]!, jsonEncode(formValue), false, ); }, child: Text( "保存", style: TextStyle(fontSize: 24, color: Colors.white), ), ), ], ) : null, endDrawer: VDynamicDrawerWrapper(scaffoldKey: scaffoldKey), resizeToAvoidBottomInset: false, body: Column( children: [ Expanded( child: Stack( children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ // _buildDiagram(), _buildContent(), ], ), if (widget.cardKey == "ZQCT") Positioned( right: 30, bottom: 20, child: Container( width: 150, height: 50, child: Row( children: [ Switch( activeTrackColor: Colors.blueAccent, value: _isAllSelectZQCT, onChanged: (value) { _isAllSelectZQCT = !_isAllSelectZQCT; widget.onAllSelectZQCTChange!(value); for (var element in currentTemplate) { for (var child in element.children!) { if ([ "Vision_Left", "Vision_Right", "Vision_Corrective_Left", "Vision_Corrective_Right", "Heart_Rate", "Examination_Other", "Pedal_Artery", "Rectal_Touch", "Mammary", "Vulvar", "Vagina", "Cervical", "Uteri_Body", "Uteri_Adnexa", "Eye_Ground" ].contains(child.key)) { continue; } if (_isAllSelectZQCT) { if (child.key == "Dentition") { formValue[child.key!] = { 'status': [0], 'detail_a': [], 'detail_b': [], 'detail_c': [], }; } else if (child.type == "checkbox") { formValue[child.key!] = ["1"]; } else { formValue[child.key!] = "1"; } } else { formValue.remove(child.key); } } } setState(() {}); }), Text( '全选正常', style: TextStyle(fontSize: 18), ), ], ), ), ), ], ), ) ], ), ); } bool CalculatesWhetherTheSelectAllButtonIsSelected() { bool isAllSelect = true; for (var element in currentTemplate) { for (var child in element.children!) { if ([ "Vision_Left", "Vision_Right", "Vision_Corrective_Left", "Vision_Corrective_Right", "Heart_Rate", "Examination_Other", "Pedal_Artery", "Rectal_Touch", "Mammary", "Vulvar", "Vagina", "Cervical", "Uteri_Body", "Uteri_Adnexa", "Eye_Ground" ].contains(child.key)) { continue; } if (child.key == "Dentition") { dynamic dentitionValue = formValue[child.key!] ?? {}; Map currentValue = {}; if (!(dentitionValue is Map)) { currentValue = {}; isAllSelect = false; } else { currentValue = dentitionValue; } if (currentValue["status"][0] != 0) { isAllSelect = false; } } else { var currentValue = formValue[child.key!]; if (currentValue == null) { isAllSelect = false; } else { if (currentValue != "1") { isAllSelect = false; } } } if (!isAllSelect) { break; } } } return isAllSelect; } Widget buildSingleItem(Widget item, int span) { return FractionallySizedBox( widthFactor: span == 24 ? 1 : 0.5, child: item, ); } Widget buildWidget(FormObject? currentFormObject) { Map widgetMap = { 'checkbox': _buildCheckBox, 'numberInput': _buildNumberInput, 'input': _buildInput, 'radio': _buildRadio, 'radioScore': _buildRadioScore, 'bloodPressure': _buildBloodPressure, 'bodyTemperature': _buildBodyTemperature, 'weight': _buildBodyWeight, 'sugar': _buildBodySugar, 'bloodOxygen': _buildBloodOxygen, 'medicalHistory': _buildMedicalHistory, 'homecareBedHistor': _buildHomecareBedHistory, 'table': _buildMainMedicationHistory, 'inoculateHistory': _buildInoculateHistory, 'safetyPrecautions': _buildToxicSubstance, 'urinalys': _buildUrinalysis, "dentition": _buildDentition, "abnormal": _buildAbnormal, "riskFactorControl": _buildRiskFactorControl, 'ability_radio': _buildAbilityRadio, 'checkBoxFrequency': _buildCheckBoxFrequency, 'checkBoxIncludeOther': _buildCheckBoxIncludeOther, // 'inputHospitalizationTimes': _buildInputHospitalizationTimes, 'radioExtraDescription': _buildRadioExtraDescription, 'inputDiagnose': _buildInputDiagnose, 'radioInformedConsent': _buildRadioInformedConsent, 'date': _buildDate, 'checkbox_guidance': _buildGuidance, 'radioPreviousTreatment': _buildRadioPreviousTreatment, }; Widget Function(FormObject) builder = widgetMap[currentFormObject?.type] ?? _buildInput; return builder(currentFormObject!); } Widget flowCardList() { int itemCount = 0; List _cardList = []; bool currentTemplateOptionsIsNotEmpty = false; if (currentTemplate.isNotEmpty) { for (int i = 0; i < currentTemplate.length; i++) { itemCount = currentTemplate[i].children?.length ?? 0; currentTemplateOptionsIsNotEmpty = currentTemplate[i].options?.isNotEmpty ?? false; List items = List.generate(itemCount, (index) { FormObject? currentFormObject = currentTemplate[i].children?[index]; int span = currentFormObject?.span ?? 12; //父结构的options不等于空或null if (true) { //子结构的options若是无值则取父类的options值 if (currentTemplateOptionsIsNotEmpty) { currentFormObject!.options = currentTemplate[i].options; } } return buildSingleItem(buildWidget(currentFormObject), span); }); _cardList.addAll(items); } } return Scrollbar( thumbVisibility: true, controller: _examScrollController, child: SingleChildScrollView( controller: _examScrollController, child: Container( alignment: Alignment.topCenter, padding: const EdgeInsets.all(15), child: Wrap( runSpacing: 20, // 纵向元素间距 alignment: WrapAlignment.start, children: _cardList, ), ), ), ); } void _scrollListener() { if (mounted) { if (_examScrollController.position.pixels == _examScrollController.position.maxScrollExtent) { // 滚动到底部 _onScrollEnd(); } } } void _onScrollEnd() { // 在这里触发您想要执行的方法 print('Scroll to the bottom!'); // widget.onChangeCurrentKeyEvent?.emit(this, true); } /// 主页面 Widget _buildContent() { return Expanded( flex: 2, child: flowCardList(), ); } /// 指导模块 Widget _buildGuidance(FormObject currentFormObject) { List