1.修复睡眠日报中睡眠规律性数据显示错误

2.更新时区设置
This commit is contained in:
wyf
2026-01-07 15:19:16 +08:00
parent 36f19a71eb
commit 575f91e8dd
42 changed files with 4236 additions and 1653 deletions

View File

@@ -625,5 +625,8 @@
"邮箱登录": "Email Login", "邮箱登录": "Email Login",
"输入邮箱": "Enter Email", "输入邮箱": "Enter Email",
"隐私协议加载失败": "Privacy Agreement Failed to Load", "隐私协议加载失败": "Privacy Agreement Failed to Load",
"请检查网络连接后重试": "Please check the network connection and try again" "请检查网络连接后重试": "Please check the network connection and try again",
"开始": "startTime",
"结束": "endTime",
"时长": "duration"
} }

View File

@@ -615,18 +615,18 @@
"原邮箱号": "原邮箱号", "原邮箱号": "原邮箱号",
"用户拒绝授权": "用户拒绝授权", "用户拒绝授权": "用户拒绝授权",
"用户取消授权": "用户取消授权", "用户取消授权": "用户取消授权",
"请输入邮箱号":"请输入邮箱号", "请输入邮箱号": "请输入邮箱号",
"中国":"中国", "中国": "中国",
"香港":"香港", "香港": "香港",
"选择区号":"选择区号", "选择区号": "选择区号",
"输入邮箱号码":"输入邮箱号码", "输入邮箱号码": "输入邮箱号码",
"通知设置":"通知设置", "通知设置": "通知设置",
"注意!关闭后将无法接受任何消息":"注意!关闭后将无法接受任何消息", "注意!关闭后将无法接受任何消息": "注意!关闭后将无法接受任何消息",
"手机号登录":"手机号登录", "手机号登录": "手机号登录",
"邮箱登录":"邮箱登录", "邮箱登录": "邮箱登录",
"输入邮箱":"输入邮箱", "输入邮箱": "输入邮箱",
"隐私协议加载失败": "隐私协议加载失败", "隐私协议加载失败": "隐私协议加载失败",
"请检查网络连接后重试": "请检查网络连接后重试" "请检查网络连接后重试": "请检查网络连接后重试",
"开始": "开始",
"结束": "结束"
} }

View File

@@ -623,5 +623,8 @@
"邮箱登录": "電子郵件登入", "邮箱登录": "電子郵件登入",
"输入邮箱": "輸入電子郵件", "输入邮箱": "輸入電子郵件",
"隐私协议加载失败": "隱私協議加載失敗", "隐私协议加载失败": "隱私協議加載失敗",
"请检查网络连接后重试": "請檢查網絡連接後重試" "请检查网络连接后重试": "請檢查網絡連接後重試",
"开始": "開始",
"结束": "結束",
"时长": "時長:"
} }

View File

@@ -642,5 +642,9 @@
"安卓启用网络提示": "The network is not enabled. Please enable the network connection", "安卓启用网络提示": "The network is not enabled. Please enable the network connection",
"ios启用网络提示": "The network is not enabled. Please enable the network connection", "ios启用网络提示": "The network is not enabled. Please enable the network connection",
"隐私协议加载失败": "Privacy Agreement Failed to Load", "隐私协议加载失败": "Privacy Agreement Failed to Load",
"请检查网络连接后重试": "Please check the network connection and try again" "请检查网络连接后重试": "Please check the network connection and try again",
"开始": "startTime",
"结束": "endTime",
"时长": "duration",
"请选择时区": "Please select a time zone"
} }

View File

@@ -649,6 +649,9 @@
"安卓启用网络提示": "网络未开启,请打开网络连接", "安卓启用网络提示": "网络未开启,请打开网络连接",
"ios启用网络提示": "网络未开启,请打开网络连接", "ios启用网络提示": "网络未开启,请打开网络连接",
"隐私协议加载失败": "隐私协议加载失败", "隐私协议加载失败": "隐私协议加载失败",
"请检查网络连接后重试": "请检查网络连接后重试" "请检查网络连接后重试": "请检查网络连接后重试",
"开始": "开始",
"结束": "结束",
"时长": "时长:",
"请选择时区": "请选择时区"
} }

View File

@@ -642,5 +642,9 @@
"安卓启用网络提示": "請開啟網絡再使用APP", "安卓启用网络提示": "請開啟網絡再使用APP",
"ios启用网络提示": "請開啟網絡再使用APP", "ios启用网络提示": "請開啟網絡再使用APP",
"隐私协议加载失败": "隱私協議加載失敗", "隐私协议加载失败": "隱私協議加載失敗",
"请检查网络连接后重试": "請檢查網絡連接後重試" "请检查网络连接后重试": "請檢查網絡連接後重試",
"开始": "開始",
"结束": "結束",
"时长": "時長:",
"请选择时区": "請選擇時區"
} }

Binary file not shown.

View File

@@ -59,4 +59,6 @@ class ServiceConstant {
static const String bgUrl = static const String bgUrl =
"https://vsbst-api.he-info.cn/vsbs_sotrage/background-image/taihe.png"; "https://vsbst-api.he-info.cn/vsbs_sotrage/background-image/taihe.png";
static const String localTimeZone =
"/api/city/data/utc/info";
} }

View File

@@ -7,6 +7,37 @@ import 'package:vbvs_app/enum/APPPackageType.dart';
class AppConstants { class AppConstants {
// App-related constants // App-related constants
// 1. 纯字符串列表格式
static const List<String> integerTimeZones = [
'UTC-12',
'UTC-11',
'UTC-10',
'UTC-9',
'UTC-8',
'UTC-7',
'UTC-6',
'UTC-5',
'UTC-4',
'UTC-3',
'UTC-2',
'UTC-1',
'UTC+0',
'UTC+1',
'UTC+2',
'UTC+3',
'UTC+4',
'UTC+5',
'UTC+6',
'UTC+7',
'UTC+8',
'UTC+9',
'UTC+10',
'UTC+11',
'UTC+12',
'UTC+13',
'UTC+14',
];
static const int code_time = 60; //验证码倒计时 static const int code_time = 60; //验证码倒计时
static const int limit = 10; //分页数量 static const int limit = 10; //分页数量

View File

@@ -12,3 +12,5 @@ class SwitchLanguageEvent {
final String language; final String language;
SwitchLanguageEvent(this.language); SwitchLanguageEvent(this.language);
} }
class ScrollNotificationEvent {}

View File

@@ -50,6 +50,8 @@ class MessageController extends GetControllerEx<MessageModel> {
int bodyPage = 1; int bodyPage = 1;
int systemPage = 1; int systemPage = 1;
bool isLoadingMore = false; // 添加加载标志位
Future<void> loadMore(String type) async { Future<void> loadMore(String type) async {
if (type == "app_vsm") { if (type == "app_vsm") {
bodyPage++; bodyPage++;

View File

@@ -55,6 +55,7 @@ class PeopleInfoController extends GetControllerEx<PeopleInfoModel> {
final CityModelController cityController = Get.find<CityModelController>(); final CityModelController cityController = Get.find<CityModelController>();
RxList diseaseList = [].obs; RxList diseaseList = [].obs;
RxString timeZone = "".obs; //选择时区
@override @override
Future<void> onInit() async { Future<void> onInit() async {
@@ -247,4 +248,35 @@ class PeopleInfoController extends GetControllerEx<PeopleInfoModel> {
} }
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
} }
getTimeZoneByLocalTime() async {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.localTimeZone;
// 获取当前本地时间并格式化为字符串
DateTime now = DateTime.now();
String time = DateFormat("yyyy-MM-dd HH:mm:ss").format(now);
// 构建查询URL对时间参数进行URL编码
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?time=${Uri.encodeComponent(time)}";
String serverTimeUtc = "";
// 发起请求
await requestWithLog(
logTitle: "查询本地时区",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
print("本地时间: $time");
print("接口返回: $res");
serverTimeUtc = res.data;
},
onFailure: (res) {
print("查询时区失败");
},
);
return serverTimeUtc;
}
} }

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:EasyDartModule/EasyDartModule.dart'; import 'package:EasyDartModule/EasyDartModule.dart';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart'; import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
@@ -9,6 +10,7 @@ import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/pojo/city.dart'; import 'package:vbvs_app/common/pojo/city.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart'; import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/enum/APPPackageType.dart'; import 'package:vbvs_app/enum/APPPackageType.dart';
import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/model/api_response.dart';
@@ -50,6 +52,7 @@ class PersonController extends GetControllerEx<PersonModel> {
RxString height = "".obs; RxString height = "".obs;
DateTime? dateTime = DateTime.now(); //选择时间 DateTime? dateTime = DateTime.now(); //选择时间
CityModel? cityModel; CityModel? cityModel;
RxString timeZone = "".obs; //选择时区
RxList diseaseList = [].obs; RxList diseaseList = [].obs;
RxString update_person_mac = "".obs; RxString update_person_mac = "".obs;
@@ -79,10 +82,10 @@ class PersonController extends GetControllerEx<PersonModel> {
queryUrl += "?lang=$language"; queryUrl += "?lang=$language";
} }
} }
if (name.value.isEmpty) { // if (name.value.isEmpty) {
apiResponse.msg = "请输入姓名".tr; // apiResponse.msg = "请输入姓名".tr;
return apiResponse; // return apiResponse;
} // }
if (birthday.value.isEmpty) { if (birthday.value.isEmpty) {
apiResponse.msg = "请选择生日".tr; apiResponse.msg = "请选择生日".tr;
return apiResponse; return apiResponse;
@@ -95,10 +98,14 @@ class PersonController extends GetControllerEx<PersonModel> {
apiResponse.msg = "请输入身高".tr; apiResponse.msg = "请输入身高".tr;
return apiResponse; return apiResponse;
} }
if (cityModel == null || cityModel!.id == null) { if (timeZone == null || timeZone.value.isEmpty) {
apiResponse.msg = "请选择城市".tr; apiResponse.msg = "请选择时区".tr;
return apiResponse; return apiResponse;
} }
// if (cityModel == null || cityModel!.id == null) {
// apiResponse.msg = "请选择城市".tr;
// return apiResponse;
// }
var data = { var data = {
"id": currentPersonId.value, "id": currentPersonId.value,
@@ -110,8 +117,8 @@ class PersonController extends GetControllerEx<PersonModel> {
"weight": weight!.value, "weight": weight!.value,
"height": height.value, "height": height.value,
"disease": selectedDiseaseIds.value, "disease": selectedDiseaseIds.value,
"city_id": cityModel!.id, "city_id": cityModel?.id,
"UTC": cityModel!.UTC, "UTC": timeZone.value,
}; };
var response = var response =
await EasyDartModule.dio.put(queryUrl, data: jsonEncode(data)); await EasyDartModule.dio.put(queryUrl, data: jsonEncode(data));
@@ -240,4 +247,35 @@ class PersonController extends GetControllerEx<PersonModel> {
} }
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
} }
getTimeZoneByLocalTime() async {
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.localTimeZone;
// 获取当前本地时间并格式化为字符串
DateTime now = DateTime.now();
String time = DateFormat("yyyy-MM-dd HH:mm:ss").format(now);
// 构建查询URL对时间参数进行URL编码
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?time=${Uri.encodeComponent(time)}";
String serverTimeUtc = "";
// 发起请求
await requestWithLog(
logTitle: "查询本地时区",
method: MyHttpMethod.get,
queryUrl: queryUrl,
onSuccess: (res) {
print("本地时间: $time");
print("接口返回: $res");
serverTimeUtc = res.data;
},
onFailure: (res) {
print("查询时区失败");
},
);
return serverTimeUtc;
}
} }

View File

@@ -40,7 +40,7 @@ class RepairController extends GetControllerEx<RepairModel> {
attr = GetModel(RepairModel()).obs; attr = GetModel(RepairModel()).obs;
} }
RxDouble device_type = 0.0.obs; RxInt device_type = 0.obs;
RxList repairList = [].obs; RxList repairList = [].obs;
RxString name = "".obs; RxString name = "".obs;

View File

@@ -69,6 +69,66 @@ Widget getOnePickers(
}) { }) {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false; final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false;
final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}');
return Obx(() {
return CupertinoPicker.builder(
key: pickerKey ?? dynamicKey,
itemExtent: 90.rpx,
useMagnifier: false,
magnification: 1,
diameterRatio: 1.3,
squeeze: 1,
scrollController:
FixedExtentScrollController(initialItem: selectedIndex.value),
selectionOverlay: Container(),
onSelectedItemChanged: (int index) {
selectedIndex.value = index;
if (onChanged != null) onChanged(index);
},
childCount: arr.length,
itemBuilder: (context, index) {
final bool isSelected = index == selectedIndex.value;
// 显示文本
String displayText;
if (isMonthName && isEn && arr[index] is int) {
displayText = DateFormat.MMMM('en').format(DateTime(0, arr[index]));
} else {
displayText = "${arr[index]}$unit";
}
return Center(
child: Text(
displayText,
style: TextStyle(
fontFamily: 'Readex Pro',
color: isSelected
? (selectedColor ??
themeController.currentColor.sc3) // ✅ 优先使用外部颜色
: const Color(0xFF9AA0B3),
fontSize: 30.rpx,
fontWeight: FontWeight.normal,
),
),
);
},
);
});
}
Widget getOnePickersCity(
BuildContext context,
List arr,
RxInt selectedIndex, {
String unit = '',
bool looping = false,
void Function(int)? onChanged,
bool isMonthName = false,
Key? pickerKey,
Color? selectedColor, // ✅ 新增:选中颜色(可选)
}) {
ThemeController themeController = Get.find();
final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false;
return Obx(() { return Obx(() {
final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}'); final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}');
@@ -132,9 +192,8 @@ Widget getOnePickersSpe(
}) { }) {
ThemeController themeController = Get.find(); ThemeController themeController = Get.find();
final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false; final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false;
return Obx(() {
final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}'); final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}');
return Obx(() {
return CupertinoPicker.builder( return CupertinoPicker.builder(
key: pickerKey ?? dynamicKey, key: pickerKey ?? dynamicKey,
itemExtent: 90.rpx, itemExtent: 90.rpx,
@@ -1777,8 +1836,7 @@ Future showCustomConfirmOfWebViewDialog(
bool showCancel = false, bool showCancel = false,
String cancelName = "取消", String cancelName = "取消",
ConfirmDialogIcon icon = ConfirmDialogIcon.warn, ConfirmDialogIcon icon = ConfirmDialogIcon.warn,
int type = 1 int type = 1}) async {
}) async {
return showDialog( return showDialog(
context: context, context: context,
barrierDismissible: true, barrierDismissible: true,
@@ -1865,7 +1923,9 @@ Future showCustomConfirmOfWebViewDialog(
onTap: () { onTap: () {
Get.back(result: "confirm"); Get.back(result: "confirm");
}, },
colors: type == 3?AppConstants().mhtNormalButton:AppConstants().thNormalButton, // 渐变背景 colors: type == 3
? AppConstants().mhtNormalButton
: AppConstants().thNormalButton, // 渐变背景
gradientDirection: GradientDirection.horizontal, gradientDirection: GradientDirection.horizontal,
child: Container( child: Container(
// width: MediaQuery.sizeOf(context).width * 0.5, // 宽度占屏幕一半 // width: MediaQuery.sizeOf(context).width * 0.5, // 宽度占屏幕一半

View File

@@ -5,8 +5,10 @@ import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart'; import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart'; import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/EventBus.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart'; import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/eventType.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart'; import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart'; import 'package:vbvs_app/component/tool/CustomCard.dart';
@@ -641,7 +643,8 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
: Padding( : Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 26.rpx, 30.rpx, 0), 30.rpx, 26.rpx, 30.rpx, 0),
child: SingleChildScrollView( child: _wrapWithScrollListener(
SingleChildScrollView(
controller: _myDeviceScrollController, controller: _myDeviceScrollController,
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@@ -650,7 +653,9 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
DeviceDataComponentWidget( DeviceDataComponentWidget(
device: device)) device: device))
.toList() .toList()
.divide(SizedBox(height: 25.rpx)), .divide(
SizedBox(height: 25.rpx)),
),
), ),
), ),
); );
@@ -668,7 +673,8 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
: Padding( : Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 26.rpx, 30.rpx, 0), 30.rpx, 26.rpx, 30.rpx, 0),
child: SingleChildScrollView( child: _wrapWithScrollListener(
SingleChildScrollView(
controller: controller:
_cloudDeviceScrollController, _cloudDeviceScrollController,
child: Column( child: Column(
@@ -678,7 +684,9 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
DeviceDataComponentWidget( DeviceDataComponentWidget(
device: device)) device: device))
.toList() .toList()
.divide(SizedBox(height: 25.rpx)), .divide(
SizedBox(height: 25.rpx)),
),
), ),
), ),
); );
@@ -743,3 +751,18 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
); );
} }
} }
// 在你的父页面类中添加这个方法
Widget _wrapWithScrollListener(Widget child) {
return NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
if (notification is ScrollStartNotification ||
notification is ScrollUpdateNotification) {
// 发送全局滚动事件
EventBus().emit(ScrollNotificationEvent());
}
return false;
},
child: child,
);
}

View File

@@ -25,7 +25,6 @@ import 'package:vbvs_app/enum/BindType.dart';
import 'package:vbvs_app/model/api_response.dart'; import 'package:vbvs_app/model/api_response.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart'; import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class DeviceDataComponentWidget extends StatefulWidget { class DeviceDataComponentWidget extends StatefulWidget {
final Map<String, dynamic> device; final Map<String, dynamic> device;
@@ -44,6 +43,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
bool _isPopupOpen = false; bool _isPopupOpen = false;
var lisObj; var lisObj;
late StreamSubscription<ScrollNotificationEvent> _scrollSubscription;
@override @override
void dispose() { void dispose() {
@@ -64,6 +64,12 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
cityController.cityList = []; cityController.cityList = [];
await initializeCityData(); await initializeCityData();
}); });
_scrollSubscription =
EventBus().on<ScrollNotificationEvent>().listen((event) {
if (_isPopupOpen) {
_closePopup();
}
});
} }
void _showPopup() { void _showPopup() {
@@ -628,7 +634,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
maxWidth: MediaQuery.sizeOf(context).width * 0.6, maxWidth: MediaQuery.sizeOf(context).width * 0.6,
), ),
child: Text( child: Text(
'${widget.device['person']?['name'] ?? '未命名'.tr}', '${(widget.device['person']?['name'] as String?)?.isNotEmpty == true ? widget.device['person']!['name'] : '体征检测设备'.tr}',
style: TextStyle( style: TextStyle(
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: 30.rpx, fontSize: 30.rpx,
@@ -1180,6 +1186,8 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
personController.dateTime = personController.dateTime =
MyUtils.formatBirthdayTime( MyUtils.formatBirthdayTime(
widget.device['person']['birthday']); widget.device['person']['birthday']);
personController.timeZone.value =
widget.device['person']['UTC'] ?? '';
if (widget.device['person']['city_id'] != null) { if (widget.device['person']['city_id'] != null) {
// 根据city_id查找完整的城市数据 // 根据city_id查找完整的城市数据
final int cityId = final int cityId =
@@ -1208,6 +1216,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
personController.weight.value = ""; personController.weight.value = "";
personController.diseaseList.value = []; personController.diseaseList.value = [];
personController.cityModel = null; personController.cityModel = null;
personController.timeZone.value = "";
} }
await Get.toNamed("/updatePersonPage", await Get.toNamed("/updatePersonPage",
arguments: widget.device['bind_type']); arguments: widget.device['bind_type']);
@@ -1701,4 +1710,12 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
} }
return false; return false;
} }
void _closePopup() {
setState(() {
_isPopupOpen = false;
});
_popupEntry?.remove();
_popupEntry = null;
}
} }

View File

@@ -659,7 +659,7 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
children: [ children: [
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 40.rpx, 40.rpx, 20.rpx), 30.rpx, 40.rpx, 30.rpx, 20.rpx),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
@@ -681,9 +681,9 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
(data["real"] as List)[i].containsKey("name")) (data["real"] as List)[i].containsKey("name"))
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 30.rpx,
i == 0 ? 20.rpx : 0, // 第一个元素顶部有20.rpx间距 i == 0 ? 20.rpx : 0, // 第一个元素顶部有20.rpx间距
40.rpx, 30.rpx,
i == (data["real"] as List).length - 1 i == (data["real"] as List).length - 1
? 20.rpx ? 20.rpx
: 0.rpx), : 0.rpx),
@@ -781,7 +781,7 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
children: [ children: [
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 40.rpx, 40.rpx, 20.rpx), 30.rpx, 40.rpx, 30.rpx, 20.rpx),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
@@ -803,9 +803,9 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
(data["report"] as List)[i].containsKey("name")) (data["report"] as List)[i].containsKey("name"))
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 30.rpx,
i == 0 ? 20.rpx : 0, // 第一个元素顶部有20.rpx间距 i == 0 ? 20.rpx : 0, // 第一个元素顶部有20.rpx间距
40.rpx, 30.rpx,
i == (data["report"] as List).length - 1 i == (data["report"] as List).length - 1
? 20.rpx ? 20.rpx
: 0.rpx), : 0.rpx),

View File

@@ -10,6 +10,7 @@ import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart'; import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/base/GradientSwitch.dart'; import 'package:vbvs_app/component/base/GradientSwitch.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/NewTopSlideNotification.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/message/common_message_setting_controller.dart'; import 'package:vbvs_app/controller/message/common_message_setting_controller.dart';
import 'package:vbvs_app/controller/message/message_setting_controller.dart'; import 'package:vbvs_app/controller/message/message_setting_controller.dart';
@@ -197,7 +198,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder( return WillPopScope(
child: LayoutBuilder(
builder: (context, bodysize) => GestureDetector( builder: (context, bodysize) => GestureDetector(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -233,7 +235,9 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
), ),
Positioned( Positioned(
left: 0, left: 0,
child: returnIconButtomAddCallback(() {}), child: returnIconButtomAddCallback(() {
NewTopSlideNotification.show(text: "保存成功".tr);
}),
), ),
], ],
), ),
@@ -245,14 +249,15 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
child: SafeArea( child: SafeArea(
top: true, top: true,
child: Padding( child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(0.rpx, 0, 0.rpx, 0), padding:
EdgeInsetsDirectional.fromSTEB(0.rpx, 0, 0.rpx, 0),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Padding( Padding(
padding: padding: EdgeInsetsDirectional.fromSTEB(
EdgeInsetsDirectional.fromSTEB(0, 30.rpx, 0, 0), 0, 30.rpx, 0, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
constraints: BoxConstraints( constraints: BoxConstraints(
@@ -272,21 +277,23 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
child: Text( child: Text(
"全部消息".tr, "全部消息".tr,
style: TextStyle( style: TextStyle(
color: color: themeController
themeController.currentColor.sc3, .currentColor.sc3,
fontSize: AppConstants() fontSize: AppConstants()
.title_text_fontSize), .title_text_fontSize),
), ),
), ),
Obx(() { Obx(() {
return GradientSwitch( return GradientSwitch(
value: getAllMessageSwitch(widget.data), value:
getAllMessageSwitch(widget.data),
onChanged: (val) { onChanged: (val) {
if (commonMessageSettingController if (commonMessageSettingController
.model.setting == .model.setting ==
0) { 0) {
TopSlideNotification.show(context, TopSlideNotification.show(context,
text: "请先在设置里的消息通知打开全部消息配置".tr, text:
"请先在设置里的消息通知打开全部消息配置".tr,
textColor: themeController textColor: themeController
.currentColor.sc9); .currentColor.sc9);
return; return;
@@ -321,20 +328,20 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
if (configIndex != -1) { if (configIndex != -1) {
// 更新找到的配置项 // 更新找到的配置项
int newSetting = val ? 1 : 0; int newSetting = val ? 1 : 0;
messageSettingController messageSettingController.model
.model.device_type_setting[ .device_type_setting[
configIndex]['setting'] = configIndex]['setting'] =
newSetting; newSetting;
// 根据 setting 的值更新 appSetting 和 serviceSetting // 根据 setting 的值更新 appSetting 和 serviceSetting
messageSettingController messageSettingController.model
.model.device_type_setting[ .device_type_setting[
configIndex]['appSetting'] =
newSetting;
messageSettingController
.model.device_type_setting[
configIndex] configIndex]
['serviceSetting'] = newSetting; ['appSetting'] = newSetting;
messageSettingController.model
.device_type_setting[
configIndex][
'serviceSetting'] = newSetting;
} else { } else {
messageSettingController messageSettingController
.model.device_type_setting .model.device_type_setting
@@ -348,11 +355,12 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
} }
var data = { var data = {
"type": type, "type": type,
"setting": messageSettingController "setting":
messageSettingController
.model.setting, .model.setting,
"device_type_setting": "device_type_setting":
messageSettingController messageSettingController.model
.model.device_type_setting, .device_type_setting,
}; };
requestWithLog( requestWithLog(
logTitle: "更新消息推送状态", logTitle: "更新消息推送状态",
@@ -374,7 +382,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
activeThumbColor: Colors.white, activeThumbColor: Colors.white,
inactiveThumbColor: inactiveThumbColor:
stringToColor("#A2A4A9"), stringToColor("#A2A4A9"),
inactiveColor: stringToColor("#161B28"), inactiveColor:
stringToColor("#161B28"),
); );
}), }),
], ],
@@ -396,7 +405,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
30.rpx, 40.rpx, 30.rpx, 54.rpx), 30.rpx, 40.rpx, 30.rpx, 54.rpx),
child: Container( child: Container(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
Row( Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
@@ -423,10 +433,13 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
0) { 0) {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "请先在设置里的消息通知打开全部消息配置" text:
"请先在设置里的消息通知打开全部消息配置"
.tr, .tr,
textColor: themeController textColor:
.currentColor.sc9); themeController
.currentColor
.sc9);
return; return;
} }
if (commonMessageSettingController if (commonMessageSettingController
@@ -434,10 +447,13 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
0) { 0) {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "请先在设置里的消息通知打开APP消息配置" text:
"请先在设置里的消息通知打开APP消息配置"
.tr, .tr,
textColor: themeController textColor:
.currentColor.sc9); themeController
.currentColor
.sc9);
return; return;
} }
if (messageSettingController if (messageSettingController
@@ -446,8 +462,10 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "请先打开消息提醒设置".tr, text: "请先打开消息提醒设置".tr,
textColor: themeController textColor:
.currentColor.sc9); themeController
.currentColor
.sc9);
return; return;
} }
String serviceAddress = String serviceAddress =
@@ -457,38 +475,45 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
ServiceConstant ServiceConstant
.server_service; .server_service;
String serviceApi = String serviceApi =
ServiceConstant.user_setting; ServiceConstant
String mac = .user_setting;
widget.data['device']['mac']; String mac = widget
.data['device']['mac'];
String type = String type =
"user_device_message_setting_$mac"; "user_device_message_setting_$mac";
String queryUrl = String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}"; "${serviceAddress}${serviceName}${serviceApi}";
int targetId = widget.data['id']; int targetId =
widget.data['id'];
int configIndex = int configIndex =
messageSettingController messageSettingController
.model.device_type_setting .model
.device_type_setting
.indexWhere((item) => .indexWhere((item) =>
item['id'] == item['id'] ==
targetId); targetId);
if (configIndex != -1) { if (configIndex != -1) {
// 更新找到的配置项 // 更新找到的配置项
messageSettingController.model messageSettingController
.model
.device_type_setting[ .device_type_setting[
configIndex][ configIndex]
'appSetting'] = val ? 1 : 0; ['appSetting'] =
val ? 1 : 0;
// 获取当前的 serviceSetting 值 // 获取当前的 serviceSetting 值
int serviceSetting = int serviceSetting =
messageSettingController messageSettingController
.model .model
.device_type_setting[ .device_type_setting[
configIndex][ configIndex]
[
'serviceSetting'] ?? 'serviceSetting'] ??
0; 0;
// 更新 setting 字段只要有一个为1setting就为1 // 更新 setting 字段只要有一个为1setting就为1
messageSettingController.model messageSettingController
.model
.device_type_setting[ .device_type_setting[
configIndex] configIndex]
['setting'] = (val || ['setting'] = (val ||
@@ -497,7 +522,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
: 0; : 0;
} else { } else {
messageSettingController messageSettingController
.model.device_type_setting .model
.device_type_setting
.add({ .add({
"id": widget.data['id'], "id": widget.data['id'],
"setting": 1, "setting": 1,
@@ -531,7 +557,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
colors: [ colors: [
themeController themeController
.currentColor.sc1, .currentColor.sc1,
themeController.currentColor.sc2 themeController
.currentColor.sc2
], ],
), ),
activeThumbColor: Colors.white, activeThumbColor: Colors.white,
@@ -546,8 +573,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
Text( Text(
"APP消息介绍".tr, "APP消息介绍".tr,
style: TextStyle( style: TextStyle(
color: color: themeController
themeController.currentColor.sc4, .currentColor.sc4,
fontSize: AppConstants() fontSize: AppConstants()
.normal_text_fontSize), .normal_text_fontSize),
), ),
@@ -801,10 +828,13 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
0) { 0) {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "请先在设置里的消息通知打开全部消息配置" text:
"请先在设置里的消息通知打开全部消息配置"
.tr, .tr,
textColor: themeController textColor:
.currentColor.sc9); themeController
.currentColor
.sc9);
return; return;
} }
if (messageSettingController if (messageSettingController
@@ -813,8 +843,10 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
TopSlideNotification.show( TopSlideNotification.show(
context, context,
text: "请先打开消息提醒设置".tr, text: "请先打开消息提醒设置".tr,
textColor: themeController textColor:
.currentColor.sc9); themeController
.currentColor
.sc9);
return; return;
} }
String serviceAddress = String serviceAddress =
@@ -824,23 +856,27 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
ServiceConstant ServiceConstant
.server_service; .server_service;
String serviceApi = String serviceApi =
ServiceConstant.user_setting; ServiceConstant
String mac = .user_setting;
widget.data['device']['mac']; String mac = widget
.data['device']['mac'];
String type = String type =
"user_device_message_setting_$mac"; "user_device_message_setting_$mac";
String queryUrl = String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}"; "${serviceAddress}${serviceName}${serviceApi}";
int targetId = widget.data['id']; int targetId =
widget.data['id'];
int configIndex = int configIndex =
messageSettingController messageSettingController
.model.device_type_setting .model
.device_type_setting
.indexWhere((item) => .indexWhere((item) =>
item['id'] == item['id'] ==
targetId); targetId);
if (configIndex != -1) { if (configIndex != -1) {
// 更新找到的配置项 // 更新找到的配置项
messageSettingController.model messageSettingController
.model
.device_type_setting[ .device_type_setting[
configIndex] configIndex]
['serviceSetting'] = ['serviceSetting'] =
@@ -852,23 +888,26 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
.model .model
.device_type_setting[ .device_type_setting[
configIndex] configIndex]
['appSetting'] ?? [
'appSetting'] ??
0; 0;
// 更新 setting 字段 // 更新 setting 字段
// 只要 appSetting 或 serviceSetting 中有一个为1setting就为1 // 只要 appSetting 或 serviceSetting 中有一个为1setting就为1
// 只有当两者都为0时setting才为0 // 只有当两者都为0时setting才为0
messageSettingController.model messageSettingController
.model
.device_type_setting[ .device_type_setting[
configIndex] configIndex][
['setting'] = (appSetting == 'setting'] = (appSetting ==
1 || 1 ||
val) val)
? 1 ? 1
: 0; : 0;
} else { } else {
messageSettingController messageSettingController
.model.device_type_setting .model
.device_type_setting
.add({ .add({
"id": widget.data['id'], "id": widget.data['id'],
"setting": 1, "setting": 1,
@@ -902,7 +941,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
colors: [ colors: [
themeController themeController
.currentColor.sc1, .currentColor.sc1,
themeController.currentColor.sc2 themeController
.currentColor.sc2
], ],
), ),
activeThumbColor: Colors.white, activeThumbColor: Colors.white,
@@ -917,8 +957,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
Text( Text(
"服务号消息介绍".tr, "服务号消息介绍".tr,
style: TextStyle( style: TextStyle(
color: color: themeController
themeController.currentColor.sc4, .currentColor.sc4,
fontSize: AppConstants() fontSize: AppConstants()
.normal_text_fontSize), .normal_text_fontSize),
), ),
@@ -931,8 +971,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
), ),
), ),
Padding( Padding(
padding: padding: EdgeInsetsDirectional.fromSTEB(
EdgeInsetsDirectional.fromSTEB(0, 30.rpx, 0, 0), 0, 30.rpx, 0, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
constraints: BoxConstraints( constraints: BoxConstraints(
@@ -952,8 +992,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
child: Text( child: Text(
"报警条件设置".tr, "报警条件设置".tr,
style: TextStyle( style: TextStyle(
color: color: themeController
themeController.currentColor.sc3, .currentColor.sc3,
fontSize: AppConstants() fontSize: AppConstants()
.title_text_fontSize), .title_text_fontSize),
), ),
@@ -970,7 +1010,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
ServiceConstant.server_service; ServiceConstant.server_service;
String serviceApi = String serviceApi =
ServiceConstant.user_setting; ServiceConstant.user_setting;
String mac = widget.data['device']['mac']; String mac =
widget.data['device']['mac'];
String type = String type =
"user_device_message_setting_$mac"; "user_device_message_setting_$mac";
String queryUrl = String queryUrl =
@@ -979,28 +1020,35 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
Map<String, dynamic>? defaultConfig; Map<String, dynamic>? defaultConfig;
defaultConfig = messageSettingController defaultConfig =
messageSettingController
.messageType['real'] .messageType['real']
?.firstWhere( ?.firstWhere(
(item) => item['id'] == targetId, (item) =>
item['id'] ==
targetId,
orElse: () => null); orElse: () => null);
if (defaultConfig == null) { if (defaultConfig == null) {
defaultConfig = messageSettingController defaultConfig =
messageSettingController
.messageType['report'] .messageType['report']
?.firstWhere( ?.firstWhere(
(item) => (item) =>
item['id'] == targetId, item['id'] ==
targetId,
orElse: () => null); orElse: () => null);
} }
int configIndex = messageSettingController int configIndex =
messageSettingController
.model.device_type_setting .model.device_type_setting
.indexWhere( .indexWhere((item) =>
(item) => item['id'] == targetId); item['id'] == targetId);
if (defaultConfig != null) { if (defaultConfig != null) {
if (configIndex != -1) { if (configIndex != -1) {
// 更新找到的配置项 - 恢复所有默认字段 // 更新找到的配置项 - 恢复所有默认字段
// 创建一个新的 map包含所有默认字段 // 创建一个新的 map包含所有默认字段
Map<String, dynamic> updatedConfig = { Map<String, dynamic>
updatedConfig = {
...defaultConfig, // 展开所有默认字段 ...defaultConfig, // 展开所有默认字段
// 保留原有的配置开关,但恢复其他字段 // 保留原有的配置开关,但恢复其他字段
'setting': messageSettingController 'setting': messageSettingController
@@ -1008,22 +1056,25 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
.device_type_setting[ .device_type_setting[
configIndex]['setting'] ?? configIndex]['setting'] ??
1, 1,
'appSetting': messageSettingController 'appSetting':
messageSettingController
.model .model
.device_type_setting[ .device_type_setting[
configIndex]['appSetting'] ?? configIndex]
['appSetting'] ??
1, 1,
'serviceSetting': 'serviceSetting':
messageSettingController.model messageSettingController
.model
.device_type_setting[ .device_type_setting[
configIndex] configIndex][
['serviceSetting'] ?? 'serviceSetting'] ??
1, 1,
}; };
// 替换原有的配置 // 替换原有的配置
messageSettingController messageSettingController.model
.model.device_type_setting[ .device_type_setting[
configIndex] = updatedConfig; configIndex] = updatedConfig;
} else { } else {
// 如果不存在,创建一个新的配置项,使用默认值 // 如果不存在,创建一个新的配置项,使用默认值
@@ -1062,8 +1113,8 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
child: Text( child: Text(
"恢复默认".tr, "恢复默认".tr,
style: TextStyle( style: TextStyle(
color: color: themeController
themeController.currentColor.sc2, .currentColor.sc2,
fontSize: AppConstants() fontSize: AppConstants()
.middler_text_fontSize), .middler_text_fontSize),
), ),
@@ -1094,7 +1145,11 @@ class _MessageSettingPageState extends State<SingleMessageSetting> {
), ),
), ),
), ),
); ),
onWillPop: () async {
NewTopSlideNotification.show(text: "保存成功".tr);
return true;
});
} }
void _fetchMessageCommonConfig() { void _fetchMessageCommonConfig() {

View File

@@ -96,7 +96,7 @@ getContentById(data, BuildContext context) {
), ),
child: Padding( child: Padding(
padding: padding:
EdgeInsetsDirectional.fromSTEB(40.rpx, 20.rpx, 40.rpx, 20.rpx), EdgeInsetsDirectional.fromSTEB(30.rpx, 20.rpx, 30.rpx, 20.rpx),
child: Column( child: Column(
children: [ children: [
/// --- 心率小于 --- /// --- 心率小于 ---
@@ -379,8 +379,8 @@ getContentById(data, BuildContext context) {
} else if (id == 100002) { } else if (id == 100002) {
// 呼吸异常 // 呼吸异常
int min = 10; // 默认 int min = 8; // 默认
int max = 40; // 默认 int max = 25; // 默认
int interval = 600; // 默认 int interval = 600; // 默认
// 若有用户配置 // 若有用户配置
@@ -434,7 +434,7 @@ getContentById(data, BuildContext context) {
), ),
child: Padding( child: Padding(
padding: padding:
EdgeInsetsDirectional.fromSTEB(40.rpx, 20.rpx, 40.rpx, 20.rpx), EdgeInsetsDirectional.fromSTEB(30.rpx, 20.rpx, 30.rpx, 20.rpx),
child: Column( child: Column(
children: [ children: [
/// ---- 呼吸小于 ---- /// ---- 呼吸小于 ----
@@ -1025,7 +1025,7 @@ getContentById(data, BuildContext context) {
} else if (id == 100005) { } else if (id == 100005) {
// 未起床 // 未起床
// 1. 优先从 device_type_setting 中查找用户配置 // 1. 优先从 device_type_setting 中查找用户配置
String time = "23:00"; // 默认值 String time = "7:00"; // 默认值
// 2. 如果找到了用户配置,使用用户配置中的 time 值 // 2. 如果找到了用户配置,使用用户配置中的 time 值
if (userConfig != null) { if (userConfig != null) {
@@ -1187,7 +1187,7 @@ getContentById(data, BuildContext context) {
); );
} else if (id == 200001) { } else if (id == 200001) {
// 1. 优先从 device_type_setting 中查找用户配置 // 1. 优先从 device_type_setting 中查找用户配置
int score = 60; // 默认值 int score = 50; // 默认值
// 2. 如果找到了用户配置,使用用户配置中的 max 值 // 2. 如果找到了用户配置,使用用户配置中的 max 值
if (userConfig != null) { if (userConfig != null) {
print('找到用户配置: $userConfig'); print('找到用户配置: $userConfig');
@@ -1195,7 +1195,7 @@ getContentById(data, BuildContext context) {
if (userConfig['max'] != null) { if (userConfig['max'] != null) {
score = userConfig['max'] is int score = userConfig['max'] is int
? userConfig['max'] ? userConfig['max']
: int.tryParse(userConfig['max'].toString()) ?? 60; : int.tryParse(userConfig['max'].toString()) ?? score;
print('从用户配置获取睡眠得分阈值: $score'); print('从用户配置获取睡眠得分阈值: $score');
} }
} else { } else {
@@ -1207,7 +1207,7 @@ getContentById(data, BuildContext context) {
if (defaultConfig['max'] != null) { if (defaultConfig['max'] != null) {
score = defaultConfig['max'] is int score = defaultConfig['max'] is int
? defaultConfig['max'] ? defaultConfig['max']
: int.tryParse(defaultConfig['max'].toString()) ?? 60; : int.tryParse(defaultConfig['max'].toString()) ?? score;
print('从默认配置获取睡眠得分阈值: $score'); print('从默认配置获取睡眠得分阈值: $score');
} }
} else { } else {
@@ -1235,8 +1235,8 @@ getContentById(data, BuildContext context) {
onTap: () async { onTap: () async {
final currentScore = score; final currentScore = score;
final initialScore = currentScore != null final initialScore = currentScore != null
? int.tryParse(currentScore.toString()) ?? 60 ? int.tryParse(currentScore.toString()) ?? score
: 60; : score;
FocusScope.of(context).requestFocus(FocusNode()); FocusScope.of(context).requestFocus(FocusNode());
Future.delayed(const Duration(milliseconds: 250), () { Future.delayed(const Duration(milliseconds: 250), () {
showScorePickerDialog( showScorePickerDialog(

File diff suppressed because it is too large Load Diff

View File

@@ -384,7 +384,7 @@ class _EPageState extends State<DeviceTypePage> {
} }
Widget _buildDeviceCard(BuildContext context, Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required double type}) { {required String title, required String imageUrl, required int type}) {
if (type != 1) { if (type != 1) {
return Container(); return Container();
} }

View File

@@ -134,7 +134,7 @@ class _DeviceTypeListPageState extends State<DeviceTypeListPage> {
} }
Widget _buildDeviceCard(BuildContext context, Widget _buildDeviceCard(BuildContext context,
{required String title, required String imageUrl, required double type}) { {required String title, required String imageUrl, required int type}) {
if (type != 1) { if (type != 1) {
return Container(); return Container();
} }

View File

@@ -728,8 +728,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
weatherModelController = Get.find(); weatherModelController = Get.find();
await weatherModelController await weatherModelController
.getCurrentLocation(); .getCurrentLocation();
await weatherModelController // await weatherModelController
.getCurrentWeather(); // .getCurrentWeather();
} }
} }
} catch (e) { } catch (e) {

View File

@@ -884,6 +884,7 @@ class _HomePageState extends State<HomePage> {
homeController.model.type = 1; homeController.model.type = 1;
deviceController.model.type = 1; deviceController.model.type = 1;
homeController.updateAll();
await deviceController await deviceController
.getDeviceList(); .getDeviceList();
await deviceController await deviceController
@@ -942,6 +943,7 @@ class _HomePageState extends State<HomePage> {
onTap: () async { onTap: () async {
homeController.model.type = 2; homeController.model.type = 2;
deviceController.model.type = 2; deviceController.model.type = 2;
homeController.updateAll();
await deviceController await deviceController
.getDeviceList(); .getDeviceList();
await deviceController await deviceController

View File

@@ -58,6 +58,16 @@ class _MessagePageState extends State<MessagePage> {
} }
void _onTabChanged(int index) { void _onTabChanged(int index) {
int currentIndex = messageController.model.type == 1 ? 0 : 1;
// 只有当切换到不同tab时才重置加载状态
if (currentIndex != index) {
messageController.isLoadingMore = false;
messageController.bodyPage = 1;
messageController.systemPage = 1;
}
messageController.model.type = index == 0 ? 1 : 2; messageController.model.type = index == 0 ? 1 : 2;
messageController.updateAll(); messageController.updateAll();
_fetchMessageData(); _fetchMessageData();
@@ -299,6 +309,7 @@ class _MessagePageState extends State<MessagePage> {
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
body: SafeArea( body: SafeArea(
top: true, top: true,
child: Scrollbar(
child: PageView( child: PageView(
controller: _pageController, controller: _pageController,
onPageChanged: _onPageChanged, onPageChanged: _onPageChanged,
@@ -317,37 +328,27 @@ class _MessagePageState extends State<MessagePage> {
}), }),
], ],
), ),
), )),
), ),
), ),
), ),
); );
} }
// Widget _buildMessageListView(List dataList) {
// return Container(
// width: double.infinity,
// padding: EdgeInsets.symmetric(horizontal: 30.rpx),
// child: SingleChildScrollView(
// child: Column(
// children: [
// SizedBox(height: 30.rpx),
// ...dataList
// .map((item) => MessageWidgetWidget(data: item))
// .toList()
// .divide(SizedBox(height: 30.rpx)),
// SizedBox(height: 30.rpx),
// ],
// ),
// ),
// );
// }
Widget _buildMessageListView(List dataList, String type) { Widget _buildMessageListView(List dataList, String type) {
return NotificationListener<ScrollNotification>( return NotificationListener<ScrollNotification>(
onNotification: (scrollInfo) { onNotification: (scrollInfo) {
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) { // 检查是否滚动到底部,并且没有正在加载
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent &&
!messageController.isLoadingMore) {
messageController.isLoadingMore = true;
// 滑到底部,加载下一页 // 滑到底部,加载下一页
messageController.loadMore(type); messageController.loadMore(type).then((_) {
// 加载完成后重置标志位
messageController.isLoadingMore = false;
}).catchError((_) {
messageController.isLoadingMore = false;
});
} }
return true; return true;
}, },

View File

@@ -48,6 +48,16 @@ class _MessageReturnPageState extends State<MessageReturnPage> {
} }
void _onTabChanged(int index) { void _onTabChanged(int index) {
int currentIndex = messageController.model.type == 1 ? 0 : 1;
// 只有当切换到不同tab时才重置加载状态
if (currentIndex != index) {
messageController.isLoadingMore = false;
messageController.bodyPage = 1;
messageController.systemPage = 1;
}
messageController.model.type = index == 0 ? 1 : 2; messageController.model.type = index == 0 ? 1 : 2;
messageController.updateAll(); messageController.updateAll();
_fetchMessageData(); _fetchMessageData();
@@ -297,7 +307,8 @@ class _MessageReturnPageState extends State<MessageReturnPage> {
height: 4.rpx, height: 4.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
color: themeController.currentColor.sc2, color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(2.rpx), borderRadius:
BorderRadius.circular(2.rpx),
), ),
), ),
); );
@@ -342,9 +353,17 @@ class _MessageReturnPageState extends State<MessageReturnPage> {
Widget _buildMessageListView(List dataList, String type) { Widget _buildMessageListView(List dataList, String type) {
return NotificationListener<ScrollNotification>( return NotificationListener<ScrollNotification>(
onNotification: (scrollInfo) { onNotification: (scrollInfo) {
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) { // 检查是否滚动到底部,并且没有正在加载
if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent &&
!messageController.isLoadingMore) {
messageController.isLoadingMore = true;
// 滑到底部,加载下一页 // 滑到底部,加载下一页
messageController.loadMore(type); messageController.loadMore(type).then((_) {
// 加载完成后重置标志位
messageController.isLoadingMore = false;
}).catchError((_) {
messageController.isLoadingMore = false;
});
} }
return true; return true;
}, },

View File

@@ -703,7 +703,7 @@ class _MinePageState extends State<MinePage> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Text( Text(
'V1.0.2512.10', 'V1.0.2601.06',
style: TextStyle( style: TextStyle(
fontFamily: 'Inter', fontFamily: 'Inter',
// color: Color(0xFFD9E3EB), // color: Color(0xFFD9E3EB),

View File

@@ -72,6 +72,21 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
}); });
} }
PeopleInfoController personController = Get.find();
personController.getTimeZoneByLocalTime().then((value) {
personController.timeZone.value = value;
if (value == null || value.isEmpty) {
personController.timeZone.value = "UTC+8";
}
if (peopleList != null && peopleList.length > 0) {
ef.log("msg");
for (int i = 0; i < peopleList.length; i++) {
peopleList[i]['UTC'] = personController.timeZone.value;
}
}
personController.updateAll();
});
// 初始化城市模型列表 // 初始化城市模型列表
cityModels = List.filled(peopleList.length, CityModel()); cityModels = List.filled(peopleList.length, CityModel());
@@ -375,7 +390,7 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
final diseaseIds = diseaseIdsList[i]; final diseaseIds = diseaseIdsList[i];
// 添加城市信息到person数据 // 添加城市信息到person数据
person['UTC'] = cityModel.UTC; // person['UTC'] = cityModel.UTC;
person['city_id'] = cityModel.id; person['city_id'] = cityModel.id;
person['disease_ids'] = diseaseIds; // 添加疾病ID person['disease_ids'] = diseaseIds; // 添加疾病ID
@@ -917,6 +932,98 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
), ),
), ),
getLine(), getLine(),
Container(
height: 90.rpx,
margin: EdgeInsets.only(
left: 40.rpx,
right: 35.rpx,
),
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250),
() {
// 获取当前时区
String? currentTimeZone;
if (cityModels.isNotEmpty &&
index < cityModels.length) {
currentTimeZone =
cityModels[index].UTC;
}
showTimeMHTZonePickerDialog(
context,
title: "请选择时区".tr,
initialTimeZone:
currentTimeZone ?? "",
onConfirm:
(String selectedTimeZone) {
setState(() {
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,
),
),
Obx(() {
PeopleInfoController
personController = Get.find();
var aa =
personController.timeZone.value;
return Row(
children: [
Text(
peopleList[index]['UTC'] ==
null ||
peopleList[index]
['UTC'] ==
""
? "请选择时区".tr
: peopleList[index]['UTC'],
style: TextStyle(
color: peopleList[index]
['UTC'] !=
null
? Colors
.white // 有时区时使用白色,保持和参考代码一致
: themeController
.currentColor.sc4,
fontSize: 30
.rpx, // 使用固定的30.rpx而不是AppConstants().title_text_fontSize
),
),
SizedBox(width: 16.rpx),
Icon(
Icons.expand_more,
color: Colors
.white, // 保持白色,和参考代码一致
size: 48.rpx,
),
],
);
})
],
),
),
),
getLine(),
// 慢病管理部分 // 慢病管理部分
Container( Container(
height: 90.rpx, height: 90.rpx,

View File

@@ -253,7 +253,7 @@ class _SettingPageState extends State<SettingPage> {
), ),
].divide(SizedBox(width: 22.rpx)), ].divide(SizedBox(width: 22.rpx)),
), ),
Text('SWES2025.12.30', Text('SWES2026.1.5',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 26.rpx, fontSize: 26.rpx,

View File

@@ -142,22 +142,6 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
isValid = false; isValid = false;
break; break;
} }
// if (d['UTC'] == null ||
// d['UTC'].toString().isEmpty) {
// TopSlideNotification.show(context,
// text: "请选择城市".tr,
// textColor: Color(0xFFFF7159));
// isValid = false;
// break;
// }
// if (d['city_id'] ==null ||
// d['city_id'].toString().isEmpty) {
// TopSlideNotification.show(context,
// text: "请选择城市".tr,
// textColor: Color(0xFFFF7159));
// isValid = false;
// break;
// }
} }
// 所有数据合法,开始保存 // 所有数据合法,开始保存
if (isValid) { if (isValid) {
@@ -890,10 +874,10 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
// 补齐并追加 // 补齐并追加
list.add(newCity); list.add(newCity);
} }
controller.model // controller.model
.peopleList[ // .peopleList[
index]['UTC'] = // index]['UTC'] =
list[index].UTC; // list[index].UTC;
controller.model controller.model
.peopleList[ .peopleList[
index] index]
@@ -953,13 +937,16 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
style: TextStyle( style: TextStyle(
color: getCityModel( color: getCityModel(
index) != index) !=
null &&
getCityModel(
index)!
.id !=
null null
? themeController ? themeController
.currentColor .currentColor
.sc3 .sc3
: themeController : Color(
.currentColor 0xFF9EA4B7),
.sc4,
fontSize: AppConstants() fontSize: AppConstants()
.title_text_fontSize, .title_text_fontSize,
), ),
@@ -981,6 +968,160 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
), ),
), ),
getLine(), 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( Container(
height: 90.rpx, height: 90.rpx,
margin: EdgeInsets.only( margin: EdgeInsets.only(

View File

@@ -60,6 +60,13 @@ class _EPageState extends State<PersonPage> {
personController.weight.value = ""; personController.weight.value = "";
personController.height.value = ""; personController.height.value = "";
personController.dateTime = null; personController.dateTime = null;
personController.cityModel = null;
personController.timeZone.value = "";
personController.getTimeZoneByLocalTime().then((value) {
personController.timeZone.value = value;
personController.updateAll();
});
cityDataFuture = cityController.loadAndSetCityData().then((success) { cityDataFuture = cityController.loadAndSetCityData().then((success) {
return cityController.cityList; return cityController.cityList;
@@ -172,7 +179,7 @@ class _EPageState extends State<PersonPage> {
children: [ children: [
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 141.rpx, 70.rpx, 0), 70.rpx, 70.rpx, 70.rpx, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: 100.rpx, height: 100.rpx,
@@ -404,30 +411,77 @@ class _EPageState extends State<PersonPage> {
}, title: "选择生日".tr); }, title: "选择生日".tr);
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
personController.dateTime != null // 文字居中
? DateFormat("yyyy/MM/dd").format( Center(
personController.dateTime!) child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.dateTime !=
null
? DateFormat(
"yyyy/MM/dd")
.format(
personController
.dateTime!)
: '人员资料.生日输入提示'.tr, : '人员资料.生日输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.dateTime != null color: personController
? themeController.currentColor.sc3 .dateTime !=
: themeController.currentColor.sc4, null
fontSize: ? themeController
AppConstants().normal_text_fontSize, .currentColor.sc3
: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0), 70.rpx, 25.rpx, 70.rpx, 0),
child: Container( child: Container(
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -464,31 +518,76 @@ class _EPageState extends State<PersonPage> {
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
personController.height.value != "" // 文字居中
? personController.height.value + Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.height.value !=
""
? personController
.height.value +
"cm".tr "cm".tr
: '身高输入提示'.tr, : '身高输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.height.value != color: personController
.height
.value !=
"" ""
? themeController.currentColor.sc3 ? themeController
: themeController.currentColor.sc4, .currentColor.sc3
fontSize: : themeController
AppConstants().normal_text_fontSize, .currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0), 70.rpx, 25.rpx, 70.rpx, 0),
child: Container( child: Container(
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -512,38 +611,184 @@ class _EPageState extends State<PersonPage> {
personController.weight.value ?? "", personController.weight.value ?? "",
onConfirm: (int selectedWeight) { onConfirm: (int selectedWeight) {
personController.weight.value = personController.weight.value =
selectedWeight selectedWeight.toString();
.toString(); // ✅ 转成字符串
personController.updateAll(); personController.updateAll();
}, },
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
personController.weight.value != "" // 文字居中
? personController.weight.value + Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.weight.value !=
""
? personController
.weight.value +
"kg".tr "kg".tr
: '人员资料.体重输入提示'.tr, : '人员资料.体重输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.weight.value != color: personController
.weight
.value !=
"" ""
? themeController.currentColor.sc3 ? themeController
: themeController.currentColor.sc4, .currentColor.sc3
fontSize: : themeController
AppConstants().normal_text_fontSize, .currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0), 70.rpx, 25.rpx, 70.rpx, 0),
child: Container(
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: InkWell(onTap: () {
final timeZone =
personController.timeZone.value;
final initialTimeZone = timeZone;
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250), () {
showTimeZonePickerDialog(
context,
title: "选择时区".tr,
initialTimeZone: initialTimeZone,
onConfirm: (String selectedtimezone) {
personController.timeZone.value =
selectedtimezone.toString();
personController.updateAll();
print("时区: $selectedtimezone");
},
);
});
}, child: Obx(() {
return Stack(
children: [
// 文字居中
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.timeZone
.value !=
""
? personController
.timeZone.value
: '选择时区'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: personController
.timeZone
.value !=
""
? themeController
.currentColor.sc3
: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0,
),
),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
);
})),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 25.rpx, 70.rpx, 0),
child: Container( child: Container(
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -577,32 +822,77 @@ class _EPageState extends State<PersonPage> {
title: "选择城市".tr, title: "选择城市".tr,
cityDataFuture: cityDataFuture:
cityDataFuture, // 传入预加载的数据 cityDataFuture, // 传入预加载的数据
colors: CitySelectionColors(
// pickerBackgroundColor:
// stringToColor("#003058"),
// confirmTextColor:
// stringToColor("#84F5FF"),
selectedCityColor:
themeController.currentColor.sc2,
selectedTextColor: Colors.white,
),
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
// 文字居中
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
_getDetailedCityDisplayText( _getDetailedCityDisplayText(
personController.cityModel), personController.cityModel),
textAlign: TextAlign.right, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.cityModel != color:
personController
.cityModel !=
null null
? themeController.currentColor.sc3 ? themeController
: themeController.currentColor.sc4, .currentColor.sc3
fontSize: : themeController
AppConstants().normal_text_fontSize, .currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
// Text(
// ' *',
// style: TextStyle(
// color: themeController
// .currentColor.sc9,
// fontSize: AppConstants()
// .normal_text_fontSize,
// fontWeight: FontWeight.bold,
// ),
// ),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
0, 117.rpx, 0, 0), 0, 60.rpx, 0, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration(), decoration: BoxDecoration(),

View File

@@ -3,9 +3,11 @@ import 'dart:convert';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/pojo/city.dart'; import 'package:vbvs_app/common/pojo/city.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/ListSearchWidget.dart'; import 'package:vbvs_app/common/util/ListSearchWidget.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/person/person_controller.dart'; import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
@@ -666,7 +668,7 @@ Widget _buildCityPickerContent(
Get.find(); Get.find();
cityModelController.tmp; cityModelController.tmp;
ef.log("${cityModelController.tmp.value}"); ef.log("${cityModelController.tmp.value}");
return getOnePickers( return getOnePickersCity(
context, context,
countries, countries,
countryIndex, countryIndex,
@@ -684,7 +686,7 @@ Widget _buildCityPickerContent(
Get.find(); Get.find();
cityModelController.tmp; cityModelController.tmp;
ef.log("${cityModelController.tmp.value}"); ef.log("${cityModelController.tmp.value}");
return getOnePickers( return getOnePickersCity(
context, context,
provinces, provinces,
provinceIndex, provinceIndex,
@@ -702,7 +704,7 @@ Widget _buildCityPickerContent(
Get.find(); Get.find();
cityModelController.tmp; cityModelController.tmp;
ef.log("${cityModelController.tmp.value}"); ef.log("${cityModelController.tmp.value}");
return getOnePickers( return getOnePickersCity(
context, context,
cities, cities,
cityIndex, cityIndex,
@@ -813,3 +815,149 @@ Widget _buildErrorBottomSheet(
), ),
); );
} }
Future<void> showTimeMHTZonePickerDialog(
BuildContext context, {
required String initialTimeZone, // 初始时区字符串,如 "UTC+8"
required Function(String selectedTimeZone) onConfirm,
String title = "选择时区",
}) async {
// 使用 AppConstants.integerTimeZones 作为数据源
List<String> timeZones = AppConstants.integerTimeZones;
int selectedIndex = timeZones.indexOf(initialTimeZone);
// 如果没有找到使用默认的UTC+8北京时间
if (selectedIndex == -1) {
selectedIndex = timeZones.indexOf("UTC+8");
if (selectedIndex == -1) {
selectedIndex = 0; // 如果连UTC+8都没有使用第一个
}
}
final RxInt tempIndex = RxInt(selectedIndex);
ThemeController themeController = Get.find();
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: stringToColor("#003058"),
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding:
EdgeInsets.fromLTRB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
color: themeController.currentColor.sc5,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
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.only(top: 0),
onTap: () {
onConfirm(timeZones[tempIndex.value]);
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: stringToColor("#84F5FF"),
),
),
),
),
],
),
),
SizedBox(height: 20.rpx),
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 95.rpx),
decoration: BoxDecoration(
color: stringToColor("#84F5FF"),
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
timeZones, // 传入字符串列表
tempIndex,
unit: "", // 时区不需要单位
selectedColor: stringToColor("#011D33"),
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}

View File

@@ -1306,3 +1306,150 @@ Future<void> showCountryCodePickerDialog(
}, },
); );
} }
Future<void> showTimeZonePickerDialog(
BuildContext context, {
required String initialTimeZone, // 初始时区字符串,如 "UTC+8"
required Function(String selectedTimeZone) onConfirm,
String title = "选择时区",
}) async {
// 使用 AppConstants.integerTimeZones 作为数据源
List<String> timeZones = AppConstants.integerTimeZones;
int selectedIndex = timeZones.indexOf(initialTimeZone);
// 如果没有找到使用默认的UTC+8北京时间
if (selectedIndex == -1) {
selectedIndex = timeZones.indexOf("UTC+8");
if (selectedIndex == -1) {
selectedIndex = 0; // 如果连UTC+8都没有使用第一个
}
}
final RxInt tempIndex = RxInt(selectedIndex);
ThemeController themeController = Get.find();
await showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Stack(
children: [
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Material(
color: Colors.transparent,
child: Dialog(
backgroundColor: themeController.currentColor.sc17,
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
child: Container(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding:
EdgeInsets.fromLTRB(30.rpx, 0.rpx, 30.rpx, 0.rpx),
color: themeController.currentColor.sc5,
height: 80.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(top: 0),
onTap: () {
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
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.only(top: 0),
onTap: () {
onConfirm(timeZones[tempIndex.value]);
Get.back();
},
child: Container(
alignment: Alignment.center,
width: 110.rpx,
height: 60.rpx,
child: Text(
"确定".tr,
style: TextStyle(
fontSize: 30.rpx,
color: themeController.currentColor.sc2,
),
),
),
),
],
),
),
SizedBox(height: 20.rpx),
Stack(
children: [
Positioned.fill(
child: IgnorePointer(
child: Center(
child: Container(
height: 90.rpx,
margin:
EdgeInsets.symmetric(horizontal: 95.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(16.rpx),
),
),
),
),
),
SizedBox(
height: 240.rpx,
child: getOnePickers(
context,
timeZones, // 传入字符串列表
tempIndex,
unit: "", // 时区不需要单位
),
),
],
),
],
),
),
),
),
),
],
);
},
);
}

View File

@@ -173,7 +173,7 @@ class _UpdatePageState extends State<UpdatePersonPage> {
children: [ children: [
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 141.rpx, 70.rpx, 0), 70.rpx, 70.rpx, 70.rpx, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: 100.rpx, height: 100.rpx,
@@ -204,7 +204,12 @@ class _UpdatePageState extends State<UpdatePersonPage> {
letterSpacing: 0.0, letterSpacing: 0.0,
color: themeController.currentColor.sc3, color: themeController.currentColor.sc3,
), ),
hintText: '人员资料.名字输入提示'.tr, hintText: (personController.name.value
as String?)
?.isNotEmpty ==
true
? personController.name.value
: '体征检测设备'.tr,
hintStyle: TextStyle( hintStyle: TextStyle(
fontFamily: 'Inter', fontFamily: 'Inter',
fontSize: 26.rpx, fontSize: 26.rpx,
@@ -432,30 +437,77 @@ class _UpdatePageState extends State<UpdatePersonPage> {
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
personController.dateTime != null // 文字居中
? DateFormat("yyyy/MM/dd").format( Center(
personController.dateTime!) child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.dateTime !=
null
? DateFormat(
"yyyy/MM/dd")
.format(
personController
.dateTime!)
: '人员资料.生日输入提示'.tr, : '人员资料.生日输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.dateTime != null color: personController
? themeController.currentColor.sc3 .dateTime !=
: themeController.currentColor.sc4, null
fontSize: ? themeController
AppConstants().normal_text_fontSize, .currentColor.sc3
: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0), 70.rpx, 25.rpx, 70.rpx, 0),
child: Container( child: Container(
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -500,31 +552,76 @@ class _UpdatePageState extends State<UpdatePersonPage> {
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
personController.height.value != "" // 文字居中
? personController.height.value + Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.height.value !=
""
? personController
.height.value +
"cm".tr "cm".tr
: '身高输入提示'.tr, : '身高输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.height.value != color: personController
.height
.value !=
"" ""
? themeController.currentColor.sc3 ? themeController
: themeController.currentColor.sc4, .currentColor.sc3
fontSize: : themeController
AppConstants().normal_text_fontSize, .currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0), 70.rpx, 25.rpx, 70.rpx, 0),
child: Container( child: Container(
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -555,38 +652,193 @@ class _UpdatePageState extends State<UpdatePersonPage> {
personController.weight.value ?? "", personController.weight.value ?? "",
onConfirm: (int selectedWeight) { onConfirm: (int selectedWeight) {
personController.weight.value = personController.weight.value =
selectedWeight selectedWeight.toString();
.toString(); // ✅ 转成字符串
personController.updateAll(); personController.updateAll();
}, },
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
personController.weight.value != "" // 文字居中
? personController.weight.value + Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.weight.value !=
""
? personController
.weight.value +
"kg".tr "kg".tr
: '人员资料.体重输入提示'.tr, : '人员资料.体重输入提示'.tr,
textAlign: TextAlign.right,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.weight.value != color: personController
.weight
.value !=
"" ""
? themeController.currentColor.sc3 ? themeController
: themeController.currentColor.sc4, .currentColor.sc3
fontSize: : themeController
AppConstants().normal_text_fontSize, .currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 50.rpx, 70.rpx, 0), 70.rpx, 25.rpx, 70.rpx, 0),
child: Container(
height: 100.rpx,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50.rpx),
border: Border.all(
color: themeController.currentColor.sc4
.withOpacity(0.5),
width: AppConstants().border_width,
),
),
child: InkWell(
onTap: () {
if (widget.status == BindType.share.code) {
TopSlideNotification.show(context,
text: "被分享用户只能修改用户名称",
textColor:
themeController.currentColor.sc9);
return;
}
final timeZone =
personController.timeZone.value;
final initialTimeZone = timeZone;
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(milliseconds: 250), () {
showTimeZonePickerDialog(
context,
title: "选择时区".tr,
initialTimeZone: initialTimeZone,
onConfirm: (String selectedtimezone) {
personController.timeZone.value =
selectedtimezone.toString();
personController.updateAll();
print("时区: $selectedtimezone");
},
);
});
},
child: Stack(
children: [
// 文字居中
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text.rich(
TextSpan(
children: [
TextSpan(
text: personController
.timeZone
.value !=
""
? personController
.timeZone.value
: '选择时区'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: personController
.timeZone
.value !=
""
? themeController
.currentColor.sc3
: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0,
),
),
TextSpan(
text: ' *',
style: TextStyle(
color: themeController
.currentColor.sc9,
fontSize: AppConstants()
.normal_text_fontSize,
fontWeight:
FontWeight.bold,
),
),
],
),
),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
70.rpx, 25.rpx, 70.rpx, 0),
child: Container( child: Container(
height: 100.rpx, height: 100.rpx,
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -627,33 +879,80 @@ class _UpdatePageState extends State<UpdatePersonPage> {
title: "选择城市".tr, title: "选择城市".tr,
cityDataFuture: cityDataFuture:
cityDataFuture, // 传入预加载的数据 cityDataFuture, // 传入预加载的数据
colors: CitySelectionColors(
// pickerBackgroundColor:
// stringToColor("#003058"),
// confirmTextColor:
// stringToColor("#84F5FF"),
selectedCityColor:
themeController.currentColor.sc2,
selectedTextColor: Colors.white,
),
); );
}); });
}, },
child: Center( child: Stack(
child: Text( children: [
MyUtils.getDetailedCityDisplayText( // 文字居中
personController.cityModel), Center(
textAlign: TextAlign.right, child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
MyUtils
.getDetailedCityDisplayText(
personController
.cityModel),
textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontFamily: 'Readex Pro', fontFamily: 'Readex Pro',
color: personController.cityModel != color:
personController
.cityModel !=
null null
? themeController.currentColor.sc3 ? themeController
: themeController.currentColor.sc4, .currentColor.sc3
fontSize: : themeController
AppConstants().normal_text_fontSize, .currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0, letterSpacing: 0,
), ),
), ),
// Text(
// ' *',
// style: TextStyle(
// color: themeController
// .currentColor.sc9,
// fontSize: AppConstants()
// .normal_text_fontSize,
// fontWeight: FontWeight.bold,
// ),
// ),
],
),
),
// 箭头居右
Positioned(
right: 30.rpx,
top: 0,
bottom: 0,
child: Icon(
Icons.expand_more,
color:
themeController.currentColor.sc4,
size: 30.rpx,
),
),
],
), ),
), ),
), ),
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
0, 117.rpx, 0, 0), 0, 60.rpx, 0, 0),
child: Container( child: Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration(), decoration: BoxDecoration(),
@@ -858,5 +1157,4 @@ class _UpdatePageState extends State<UpdatePersonPage> {
onFailure: (res) {}, onFailure: (res) {},
); );
} }
} }

View File

@@ -127,18 +127,66 @@ class BarChartPainter extends CustomPainter {
final textPainter = TextPainter(textDirection: ui.TextDirection.ltr); final textPainter = TextPainter(textDirection: ui.TextDirection.ltr);
final stepValue = maxYValue / yStepCount; final stepValue = maxYValue / yStepCount;
// Y轴刻度
// for (int i = 0; i <= yStepCount; i++) {
// final value = stepValue * i;
// final y = topPadding + chartHeight - (value / maxYValue) * chartHeight;
// final dashPaint = Paint()
// ..color = Colors.grey.withOpacity(0.4)
// ..strokeWidth = 1.rpx;
// drawDashedLine(
// canvas, Offset(leftPadding, y), Offset(size.width, y), dashPaint);
// textPainter.text = TextSpan(
// text: value.toStringAsFixed(0),
// style: TextStyle(
// fontSize: 18.rpx,
// color: themeController.currentColor.sc4,
// ),
// );
// textPainter.layout();
// textPainter.paint(
// canvas,
// Offset(leftPadding - textPainter.width - 4, y - textPainter.height / 2),
// );
// }
// Y轴刻度 // Y轴刻度
for (int i = 0; i <= yStepCount; i++) { for (int i = 0; i <= yStepCount; i++) {
final value = stepValue * i; final value = stepValue * i;
final y = topPadding + chartHeight - (value / maxYValue) * chartHeight; final y = topPadding + chartHeight - (value / maxYValue) * chartHeight;
// 判断是否是基线i == 0
final bool isBaseline = i == 0;
if (isBaseline) {
// 基线画实线
final baselinePaint = Paint()
..color = Colors.grey.withOpacity(0.6)
..strokeWidth = 1.rpx
..style = PaintingStyle.stroke;
canvas.drawLine(
Offset(leftPadding, y),
Offset(size.width, y),
baselinePaint,
);
} else {
// 其他刻度画虚线
final dashPaint = Paint() final dashPaint = Paint()
..color = Colors.grey.withOpacity(0.4) ..color = Colors.grey.withOpacity(0.4)
..strokeWidth = 1.rpx; ..strokeWidth = 1.rpx;
drawDashedLine( drawDashedLine(
canvas, Offset(leftPadding, y), Offset(size.width, y), dashPaint); canvas,
Offset(leftPadding, y),
Offset(size.width, y),
dashPaint,
);
}
// 绘制刻度文字
textPainter.text = TextSpan( textPainter.text = TextSpan(
text: value.toStringAsFixed(0), text: value.toStringAsFixed(0),
style: TextStyle( style: TextStyle(
@@ -163,14 +211,14 @@ class BarChartPainter extends CustomPainter {
final startHour = startDate.hour; final startHour = startDate.hour;
// 绘制X轴主线实线 // 绘制X轴主线实线
final xAxisPaint = Paint() // final xAxisPaint = Paint()
..color = Colors.grey.withOpacity(0.4) // ..color = Colors.grey.withOpacity(0.4)
..strokeWidth = 1.rpx; // ..strokeWidth = 1.rpx;
canvas.drawLine( // canvas.drawLine(
Offset(leftPadding, xAxisY), // Offset(leftPadding, xAxisY),
Offset(size.width, xAxisY), // Offset(size.width, xAxisY),
xAxisPaint, // xAxisPaint,
); // );
// 绘制左右两侧时间标签HH:mm格式 // 绘制左右两侧时间标签HH:mm格式
final leftLabel = DateFormat('HH:mm').format(startDate); final leftLabel = DateFormat('HH:mm').format(startDate);

File diff suppressed because it is too large Load Diff

View File

@@ -98,8 +98,9 @@ class _BreatheCardState extends State<BreatheCard>
BorderRadius.circular(AppConstants().normal_container_radius), BorderRadius.circular(AppConstants().normal_container_radius),
), ),
child: Padding( child: Padding(
padding: // padding:
EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), // EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
padding: EdgeInsets.all(0),
child: Wrap( child: Wrap(
spacing: 23.rpx, spacing: 23.rpx,
runSpacing: 25.rpx, runSpacing: 25.rpx,
@@ -110,7 +111,8 @@ class _BreatheCardState extends State<BreatheCard>
_shouldAnimate && item['id'] == _highlightedId; _shouldAnimate && item['id'] == _highlightedId;
return SizedBox( return SizedBox(
width: (MediaQuery.of(context).size.width - 160.rpx) / 3, // width: (MediaQuery.of(context).size.width - 160.rpx) / 3,
width: (MediaQuery.of(context).size.width - 120.rpx) / 3,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: _animationController ?? AlwaysStoppedAnimation(0), animation: _animationController ?? AlwaysStoppedAnimation(0),
builder: (context, child) { builder: (context, child) {
@@ -137,7 +139,7 @@ class _BreatheCardState extends State<BreatheCard>
), ),
); );
} catch (e) { } catch (e) {
es.EasyDartModule.logger.error("呼吸监测绘制异常${e}"); es.EasyDartModule.logger.error("呼吸卡片绘制异常${e}");
return Container(); return Container();
} }
} }

View File

@@ -100,15 +100,17 @@ class _HeartRateCardState extends State<HeartRateCard>
}).toList(); // 添加 .toList() }).toList(); // 添加 .toList()
return Container( return Container(
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( // decoration: BoxDecoration(
color: themeController.currentColor.sc5, // color: themeController.currentColor.sc5,
borderRadius: // borderRadius:
BorderRadius.circular(AppConstants().normal_container_radius), // BorderRadius.circular(AppConstants().normal_container_radius),
), // ),
child: Padding( child: Padding(
padding: // padding:
EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx), // EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
padding: EdgeInsets.all(0),
child: Wrap( child: Wrap(
alignment: WrapAlignment.spaceBetween,
spacing: 23.rpx, spacing: 23.rpx,
runSpacing: 25.rpx, runSpacing: 25.rpx,
children: List.generate(data.length, (index) { children: List.generate(data.length, (index) {
@@ -118,7 +120,7 @@ class _HeartRateCardState extends State<HeartRateCard>
_shouldAnimate && item['id'] == _highlightedId; _shouldAnimate && item['id'] == _highlightedId;
return SizedBox( return SizedBox(
width: (MediaQuery.of(context).size.width - 160.rpx) / 3, width: (MediaQuery.of(context).size.width - 120.rpx) / 3,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: _animationController ?? AlwaysStoppedAnimation(0), animation: _animationController ?? AlwaysStoppedAnimation(0),
builder: (context, child) { builder: (context, child) {
@@ -145,7 +147,7 @@ class _HeartRateCardState extends State<HeartRateCard>
), ),
); );
} catch (e) { } catch (e) {
es.EasyDartModule.logger.error("心率监测绘制异常${e}"); es.EasyDartModule.logger.error("心率卡片绘制异常${e}");
return Container(); return Container();
} }
} }

View File

@@ -136,7 +136,8 @@ class _HeartRateStandardWidgetState extends State<HeartRateStandardWidget> {
14.rpx, 10.rpx, 14.rpx, 10.rpx), // 14.rpx, 10.rpx, 14.rpx, 10.rpx), //
borderRadius: 0.rpx, // 圆形点击区域 borderRadius: 0.rpx, // 圆形点击区域
onTap: () { onTap: () {
if (AppConstants().ent_type == APPPackageType.MHT.code) { if (AppConstants().ent_type ==
APPPackageType.MHT.code) {
showTipDialog( showTipDialog(
context, context,
Container( Container(

View File

@@ -104,18 +104,8 @@ class _SleepCardState extends State<SleepCard> with TickerProviderStateMixin {
.where((item) => item['show'] != false) .where((item) => item['show'] != false)
.toList(); .toList();
return Container( return Wrap(
width: double.infinity, alignment: WrapAlignment.spaceBetween,
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius:
BorderRadius.circular(AppConstants().normal_container_radius),
),
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
child: Wrap(
alignment: WrapAlignment.center,
spacing: 23.rpx, spacing: 23.rpx,
runSpacing: 25.rpx, runSpacing: 25.rpx,
children: List.generate(data.length, (index) { children: List.generate(data.length, (index) {
@@ -124,7 +114,7 @@ class _SleepCardState extends State<SleepCard> with TickerProviderStateMixin {
final bool isHighlighted = final bool isHighlighted =
_shouldAnimate && item['id'] == _highlightedId; _shouldAnimate && item['id'] == _highlightedId;
return SizedBox( return SizedBox(
width: (MediaQuery.of(context).size.width - 160.rpx) / num, width: (MediaQuery.of(context).size.width - 120.rpx) / num,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: _animationController ?? AlwaysStoppedAnimation(0), animation: _animationController ?? AlwaysStoppedAnimation(0),
builder: (context, child) { builder: (context, child) {
@@ -134,8 +124,7 @@ class _SleepCardState extends State<SleepCard> with TickerProviderStateMixin {
? BoxDecoration( ? BoxDecoration(
border: Border.all( border: Border.all(
color: themeController.currentColor.sc2 color: themeController.currentColor.sc2
.withOpacity( .withOpacity(_animationController?.value ?? 0),
_animationController?.value ?? 0),
width: 1.rpx, width: 1.rpx,
), ),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
@@ -150,8 +139,6 @@ class _SleepCardState extends State<SleepCard> with TickerProviderStateMixin {
), ),
); );
}), }),
),
),
); );
} catch (e) { } catch (e) {
es.EasyDartModule.logger.error("数据卡片渲染异常${e}"); es.EasyDartModule.logger.error("数据卡片渲染异常${e}");

View File

@@ -70,6 +70,22 @@ class _SleepViewWidgetState extends State<SleepViewWidget> {
// "name": "rem", // "name": "rem",
// "color": "#FFC0CB", // "color": "#FFC0CB",
// }); // });
// List typeZeroStages =
// stages.where((stage) => stage['type'] == 0).toList();
// List snoreStages = stages.where((stage) => stage['type'] == 5).toList();
// for (int i = 0; i < typeZeroStages.length; i++) {
// var stage = typeZeroStages[i];
// int st = stage['st'];
// int et = stage['et'];
// // 转换为DateTime
// DateTime stDate = DateTime.fromMillisecondsSinceEpoch(st);
// DateTime etDate = DateTime.fromMillisecondsSinceEpoch(et);
// // 一行打印所有信息
// print(
// '离床元素 ${i + 1}: st=${formatDate(stDate)} et=${formatDate(etDate)}');
// }
return Container( return Container(
width: double.infinity, width: double.infinity,
@@ -306,7 +322,7 @@ class _SleepViewWidgetState extends State<SleepViewWidget> {
), ),
), ),
SizedBox( SizedBox(
height: 49.rpx, height: 70.rpx,
), ),
Padding( Padding(
padding: EdgeInsetsDirectional.fromSTEB( padding: EdgeInsetsDirectional.fromSTEB(
@@ -359,8 +375,13 @@ class _SleepViewWidgetState extends State<SleepViewWidget> {
), ),
); );
} catch (e) { } catch (e) {
es.EasyDartModule.logger.error("打鼾监测绘制异常${e}"); es.EasyDartModule.logger.error("睡眠规律性异常${e}");
return Container(); return Container();
} }
} }
String formatDate(DateTime date) {
return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')} '
'${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}:${date.second.toString().padLeft(2, '0')}';
}
} }