// ignore_for_file: must_be_immutable import 'package:date_format/date_format.dart'; import 'package:fis_common/extensions/string.dart'; import 'package:fis_jsonrpc/rpc.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:vitalapp/architecture/app_parameters.dart'; import 'package:vitalapp/architecture/utils/prompt_box.dart'; import 'package:vitalapp/components/alert_dialog.dart'; import 'package:vitalapp/components/dialog_date.dart'; import 'package:vitalapp/components/dialog_input.dart'; import 'package:vitalapp/components/dialog_select.dart'; import 'package:vitalapp/components/input.dart'; import 'package:vitalapp/helper/id_card_helper.dart'; import 'package:vitalapp/pages/medical_checkup_station/registration/controller.dart'; import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart'; import 'package:vitalapp/store/store.dart'; class RegistrationFormDialog extends StatefulWidget { final RegistrationInfoModel? patient; final bool? isEdit; RegistrationFormDialog({Key? key, this.patient, this.isEdit = false}) : super(key: key); @override _RegistrationFormDialogState createState() => _RegistrationFormDialogState(); } class _RegistrationFormDialogState extends State { var controller = Get.find(); @override Widget build(BuildContext context) { return GetBuilder( id: "registration_Form", builder: (_) { return VAlertDialog( title: widget.isEdit! ? "编辑登记信息" : "体检信息录入", width: 900, content: _buildView(), onConfirm: _onSubmitIdentityVerify, ); }, ); } Widget _buildView() { return Container( child: ListView( shrinkWrap: true, children: [ Column( children: [ _buildInputItem( "身份证号", value: widget.patient?.cardNo ?? '', onTap: () async { var result = await VDialogInput( initialValue: widget.patient?.cardNo ?? '', title: "身份证号", onConfirmVerification: (v) { bool isValid = IdCardHelper.validateIDCard(v); if (!isValid) { PromptBox.showToast("请填写正确的证件号"); } return isValid; }, showCancel: true, ).show(); if (result == null) { return; } if (widget.patient == null) { return; } result = result.toString().toUpperCase(); final patient = widget.patient!; patient.cardNo = result; patient.birthday = _getBirthDayofIdNumber(result); patient.patientGender = _checkGenderFromID(result); final patientDto = await controller.getPatientByID(result); if (patientDto != null) { patient.patientName = patientDto.patientName; patient.phone = patientDto.phone; patient.patientAddress = patientDto.patientAddress; } controller.update(["registration_Form"]); }, ), _buildInputItem( "姓名", value: widget.patient?.patientName ?? '', onTap: () async { var result = await VDialogInput( initialValue: widget.patient?.patientName ?? '', title: "姓名", ).show(); if (result != null) { widget.patient?.patientName = result; controller.update(["registration_Form"]); } }, ), _buildInputItem( "性别", value: controller.formController.selectGenderList .firstWhereOrNull((element) => element.code == widget.patient?.patientGender) ?.name, onTap: () async { String? result = await VDialogSelect( source: controller.formController.selectGenderList, labelGetter: (data) => data.name, valueGetter: (data) => data.code.index.toString(), initialValue: widget.patient?.patientGender?.index.toString(), title: "性别", ).show(); if (result != null) { widget.patient?.patientGender = GenderEnum.values[int.parse(result)]; controller.update(["registration_Form"]); } }, suffixIcon: Icon( Icons.chevron_right_rounded, size: 30, ), ), _buildInputItem( "生日", value: getBirthDay(widget.patient?.birthday), onTap: () async { DateTime? result; bool _isLocalStation = AppParameters.data.isLocalStation; if (kIsWeb || _isLocalStation) { result = await showDatePicker( context: Get.context!, initialDate: widget.patient?.birthday ?? DateTime.now(), firstDate: DateTime(1900), lastDate: DateTime(2100), ); } else { result = await VDialogDate( initialValue: widget.patient?.birthday, title: "生日", ).show(); } if (result != null) { widget.patient?.birthday = result; controller.update(["registration_Form"]); } }, suffixIcon: Icon( Icons.chevron_right_rounded, size: 30, ), ), _buildInputItem( "手机号", value: widget.patient?.phone, onTap: () async { var result = await VDialogInput( initialValue: widget.patient?.phone ?? '', title: "手机号", showCancel: true, onConfirmVerification: (v) { var isValid = (v.length == 11 && IdCardHelper.isNumeric(v)); if (!isValid) { PromptBox.showToast("请填写正确的手机号"); } return isValid; }, ).show(); if (result != null) { widget.patient?.phone = result; controller.update(["registration_Form"]); } }, ), _buildInputItem( "家庭住址", value: widget.patient?.patientAddress ?? '', onTap: () async { var result = await VDialogInput( initialValue: widget.patient?.patientAddress ?? '', title: "家庭住址", ).show(); if (result != null) { widget.patient?.patientAddress = result; controller.update(["registration_Form"]); } }, ), SizedBox( height: 40, ) ], ), ], ), ); } Widget _buildInputItem(String title, {String? value, Function()? onTap, Widget? suffixIcon, int? maxLines}) { return Container( padding: const EdgeInsets.only( left: 80, right: 110, ), child: Row( children: [ Container( width: 150, padding: const EdgeInsets.symmetric(vertical: 16), child: Text( title, style: const TextStyle(fontSize: 22), ), ), Expanded( child: VInput( initialValue: value, radius: 4, readOnly: true, suffixIcon: suffixIcon, maxLines: maxLines, onTap: () { onTap?.call(); }, ), ) ], ), ); } void _onSubmitIdentityVerify() async { String? isValidate = await _validateForm(widget.patient); if (isValidate != null) { PromptBox.toast(isValidate); return; } else { final patientDto = await controller.getPatientByID(widget.patient!.cardNo!, false); if (patientDto != null) { if (patientDto.currentOrgCode != Store.user.organizationCode) { PromptBox.toast("该居民已被其他医院建档"); return; } } Get.back(result: widget.patient); } } Future _validateForm(RegistrationInfoModel? patient) async { if (patient == null) { return "当前不存在病人"; } if (patient.patientName == null || patient.patientName!.isEmpty) { return "请填写姓名"; } if (patient.cardNo == null || patient.cardNo!.isEmpty) { return "请填写身份证"; } if (patient.patientGender == null) { return "请填写性别"; } bool isNotIDCard = IdCardHelper.validateIDCard(patient.cardNo ?? ''); if (!isNotIDCard) { return "请填写正确的身份证号"; } if (patient.phone.isNotNullOrEmpty) { if (patient.phone!.length != 11 || !isNumeric(patient.phone!)) { return "请填写正确的联系电话"; } } /// TODO 需求变更暂时删除 // 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; } bool isNumeric(String str) { if (str.isEmpty) { return false; } return double.tryParse(str) != null; } DateTime? _getBirthDayofIdNumber(String idCardNumber) { if (idCardNumber.isEmpty) return DateTime(1970, 1, 1); final idCardRegex = RegExp(r'^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})(\d|X)$'); final match = idCardRegex.firstMatch(idCardNumber); if (match != null) { final year = int.parse(match.group(2)!); final month = int.parse(match.group(3)!); final day = int.parse(match.group(4)!); final birthDate = DateTime(year, month, day); return birthDate; } return null; // 返回一个默认值,表示无法提取出生日期 } GenderEnum _checkGenderFromID(String idNumber) { if (idNumber.isNullOrEmpty) { return GenderEnum.Unspecified; } int secondLastDigit = int.parse(idNumber[idNumber.length - 2]); if (secondLastDigit % 2 == 0) { return GenderEnum.Female; } else { return GenderEnum.Male; } } String getBirthDay(DateTime? birthDay) { if (birthDay == null) { return ""; } return formatDate(birthDay, [yyyy, "-", mm, "-", dd]); } } // 由于 PatientDTO 的不可控,故创建自有模型,用于创建新记录 class RegistrationInfoModel { String? code; String? patientName; String? phone; String? cardNo; String? nationality; DateTime? birthday; GenderEnum? patientGender; String? patientAddress; String? permanentResidenceAddress; RegistrationInfoModel({ this.code, this.patientName, this.phone, this.cardNo, this.nationality, this.birthday, this.patientGender, this.patientAddress, }); factory RegistrationInfoModel.fromPatientDTO(PatientDTO patient) { return RegistrationInfoModel( code: patient.code, patientName: patient.patientName, phone: patient.phone, cardNo: patient.cardNo, nationality: patient.nationality, birthday: patient.birthday, patientGender: patient.patientGender, patientAddress: patient.patientAddress, ); } PatientDTO addToPatientDTO(PatientDTO patient) { patient.code = code; patient.patientName = patientName; patient.phone = phone; patient.cardNo = cardNo; patient.nationality = nationality; patient.birthday = birthday; patient.patientGender = patientGender ?? GenderEnum.Unspecified; patient.patientAddress = patientAddress; patient.permanentResidenceAddress = permanentResidenceAddress; return patient; } static GenderEnum getGenderEnum(String? genderString) { switch (genderString) { case "男": return GenderEnum.Male; case "女": return GenderEnum.Female; case "未知的性别": return GenderEnum.Unknown; case "未说明的性别": return GenderEnum.Unspecified; default: return GenderEnum.Unspecified; } } static String getGenderString(GenderEnum? enumValue) { switch (enumValue) { case GenderEnum.Male: return "男"; case GenderEnum.Female: return "女"; case GenderEnum.Unknown: return "未知的性别"; case GenderEnum.Unspecified: return "未说明的性别"; default: return "未说明的性别"; } } }