Browse Source

1、血常规和生化的页面提交

guanxinyi 1 year ago
parent
commit
d9ada6d11b

+ 19 - 0
lib/managers/interfaces/registration.dart

@@ -29,4 +29,23 @@ abstract class IRegistrationManager implements IManager {
   Future<List<ReportDTO2>?> getVitalReportInfoAsync({
     required String physicalExamNumber,
   });
+
+  ///
+  Future<ElectrocardiogramRecord?> getElectrocardiogramRecordAsync({
+    required String physicalExamNumber,
+  });
+
+  ///
+  Future<PageCollection<ElectrocardiogramRecord>?>
+      getElectrocardiogramRecordPageAsync({
+    int? pageSize = 10,
+    int? pageIndex = 1,
+    String? keyword,
+  });
+
+  ///
+  Future<ElectrocardiogramRecord?>
+      getElectrocardiogramRecordByPhysicalExamNumberAsync({
+    required String physicalExamNumber,
+  });
 }

+ 68 - 0
lib/managers/registration.dart

@@ -106,4 +106,72 @@ class RegistrationManager implements IRegistrationManager {
       return null;
     }
   }
+
+  @override
+  Future<ElectrocardiogramRecord?> getElectrocardiogramRecordAsync({
+    required String physicalExamNumber,
+  }) async {
+    try {
+      var request = GetElectrocardiogramRecordRequest();
+      // request.token = Store.user.token;
+      // request.physicalExamNumber = physicalExamNumber;
+      final examList =
+          await rpc.vitalElectrocardiogram.getElectrocardiogramRecordAsync(
+        request,
+      );
+      return examList;
+    } catch (e) {
+      logger.e(
+          "RegistrationManager sync getElectrocardiogramRecordAsync error.", e);
+      return null;
+    }
+  }
+
+  @override
+  Future<ElectrocardiogramRecord?>
+      getElectrocardiogramRecordByPhysicalExamNumberAsync({
+    required String physicalExamNumber,
+  }) async {
+    try {
+      var request = GetElectrocardiogramRecordByPhysicalExamNumberRequest();
+      request.physicalExamNumber = physicalExamNumber;
+      final examList = await rpc.vitalElectrocardiogram
+          .getElectrocardiogramRecordByPhysicalExamNumberAsync(
+        request,
+      );
+      return examList;
+    } catch (e) {
+      logger.e(
+          "RegistrationManager sync getElectrocardiogramRecordByPhysicalExamNumberAsync error.",
+          e);
+      return null;
+    }
+  }
+
+  @override
+  Future<PageCollection<ElectrocardiogramRecord>?>
+      getElectrocardiogramRecordPageAsync({
+    int? pageSize = 10,
+    int? pageIndex = 1,
+    String? keyword,
+  }) async {
+    try {
+      var request = ElectrocardiogramRecordPageRequest(
+        pageSize: pageSize!,
+        pageIndex: pageIndex!,
+        keyWord: keyword,
+      );
+      request.token = Store.user.token;
+      final electrocardiogramRecordList =
+          await rpc.vitalElectrocardiogram.getElectrocardiogramRecordPageAsync(
+        request,
+      );
+      return electrocardiogramRecordList;
+    } catch (e) {
+      logger.e(
+          "RegistrationManager sync getElectrocardiogramRecordPageAsync error.",
+          e);
+      return null;
+    }
+  }
 }

+ 4 - 0
lib/pages/medical/views/biochemistry_check.dart

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:vitalapp/pages/medical/views/table_input_dialog/mock_data.dart';
 import 'package:vitalapp/pages/medical/views/table_input_dialog/view.dart';
 import 'package:vitalapp/pages/medical/widgets/health_check/view.dart';
+import 'package:vitalapp/store/store.dart';
 
 /// 生化
 class BiochemistryCheck extends StatelessWidget {
@@ -18,6 +19,9 @@ class BiochemistryCheck extends StatelessWidget {
           checkDialog: TableInputDialog(
             tableDataConfig: MockData.mockBiochemistryTestData,
             title: '检验科-生化数据',
+            physicalExamNumber:
+                Store.user.currentSelectRegisterPersonInfo?.physicalExamNumber,
+            keyValue: "HEIBiochemical",
           ),
           checkKey: "HEIBiochemical",
         ),

+ 31 - 0
lib/pages/medical/views/blood_check.dart

@@ -0,0 +1,31 @@
+import 'package:flutter/material.dart';
+import 'package:vitalapp/pages/medical/views/table_input_dialog/mock_data.dart';
+import 'package:vitalapp/pages/medical/views/table_input_dialog/view.dart';
+import 'package:vitalapp/pages/medical/widgets/health_check/view.dart';
+import 'package:vitalapp/store/store.dart';
+
+/// 生化
+class BloodCheck extends StatelessWidget {
+  BloodCheck({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      resizeToAvoidBottomInset: false,
+      body: Container(
+        height: double.maxFinite,
+        color: Colors.white,
+        child: HealthCheck(
+          checkDialog: TableInputDialog(
+            tableDataConfig: MockData.mockBloodRoutineTestData,
+            title: '检验科-血常规数据',
+            physicalExamNumber:
+                Store.user.currentSelectRegisterPersonInfo?.physicalExamNumber,
+            keyValue: "HEIBloodRoutine",
+          ),
+          checkKey: "HEIBloodRoutine",
+        ),
+      ),
+    );
+  }
+}

+ 162 - 0
lib/pages/medical/views/heart_check_new.dart

@@ -0,0 +1,162 @@
+/// 领导展示(后面要删,莫名其妙的一堆演示)
+
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:vitalapp/architecture/utils/advance_debounce.dart';
+import 'package:vitalapp/components/appbar.dart';
+import 'package:vitalapp/pages/medical/widgets/health_check/view.dart';
+import 'package:vitalapp/pages/medical/widgets/twelve_ecg.dart';
+import 'package:vnote_device_plugin/consts/types.dart';
+import 'package:vitalapp/pages/medical/controller.dart';
+import 'package:vitalapp/store/store.dart';
+
+class HeartCheckNew extends GetView<MedicalController> {
+  const HeartCheckNew({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      resizeToAvoidBottomInset: false,
+      body: Container(
+        height: double.maxFinite,
+        color: Colors.white,
+        child: HealthCheck(
+          checkDialog: _buildMedical(),
+          checkKey: "HEIECG",
+        ),
+      ),
+    );
+  }
+
+  Widget _buildMedical() {
+    return Scaffold(
+      appBar: VAppBar(
+        titleText: "体检心电",
+      ),
+      body: Container(
+        color: Colors.white,
+        child: Stack(
+          children: [
+            Row(
+              children: [
+                _buildDeviceImage(DeviceTypes.TWELVEHEART),
+                _buildMedicalInput(DeviceTypes.TWELVEHEART),
+              ],
+            ),
+            Positioned(
+              right: 16,
+              bottom: 16,
+              child: _buildSaveButton(),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildMedicalInput(String? currentTab) {
+    return Expanded(
+      flex: currentTab == DeviceTypes.TWELVEHEART ? 18 : 11,
+      child: Stack(
+        children: [
+          Container(
+            padding: const EdgeInsets.all(16),
+            child: Column(
+              children: [
+                _buildContent(),
+              ],
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  String _deviceImageUrl(String? currentTab) {
+    switch (currentTab) {
+      case DeviceTypes.TEMP:
+        return 'assets/images/healthCheck/temp.png';
+      case DeviceTypes.SUGAR:
+        return 'assets/images/healthCheck/sugar.png';
+      case DeviceTypes.NIBP:
+        return 'assets/images/healthCheck/nibp.png';
+      case DeviceTypes.SPO2:
+        return 'assets/images/healthCheck/spo2.png';
+      case DeviceTypes.WEIGHT:
+        return 'assets/images/healthCheck/bmi.png';
+      case DeviceTypes.URINE:
+        return 'assets/images/healthCheck/urine.png';
+      case DeviceTypes.WAIST:
+        return 'assets/images/healthCheck/whb.png';
+      default:
+        return 'assets/images/exam/normalMeasurementChart.png';
+    }
+  }
+
+  Widget _buildDeviceImage(String? currentTab) {
+    if (currentTab == DeviceTypes.TWELVEHEART) {
+      return const SizedBox();
+    }
+    return Expanded(
+      flex: 7,
+      child: Container(
+        alignment: Alignment.topCenter,
+        margin: const EdgeInsets.all(16).copyWith(top: 10),
+        child: Obx(
+          () => ClipRect(
+            child: Align(
+              alignment: Alignment.bottomCenter,
+              heightFactor: 0.8,
+              child: controller.state.currentTab != null
+                  ? Image.asset(
+                      _deviceImageUrl(controller.state.currentTab),
+                      height: double.infinity,
+                      fit: BoxFit.contain, // 设置图像的适应方式
+                    )
+                  : Container(),
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+
+  Widget _buildSaveButton() {
+    return Obx(() {
+      if (Store.user.currentSelectRegisterPersonInfo == null) {
+        return const SizedBox();
+      }
+      return FloatingActionButton.extended(
+        // backgroundColor: Theme.of(context).primaryColor,
+        onPressed: () {
+          advanceDebounce(
+            () => controller.createCheckup(
+              Store.user.currentSelectRegisterPersonInfo?.physicalExamNumber ??
+                  '',
+              'HEIECG',
+            ),
+            "createCheckup",
+            1500,
+          );
+        },
+        label: const SizedBox(
+          width: 240,
+          height: 60,
+          child: Center(
+            child: Text(
+              '提交',
+              style: TextStyle(
+                fontSize: 26,
+                color: Colors.white,
+              ),
+            ),
+          ),
+        ),
+      );
+    });
+  }
+
+  Widget _buildContent() {
+    return const TwelveHeartRate();
+  }
+}

+ 35 - 26
lib/pages/medical/views/table_input_dialog/controller.dart

@@ -1,6 +1,10 @@
+import 'dart:convert';
+
+import 'package:fis_jsonrpc/rpc.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:vitalapp/managers/interfaces/exam.dart';
+import 'package:vitalapp/store/store.dart';
 
 class TableInputDialogController extends GetxController {
   TableInputDialogController({
@@ -12,7 +16,10 @@ class TableInputDialogController extends GetxController {
 
   final List<TableElementData> tableData = [];
 
-  void onConfirm() {
+  Future<void> onConfirm(
+    String? physicalExamNumber,
+    String? keyValue,
+  ) async {
     final result = <String, String>{};
     tableData.forEach((element) {
       String vlaue = element.textController.text;
@@ -21,33 +28,35 @@ class TableInputDialogController extends GetxController {
       }
       result[element.config.id] = vlaue;
     });
-    // createCheckup();
-    Get.back(result: TableInputResult(data: result));
+    await createCheckup(physicalExamNumber, keyValue, result);
+    // Get.back(result: TableInputResult(data: result));
   }
 
-  // ///  体检  检查提交
-  // Future<void> createCheckup(
-  //   String? physicalExamNumber,
-  //   String? keyValue,
-  // ) async {
-  //   Map<String, dynamic> input = diagnosisDataValue;
-  //   Map<String, dynamic> output = {};
-
-  //   input.forEach((key, value) {
-  //     value.forEach((innerKey, innerValue) {
-  //       output[innerKey] = innerValue;
-  //     });
-  //   });
-  //   var result = await _examManager.createExam(CreateExamRequest(
-  //     key: keyValue ?? "HEIBasic",
-  //     examData: jsonEncode(output),
-  //     physicalExamNumber: physicalExamNumber,
-  //   ));
-  //   if (result == true) {
-  //     Get.back();
-  //   }
-  //   print(result);
-  // }
+  ///  体检  检查提交
+  Future<void> createCheckup(
+    String? physicalExamNumber,
+    String? keyValue,
+    Map<String, dynamic> diagnosisDataValue,
+  ) async {
+    // Map<String, dynamic> input = diagnosisDataValue;
+    // Map<String, dynamic> output = {};
+
+    // input.forEach((key, value) {
+    //   value.forEach((innerKey, innerValue) {
+    //     output[innerKey] = innerValue;
+    //   });
+    // });
+    var result = await _examManager.createExam(CreateExamRequest(
+      key: keyValue ?? "HEIBasic",
+      examData: jsonEncode(diagnosisDataValue),
+      physicalExamNumber:
+          Store.user.currentSelectRegisterPersonInfo?.physicalExamNumber,
+    ));
+    if (result == true) {
+      Get.back();
+    }
+    print(result);
+  }
 
   void focusPre() {
     int index = getCurrFocusIndex();

+ 33 - 33
lib/pages/medical/views/table_input_dialog/mock_data.dart

@@ -4,72 +4,72 @@ class MockData {
   // 生化检查数据
   static List<TableElementConfig> mockBiochemistryTestData = [
     TableElementConfig(
-      id: "0",
+      id: "Liver_Alt",
       name: "血清谷丙转氨酶",
       unit: "U/L",
     ),
     TableElementConfig(
-      id: "1",
+      id: "Liver_Ast",
       name: "血清谷草转氨酶",
       unit: "U/L",
     ),
     TableElementConfig(
-      id: "2",
+      id: "Liver_Tbil",
       name: "总胆红素",
       unit: "umol/L",
     ),
     TableElementConfig(
-      id: "3",
+      id: "Liver_Alb",
       name: "白蛋白",
       unit: "g/L",
     ),
     TableElementConfig(
-      id: "4",
+      id: "Liver_Dbil",
       name: "结合胆红素",
       unit: "umol/L",
     ),
     TableElementConfig(
-      id: "5",
+      id: "Renal_Cr",
       name: "肌酐",
       unit: "umol/L",
     ),
     TableElementConfig(
-      id: "6",
+      id: "Renal_Bun",
       name: "尿素氮",
       unit: "mmol/L",
     ),
     TableElementConfig(
-      id: "7",
+      id: "Renal_Spc",
       name: "血钾浓度",
       unit: "mmol/L",
     ),
     TableElementConfig(
-      id: "8",
+      id: "Renal_Ssc",
       name: "血钠浓度",
       unit: "mmol/L",
     ),
     TableElementConfig(
-      id: "9",
+      id: "Lipid_Cho",
       name: "总胆固醇",
-      unit: "mmol/L",
+      unit: "umol/L",
     ),
     TableElementConfig(
-      id: "10",
+      id: "Lipid_Tg",
       name: "甘油三酯",
       unit: "mmol/L",
     ),
     TableElementConfig(
-      id: "11",
+      id: "Lipid_Ldl",
       name: "血清低密度脂蛋白胆固醇",
       unit: "mmol/L",
     ),
     TableElementConfig(
-      id: "12",
+      id: "Lipid_Hdl",
       name: "血清高密度脂蛋白胆固醇",
       unit: "mmol/L",
     ),
     TableElementConfig(
-      id: "13",
+      id: "GLU",
       name: "葡萄糖",
       unit: "mmol/L",
     ),
@@ -78,92 +78,92 @@ class MockData {
   // 血常规数据
   static List<TableElementConfig> mockBloodRoutineTestData = [
     TableElementConfig(
-      id: "0",
+      id: "Blood_Hgb",
       name: "血红蛋白",
       unit: "g/L",
     ),
     TableElementConfig(
-      id: "1",
+      id: "Blood_Wbc",
       name: "白细胞",
       unit: "10^9/L",
     ),
     TableElementConfig(
-      id: "2",
+      id: "Blood_Rlt",
       name: "血小板",
       unit: "10^9/L",
     ),
     TableElementConfig(
-      id: "3",
+      id: "Blood_Lymphocyte",
       name: "淋巴细胞",
       unit: "%",
     ),
     TableElementConfig(
-      id: "4",
+      id: "Blood_Neutrophils",
       name: "中性粒细胞",
       unit: "%",
     ),
     TableElementConfig(
-      id: "5",
+      id: "Blood_Monocyte",
       name: "单核细胞",
       unit: "%",
     ),
     TableElementConfig(
-      id: "6",
+      id: "Blood_LymphocyteRatio",
       name: "淋巴细胞比率",
       unit: "%",
     ),
     TableElementConfig(
-      id: "7",
+      id: "Blood_NeutrophilRatio",
       name: "中性粒细胞比率",
       unit: "%",
     ),
     TableElementConfig(
-      id: "8",
+      id: "Blood_MonocyteRatio",
       name: "单核细胞比率",
       unit: "%",
     ),
     TableElementConfig(
-      id: "9",
+      id: "BLD",
       name: "红细胞",
       unit: "10^12/L",
     ),
     TableElementConfig(
-      id: "10",
+      id: "Blood_Mch",
       name: "平均血红蛋白量",
       unit: "pg",
     ),
     TableElementConfig(
-      id: "11",
+      id: "Blood_McV",
       name: "红细胞平均体积",
       unit: "fL",
     ),
     TableElementConfig(
-      id: "12",
+      id: "Blood_Mchc",
       name: "平均血红蛋白浓度",
       unit: "g/L",
     ),
     TableElementConfig(
-      id: "13",
+      id: "Blood_ErythrocyteDW",
       name: "红细胞分布宽度",
       unit: "%",
     ),
     TableElementConfig(
-      id: "14",
+      id: "Blood_Hematocrit",
       name: "红细胞压积",
       unit: "%",
     ),
     TableElementConfig(
-      id: "15",
+      id: "Blood_MeanPlateletVolume",
       name: "平均血小板体积",
       unit: "fL",
     ),
     TableElementConfig(
-      id: "16",
+      id: "Blood_PlateletDW",
       name: "血小板分布宽度",
       unit: "%",
     ),
     TableElementConfig(
-      id: "17",
+      id: "Blood_PlateletPct",
       name: "血小板比积",
       unit: "%",
     ),

+ 10 - 3
lib/pages/medical/views/table_input_dialog/view.dart

@@ -8,8 +8,12 @@ import 'package:vitalapp/pages/medical/views/table_input_dialog/widgets/table_ti
 import 'index.dart';
 
 class TableInputDialog extends GetView<TableInputDialogController> {
-  const TableInputDialog(
-      {Key? key, required this.tableDataConfig, required this.title})
+  TableInputDialog(
+      {Key? key,
+      required this.tableDataConfig,
+      required this.title,
+      this.physicalExamNumber,
+      this.keyValue})
       : super(key: key);
 
   /// 列表配置项
@@ -17,6 +21,9 @@ class TableInputDialog extends GetView<TableInputDialogController> {
   // 弹窗标题
   final String title;
 
+  String? physicalExamNumber;
+  String? keyValue;
+
   // 主视图
   Widget _buildView() {
     const designWidth = 1280.0; // 设计尺寸宽度:1280
@@ -146,7 +153,7 @@ class TableInputDialog extends GetView<TableInputDialogController> {
           ),
           VButton(
             onTap: () {
-              controller.onConfirm();
+              controller.onConfirm(physicalExamNumber, keyValue);
             },
             child: const Text('提交'),
           ),

+ 3 - 3
lib/pages/medical/widgets/health_check/health_check_left/index.dart

@@ -8,8 +8,8 @@ import 'package:vitalapp/pages/medical/widgets/health_check/health_check_list/co
 import 'package:vitalapp/pages/medical/widgets/health_check/health_check_list/view.dart';
 import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
 
-class HeartCheckLeft extends GetView<HealthCheckListController> {
-  HeartCheckLeft({
+class HealthCheckLeft extends GetView<HealthCheckListController> {
+  HealthCheckLeft({
     super.key,
     required this.onRowTap,
   });
@@ -23,7 +23,7 @@ class HeartCheckLeft extends GetView<HealthCheckListController> {
         children: [
           _buildHeartCheckFilter(),
           Expanded(
-            child: HeartCheckTable(
+            child: HealthCheckTable(
               onRowTap: (value) {
                 onRowTap.call(value);
               },

+ 5 - 5
lib/pages/medical/widgets/health_check/health_check_list/view.dart

@@ -11,8 +11,8 @@ import 'package:vitalapp/pages/medical/widgets/health_check/health_check_list/co
 import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
 import 'package:vitalapp/store/store.dart';
 
-class HeartCheckTable extends GetView<HealthCheckListController> {
-  HeartCheckTable({
+class HealthCheckTable extends GetView<HealthCheckListController> {
+  HealthCheckTable({
     super.key,
     required this.onRowTap,
   });
@@ -48,7 +48,7 @@ class HeartCheckTable extends GetView<HealthCheckListController> {
             },
           ),
         ),
-        HeartCheckTablePagination(),
+        HealthCheckTablePagination(),
         SizedBox(
           height: 16,
         )
@@ -81,8 +81,8 @@ class HeartCheckTable extends GetView<HealthCheckListController> {
   }
 }
 
-class HeartCheckTablePagination extends GetView<HealthCheckListController> {
-  const HeartCheckTablePagination({
+class HealthCheckTablePagination extends GetView<HealthCheckListController> {
+  const HealthCheckTablePagination({
     super.key,
   });
   @override

+ 3 - 3
lib/pages/medical/widgets/health_check/view.dart

@@ -25,7 +25,7 @@ class HealthCheck extends GetView<HealthCheckListController> {
     return Row(
       children: [
         Expanded(
-          child: HeartCheckLeft(
+          child: HealthCheckLeft(
             onRowTap: (value) async {
               final medicalController = await Get.put(MedicalController());
               medicalController.diagnosisDataValue.clear();
@@ -114,9 +114,9 @@ class HealthCheck extends GetView<HealthCheckListController> {
         continue;
       }
       currentDiagnosis.add([
-        dto?.name ?? '',
+        dto.name ?? '',
         value,
-        dto?.unit ?? '',
+        dto.unit ?? '',
       ]);
     }
 

+ 61 - 0
lib/pages/medical/widgets/health_heart_check/health_check_left/index.dart

@@ -0,0 +1,61 @@
+// ignore_for_file: must_be_immutable
+
+import 'package:fis_ui/types/widget_builders.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:vitalapp/components/search_input.dart';
+import 'package:vitalapp/pages/medical/widgets/health_heart_check/health_check_list/controller.dart';
+import 'package:vitalapp/pages/medical/widgets/health_heart_check/health_check_list/view.dart';
+import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
+
+class HeartCheckLeft extends GetView<HeartCheckListController> {
+  HeartCheckLeft({
+    super.key,
+    required this.onRowTap,
+  });
+  ValueCallback<ResidentModel> onRowTap;
+
+  @override
+  Widget build(BuildContext context) {
+    return Center(
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          _buildHeartCheckFilter(),
+          Expanded(
+            child: HeartCheckTable(
+              onRowTap: (value) {
+                onRowTap.call(value);
+              },
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildHeartCheckFilter() {
+    return Container(
+      alignment: Alignment.centerLeft,
+      margin: const EdgeInsets.all(10.0), // 设置外边距
+      padding: const EdgeInsets.all(5.0), // 设置内边距
+      decoration: BoxDecoration(
+        color: Colors.grey[200], // 设置背景颜色
+        borderRadius: BorderRadius.circular(16.0), // 设置圆角边框
+      ),
+      height: 60,
+      width: 520,
+      child: VSearchInput(
+        textEditingController: TextEditingController(text: ""),
+        placeholder: "请输入身份证号码",
+        clearable: true,
+        onClear: () {},
+        onSearch: (value) {
+          controller.getRegisterInfoPage(
+            keyword: value,
+          );
+        },
+      ),
+    );
+  }
+}

+ 148 - 0
lib/pages/medical/widgets/health_heart_check/health_check_list/controller.dart

@@ -0,0 +1,148 @@
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:vitalapp/components/table/table_column.dart';
+import 'package:vitalapp/managers/interfaces/appointment.dart';
+import 'package:vitalapp/managers/interfaces/registration.dart';
+import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
+
+/// 心电表格控制器
+class HeartCheckListController extends GetxController {
+  final appointmentManager = Get.find<IAppointmentManager>();
+  final registrationManager = Get.find<IRegistrationManager>();
+  final state = ListState();
+
+  HeartCheckListController() {}
+
+  /// 登记
+  ResidentModel resident = ResidentModel(
+    idNumber: '',
+  );
+
+  /// 手动填写的病人名字
+  PatientDTO? patientInfo = PatientDTO();
+
+  /// 预约列表
+  List<ResidentModel> residentList = [];
+
+  /// 预约列表的总数
+  int appointmentModelListLength = 0;
+
+  /// 表格loading
+  bool tableLoading = true;
+
+  /// 当前表格页数
+  int currPageIndex = 1;
+
+  /// 当前检测详情
+  List<List<String>>? tableData = null;
+
+  Future<void> getRegisterInfoPage({
+    int? pageSize = 10,
+    int? pageIndex = 1,
+    String? keyword = "",
+  }) async {
+    tableLoading = true;
+    currPageIndex = pageIndex!;
+
+    var result = await registrationManager.getElectrocardiogramRecordPageAsync(
+      pageSize: pageSize,
+      pageIndex: pageIndex,
+      keyword: keyword,
+    );
+
+    List<ResidentModel> _residentList = [];
+    if (result?.pageData != null) {
+      for (ElectrocardiogramRecord i in result!.pageData!) {
+        _residentList.add(
+          ResidentModel(
+            name: i.patientName ?? '',
+            idNumber: i.cardNo ?? '',
+            homeAddress: i.patientAddress,
+            age: null,
+            physicalExamNumber: i.physicalExamNumber,
+            phone: "11111",
+          ),
+        );
+      }
+      appointmentModelListLength = result.totalCount;
+    }
+
+    residentList = _residentList;
+    tableLoading = false;
+    update(["healthCheck_table"]);
+    update(["healthCheck_table_pagination"]);
+  }
+
+  /// 登记列表表头
+  List<TableColumn<ResidentModel>> buildTableColumns() {
+    var textStyle = TextStyle(
+      fontSize: 16,
+      overflow: TextOverflow.ellipsis,
+    );
+    return <TableColumn<ResidentModel>>[
+      TableColumn<ResidentModel>(
+        headerText: "体检号",
+        maxWidth: 150,
+        render: (rowData, index) => Container(
+          padding: const EdgeInsets.symmetric(vertical: 16),
+          child: Text(
+            rowData.physicalExamNumber ?? '',
+            style: textStyle,
+          ),
+        ),
+      ),
+      TableColumn<ResidentModel>(
+        headerText: "姓名",
+        // maxWidth: 100,
+        render: (rowData, index) => Center(
+          child: Text(
+            rowData.name ?? '',
+            style: textStyle,
+          ),
+        ),
+      ),
+      TableColumn<ResidentModel>(
+        headerText: "身份证号",
+        // maxWidth: 200,
+        render: (rowData, index) => Center(
+          child: Text(
+            rowData.idNumber,
+            style: textStyle,
+          ),
+        ),
+      ),
+      TableColumn<ResidentModel>(
+        headerText: "手机号",
+        render: (rowData, index) => Center(
+          child: Text(
+            rowData.phone ?? '',
+            style: textStyle,
+          ),
+        ),
+      ),
+    ];
+  }
+
+  _initData() async {
+    await getRegisterInfoPage();
+  }
+
+  void onTap() {}
+
+  // @override
+  // void onInit() {
+  //   super.onInit();
+  // }
+
+  @override
+  void onReady() {
+    super.onReady();
+    _initData();
+  }
+
+  // @override
+  // void onClose() {
+  //   super.onClose();
+  // }
+}

+ 120 - 0
lib/pages/medical/widgets/health_heart_check/health_check_list/view.dart

@@ -0,0 +1,120 @@
+// ignore_for_file: must_be_immutable
+
+import 'package:fis_i18n/i18n.dart';
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:fis_ui/index.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:vitalapp/components/table/table.dart';
+import 'package:vitalapp/managers/interfaces/patient.dart';
+import 'package:vitalapp/pages/medical/widgets/health_heart_check/health_check_list/controller.dart';
+import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
+import 'package:vitalapp/store/store.dart';
+
+class HeartCheckTable extends GetView<HeartCheckListController> {
+  HeartCheckTable({
+    super.key,
+    required this.onRowTap,
+  });
+
+  ValueCallback<ResidentModel> onRowTap;
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        Expanded(
+          child: GetBuilder<HeartCheckListController>(
+            id: "healthCheck_table",
+            builder: (_) {
+              return VitalTable<ResidentModel>(
+                autoHeight: false,
+                noDataHintText: "暂无数据",
+                columns: controller.buildTableColumns(),
+                source: controller.residentList,
+                loading: controller.tableLoading,
+                onRowSelected: (value, index, idxs) {},
+                onRowTap: (index) async {
+                  ResidentModel resident = controller.residentList[index];
+                  await changeHeartCheck(resident);
+                  onRowTap.call(resident);
+                },
+                onAllRowsSelected: (value, idxs) => {},
+                headerTextStyle: const TextStyle(
+                  fontSize: 20,
+                ),
+              );
+            },
+          ),
+        ),
+        HeartCheckTablePagination(),
+        SizedBox(
+          height: 16,
+        )
+      ],
+    );
+  }
+
+  Future<void> changeHeartCheck(ResidentModel resident) async {
+    final _patientManager = Get.find<IPatientManager>();
+
+    RegisterPersonInfoDTO? registerPersonInfo =
+        await _patientManager.getRegisterPersonInfoByPhysicalExamNumberAsync(
+      physicalExamNumber: resident.physicalExamNumber ?? '',
+    );
+    PatientDTO? patientInfo = PatientDTO();
+    if (registerPersonInfo != null &&
+        registerPersonInfo.physicalExamNumber != null) {
+      patientInfo.code = registerPersonInfo.code;
+      patientInfo.patientName = registerPersonInfo.name;
+      Store.user.currentSelectRegisterPersonInfo = registerPersonInfo;
+      Store.user.currentSelectPatientInfo = patientInfo;
+    }
+
+    /// 【TODO】 需要根据体检号码看是否有体检
+    // List<ExamDTO>? examList = await controller.registrationManager
+    //     .getExamListByPhysicalExamNumberAsync(
+    //   physicalExamNumber: resident.physicalExamNumber ?? "",
+    // );
+    // print(examList?.first.examData);
+  }
+}
+
+class HeartCheckTablePagination extends GetView<HeartCheckListController> {
+  const HeartCheckTablePagination({
+    super.key,
+  });
+  @override
+  Widget build(BuildContext context) {
+    return GetBuilder<HeartCheckListController>(
+      id: "healthCheck_table_pagination",
+      builder: (_) {
+        return Row(
+          mainAxisAlignment: MainAxisAlignment.end,
+          children: [
+            FTablePagination(
+              currListLength: controller.appointmentModelListLength,
+              currPageIndex: controller.currPageIndex,
+              pageSize: 10,
+              onChangePage: (pageIndex, listLength) {
+                controller.getRegisterInfoPage(
+                  pageIndex: pageIndex,
+                  pageSize: listLength,
+                );
+                // _tableScrollToTop();
+              },
+              totalItemNumText: i18nBook.common.ofTerm
+                  .translate(['${controller.appointmentModelListLength}']),
+              previousFivePageText: i18nBook.common.previousFivePageText.t,
+              nextFivePageText: i18nBook.common.nextFivePageText.t,
+            ),
+            SizedBox(
+              width: 20,
+            )
+          ],
+        );
+      },
+    );
+  }
+}

+ 125 - 0
lib/pages/medical/widgets/health_heart_check/view.dart

@@ -0,0 +1,125 @@
+// ignore_for_file: must_be_immutable
+
+import 'dart:convert';
+
+import 'package:fis_jsonrpc/rpc.dart';
+import 'package:flutter/material.dart';
+import 'package:get/get.dart';
+import 'package:vitalapp/managers/interfaces/dictionary.dart';
+import 'package:vitalapp/pages/medical/controller.dart';
+import 'package:vitalapp/pages/medical/widgets/health_heart_check/health_check_left/index.dart';
+import 'package:vitalapp/pages/medical/widgets/health_heart_check/health_check_list/controller.dart';
+import 'package:vitalapp/pages/patient/detail/widgets/last_record.dart';
+
+class HealthCheck extends GetView<HeartCheckListController> {
+  HealthCheck({
+    super.key,
+    this.checkDialog,
+    required this.checkKey,
+  });
+
+  final String checkKey;
+  Widget? checkDialog;
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      children: [
+        Expanded(
+          child: HeartCheckLeft(
+            onRowTap: (value) async {
+              final medicalController = await Get.put(MedicalController());
+              medicalController.diagnosisDataValue.clear();
+              controller.tableData == null;
+              controller.update(['health_detail']);
+              if (value.physicalExamNumber?.isEmpty ?? true) {
+                return;
+              }
+              List<ExamDTO>? examList = await controller.registrationManager
+                  .getExamListByPhysicalExamNumberAsync(
+                      physicalExamNumber: value.physicalExamNumber ?? '');
+              ExamDTO? currentExam = examList
+                  ?.firstWhereOrNull((element) => element.key == checkKey);
+
+              if (currentExam == null) {
+                Get.dialog(checkDialog ?? Container());
+              } else {
+                controller.tableData = await getTableData(
+                  currentExam.examData ?? '',
+                );
+                controller.update(['health_detail']);
+              }
+              // if (examList == null || examList.length == 0) {
+              //   Get.dialog(checkDialog ?? Container());
+              // } else {
+              //   controller.tableData = await getTableData(
+              //     examList.first.examData ?? '',
+              //   );
+              //   controller.update(['health_detail']);
+              // }
+            },
+          ),
+        ),
+        Container(
+          width: 320,
+          decoration: BoxDecoration(
+            border: Border(
+              left: BorderSide(
+                color: Colors.grey[300]!,
+                width: 1,
+              ),
+            ),
+          ),
+          child: _buildDetail(),
+        )
+      ],
+    );
+  }
+
+  Widget _buildDetail() {
+    return GetBuilder<HeartCheckListController>(
+      id: "health_detail",
+      builder: (_) {
+        if (controller.tableData == null) return Container();
+        return LastRecordTable(
+          columnNames: const ['检测项目', '检测结果', '单位'],
+          tableData: controller.tableData ?? [[]],
+        );
+      },
+    );
+  }
+
+  Future<List<List<String>>> getTableData(String data) async {
+    var currentDiagnosis = <List<String>>[];
+
+    var jsonData = json.decode(data);
+    List<String> keys = jsonData.keys.toList();
+
+    List<DictionaryWithUnitDTO>? dtos = [];
+
+    dtos = await Get.find<IDictionaryManager>()
+            .getDictionaryNameAndUnitByKeysAsync(keys) ??
+        [];
+
+    for (var key in keys) {
+      if (key == "ECG_POINT" || key == "ECG_POINT12") {
+        continue;
+      }
+      var dto = dtos.firstWhereOrNull((item) => item.key == key);
+      if (dto == null) {
+        continue;
+      }
+      final value = jsonData[key].toString();
+      if (value.isEmpty) {
+        // 不展示空值
+        continue;
+      }
+      currentDiagnosis.add([
+        dto.name ?? '',
+        value,
+        dto.unit ?? '',
+      ]);
+    }
+
+    return currentDiagnosis;
+  }
+}

+ 1 - 1
lib/pages/medical_checkup_station/registration/widgets/report/report_preview.dart

@@ -45,7 +45,7 @@ class ReportPreview extends StatelessWidget {
               pdfTypeEnum: PDFTypeEnum.pdfJpeg,
               demoMode: false,
               pdfAccessTypeEnum: PDFAccessTypeEnum.preview,
-              fileName: pdfUrl,
+              fileName: "pdfUrl",
               pdfExporter: TextMediaFileExporterForShell.exportFile,
               cacheGet: (a) async {
                 return null;

+ 7 - 4
lib/routes/routes.dart

@@ -27,11 +27,12 @@ import 'package:vitalapp/pages/medical/records/view.dart';
 import 'package:vitalapp/pages/medical/view.dart';
 import 'package:vitalapp/pages/medical/views/basic_check.dart';
 import 'package:vitalapp/pages/medical/views/biochemistry_check.dart';
+import 'package:vitalapp/pages/medical/views/blood_check.dart';
+import 'package:vitalapp/pages/medical/views/heart_check_new.dart';
 import 'package:vitalapp/pages/medical/views/traditional_chinese_check.dart';
 import 'package:vitalapp/pages/medical/views/urine_check.dart';
-import 'package:vitalapp/pages/medical/views/heart_check.dart';
 import 'package:vitalapp/pages/medical/widgets/health_check/health_check_list/controller.dart';
-import 'package:vitalapp/pages/medical/views/blood_test.dart';
+import 'package:vitalapp/pages/medical/widgets/health_heart_check/health_check_list/controller.dart';
 import 'package:vitalapp/pages/medical_checkup_station/appointment/controller.dart';
 import 'package:vitalapp/pages/medical_checkup_station/appointment/view.dart';
 import 'package:vitalapp/pages/medical_checkup_station/registration/controller.dart';
@@ -477,7 +478,7 @@ class Routes {
     // ),
     VRouteSetting(
       '/electrocardiogram',
-      () => const HeartCheck(),
+      () => const HeartCheckNew(),
       binding: BindingsBuilder(
         () {
           if (!Get.isRegistered<MedicalController>()) {
@@ -485,6 +486,7 @@ class Routes {
           }
           Get.put(PatientDetailController());
           Get.put(HealthCheckListController());
+          Get.put(HeartCheckListController());
         },
       ),
     ),
@@ -513,13 +515,14 @@ class Routes {
     ),
     VRouteSetting(
       '/bloodTest',
-      () => const BloodTest(),
+      () => BloodCheck(),
       binding: BindingsBuilder(
         () {
           if (!Get.isRegistered<MedicalController>()) {
             Get.lazyPut(() => MedicalController());
           }
           Get.put(PatientDetailController());
+          Get.put(HealthCheckListController());
         },
       ),
     ),