Browse Source

1、优化血压逻辑

guanxinyi 1 year ago
parent
commit
4929425d6a

+ 11 - 0
lib/pages/mappers/nibp.dart

@@ -0,0 +1,11 @@
+import 'package:vnote_device_plugin/models/exams/nibp.dart';
+
+class NibpExamDataMapper {
+  static Map<String, dynamic> convertNibpExamDataToMap(NibpExamValue data) {
+    return {
+      'Sbp': data.systolicPressure,
+      'Pulse_Beat': data.pulse,
+      'Dbp': data.diastolicPressure,
+    };
+  }
+}

+ 17 - 11
lib/pages/medical/view.dart

@@ -18,19 +18,25 @@ class MedicalPage extends GetView<MedicalController> {
 
   @override
   Widget build(BuildContext context) {
-    return Scaffold(
-      resizeToAvoidBottomInset: false,
-      body: Column(
-        children: [
-          Expanded(
-              child: Stack(
+    return GetBuilder<MedicalController>(
+      init: MedicalController(),
+      id: "ecg_view",
+      builder: (_) {
+        return Scaffold(
+          resizeToAvoidBottomInset: false,
+          body: Column(
             children: [
-              _buildMedical(),
-              // _buildGenerateReport(),
+              Expanded(
+                  child: Stack(
+                children: [
+                  _buildMedical(),
+                  // _buildGenerateReport(),
+                ],
+              )),
             ],
-          )),
-        ],
-      ),
+          ),
+        );
+      },
     );
   }
 

+ 94 - 60
lib/pages/medical/widgets/blood_pressure.dart

@@ -3,6 +3,7 @@ import 'dart:convert';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:get/get.dart';
+import 'package:vitalapp/components/dialog_number.dart';
 import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
 import 'package:vnote_device_plugin/consts/types.dart';
 import 'package:vnote_device_plugin/devices/nibp.dart';
@@ -187,12 +188,15 @@ class _ExamBloodPressureState extends State<BloodPressure> {
   NibpDeviceWorker? worker;
   int liveValue = 0;
   int errorCount = 0; //设备重连失败次数
-  late NibpExamValue? value = NibpExamValue(
-      diastolicPressure: controller.diagnosisDataValue['NIBP']?['Sbp'],
-      // int.parse(controller.diagnosisDataValue['NIBP']?['Sbp'] ?? '0'),
-      systolicPressure: controller.diagnosisDataValue['NIBP']?['Dbp'],
-      // int.parse(controller.diagnosisDataValue['NIBP']?['Dbp'] ?? '0'),
-      pulse: 0);
+  // late NibpExamValue? value = NibpExamValue(
+  //   diastolicPressure: int.parse(
+  //     controller.diagnosisDataValue['NIBP']?['Sbp']?.toString() ?? '',
+  //   ),
+  //   systolicPressure: int.parse(
+  //     controller.diagnosisDataValue['NIBP']?['Dbp']?.toString() ?? '',
+  //   ),
+  //   pulse: 0,
+  // );
 
   WorkerStatus _connectStatus = WorkerStatus.connecting;
   @override
@@ -256,27 +260,13 @@ class _ExamBloodPressureState extends State<BloodPressure> {
   /// TODO 需求不清,检测的数据需要传给体检,但是检测又不区分左右侧血压
   void _onSuccess(_, NibpExamValue e) {
     setState(() {
-      value = e;
-
       /// 这是第三方需要的数据
       controller.diagnosisDataValue['NIBP'] = {
-        'Sbp': value?.diastolicPressure ?? '0',
-        'Dbp': value?.systolicPressure ?? '0',
-        'Pulse_Beat': value?.pulse,
+        'Sbp': e.systolicPressure.toString(),
+        'Dbp': e.diastolicPressure.toString(),
+        'Pulse_Beat': e.pulse.toString(),
       };
       controller.saveCachedRecord();
-      // /// 这是我们需要的数据
-      // if (pressureStatus == PressureStatus.left) {
-      //   controller.diagnosisDataValue['NIBP']['Sbp_Left'] =
-      //       value?.diastolicPressure ?? '0';
-      //   controller.diagnosisDataValue['NIBP']['Dbp_Left'] =
-      //       value?.diastolicPressure ?? '0';
-      // } else {
-      //   controller.diagnosisDataValue['NIBP']['Sbp_Right'] =
-      //       value?.diastolicPressure ?? '0';
-      //   controller.diagnosisDataValue['NIBP']['Dbp_Right'] =
-      //       value?.diastolicPressure ?? '0';
-      // }
     });
   }
 
@@ -321,42 +311,86 @@ class _ExamBloodPressureState extends State<BloodPressure> {
     return Stack(
       children: [
         ExamCard(
-          clickCard: () async {
-            String? result = await VDialogBloodPressure(
-              title: pressureStatus == PressureStatus.left ? '左侧血压' : '右侧血压',
-              initialValue: [
-                controller.diagnosisDataValue['NIBP']?['Sbp'] ?? '',
-                controller.diagnosisDataValue['NIBP']?['Dbp'] ?? '',
-              ],
-            ).show();
-            if (result != null) {
-              controller.diagnosisDataValue['NIBP'] = {
-                'Sbp': jsonDecode(result)?.first,
-                'Dbp': jsonDecode(result)?.last,
-                'Pulse_Beat': '70',
-              };
-              print(result);
-              value = NibpExamValue(
-                diastolicPressure: int.parse(jsonDecode(result)?.first),
-                pulse: 70,
-                systolicPressure: int.parse(jsonDecode(result)?.last),
-              );
-              controller.saveCachedRecord();
-              print(value);
-              // value.diastolicPressure = jsonDecode(result)?.first;
-              // systolicPressure: jsonDecode(result)?.last ?? 0,
-
-              // print(value?.diastolicPressure);
-            }
-
-            setState(() {});
-          },
           title: '血压',
           content: Container(
             padding: const EdgeInsets.only(top: 50),
-            child: _SideBar(
-              value: _buildValue(),
-              unit: 'mmHg',
+            child: Column(
+              children: [
+                InkWell(
+                  child: _SideBar(
+                    value: _buildValue(),
+                    unit: 'mmHg',
+                  ),
+                  onTap: () async {
+                    String? result = await VDialogBloodPressure(
+                      title: '血压',
+                      initialValue: [
+                        controller.diagnosisDataValue['NIBP']?['Sbp']
+                                .toString() ??
+                            '',
+                        controller.diagnosisDataValue['NIBP']?['Dbp']
+                                .toString() ??
+                            '',
+                      ],
+                    ).show();
+                    if (result != null &&
+                        jsonDecode(result)?.first != '' &&
+                        jsonDecode(result)?.last != '') {
+                      controller.diagnosisDataValue['NIBP'] = {
+                        'Sbp': jsonDecode(result)?.first,
+                        'Dbp': jsonDecode(result)?.last,
+                        'Pulse_Beat': '',
+                      };
+                      print(result);
+
+                      controller.saveCachedRecord();
+                    }
+
+                    setState(() {});
+                  },
+                ),
+                InkWell(
+                  onTap: () async {
+                    String? result = await VDialogNumber(
+                      title: '脉率',
+                      initialValue: controller.diagnosisDataValue['NIBP']
+                              ?['Pulse_Beat'] ??
+                          '',
+                    ).show();
+                    if (result != null && result.isNotEmpty) {
+                      controller.diagnosisDataValue['NIBP'] = {
+                        'Sbp': controller.diagnosisDataValue['NIBP']['Sbp'],
+                        'Dbp': controller.diagnosisDataValue['NIBP']['Dbp'],
+                        'Pulse_Beat': result
+                      };
+
+                      controller.saveCachedRecord();
+                    }
+
+                    setState(() {});
+                  },
+                  child: Container(
+                    padding: const EdgeInsets.symmetric(horizontal: 28),
+                    child: Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        const Text(
+                          '脉率',
+                          style: TextStyle(fontSize: 25),
+                        ),
+                        Text(
+                          controller.diagnosisDataValue['NIBP']?['Pulse_Beat']
+                                  .toString() ??
+                              '',
+                          style: const TextStyle(
+                            fontSize: 48,
+                          ),
+                        )
+                      ],
+                    ),
+                  ),
+                )
+              ],
             ),
           ),
         ),
@@ -452,16 +486,16 @@ class _ExamBloodPressureState extends State<BloodPressure> {
           crossAxisAlignment: CrossAxisAlignment.center,
           children: [
             Align(
-              alignment: Alignment.centerLeft,
+              alignment: Alignment.centerRight,
               child: Text(
-                value!.systolicPressure.toString(),
+                controller.diagnosisDataValue['NIBP']['Sbp'],
                 style: textStyle,
               ),
             ),
             Align(
-              alignment: Alignment.centerRight,
+              alignment: Alignment.centerLeft,
               child: Text(
-                value!.diastolicPressure.toString(),
+                controller.diagnosisDataValue['NIBP']['Dbp'],
                 style: textStyle,
               ),
             ),

+ 1 - 1
lib/pages/medical/widgets/ecg_view/controller.dart

@@ -153,7 +153,7 @@ class EcgViewController extends GetxController {
   /// 将字节数组转换为base64
   String _convertToBase64Url(Uint8List imageData) {
     String base64Image = base64Encode(imageData);
-    String base64Url = 'data:image/png;base64,$base64Image';
+    String base64Url = base64Image;
     return base64Url;
   }
 

+ 142 - 67
lib/pages/medical/widgets/heart_rate.dart

@@ -6,6 +6,7 @@ import 'package:get/get.dart';
 import 'package:vitalapp/managers/interfaces/models/device.dart';
 import 'package:vitalapp/pages/medical/controllers/heart.dart';
 import 'package:vitalapp/pages/medical/widgets/device_status.dart';
+import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
 import 'package:vitalapp/pages/medical/widgets/ecg_view/index.dart';
 import 'package:vnote_device_plugin/consts/types.dart';
 import 'package:vnote_device_plugin/devices/heart.dart';
@@ -35,10 +36,11 @@ class _HeartRateState extends State<HeartRate> {
 
   WorkerStatus _connectStatus = WorkerStatus.connecting;
   List<int> ecgPoint = [];
+  int errorCount = 0; //设备重连失败次数
 
-  late String _heart = controller.diagnosisDataValue['Heart']?['HEART'] ?? '';
-  late final String _assess =
-      controller.diagnosisDataValue['Heart']?['ASSESS'] ?? '';
+  late String _heart =
+      controller.diagnosisDataValue['Heart']?['HEART'].toString() ?? '';
+  late String _assess = controller.diagnosisDataValue['Heart']?['ASSESS'] ?? '';
   late final String _ecg = controller.diagnosisDataValue['Heart']?['ECG'] ?? '';
   late final String _ecgPoint =
       controller.diagnosisDataValue['Heart']?['ECG_POINT'] ?? '';
@@ -68,6 +70,7 @@ class _HeartRateState extends State<HeartRate> {
     worker.hrValueUpdateEvent.removeListener(_onHrValueUpdate);
     worker.ecgValueUpdateEvent.removeListener(_onEcgValueUpdate);
     worker.resultReceivedEvent.removeListener(_onRCesultReceived);
+    worker.errorEvent.removeListener(_onError);
   }
 
   @override
@@ -84,6 +87,7 @@ class _HeartRateState extends State<HeartRate> {
     worker.hrValueUpdateEvent.addListener(_onHrValueUpdate);
     worker.ecgValueUpdateEvent.addListener(_onEcgValueUpdate);
     worker.resultReceivedEvent.addListener(_onRCesultReceived);
+    worker.errorEvent.addListener(_onError);
     worker.connect();
   }
 
@@ -127,16 +131,35 @@ class _HeartRateState extends State<HeartRate> {
     });
   }
 
+  void _onError(_, String e) {
+    _assess = e;
+    ecgPoint = [];
+    try {
+      EcgViewController ecgViewController = Get.find<EcgViewController>();
+      ecgPoint = [];
+      ecgViewController.reset();
+    } catch (e) {}
+    setState(() {});
+  }
+
   void _onRCesultReceived(_, HeartExamResult e) {
     setState(() async {
       print(ecgPoint.toString());
       // _heart = e.toString();
+      _assess = e.analysis.first;
       controller.diagnosisDataValue['Heart']?['HEART'] = e.heartRate;
       controller.diagnosisDataValue['Heart']?['ASSESS'] = e.analysis.first;
-      controller.diagnosisDataValue['Heart']?['ECG'] =
-          await createEcgImageBase64(ecgPoint);
-      controller.diagnosisDataValue['Heart']?['ECG_POINT'] =
-          ecgPoint.toString();
+
+      try {
+        EcgViewController ecgViewController = Get.find<EcgViewController>();
+        controller.diagnosisDataValue['Heart']?['ECG_POINT'] =
+            ecgViewController.allPoints.toString();
+        controller.diagnosisDataValue['Heart']?['ECG'] =
+            await ecgViewController.getFullDataImageBase64();
+      } catch (e) {
+        print(e);
+      }
+      controller.saveCachedRecord();
       print(controller.diagnosisDataValue);
       // late final String _assess =
       //     controller.diagnosisDataValue['Heart']?['ASSESS'] ?? '';
@@ -167,18 +190,30 @@ class _HeartRateState extends State<HeartRate> {
 
   void _onConnectFail(sender, e) {
     print('连接设备失败');
-    _connectStatus = WorkerStatus.connectionFailed;
-    setState(() {});
-  }
 
-  void _onConnectSuccess(sender, e) {
-    _connectStatus = WorkerStatus.connected;
-    setState(() {});
+    if (errorCount < 3) {
+      worker.connect();
+    }
+    setState(() {
+      errorCount++;
+      _connectStatus = WorkerStatus.connectionFailed;
+    });
   }
 
   void _onDisconnected(sender, e) {
     print('设备连接中断');
-    _connectStatus = WorkerStatus.disconnected;
+
+    if (errorCount < 3) {
+      worker.connect();
+    }
+    setState(() {
+      errorCount++;
+      _connectStatus = WorkerStatus.disconnected;
+    });
+  }
+
+  void _onConnectSuccess(sender, e) {
+    _connectStatus = WorkerStatus.connected;
     setState(() {});
   }
 
@@ -220,60 +255,100 @@ class _HeartRateState extends State<HeartRate> {
     return base64Image;
   }
 
+  /// 需要封装一下
+  Widget _buildErrorButton() {
+    return DeviceStatusPosition(
+      deviceStatus: Row(
+        children: [
+          const Text(
+            '请确认设备是否启动',
+            style: TextStyle(fontSize: 24, color: Colors.red),
+          ),
+          const SizedBox(
+            width: 8,
+          ),
+          IconButton(
+            onPressed: () {
+              worker.connect();
+              setState(() {
+                _connectStatus = WorkerStatus.connecting;
+                errorCount = 0;
+              });
+            },
+            icon: const Icon(Icons.refresh),
+            iconSize: 32,
+          ),
+          const SizedBox(
+            width: 32,
+          ),
+        ],
+      ),
+    );
+  }
+
   @override
   Widget build(BuildContext context) {
-    return ExamCard(
-        titleText: const SizedBox(),
-        // clickCard: () {},
-        content: Column(
-          mainAxisAlignment: MainAxisAlignment.start,
-          children: [
-            Padding(
-                padding: const EdgeInsets.all(10),
-                child: DeviceStatus(connectStatus: _connectStatus)),
-            SideBar(
-              title: '心率',
-              value: _heart.isEmpty ? '--' : _heart,
-              unit: '',
-            ),
-            SizedBox(
-              height: 240,
-              child: LayoutBuilder(builder: (context, constraints) {
-                print(constraints.maxWidth);
-                print(constraints.maxHeight);
-                return EcgView(
-                  width: constraints.maxWidth,
-                  height: constraints.maxHeight,
-                );
-              }),
-            )
-            // CustomPaint(
-            //   painter: GridCanvasPainter(),
-            //   child: EcgPage(
-            //     points: ecgPoint,
-            //   ),
-            // ),
-            // const Divider(indent: 30),
-            // Stack(
-            //   children: [
-            //     SideBar(
-            //       title: '心率评估',
-            //       value: _assess.isEmpty ? '--' : _assess,
-            //       hasDevice: true,
-            //       unit: '',
-            //     ),
-            //     // DeviceStatus(connectStatus: _connectStatus),
-            //   ],
-            // ),
-            // const Divider(indent: 30),
-            // MyWidget()
-            // const EcgPage(),
-            // SideBar(
-            //   title: '心电图',
-            //   value: _assess.isEmpty ? '--' : _assess,
-            //   unit: '',
-            // ),
-          ],
-        ));
+    return Stack(
+      children: [
+        ExamCard(
+            titleText: const SizedBox(),
+            // clickCard: () {},
+            content: Column(
+              mainAxisAlignment: MainAxisAlignment.start,
+              children: [
+                SideBar(
+                  title: '心率',
+                  value: _heart.isEmpty ? '--' : _heart,
+                  unit: '',
+                ),
+                if (_assess.isNotEmpty)
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    crossAxisAlignment: CrossAxisAlignment.start,
+                    children: [
+                      Container(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 30,
+                        ),
+                        child: const Text(
+                          '心率评估',
+                          style: TextStyle(
+                            fontSize: 25,
+                          ),
+                        ),
+                      ),
+                      Container(
+                        padding: const EdgeInsets.symmetric(
+                          horizontal: 50,
+                        ),
+                        child: Text(
+                          _assess,
+                          style: const TextStyle(
+                            fontSize: 24,
+                          ),
+                        ),
+                      ),
+                    ],
+                  ),
+                SizedBox(
+                  height: 240,
+                  child: LayoutBuilder(builder: (context, constraints) {
+                    print(constraints.maxWidth);
+                    print(constraints.maxHeight);
+                    return EcgView(
+                      width: constraints.maxWidth,
+                      height: constraints.maxHeight,
+                    );
+                  }),
+                )
+              ],
+            )),
+        if (errorCount < 3)
+          DeviceStatusPosition(
+            deviceStatus: DeviceStatus(connectStatus: _connectStatus),
+          ),
+        if (errorCount >= 3) _buildErrorButton(),
+      ],
+    );
   }
 }

+ 3 - 5
lib/pages/patient/list/controller.dart

@@ -22,15 +22,13 @@ class PatientListController extends FControllerBase {
   /// 前进到详情页
   Future<void> gotoDetail(String code) async {
     _homeController.updateMenus();
-    _homeController.currentIndex = -1;
 
     PatientDTO? patientInfoDto = await _patientManager.getDetail(code);
     Store.user.currentSelectPatientInfo = patientInfoDto;
     Get.back();
-    Get.find<PatientDetailController>().loadData();
-    Get.find<MedicalController>().initData();
-    // _homeController.switchNavByName('/')
-    _homeController.currentIndex = 0;
+
+    await Get.find<PatientDetailController>().loadData();
+    await Get.find<MedicalController>().initData();
   }
 
   /// 新建档案

+ 1 - 2
lib/routes/routes.dart

@@ -11,7 +11,6 @@ import 'package:vitalapp/pages/check/follow_up_record/controller.dart';
 import 'package:vitalapp/pages/check/follow_up_record/view.dart';
 import 'package:vitalapp/pages/home/personal_center/controller.dart';
 import 'package:vitalapp/pages/home/personal_center/view.dart';
-import 'package:vitalapp/pages/medical/controller.dart';
 import 'package:vitalapp/pages/medical/records/controller.dart';
 import 'package:vitalapp/pages/medical/records/view.dart';
 import 'package:vitalapp/pages/medical/view.dart';
@@ -326,7 +325,7 @@ class Routes {
       () => const MedicalPage(),
       binding: BindingsBuilder(
         () {
-          Get.put(MedicalController());
+          // Get.put(MedicalController());
           Get.put(PatientDetailController());
         },
       ),