import 'dart:async'; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/pojo/city.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/mh_controller/people_info_controller.dart'; import 'package:vbvs_app/pages/common/selectDialog.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; import 'package:vbvs_app/pages/mh_page/test/WebviewTestModel.dart'; import 'package:vbvs_app/pages/person/select_city.dart'; import 'package:vbvs_app/pages/person/select_disease.dart'; //更新人员信息 class PeopleInfoPage extends GetView { Map data; PeopleInfoPage({required this.data}); getLine() { return Divider( color: Color(0XFF929699), thickness: 0.5.rpx, height: 0, ); } PeopleInfoController controller = Get.put(PeopleInfoController()); final CityModelController cityController = Get.find(); @override Widget build(BuildContext context) { controller.getDiseaseData().then((apiResponse) { WidgetsBinding.instance.addPostFrameCallback((_) { if (apiResponse.code != HttpStatusCodes.ok) { TopSlideNotification.show( context, text: apiResponse.msg ?? '', textColor: themeController.currentColor.sc9, ); } }); }); getPersonData(); controller.cityDataFuture = cityController.loadAndSetCityData().then((success) { return cityController.cityList; }); return LayoutBuilder( builder: (context, boxConstraints) => GestureDetector( onTap: () { // 触摸收起键盘 FocusScope.of(context).requestFocus(FocusNode()); }, child: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/new_background.png'), // 本地图片 fit: BoxFit.fill, // 填满整个 Container ), ), child: Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( elevation: 0, surfaceTintColor: Colors.transparent, backgroundColor: Colors.transparent, automaticallyImplyLeading: false, iconTheme: IconThemeData(color: Colors.white), titleSpacing: 0, title: SizedBox( width: double.infinity, height: 180.rpx, child: Stack( alignment: Alignment.center, children: [ // 中间居中的标题 Text( '人员资料'.tr, textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 30.rpx, ), ), // 左侧图标 Positioned( left: 0.rpx, child: returnIconButtomNew(), ), Positioned( right: 30.rpx, child: CustomCard( borderRadius: 16.rpx, gradientDirection: GradientDirection.vertical, onTap: () async { bool isValid = true; // 数据验证 for (int i = 0; i < controller.model.peopleList.length; i++) { var d = controller.model.peopleList[i]; // String prefix = "人员信息${i == 0 ? "A" : "B"}:"; if (d['height'] != null && d['height'].toString().isNotEmpty && int.tryParse(d['height'].toString()) == null) { TopSlideNotification.show(context, text: "请选择身高".tr, textColor: Color(0xFFFF7159)); isValid = false; break; } if (d['weight'] != null && d['weight'].toString().isNotEmpty && int.tryParse(d['weight'].toString()) == null) { TopSlideNotification.show(context, text: "请选择体重".tr, textColor: Color(0xFFFF7159)); isValid = false; break; } if (d['contact'] != null && d['contact'].toString().isNotEmpty && !MyUtils.isValidPhoneNumber( d['contact'].toString())) { TopSlideNotification.show(context, text: "请输入正确的联系人电话".tr, textColor: Color(0xFFFF7159)); isValid = false; break; } } // 所有数据合法,开始保存 if (isValid) { for (var data in controller.model.peopleList) { try { await controller.savePeoples(data, context); MHTHomeController mhtHomeController = Get.find(); await Future.delayed(Duration(seconds: 1)); await mhtHomeController.getPersonList(); WebviewTestController webviewTestController = Get.find(); webviewTestController .queryPersonInfoByMac(); } catch (e) { print("保存失败:$e"); TopSlideNotification.show(context, text: "更新失败".tr, textColor: Color(0xFFFF7159)); } } } }, colors: const [ Color(0xFFFCFCFC), Color(0xFFF8FAF9), Color(0XFFECF6F3), Color(0XFFD9F0E9), Color(0xFFCEECE3) ], child: Container( width: 120.rpx, height: 60.rpx, alignment: Alignment.center, // decoration: BoxDecoration( // borderRadius: BorderRadius.circular(5), // color: stringToColor("#182B7C"), // ), child: Text( "保存".tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0XFF011D33), letterSpacing: 0, fontSize: 30.rpx, ), ), ), )) ], ), ), centerTitle: false, ), body: SafeArea( top: true, child: Container( padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height * 1.123, // decoration: BoxDecoration( // color: Colors.transparent, // image: DecorationImage( // image: AssetImage("assets/images/background.png"), // fit: BoxFit.cover, // ), // ), child: SingleChildScrollView( child: Obx(() => Column( children: [ if (controller.model.peopleList.isNotEmpty) ...List.generate( controller.model.peopleList.length, (index) { final person = controller.model.peopleList[index]; String location_ = ''; // if ("${data["bindMacB"]}".length > 6 && // (person["direction"] == 1 || // person["direction"] == 2)) { // location_ = person["direction"] == 1 ? '左侧' : '右侧'; // } return Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only( left: 18.rpx, top: index == 0 ? 30.rpx : 90.rpx, bottom: 20.rpx), child: Text( index == 0 ? 'person_info_A'.tr : 'person_info_B'.tr, style: TextStyle( color: Colors.white, fontSize: 30.rpx), )), Container( child: Column( children: [ getLine(), Obx( () => Container( width: double.infinity, height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '姓名'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Container( width: 300.rpx, child: TextField( obscureText: false, textAlign: TextAlign.right, style: TextStyle( fontSize: 30.rpx, color: Colors.white), decoration: InputDecoration( fillColor: Colors .transparent, filled: true, hintText: "请输入姓名".tr, hintStyle: TextStyle( color: themeController .currentColor .sc4, ), border: InputBorder .none, contentPadding: EdgeInsets .all( 0)), onChanged: (value) { controller.model .peopleList[ index] ["name"] = value; }, controller: controller.onReDraw( TextEditingController( text: controller .model .peopleList[index] [ "name"] ?? ""), (textEditingController) { textEditingController .text = controller .model .peopleList[ index]["name"] ?? ""; }, "people_name_$index"), ), ), ], ), ), ), getLine(), Obx( () => InkWell( onTap: () { // 延迟执行的代码 FocusScope.of(context) .requestFocus( FocusNode()); Future.delayed( const Duration( milliseconds: 250), () { showOneSelectionDialog( context, title: "选择性别".tr, arr: ["女".tr, "男".tr], checkIndex: controller .model .peopleList[ index] ['gender'] ?? 0, checkChange: (sindex) { controller.model.peopleList[ index]['gender'] = sindex; // 👈 保存为 0 / 1 controller.updateAll(); }); }); }, child: Container( margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), width: double.infinity, height: 90.rpx, decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '性别'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Row( mainAxisSize: MainAxisSize.max, children: [ Container( width: 200.rpx, child: Text( controller.model.peopleList[ index] [ 'gender'] == 0 ? '女'.tr : '男'.tr, textAlign: TextAlign .right, style: TextStyle( fontFamily: 'Readex Pro', color: Colors .white, fontSize: 30.rpx, letterSpacing: 0, ), ), ), SizedBox( width: 16.rpx, ), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture .asset( 'assets/img/icon/expand_more.svg', color: Colors .white, )) ], ), ], ), ), ), ), getLine(), InkWell( onTap: () { // Convert string height to int for initial value final currentHeight = controller .model.peopleList[index] ['height']; final initialHeight = currentHeight != null ? int.tryParse( currentHeight .toString()) ?? 170 : 170; FocusScope.of(context) .requestFocus(FocusNode()); Future.delayed( const Duration( milliseconds: 250), () { showHeightPickerDialog( context, title: "选择身高".tr, initialHeight: initialHeight, onConfirm: (int selectedHeight) { controller.model.peopleList[ index]['height'] = selectedHeight .toString(); controller.updateAll(); print( "身高: $selectedHeight cm"); }, ); }); }, child: Container( width: double.infinity, height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '身高(cm)'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Row( children: [ Text( controller.model.peopleList[ index] [ 'height'] != null ? "${controller.model.peopleList[index]['height']} cm" : '', style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, ), ), SizedBox(width: 16.rpx), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture .asset( 'assets/img/icon/expand_more.svg', color: Colors.white, )), ], ), ], ), ), ), getLine(), Obx( () => InkWell( onTap: () { FocusScope.of(context) .requestFocus( FocusNode()); Future.delayed( const Duration( milliseconds: 250), () { showWeightPickerDialog( context, title: "选择体重".tr, initialWeight: controller .model .peopleList[ index]['weight'] ?? "", onConfirm: (int selectedWeight) { controller.model .peopleList[ index]['weight'] = selectedWeight .toString(); // ✅ 转成字符串 controller.updateAll(); }, ); }); }, child: Container( width: double.infinity, height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '体重(kg)'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Row( children: [ Text( controller.model.peopleList[ index] [ 'weight'] != null ? "${controller.model.peopleList[index]['weight']} kg" : '', style: TextStyle( fontFamily: 'Readex Pro', color: Colors.white, fontSize: 30.rpx, ), ), SizedBox( width: 16.rpx), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture .asset( 'assets/img/icon/expand_more.svg', color: Colors .white, )) ], ), ], ), ), ), ), getLine(), Obx(() => InkWell( onTap: () { // 延迟执行的代码 FocusScope.of(context) .requestFocus( FocusNode()); Future.delayed( const Duration( milliseconds: 250), () { showDateSelectionDialog( context, title: "选择生日".tr, checkDate: controller .model .peopleList[index] ['birthday'] is DateTime ? controller.model .peopleList[index] ['birthday'] : DateTime.tryParse( controller.model.peopleList[index]['birthday'] ?? '') ?? DateTime.now(), checkChange: (DateTime d) { controller.model .peopleList[ index] ['birthday'] = d; controller.updateAll(); }); }); }, child: Container( width: double.infinity, height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '生日'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color( 0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Row( mainAxisSize: MainAxisSize.max, children: [ Container( constraints: BoxConstraints( minWidth: 200.rpx), child: Text( controller.model.peopleList[index]['birthday'] != null ? time_08_Formatter_pattern( controller.model.peopleList[index] [ 'birthday'], "yyyy年MM月dd日" .tr) : '', textAlign: TextAlign .right, style: TextStyle( fontFamily: 'Readex Pro', color: Colors .white, fontSize: 30.rpx, letterSpacing: 0, ), ), ), SizedBox( width: 16.rpx, ), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture .asset( 'assets/img/icon/expand_more.svg', color: Colors .white, )) ], ), ], ), ), )), getLine(), Container( width: double.infinity, height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), decoration: BoxDecoration(), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '联系方式'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Container( width: 300.rpx, child: TextField( obscureText: false, keyboardType: TextInputType.number, textInputAction: TextInputAction.done, textAlign: TextAlign.right, style: TextStyle( fontSize: 30.rpx, color: Colors.white), decoration: InputDecoration( fillColor: Colors .transparent, filled: true, hintText: "请输入联系方式".tr, hintStyle: TextStyle( color: themeController .currentColor .sc4, ), border: InputBorder .none, contentPadding: EdgeInsets .all(0)), onChanged: (value) { controller.model .peopleList[ index] ['contact'] = value; }, controller: controller.onReDraw( TextEditingController( text: controller .model .peopleList[index] [ 'contact'] ?? ""), (textEditingController) { textEditingController .text = controller .model .peopleList[ index]['contact'] ?? ""; }, "contact_$index"), ), ), ], ), ), getLine(), Container( height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), child: InkWell( onTap: () { // if (widget.status == // BindType.share.code) { // TopSlideNotification.show( // context, // text: "被分享用户只能修改用户名称", // textColor: // themeController // .currentColor // .sc9); // return; // } FocusScope.of(context) .requestFocus( FocusNode()); Future.delayed( Duration( milliseconds: 250), () { // 使用当前选中的城市数据,如果没有则创建默认 CityModel? currentCity; if (controller .model .cityModels .isNotEmpty && index < controller .model .cityModels .length) { currentCity = controller .model .cityModels[index]; } else { currentCity = CityModel(); } showCitySelectionDialog( context, selectedCity: currentCity, onCityChanged: (CityModel newCity) { final list = controller .model.cityModels; if (index < list.length) { // 替换 list[index] = newCity; } else { // 补齐并追加 list.add(newCity); } // controller.model // .peopleList[ // index]['UTC'] = // list[index].UTC; controller.model .peopleList[ index] ['city_id'] = list[ index] .id; controller.updateAll(); }, title: "选择城市".tr, cityDataFuture: controller .cityDataFuture, // 传入预加载的数据 colors: CitySelectionColors( pickerBackgroundColor: stringToColor( "#003058"), confirmTextColor: stringToColor( "#84F5FF"), selectedCityColor: stringToColor( "#84F5FF"), selectedTextColor: stringToColor( "#011D33"), ), ); }); }, child: Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '请选择城市'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Row( children: [ Text( getCityModel(index) != null ? MyUtils .getDetailedCityDisplayText( getCityModel( index)) : "请选择城市".tr, style: TextStyle( color: getCityModel( index) != null && getCityModel( index)! .id != null ? themeController .currentColor .sc3 : Color( 0xFF9EA4B7), fontSize: AppConstants() .title_text_fontSize, ), ), SizedBox(width: 16.rpx), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture .asset( 'assets/img/icon/expand_more.svg', color: Colors.white, )), ], ), ], ), ), ), getLine(), Container( height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx, ), child: InkWell( onTap: () { // if (widget.status == // BindType.share.code) { // TopSlideNotification.show( // context, // text: "被分享用户只能修改用户名称", // textColor: // themeController // .currentColor // .sc9); // return; // } FocusScope.of(context) .requestFocus( FocusNode()); Future.delayed( Duration( milliseconds: 250), () { // 获取当前时区 String? currentTimeZone; if (controller .model .peopleList .isNotEmpty && index < controller .model .peopleList .length && controller.model .peopleList[ index]['UTC'] != null) { currentTimeZone = controller.model .peopleList[ index]['UTC']; } showTimeMHTZonePickerDialog( context, title: "请选择时区".tr, initialTimeZone: currentTimeZone ?? "", onConfirm: (String selectedTimeZone) { controller.model .peopleList[ index]['UTC'] = selectedTimeZone; }, ); }); }, child: Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '请选择时区'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Row( children: [ Text( controller .model .peopleList .isNotEmpty && index < controller .model .peopleList .length && controller.model .peopleList[index] [ 'UTC'] != null && controller .model .peopleList[ index] [ 'UTC']! .isNotEmpty ? controller.model .peopleList[ index]['UTC']! : "请选择时区".tr, style: TextStyle( color: controller .model .peopleList .isNotEmpty && index < controller .model .peopleList .length && controller.model .peopleList[index] [ 'UTC'] != null && controller .model .peopleList[ index] [ 'UTC']! .isNotEmpty ? themeController .currentColor .sc3 : Color( 0xFF9EA4B7), fontSize: AppConstants() .title_text_fontSize, ), ), SizedBox(width: 16.rpx), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture.asset( 'assets/img/icon/expand_more.svg', color: Colors.white, ), ), ], ), ], ), ), ), getLine(), Container( height: 90.rpx, margin: EdgeInsets.only( left: 40.rpx, right: 35.rpx), child: InkWell( onTap: () { FocusScope.of(context) .requestFocus( FocusNode()); Future.delayed( Duration( milliseconds: 250), () { // 获取当前已选择的慢病ID列表 final currentDiseaseIds = List< String>.from(controller .model .peopleList[ index] ['disease_ids'] ?? []); showDiseaseSelectionDialog( context, selectedIds: currentDiseaseIds, onDiseasesChanged: (List newDiseaseIds) { // 更新模型数据 controller.model.peopleList[ index][ 'disease_ids'] = newDiseaseIds; controller.updateAll(); }, title: "选择慢病".tr, colors: DiseaseSelectionColors( pickerBackgroundColor: stringToColor( "#003058"), confirmTextColor: stringToColor( "#84F5FF"), selectedDiseaseColor: stringToColor( "#84F5FF"), ), diseaseList: controller .diseaseList, ); }); }, child: Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Text( '慢病管理'.tr, style: TextStyle( fontFamily: 'Readex Pro', color: Color(0xFF9EA4B7), fontSize: 30.rpx, letterSpacing: 0, ), ), Obx(() { final selectedIds = controller .model .peopleList[ index] ['disease_ids'] ?? []; final diseases = controller .diseaseList; return Row( children: [ Text( getSelectedDiseaseNames( diseases, List.from( selectedIds)), style: TextStyle( color: selectedIds.isNotEmpty ? themeController .currentColor .sc3 : themeController .currentColor .sc4, fontSize: AppConstants() .title_text_fontSize, ), ), SizedBox( width: 16.rpx, ), Container( height: 30.rpx, width: 30.rpx, child: SvgPicture .asset( 'assets/img/icon/expand_more.svg', color: Colors .white, )) ], ); }), ], ), ), ), getLine(), ], ), ) ], ); }), SizedBox( height: 100.rpx, ), ], )), )), ), ), )), ); } String time_08_Formatter_pattern(dynamic date, String pattern) { if (date == null || date.toString().isEmpty) return "-"; try { String normalized = date.toString().replaceAll("/", "-"); DateTime dt = DateTime.parse(normalized); return DateFormat(pattern).format(dt); } catch (e) { return "-"; } } Future getPersonData() async { PeopleInfoController peopleInfoController = Get.find(); await peopleInfoController .getPeoples(Get.arguments['mac'.tr]); // 控制器创建时立即执行 } CityModel? getCityModel(int index) { final list = controller.model.cityModels; if (list.isEmpty || index >= list.length) return null; return list[index]; } }