From 0ad6a1e3261f52a6c01c77e5d8893731fafaf958 Mon Sep 17 00:00:00 2001 From: wyf <494641114@qq.com> Date: Wed, 17 Dec 2025 14:55:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=9C=A0=E8=8A=B1=E7=B3=96?= =?UTF-8?q?=E6=85=A2=E7=97=85=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mh_controller/people_info_controller.dart | 87 +++++- lib/pages/mh_page/device/mht_people_info.dart | 138 +++++++++- lib/pages/person/select_disease.dart | 256 ++++++++++++++++++ 3 files changed, 458 insertions(+), 23 deletions(-) create mode 100644 lib/pages/person/select_disease.dart diff --git a/lib/controller/mh_controller/people_info_controller.dart b/lib/controller/mh_controller/people_info_controller.dart index 17f02a7..52d5b73 100644 --- a/lib/controller/mh_controller/people_info_controller.dart +++ b/lib/controller/mh_controller/people_info_controller.dart @@ -1,15 +1,19 @@ import 'dart:ui'; + import 'package:EasyDartModule/EasyDartModule.dart'; import 'package:ef/ef.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:vbvs_app/common/color/ServiceConstant.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/DailyLogUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; -import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/model/api_response.dart'; part 'people_info_controller.g.dart'; // 由json_serializable自动生成的部分 @@ -25,6 +29,7 @@ class PeopleInfoModel { String? contact; List peopleList = []; List cityModels = []; + List selectedDiseaseIds = []; PeopleInfoModel(); factory PeopleInfoModel.fromJson(Map json) { @@ -46,6 +51,8 @@ class PeopleInfoController extends GetControllerEx { } final CityModelController cityController = Get.find(); + RxList diseaseList = [].obs; + @override Future onInit() async { @@ -113,29 +120,32 @@ class PeopleInfoController extends GetControllerEx { if (!cityController.isDataLoaded) { await cityController.loadAndSetCityData(); } - + // 清空现有的城市模型列表 model.cityModels = []; - + // 遍历peopleList中的每个人,查找对应的城市数据 for (var person in model.peopleList) { if (person is Map) { // 获取person中的city_id final cityId = person['city_id']?.toString(); - + if (cityId != null && cityId.isNotEmpty) { ef.log("开始查找city_id: $cityId"); - + // 使用cityController查找完整的城市数据 - final CityModel? completeCityData = cityController.findCityById(cityId); - + final CityModel? completeCityData = + cityController.findCityById(cityId); + if (completeCityData != null) { // 将找到的城市数据添加到cityModels列表中 model.cityModels.add(completeCityData); - ef.log("成功添加城市数据: ${completeCityData.displayName} for person: ${person['name'] ?? 'Unknown'}"); + ef.log( + "成功添加城市数据: ${completeCityData.displayName} for person: ${person['name'] ?? 'Unknown'}"); } else { // 如果找不到对应的城市数据,添加一个空的CityModel,但保留city_id - final CityModel emptyCityModel = CityModel(id: int.tryParse(cityId)); + final CityModel emptyCityModel = + CityModel(id: int.tryParse(cityId)); model.cityModels.add(emptyCityModel); ef.log("未找到对应城市数据,创建默认CityModel for city_id: $cityId"); } @@ -146,16 +156,17 @@ class PeopleInfoController extends GetControllerEx { } } } - + // 确保cityModels列表长度与peopleList一致 while (model.cityModels.length < model.peopleList.length) { model.cityModels.add(CityModel()); } - + // 更新UI updateAll(); - - ef.log("初始化城市数据完成,peopleList长度: ${model.peopleList.length}, cityModels长度: ${model.cityModels.length}"); + + ef.log( + "初始化城市数据完成,peopleList长度: ${model.peopleList.length}, cityModels长度: ${model.cityModels.length}"); } catch (e) { ef.log("初始化城市数据失败: $e"); } @@ -176,4 +187,52 @@ class PeopleInfoController extends GetControllerEx { updateAll(); } } -} \ No newline at end of file + + Future getDiseaseData() async { + try { + ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr); + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.server_service; + String serviceApi = ServiceConstant.disease_list; + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + String? language = ""; + if (AppConstants().ent_type == APPPackageType.MHT.code) { + if (mhLanguageController.selectLanguage != null) { + language = mhLanguageController.selectLanguage.value!.language_code; + } + } else { + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + } + if (language != null && language.isNotEmpty) { + if (queryUrl.contains("?")) { + queryUrl += "&lang=$language"; + } else { + queryUrl += "?lang=$language"; + } + } + var response = await EasyDartModule.dio.get(queryUrl); + if (response != null) { + var responseData = + response.data is String ? jsonDecode(response.data) : response.data; + ApiResponse res = + ApiResponse.fromJson(responseData, (object) => object); + MyUtils.formatResponse(res, "请求成功".tr, "请求失败".tr); + if (res.code == HttpStatusCodes.ok) { + // bindDeviceNum.value = res.total!; + diseaseList.value = res.data!; + updateAll(); + return res; + } + } else { + return ApiResponse(code: -1, msg: "失败".tr); + } + return apiResponse; + } catch (e) { + EasyDartModule.logger.info("疾病请求列表: $e"); + DailyLogUtils.writeLog("疾病请求列表: $e"); + } + return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement + } +} diff --git a/lib/pages/mh_page/device/mht_people_info.dart b/lib/pages/mh_page/device/mht_people_info.dart index 0409f88..f864ead 100644 --- a/lib/pages/mh_page/device/mht_people_info.dart +++ b/lib/pages/mh_page/device/mht_people_info.dart @@ -10,10 +10,12 @@ import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/requestWithLog.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/device/controller/mht_bluetooth_controller.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; import 'package:vbvs_app/pages/person/select_city.dart'; +import 'package:vbvs_app/pages/person/select_disease.dart'; // 导入疾病选择 //保存人员信息 class MHTPeopleInfoPage extends StatefulWidget { @@ -30,9 +32,13 @@ class _MHTPeopleInfoPageState extends State { final List _contactControllers = []; List> peopleList = []; List cityModels = []; // 存储每个person的城市数据 + List> diseaseIdsList = []; // 存储每个person的疾病ID列表 bool isLoading = true; late Future> cityDataFuture; + // 添加疾病数据(这里需要根据实际情况获取,可以先设为空列表) + List diseaseList = []; + @override void initState() { super.initState(); @@ -69,11 +75,29 @@ class _MHTPeopleInfoPageState extends State { // 初始化城市模型列表 cityModels = List.filled(peopleList.length, CityModel()); + // 初始化疾病ID列表 + diseaseIdsList = List.generate(peopleList.length, (index) => []); + + // 加载疾病数据(这里需要实现获取疾病数据的方法) + await _loadDiseaseData(); + // Initialize controllers after data is loaded _initializeControllers(); setState(() => isLoading = false); } + // 加载疾病数据的方法 + Future _loadDiseaseData() async { + try { + PeopleInfoController controller = Get.find(); + await controller.getDiseaseData(); + diseaseList = controller.diseaseList.value; + } catch (e) { + print("加载疾病数据失败: $e"); + diseaseList = []; + } + } + void _initializeControllers() { for (var person in peopleList) { _nameControllers.add(TextEditingController(text: person["name"] ?? "")); @@ -112,6 +136,23 @@ class _MHTPeopleInfoPageState extends State { } } + // 获取已选择的慢病名称 + String getSelectedDiseaseNames(List selectedIds) { + if (selectedIds.isEmpty) return "请选择慢病".tr; + + final selectedNames = diseaseList + .where((disease) => selectedIds.contains(disease['_id'].toString())) + .map((disease) => disease['disease_type_name'].toString()) + .toList(); + + String displayText = selectedNames.join('、'); + if (displayText.length > 10) { + displayText = '${displayText.substring(0, 10)}...'; + } + + return displayText; + } + Future _savePersonData( Map personData, BuildContext context) async { String serviceAddress = ServiceConstant.service_address; @@ -133,6 +174,7 @@ class _MHTPeopleInfoPageState extends State { 'id': personData['id'], 'UTC': personData['UTC'], 'city_id': personData['city_id'], + 'disease_ids': personData['disease_ids'], // 添加疾病ID字段 }; await requestWithLog( logTitle: "保存用户信息".tr, @@ -315,14 +357,14 @@ class _MHTPeopleInfoPageState extends State { } // 验证城市选择 - final cityModel = cityModels[i]; - if (cityModel.id == null) { - TopSlideNotification.show(context, - text: "请选择城市".tr, - textColor: Color(0xFFFF7159)); - isValid = false; - break; - } + // final cityModel = cityModels[i]; + // if (cityModel.id == null) { + // TopSlideNotification.show(context, + // text: "请选择城市".tr, + // textColor: Color(0xFFFF7159)); + // isValid = false; + // break; + // } } if (isValid) { @@ -330,10 +372,12 @@ class _MHTPeopleInfoPageState extends State { for (int i = 0; i < peopleList.length; i++) { final person = peopleList[i]; final cityModel = cityModels[i]; + final diseaseIds = diseaseIdsList[i]; // 添加城市信息到person数据 person['UTC'] = cityModel.UTC; person['city_id'] = cityModel.id; + person['disease_ids'] = diseaseIds; // 添加疾病ID await _savePersonData(person, context); } @@ -867,6 +911,83 @@ class _MHTPeopleInfoPageState extends State { ), ), 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.from( + diseaseIdsList[index]); + + showDiseaseSelectionDialog( + context, + selectedIds: currentDiseaseIds, + diseaseList: diseaseList, + onDiseasesChanged: + (List newDiseaseIds) { + setState(() { + diseaseIdsList[index] = + newDiseaseIds; + }); + }, + title: "选择慢病".tr, + colors: DiseaseSelectionColors( + pickerBackgroundColor: + stringToColor("#003058"), + confirmTextColor: + stringToColor("#84F5FF"), + selectedDiseaseColor: + stringToColor("#84F5FF"), + ), + ); + }); + }, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '慢病管理'.tr, + style: TextStyle( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Row( + children: [ + Text( + getSelectedDiseaseNames( + diseaseIdsList[index]), + style: TextStyle( + color: diseaseIdsList[index] + .isNotEmpty + ? Colors.white + : themeController + .currentColor.sc4, + fontSize: 30.rpx, + ), + ), + SizedBox(width: 16.rpx), + Icon(Icons.expand_more, + color: Colors.white, + size: 48.rpx), + ], + ), + ], + ), + ), + ), + getLine(), ], )) ], @@ -884,4 +1005,3 @@ class _MHTPeopleInfoPageState extends State { ); } } - diff --git a/lib/pages/person/select_disease.dart b/lib/pages/person/select_disease.dart new file mode 100644 index 0000000..148d0e7 --- /dev/null +++ b/lib/pages/person/select_disease.dart @@ -0,0 +1,256 @@ +// 慢病选择弹窗方法(简化版,不需要Future参数) +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; + +void showDiseaseSelectionDialog( + BuildContext context, { + required List selectedIds, + required List diseaseList, + Function(List)? onDiseasesChanged, + String title = "选择慢病", + DiseaseSelectionColors? colors, +}) { + ThemeController themeController = Get.find(); + + // 使用传入的颜色,如果没传则使用主题颜色 + final Color pickerBackgroundColor = + colors?.pickerBackgroundColor ?? themeController.currentColor.sc17; + final Color confirmTextColor = + colors?.confirmTextColor ?? themeController.currentColor.sc2; + final Color selectedDiseaseColor = + colors?.selectedDiseaseColor ?? themeController.currentColor.sc2; + + final RxList selectedDiseaseIds = selectedIds.obs; + + showModalBottomSheet( + context: context, + backgroundColor: Colors.transparent, + isScrollControlled: true, + enableDrag: false, + isDismissible: true, + builder: (BuildContext context) { + return Container( + color: Colors.transparent, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // 半透明遮罩层,点击关闭 + Expanded( + child: GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + color: Colors.black.withOpacity(0.5), + ), + ), + ), + // 弹窗内容 + _buildDiseasePickerContent( + context, + themeController, + title, + diseaseList, + selectedDiseaseIds, + onDiseasesChanged, + pickerBackgroundColor: pickerBackgroundColor, + confirmTextColor: confirmTextColor, + selectedDiseaseColor: selectedDiseaseColor, + ), + ], + ), + ); + }, + ); +} + +// 慢病选择器颜色配置 +class DiseaseSelectionColors { + final Color? pickerBackgroundColor; // 选择器整体背景色 + final Color? confirmTextColor; // 确定按钮文字颜色 + final Color? selectedDiseaseColor; // 选中的慢病颜色 + + const DiseaseSelectionColors({ + this.pickerBackgroundColor, + this.confirmTextColor, + this.selectedDiseaseColor, + }); +} + +// 慢病选择器内容 +Widget _buildDiseasePickerContent( + BuildContext context, + ThemeController themeController, + String title, + List diseaseList, + RxList selectedIds, + Function(List)? onDiseasesChanged, { + required Color pickerBackgroundColor, + required Color confirmTextColor, + required Color selectedDiseaseColor, +}) { + final bottomInsets = MediaQuery.of(context).viewInsets.bottom; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: pickerBackgroundColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20.rpx), + topRight: Radius.circular(20.rpx), + ), + ), + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height * 0.35, + ), + child: Padding( + padding: + EdgeInsets.fromLTRB(30.rpx, 10.rpx, 30.rpx, bottomInsets + 10.rpx), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.zero, + onTap: () => Navigator.of(context).pop(), + child: Container( + width: 110.rpx, + height: 60.rpx, + alignment: Alignment.center, + child: Text("取消".tr, + style: TextStyle(fontSize: 30.rpx, color: Colors.white)), + ), + ), + Text( + title, + style: TextStyle( + fontFamily: 'Readex Pro', + color: themeController.currentColor.sc3, + fontSize: 30.rpx, + ), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.zero, + onTap: () { + onDiseasesChanged?.call(List.from(selectedIds)); + Navigator.of(context).pop(); + }, + child: Container( + width: 110.rpx, + height: 60.rpx, + alignment: Alignment.center, + child: Text("确定".tr, + style: TextStyle( + fontSize: 30.rpx, + color: confirmTextColor, + )), + ), + ), + ], + ), + + SizedBox(height: 20.rpx), + + // 慢病标签选择区域 + Expanded( + child: SingleChildScrollView( + child: Obx(() { + if (diseaseList.isEmpty) { + return Center( + child: Padding( + padding: EdgeInsets.only(top: 100.rpx), + child: Text( + "暂无慢病数据".tr, + style: TextStyle( + color: themeController.currentColor.sc4, + fontSize: 28.rpx, + ), + ), + ), + ); + } + + return Padding( + padding: EdgeInsetsDirectional.fromSTEB(10.rpx, 0, 10.rpx, 0), + child: Wrap( + spacing: 20.rpx, + runSpacing: 20.rpx, + children: diseaseList.map((disease) { + final id = disease['_id'].toString(); + final name = disease['disease_type_name'].toString(); + final isSelected = selectedIds.contains(id); + + return GestureDetector( + onTap: () { + if (isSelected) { + selectedIds.remove(id); + } else { + selectedIds.add(id); + } + }, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 30.rpx, + vertical: 15.rpx, + ), + decoration: BoxDecoration( + color: isSelected + ? selectedDiseaseColor + : Colors.transparent, + border: Border.all( + color: isSelected + ? selectedDiseaseColor + : themeController.currentColor.sc4, + width: 1.rpx, + ), + borderRadius: BorderRadius.circular(30.rpx), + ), + child: Text( + name, + style: TextStyle( + color: isSelected + ? pickerBackgroundColor + : themeController.currentColor.sc3, + fontSize: 28.rpx, + ), + ), + ), + ); + }).toList(), + ), + ); + }), + ), + ), + + SizedBox(height: 10.rpx), + ], + ), + ), + ); +} + +// 获取已选择的慢病名称 +String getSelectedDiseaseNames(List diseaseList, List selectedIds) { + if (selectedIds.isEmpty) return "请选择慢病".tr; + + final selectedNames = diseaseList + .where((disease) => selectedIds.contains(disease['_id'].toString())) + .map((disease) => disease['disease_type_name'].toString()) + .toList(); + + String displayText = selectedNames.join('、'); + if (displayText.length > 10) { + displayText = '${displayText.substring(0, 10)}...'; + } + + return displayText; +}