Browse Source

人群分类修改和填入之间互斥处理

finlay 1 year ago
parent
commit
b5ea24b274

+ 158 - 0
lib/components/selectBox_button.dart

@@ -0,0 +1,158 @@
+import 'package:flutter/material.dart';
+
+///按钮式单选框组
+class VSelectBoxButtonGroup<T, TValue> extends StatefulWidget {
+  final List<T> source;
+  final TValue? value;
+  final String Function(T data) labelGetter;
+  final TValue Function(T data) valueGetter;
+  final ValueChanged<TValue?>? onChanged;
+  final double? itemWidth;
+  const VSelectBoxButtonGroup({
+    super.key,
+    required this.source,
+    this.value,
+    required this.labelGetter,
+    required this.valueGetter,
+    this.onChanged,
+    this.itemWidth,
+  });
+
+  @override
+  State<StatefulWidget> createState() => _VSelectBoxGroupState<T, TValue>();
+}
+
+class _VSelectBoxGroupState<T, TValue>
+    extends State<VSelectBoxButtonGroup<T, TValue>> {
+  late TValue? _selectedValue;
+  @override
+  void initState() {
+    _selectedValue = widget.value;
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final children = <Widget>[];
+    final length = widget.source.length;
+    for (var i = 0; i < length; i++) {
+      final e = widget.source[i];
+      final value = widget.valueGetter(e);
+      final isSelect = _selectedValue == value;
+      children.add(VSelectBoxButton(
+          // key: UniqueKey(),
+          label: widget.labelGetter(e),
+          isSelected: isSelect,
+          onChanged: (status) {
+            setState(() {
+              if (status) {
+                _onChanged(value);
+              } else {
+                _onChanged(null);
+              }
+            });
+          }));
+    }
+    return Wrap(
+      spacing: 12,
+      runSpacing: 8,
+      children: children,
+    );
+  }
+
+  void _onChanged(TValue? value) {
+    _selectedValue = value;
+    widget.onChanged?.call(_selectedValue);
+  }
+}
+
+class VSelectBoxButton extends StatefulWidget {
+  final String label;
+  final bool? isSelected;
+  final ValueChanged<bool>? onChanged;
+
+  const VSelectBoxButton(
+      {super.key,
+      required this.label,
+      this.isSelected,
+      required this.onChanged});
+
+  @override
+  State<StatefulWidget> createState() => _VSelectBoxState();
+}
+
+class _VSelectBoxState extends State<VSelectBoxButton> {
+  bool _isSelected = false;
+  @override
+  void initState() {
+    if (widget.isSelected != null) {
+      _isSelected = widget.isSelected!;
+    }
+    super.initState();
+  }
+
+
+  @override
+  void didUpdateWidget(covariant VSelectBoxButton oldWidget) {
+    _isSelected=widget.isSelected==true;
+    super.didUpdateWidget(oldWidget);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    const height = 56.0;
+    const borderRadius = height / 2;
+    final primaryColor = Theme.of(context).primaryColor;
+    return Material(
+      child: Ink(
+        child: InkWell(
+          borderRadius: BorderRadius.circular(borderRadius),
+          onTap: () {
+            setState(
+              () {
+                _isSelected = !_isSelected;
+                widget.onChanged?.call(_isSelected);
+              },
+            );
+          },
+          child: Container(
+            padding: const EdgeInsets.only(left: 0, right: borderRadius),
+            alignment: Alignment.center,
+            height: height,
+            decoration: BoxDecoration(
+              color: _isSelected ? primaryColor : Colors.white,
+              borderRadius: BorderRadius.circular(borderRadius),
+              border: _isSelected ? null : Border.all(color: primaryColor),
+            ),
+            child: Row(
+              mainAxisSize: MainAxisSize.min,
+              crossAxisAlignment: CrossAxisAlignment.center,
+              children: [
+                if (_isSelected) ...[
+                  const Icon(
+                    Icons.check_rounded,
+                    color: Colors.green,
+                    size: 24,
+                  ),
+                  const SizedBox(
+                    width: 8,
+                  ),
+                ],
+                if (!_isSelected)
+                  const SizedBox(
+                    width: 32,
+                  ),
+                Text(
+                  widget.label,
+                  style: TextStyle(
+                      color: _isSelected ? Colors.white : primaryColor,
+                      fontSize: 20),
+                )
+              ],
+            ),
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 1 - 1
lib/pages/medical/records/view.dart

@@ -201,7 +201,7 @@ class _MedicalRecordCard extends GetView<MedicalRecordsController> {
           onTap: () async {
             var result = await controller.getTableData(dto);
             await VDialogTable(
-              title: '检测结果结果检查单',
+              title: '数据展示',
               columnNames: const ['序号', '检测项目', '检测结果', '单位'],
               tableData: result,
               diagnosisTime:

+ 12 - 5
lib/pages/patient/create/controller.dart

@@ -11,7 +11,7 @@ import 'package:vnoteapp/routes/nav_ids.dart';
 
 class CreatePatientController extends FControllerBase with HomeNavMixin {
   final _patientManager = Get.find<IPatientManager>();
-
+  final crowdLabelsController = Get.find<CrowdLabelsController>();
   final state = CreatePatientState();
 
   @override
@@ -139,8 +139,7 @@ class CreatePatientController extends FControllerBase with HomeNavMixin {
       return null;
     }
 
-    final crowdLabelCodes =
-        Get.find<CrowdLabelsController>().state.selectedCodes;
+    final crowdLabelCodes = crowdLabelsController.state.selectedCodes;
     final request = CreatePatientRequest(
       patientName: state.name,
       phone: state.phoneNo,
@@ -164,11 +163,19 @@ class CreatePatientController extends FControllerBase with HomeNavMixin {
     if (state.cardNo.isEmpty) {
       return "请填写证件号";
     }
-    final crowdLabelCodes =
-        Get.find<CrowdLabelsController>().state.selectedCodes;
+    final selectedNormalCodes = crowdLabelsController.state.selectedNormalCodes;
+
+    if (selectedNormalCodes.length > 1) {
+      return "人群分类:一般人群、儿童、孕妇、老年人,只可选择其一!";
+    }
+    final crowdLabelCodes = crowdLabelsController.state.selectedCodes;
     if (crowdLabelCodes.isEmpty) {
       return "请选择人群分类";
     }
+    if (state.gender == GenderEnum.Male &&
+        crowdLabelCodes.contains('RQFL_YF')) {
+      return "当前居民性别为“男”,人群分类不可选择孕妇!";
+    }
     return null;
   }
 }

+ 0 - 27
lib/pages/patient/create/view.dart

@@ -26,12 +26,6 @@ class CreatePatientPage extends GetView<CreatePatientController> {
           child: Row(
             mainAxisAlignment: MainAxisAlignment.spaceAround,
             children: [
-              // VButton(
-              //   label: "下一步",
-              //   onTap: () {
-              //     controller.gotoSignContract();
-              //   },
-              // ),
               VButton(
                 label: "保存",
                 onTap: () {
@@ -57,19 +51,9 @@ class CreatePatientPage extends GetView<CreatePatientController> {
     return VSideNavMenuItem(
       title: "服务信息",
       icon: Icon(Icons.edit_document, color: Colors.grey.shade700),
-      // onTap: () {}
       pageBuilder: (_) => _buildInterval(
         const Area(),
       ),
-      // route: VRouteSetting(
-      //   "/area_panel",
-      //   () => const Area(),
-      //   binding: BindingsBuilder(
-      //     () {
-      //       Get.lazyPut(() => CreatePatientController());
-      //     },
-      //   ),
-      // ),
     );
   }
 
@@ -81,17 +65,6 @@ class CreatePatientPage extends GetView<CreatePatientController> {
       pageBuilder: (_) => _buildInterval(
         const CrowdLabelView(),
       ),
-      // route: VRouteSetting(
-      //   "/crowd_label_panel",
-      //   () => const CrowdLabelView(),
-      //   binding: BindingsBuilder(
-      //     () {
-      //       Get.lazyPut(() => CrowdLabelsController());
-      //       Get.lazyPut(() => CreatePatientController());
-      //     },
-      //   ),
-      // ),
-      // route: VRouteSetting("/about", () => const AboutPage()),
     );
   }
 

+ 16 - 19
lib/pages/patient/create/widgets/crowd_label.dart

@@ -43,28 +43,25 @@ class CrowdLabelView extends GetView<CrowdLabelsController> {
       onTap: () {
         controller.onItemCheckChanged(dto.code!);
       },
-      child: Container(
-        // margin: const EdgeInsets.symmetric(vertical: 8),
-        child: Row(
-          children: [
-            Expanded(
-              child: VListFormCell(
-                label: dto.labelName ?? '',
-                contentWidget: Obx(
-                  () => Switch(
-                    value: controller.state.selectedCodes.contains(dto.code),
-                    onChanged: (value) {
-                      controller.onItemCheckChanged(dto.code!);
-                    },
-                    activeColor: Theme.of(context).primaryColor,
-                    inactiveThumbColor: Colors.grey,
-                    // inactiveTrackColor:Colors.grey,
-                  ),
+      child: Row(
+        children: [
+          Expanded(
+            child: VListFormCell(
+              label: dto.labelName ?? '',
+              contentWidget: Obx(
+                () => Switch(
+                  value: controller.state.selectedCodes.contains(dto.code),
+                  onChanged: (value) {
+                    controller.onItemCheckChanged(dto.code!);
+                  },
+                  activeColor: Theme.of(context).primaryColor,
+                  inactiveThumbColor: Colors.grey,
+                  // inactiveTrackColor:Colors.grey,
                 ),
               ),
             ),
-          ],
-        ),
+          ),
+        ],
       ),
     );
   }

+ 14 - 3
lib/pages/patient/detail/widgets/tag_cards.dart

@@ -3,8 +3,10 @@
 import 'package:fis_jsonrpc/rpc.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
+import 'package:vnoteapp/architecture/utils/prompt_box.dart';
 import 'package:vnoteapp/components/checkbox_button.dart';
 import 'package:vnoteapp/components/dynamic_drawer.dart';
+import 'package:vnoteapp/components/selectBox_button.dart';
 import 'package:vnoteapp/consts/styles.dart';
 import 'package:vnoteapp/managers/contract/index.dart';
 import 'package:vnoteapp/pages/controllers/crowd_labels.dart';
@@ -96,6 +98,10 @@ class CrowdLabelsCard extends GetView<PatientDetailController> {
         VDynamicDrawerWrapper.hide(
           scaffoldKey: controller.homeScaffoldKey,
         );
+        if (selectedNormalCodes.contains("RQFL_YF")) {
+          PromptBox.toast('当前居民性别为“男”,不可选择孕妇!');
+          selectedNormalCodes.clear();
+        }
         crowdLabelsState.selectedNormalCodes = selectedNormalCodes;
         crowdLabelsState.selectedDiseaseCodes = selectedDiseaseCodes;
         crowdLabelsState.selectedSpecialCareCodes = selectedSpecialCareCodes;
@@ -112,13 +118,18 @@ class CrowdLabelsCard extends GetView<PatientDetailController> {
             child: Column(
               children: [
                 const SizedBox(height: 24),
-                VCheckBoxButtonGroup<LabelDTO, String>(
+                VSelectBoxButtonGroup<LabelDTO, String>(
                   source: crowdLabelsState.normalOptions,
-                  values: crowdLabelsState.selectedNormalCodes,
+                  value: crowdLabelsState.selectedNormalCodes.isNotEmpty
+                      ? crowdLabelsState.selectedNormalCodes.first
+                      : '',
                   labelGetter: (LabelDTO data) => data.labelName!,
                   valueGetter: (LabelDTO data) => data.code!,
                   onChanged: (value) {
-                    selectedNormalCodes = value;
+                    selectedNormalCodes.clear();
+                    if (value != null) {
+                      selectedNormalCodes.add(value);
+                    }
                   },
                 ),
                 const SizedBox(height: 8),

+ 1 - 1
lib/pages/patient/list/view.dart

@@ -53,7 +53,7 @@ class PatientListPage extends GetView<PatientListController> {
                         width: 150,
                       ),
                       TabButton(
-                        tabTitle: '病人列表',
+                        tabTitle: '居民列表',
                         index: 1,
                         activeIndex: controller.state.currentTabIndex,
                         onCallbackTap: () {

+ 1 - 1
lib/pages/settings/devices/widgets/consts.dart

@@ -3,7 +3,7 @@ import 'package:vnote_device_plugin/consts/types.dart';
 abstract class DevicesSettingConsts {
   // ignore: non_constant_identifier_names
   static final TYPE_NAMES = <String, String>{
-    DeviceTypes.TEMP: "额温枪",
+    DeviceTypes.TEMP: "体温计",
     DeviceTypes.WEIGHT: "体重秤",
     DeviceTypes.SUGAR: "血糖仪",
     DeviceTypes.SPO2: "血氧仪",

+ 4 - 4
pubspec.lock

@@ -502,10 +502,10 @@ packages:
     dependency: transitive
     description:
       name: plugin_platform_interface
-      sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
+      sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
       url: "https://pub.flutter-io.cn"
     source: hosted
-    version: "2.1.6"
+    version: "2.1.7"
   pointycastle:
     dependency: transitive
     description:
@@ -603,10 +603,10 @@ packages:
     dependency: transitive
     description:
       name: sqflite_common
-      sha256: "8ed044102f3135add97be8653662052838859f5400075ef227f8ad72ae320803"
+      sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6
       url: "https://pub.flutter-io.cn"
     source: hosted
-    version: "2.5.0+1"
+    version: "2.5.0+2"
   stack_trace:
     dependency: transitive
     description: