1.修复睡眠日报中睡眠规律性数据显示错误
2.更新时区设置
This commit is contained in:
@@ -624,6 +624,9 @@
|
||||
"手机号登录": "Phone Login",
|
||||
"邮箱登录": "Email Login",
|
||||
"输入邮箱": "Enter Email",
|
||||
"隐私协议加载失败": "Privacy Agreement Failed to Load",
|
||||
"请检查网络连接后重试": "Please check the network connection and try again"
|
||||
"隐私协议加载失败": "Privacy Agreement Failed to Load",
|
||||
"请检查网络连接后重试": "Please check the network connection and try again",
|
||||
"开始": "startTime",
|
||||
"结束": "endTime",
|
||||
"时长": "duration:"
|
||||
}
|
||||
@@ -615,18 +615,18 @@
|
||||
"原邮箱号": "原邮箱号",
|
||||
"用户拒绝授权": "用户拒绝授权",
|
||||
"用户取消授权": "用户取消授权",
|
||||
"请输入邮箱号":"请输入邮箱号",
|
||||
"中国":"中国",
|
||||
"香港":"香港",
|
||||
"选择区号":"选择区号",
|
||||
"输入邮箱号码":"输入邮箱号码",
|
||||
"通知设置":"通知设置",
|
||||
"注意!关闭后将无法接受任何消息":"注意!关闭后将无法接受任何消息",
|
||||
"手机号登录":"手机号登录",
|
||||
"邮箱登录":"邮箱登录",
|
||||
"输入邮箱":"输入邮箱",
|
||||
"隐私协议加载失败": "隐私协议加载失败",
|
||||
"请检查网络连接后重试": "请检查网络连接后重试"
|
||||
|
||||
|
||||
"请输入邮箱号": "请输入邮箱号",
|
||||
"中国": "中国",
|
||||
"香港": "香港",
|
||||
"选择区号": "选择区号",
|
||||
"输入邮箱号码": "输入邮箱号码",
|
||||
"通知设置": "通知设置",
|
||||
"注意!关闭后将无法接受任何消息": "注意!关闭后将无法接受任何消息",
|
||||
"手机号登录": "手机号登录",
|
||||
"邮箱登录": "邮箱登录",
|
||||
"输入邮箱": "输入邮箱",
|
||||
"隐私协议加载失败": "隐私协议加载失败",
|
||||
"请检查网络连接后重试": "请检查网络连接后重试",
|
||||
"开始": "开始",
|
||||
"结束": "结束"
|
||||
}
|
||||
@@ -623,5 +623,8 @@
|
||||
"邮箱登录": "電子郵件登入",
|
||||
"输入邮箱": "輸入電子郵件",
|
||||
"隐私协议加载失败": "隱私協議加載失敗",
|
||||
"请检查网络连接后重试": "請檢查網絡連接後重試"
|
||||
"请检查网络连接后重试": "請檢查網絡連接後重試",
|
||||
"开始": "開始",
|
||||
"结束": "結束",
|
||||
"时长": "時長:"
|
||||
}
|
||||
@@ -642,5 +642,9 @@
|
||||
"安卓启用网络提示": "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",
|
||||
"请检查网络连接后重试": "Please check the network connection and try again"
|
||||
"请检查网络连接后重试": "Please check the network connection and try again",
|
||||
"开始": "startTime",
|
||||
"结束": "endTime",
|
||||
"时长": "duration:",
|
||||
"请选择时区": "Please select a time zone"
|
||||
}
|
||||
@@ -649,6 +649,9 @@
|
||||
"安卓启用网络提示": "网络未开启,请打开网络连接",
|
||||
"ios启用网络提示": "网络未开启,请打开网络连接",
|
||||
"隐私协议加载失败": "隐私协议加载失败",
|
||||
"请检查网络连接后重试": "请检查网络连接后重试"
|
||||
|
||||
"请检查网络连接后重试": "请检查网络连接后重试",
|
||||
"开始": "开始",
|
||||
"结束": "结束",
|
||||
"时长": "时长:",
|
||||
"请选择时区": "请选择时区"
|
||||
}
|
||||
@@ -642,5 +642,9 @@
|
||||
"安卓启用网络提示": "請開啟網絡,再使用APP",
|
||||
"ios启用网络提示": "請開啟網絡,再使用APP",
|
||||
"隐私协议加载失败": "隱私協議加載失敗",
|
||||
"请检查网络连接后重试": "請檢查網絡連接後重試"
|
||||
"请检查网络连接后重试": "請檢查網絡連接後重試",
|
||||
"开始": "開始",
|
||||
"结束": "結束",
|
||||
"时长": "時長:",
|
||||
"请选择时区": "請選擇時區"
|
||||
}
|
||||
Binary file not shown.
@@ -59,4 +59,6 @@ class ServiceConstant {
|
||||
|
||||
static const String bgUrl =
|
||||
"https://vsbst-api.he-info.cn/vsbs_sotrage/background-image/taihe.png";
|
||||
static const String localTimeZone =
|
||||
"/api/city/data/utc/info";
|
||||
}
|
||||
|
||||
@@ -7,6 +7,37 @@ import 'package:vbvs_app/enum/APPPackageType.dart';
|
||||
|
||||
class AppConstants {
|
||||
// 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 limit = 10; //分页数量
|
||||
|
||||
|
||||
@@ -12,3 +12,5 @@ class SwitchLanguageEvent {
|
||||
final String language;
|
||||
SwitchLanguageEvent(this.language);
|
||||
}
|
||||
|
||||
class ScrollNotificationEvent {}
|
||||
@@ -50,6 +50,8 @@ class MessageController extends GetControllerEx<MessageModel> {
|
||||
int bodyPage = 1;
|
||||
int systemPage = 1;
|
||||
|
||||
bool isLoadingMore = false; // 添加加载标志位
|
||||
|
||||
Future<void> loadMore(String type) async {
|
||||
if (type == "app_vsm") {
|
||||
bodyPage++;
|
||||
|
||||
@@ -55,6 +55,7 @@ class PeopleInfoController extends GetControllerEx<PeopleInfoModel> {
|
||||
|
||||
final CityModelController cityController = Get.find<CityModelController>();
|
||||
RxList diseaseList = [].obs;
|
||||
RxString timeZone = "".obs; //选择时区
|
||||
|
||||
@override
|
||||
Future<void> onInit() async {
|
||||
@@ -247,4 +248,35 @@ class PeopleInfoController extends GetControllerEx<PeopleInfoModel> {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:EasyDartModule/EasyDartModule.dart';
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:vbvs_app/common/color/ServiceConstant.dart';
|
||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||
@@ -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/util/DailyLogUtils.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/model/api_response.dart';
|
||||
|
||||
@@ -50,6 +52,7 @@ class PersonController extends GetControllerEx<PersonModel> {
|
||||
RxString height = "".obs;
|
||||
DateTime? dateTime = DateTime.now(); //选择时间
|
||||
CityModel? cityModel;
|
||||
RxString timeZone = "".obs; //选择时区
|
||||
|
||||
RxList diseaseList = [].obs;
|
||||
RxString update_person_mac = "".obs;
|
||||
@@ -79,10 +82,10 @@ class PersonController extends GetControllerEx<PersonModel> {
|
||||
queryUrl += "?lang=$language";
|
||||
}
|
||||
}
|
||||
if (name.value.isEmpty) {
|
||||
apiResponse.msg = "请输入姓名".tr;
|
||||
return apiResponse;
|
||||
}
|
||||
// if (name.value.isEmpty) {
|
||||
// apiResponse.msg = "请输入姓名".tr;
|
||||
// return apiResponse;
|
||||
// }
|
||||
if (birthday.value.isEmpty) {
|
||||
apiResponse.msg = "请选择生日".tr;
|
||||
return apiResponse;
|
||||
@@ -95,10 +98,14 @@ class PersonController extends GetControllerEx<PersonModel> {
|
||||
apiResponse.msg = "请输入身高".tr;
|
||||
return apiResponse;
|
||||
}
|
||||
if (cityModel == null || cityModel!.id == null) {
|
||||
apiResponse.msg = "请选择城市".tr;
|
||||
if (timeZone == null || timeZone.value.isEmpty) {
|
||||
apiResponse.msg = "请选择时区".tr;
|
||||
return apiResponse;
|
||||
}
|
||||
// if (cityModel == null || cityModel!.id == null) {
|
||||
// apiResponse.msg = "请选择城市".tr;
|
||||
// return apiResponse;
|
||||
// }
|
||||
|
||||
var data = {
|
||||
"id": currentPersonId.value,
|
||||
@@ -110,8 +117,8 @@ class PersonController extends GetControllerEx<PersonModel> {
|
||||
"weight": weight!.value,
|
||||
"height": height.value,
|
||||
"disease": selectedDiseaseIds.value,
|
||||
"city_id": cityModel!.id,
|
||||
"UTC": cityModel!.UTC,
|
||||
"city_id": cityModel?.id,
|
||||
"UTC": timeZone.value,
|
||||
};
|
||||
var response =
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class RepairController extends GetControllerEx<RepairModel> {
|
||||
attr = GetModel(RepairModel()).obs;
|
||||
}
|
||||
|
||||
RxDouble device_type = 0.0.obs;
|
||||
RxInt device_type = 0.obs;
|
||||
RxList repairList = [].obs;
|
||||
|
||||
RxString name = "".obs;
|
||||
|
||||
@@ -69,6 +69,66 @@ Widget getOnePickers(
|
||||
}) {
|
||||
ThemeController themeController = Get.find();
|
||||
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(() {
|
||||
final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}');
|
||||
@@ -132,9 +192,8 @@ Widget getOnePickersSpe(
|
||||
}) {
|
||||
ThemeController themeController = Get.find();
|
||||
final bool isEn = Get.locale?.languageCode.startsWith('en') ?? false;
|
||||
|
||||
final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}');
|
||||
return Obx(() {
|
||||
final dynamicKey = ValueKey('picker_${arr.length}_${selectedIndex.value}');
|
||||
return CupertinoPicker.builder(
|
||||
key: pickerKey ?? dynamicKey,
|
||||
itemExtent: 90.rpx,
|
||||
@@ -1777,8 +1836,7 @@ Future showCustomConfirmOfWebViewDialog(
|
||||
bool showCancel = false,
|
||||
String cancelName = "取消",
|
||||
ConfirmDialogIcon icon = ConfirmDialogIcon.warn,
|
||||
int type = 1
|
||||
}) async {
|
||||
int type = 1}) async {
|
||||
return showDialog(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
@@ -1865,7 +1923,9 @@ Future showCustomConfirmOfWebViewDialog(
|
||||
onTap: () {
|
||||
Get.back(result: "confirm");
|
||||
},
|
||||
colors: type == 3?AppConstants().mhtNormalButton:AppConstants().thNormalButton, // 渐变背景
|
||||
colors: type == 3
|
||||
? AppConstants().mhtNormalButton
|
||||
: AppConstants().thNormalButton, // 渐变背景
|
||||
gradientDirection: GradientDirection.horizontal,
|
||||
child: Container(
|
||||
// width: MediaQuery.sizeOf(context).width * 0.5, // 宽度占屏幕一半
|
||||
|
||||
@@ -5,8 +5,10 @@ import 'package:flutter_svg/svg.dart';
|
||||
import 'package:flutterflow_ui/flutterflow_ui.dart';
|
||||
import 'package:vbvs_app/common/color/appConstants.dart';
|
||||
import 'package:vbvs_app/common/color/app_uri_status.dart';
|
||||
import 'package:vbvs_app/common/util/EventBus.dart';
|
||||
import 'package:vbvs_app/common/util/FitTool.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/tool/ClickableContainer.dart';
|
||||
import 'package:vbvs_app/component/tool/CustomCard.dart';
|
||||
@@ -641,16 +643,19 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
|
||||
: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
30.rpx, 26.rpx, 30.rpx, 0),
|
||||
child: SingleChildScrollView(
|
||||
controller: _myDeviceScrollController,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: myDeviceList
|
||||
.map((device) =>
|
||||
DeviceDataComponentWidget(
|
||||
device: device))
|
||||
.toList()
|
||||
.divide(SizedBox(height: 25.rpx)),
|
||||
child: _wrapWithScrollListener(
|
||||
SingleChildScrollView(
|
||||
controller: _myDeviceScrollController,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: myDeviceList
|
||||
.map((device) =>
|
||||
DeviceDataComponentWidget(
|
||||
device: device))
|
||||
.toList()
|
||||
.divide(
|
||||
SizedBox(height: 25.rpx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -668,17 +673,20 @@ class _BodyDevicePageState extends State<BodyDeviceWidget> {
|
||||
: Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
30.rpx, 26.rpx, 30.rpx, 0),
|
||||
child: SingleChildScrollView(
|
||||
controller:
|
||||
_cloudDeviceScrollController,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: cloudDeviceList
|
||||
.map((device) =>
|
||||
DeviceDataComponentWidget(
|
||||
device: device))
|
||||
.toList()
|
||||
.divide(SizedBox(height: 25.rpx)),
|
||||
child: _wrapWithScrollListener(
|
||||
SingleChildScrollView(
|
||||
controller:
|
||||
_cloudDeviceScrollController,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: cloudDeviceList
|
||||
.map((device) =>
|
||||
DeviceDataComponentWidget(
|
||||
device: device))
|
||||
.toList()
|
||||
.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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import 'package:vbvs_app/enum/BindType.dart';
|
||||
import 'package:vbvs_app/model/api_response.dart';
|
||||
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
|
||||
|
||||
|
||||
class DeviceDataComponentWidget extends StatefulWidget {
|
||||
final Map<String, dynamic> device;
|
||||
|
||||
@@ -44,6 +43,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
|
||||
bool _isPopupOpen = false;
|
||||
|
||||
var lisObj;
|
||||
late StreamSubscription<ScrollNotificationEvent> _scrollSubscription;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@@ -64,6 +64,12 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
|
||||
cityController.cityList = [];
|
||||
await initializeCityData();
|
||||
});
|
||||
_scrollSubscription =
|
||||
EventBus().on<ScrollNotificationEvent>().listen((event) {
|
||||
if (_isPopupOpen) {
|
||||
_closePopup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _showPopup() {
|
||||
@@ -628,7 +634,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
|
||||
maxWidth: MediaQuery.sizeOf(context).width * 0.6,
|
||||
),
|
||||
child: Text(
|
||||
'${widget.device['person']?['name'] ?? '未命名'.tr}',
|
||||
'${(widget.device['person']?['name'] as String?)?.isNotEmpty == true ? widget.device['person']!['name'] : '体征检测设备'.tr}',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 30.rpx,
|
||||
@@ -1180,6 +1186,8 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
|
||||
personController.dateTime =
|
||||
MyUtils.formatBirthdayTime(
|
||||
widget.device['person']['birthday']);
|
||||
personController.timeZone.value =
|
||||
widget.device['person']['UTC'] ?? '';
|
||||
if (widget.device['person']['city_id'] != null) {
|
||||
// 根据city_id查找完整的城市数据
|
||||
final int cityId =
|
||||
@@ -1208,6 +1216,7 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
|
||||
personController.weight.value = "";
|
||||
personController.diseaseList.value = [];
|
||||
personController.cityModel = null;
|
||||
personController.timeZone.value = "";
|
||||
}
|
||||
await Get.toNamed("/updatePersonPage",
|
||||
arguments: widget.device['bind_type']);
|
||||
@@ -1701,4 +1710,12 @@ class _DeviceDataComponentWidgetState extends State<DeviceDataComponentWidget> {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _closePopup() {
|
||||
setState(() {
|
||||
_isPopupOpen = false;
|
||||
});
|
||||
_popupEntry?.remove();
|
||||
_popupEntry = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +659,7 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
40.rpx, 40.rpx, 40.rpx, 20.rpx),
|
||||
30.rpx, 40.rpx, 30.rpx, 20.rpx),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
@@ -681,9 +681,9 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
|
||||
(data["real"] as List)[i].containsKey("name"))
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
40.rpx,
|
||||
30.rpx,
|
||||
i == 0 ? 20.rpx : 0, // 第一个元素顶部有20.rpx间距
|
||||
40.rpx,
|
||||
30.rpx,
|
||||
i == (data["real"] as List).length - 1
|
||||
? 20.rpx
|
||||
: 0.rpx),
|
||||
@@ -781,7 +781,7 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
40.rpx, 40.rpx, 40.rpx, 20.rpx),
|
||||
30.rpx, 40.rpx, 30.rpx, 20.rpx),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
@@ -803,9 +803,9 @@ class _MessageSettingPageState extends State<MessageSettingPage> {
|
||||
(data["report"] as List)[i].containsKey("name"))
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
40.rpx,
|
||||
30.rpx,
|
||||
i == 0 ? 20.rpx : 0, // 第一个元素顶部有20.rpx间距
|
||||
40.rpx,
|
||||
30.rpx,
|
||||
i == (data["report"] as List).length - 1
|
||||
? 20.rpx
|
||||
: 0.rpx),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -96,7 +96,7 @@ getContentById(data, BuildContext context) {
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(40.rpx, 20.rpx, 40.rpx, 20.rpx),
|
||||
EdgeInsetsDirectional.fromSTEB(30.rpx, 20.rpx, 30.rpx, 20.rpx),
|
||||
child: Column(
|
||||
children: [
|
||||
/// --- 心率小于 ---
|
||||
@@ -379,8 +379,8 @@ getContentById(data, BuildContext context) {
|
||||
} else if (id == 100002) {
|
||||
// 呼吸异常
|
||||
|
||||
int min = 10; // 默认
|
||||
int max = 40; // 默认
|
||||
int min = 8; // 默认
|
||||
int max = 25; // 默认
|
||||
int interval = 600; // 默认
|
||||
|
||||
// 若有用户配置
|
||||
@@ -434,7 +434,7 @@ getContentById(data, BuildContext context) {
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(40.rpx, 20.rpx, 40.rpx, 20.rpx),
|
||||
EdgeInsetsDirectional.fromSTEB(30.rpx, 20.rpx, 30.rpx, 20.rpx),
|
||||
child: Column(
|
||||
children: [
|
||||
/// ---- 呼吸小于 ----
|
||||
@@ -1025,7 +1025,7 @@ getContentById(data, BuildContext context) {
|
||||
} else if (id == 100005) {
|
||||
// 未起床
|
||||
// 1. 优先从 device_type_setting 中查找用户配置
|
||||
String time = "23:00"; // 默认值
|
||||
String time = "7:00"; // 默认值
|
||||
|
||||
// 2. 如果找到了用户配置,使用用户配置中的 time 值
|
||||
if (userConfig != null) {
|
||||
@@ -1187,7 +1187,7 @@ getContentById(data, BuildContext context) {
|
||||
);
|
||||
} else if (id == 200001) {
|
||||
// 1. 优先从 device_type_setting 中查找用户配置
|
||||
int score = 60; // 默认值
|
||||
int score = 50; // 默认值
|
||||
// 2. 如果找到了用户配置,使用用户配置中的 max 值
|
||||
if (userConfig != null) {
|
||||
print('找到用户配置: $userConfig');
|
||||
@@ -1195,7 +1195,7 @@ getContentById(data, BuildContext context) {
|
||||
if (userConfig['max'] != null) {
|
||||
score = userConfig['max'] is int
|
||||
? userConfig['max']
|
||||
: int.tryParse(userConfig['max'].toString()) ?? 60;
|
||||
: int.tryParse(userConfig['max'].toString()) ?? score;
|
||||
print('从用户配置获取睡眠得分阈值: $score');
|
||||
}
|
||||
} else {
|
||||
@@ -1207,7 +1207,7 @@ getContentById(data, BuildContext context) {
|
||||
if (defaultConfig['max'] != null) {
|
||||
score = defaultConfig['max'] is int
|
||||
? defaultConfig['max']
|
||||
: int.tryParse(defaultConfig['max'].toString()) ?? 60;
|
||||
: int.tryParse(defaultConfig['max'].toString()) ?? score;
|
||||
print('从默认配置获取睡眠得分阈值: $score');
|
||||
}
|
||||
} else {
|
||||
@@ -1235,8 +1235,8 @@ getContentById(data, BuildContext context) {
|
||||
onTap: () async {
|
||||
final currentScore = score;
|
||||
final initialScore = currentScore != null
|
||||
? int.tryParse(currentScore.toString()) ?? 60
|
||||
: 60;
|
||||
? int.tryParse(currentScore.toString()) ?? score
|
||||
: score;
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
Future.delayed(const Duration(milliseconds: 250), () {
|
||||
showScorePickerDialog(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -384,7 +384,7 @@ class _EPageState extends State<DeviceTypePage> {
|
||||
}
|
||||
|
||||
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) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ class _DeviceTypeListPageState extends State<DeviceTypeListPage> {
|
||||
}
|
||||
|
||||
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) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
@@ -728,8 +728,8 @@ class _OtherLoginPageState extends State<OtherLoginPage> {
|
||||
weatherModelController = Get.find();
|
||||
await weatherModelController
|
||||
.getCurrentLocation();
|
||||
await weatherModelController
|
||||
.getCurrentWeather();
|
||||
// await weatherModelController
|
||||
// .getCurrentWeather();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -884,6 +884,7 @@ class _HomePageState extends State<HomePage> {
|
||||
|
||||
homeController.model.type = 1;
|
||||
deviceController.model.type = 1;
|
||||
homeController.updateAll();
|
||||
await deviceController
|
||||
.getDeviceList();
|
||||
await deviceController
|
||||
@@ -942,6 +943,7 @@ class _HomePageState extends State<HomePage> {
|
||||
onTap: () async {
|
||||
homeController.model.type = 2;
|
||||
deviceController.model.type = 2;
|
||||
homeController.updateAll();
|
||||
await deviceController
|
||||
.getDeviceList();
|
||||
await deviceController
|
||||
|
||||
@@ -58,6 +58,16 @@ class _MessagePageState extends State<MessagePage> {
|
||||
}
|
||||
|
||||
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.updateAll();
|
||||
_fetchMessageData();
|
||||
@@ -298,56 +308,47 @@ class _MessagePageState extends State<MessagePage> {
|
||||
),
|
||||
backgroundColor: Colors.transparent,
|
||||
body: SafeArea(
|
||||
top: true,
|
||||
child: PageView(
|
||||
controller: _pageController,
|
||||
onPageChanged: _onPageChanged,
|
||||
children: [
|
||||
Obx(() {
|
||||
final list = messageController.messageList.value;
|
||||
return list.isEmpty
|
||||
? const NullDataWidget()
|
||||
: _buildMessageListView(list, "app_vsm");
|
||||
}),
|
||||
Obx(() {
|
||||
final list = messageController.messageList.value;
|
||||
return list.isEmpty
|
||||
? const NullDataWidget()
|
||||
: _buildMessageListView(list, "app_system");
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
top: true,
|
||||
child: Scrollbar(
|
||||
child: PageView(
|
||||
controller: _pageController,
|
||||
onPageChanged: _onPageChanged,
|
||||
children: [
|
||||
Obx(() {
|
||||
final list = messageController.messageList.value;
|
||||
return list.isEmpty
|
||||
? const NullDataWidget()
|
||||
: _buildMessageListView(list, "app_vsm");
|
||||
}),
|
||||
Obx(() {
|
||||
final list = messageController.messageList.value;
|
||||
return list.isEmpty
|
||||
? const NullDataWidget()
|
||||
: _buildMessageListView(list, "app_system");
|
||||
}),
|
||||
],
|
||||
),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return NotificationListener<ScrollNotification>(
|
||||
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;
|
||||
},
|
||||
|
||||
@@ -48,6 +48,16 @@ class _MessageReturnPageState extends State<MessageReturnPage> {
|
||||
}
|
||||
|
||||
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.updateAll();
|
||||
_fetchMessageData();
|
||||
@@ -297,7 +307,8 @@ class _MessageReturnPageState extends State<MessageReturnPage> {
|
||||
height: 4.rpx,
|
||||
decoration: BoxDecoration(
|
||||
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) {
|
||||
return NotificationListener<ScrollNotification>(
|
||||
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;
|
||||
},
|
||||
|
||||
@@ -703,7 +703,7 @@ class _MinePageState extends State<MinePage> {
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
'V1.0.2512.10',
|
||||
'V1.0.2601.06',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
// color: Color(0xFFD9E3EB),
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -375,7 +390,7 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
|
||||
final diseaseIds = diseaseIdsList[i];
|
||||
|
||||
// 添加城市信息到person数据
|
||||
person['UTC'] = cityModel.UTC;
|
||||
// person['UTC'] = cityModel.UTC;
|
||||
person['city_id'] = cityModel.id;
|
||||
person['disease_ids'] = diseaseIds; // 添加疾病ID
|
||||
|
||||
@@ -917,6 +932,98 @@ class _MHTPeopleInfoPageState extends State<MHTPeopleInfoPage> {
|
||||
),
|
||||
),
|
||||
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(
|
||||
height: 90.rpx,
|
||||
|
||||
@@ -253,7 +253,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
),
|
||||
].divide(SizedBox(width: 22.rpx)),
|
||||
),
|
||||
Text('SWES2025.12.30',
|
||||
Text('SWES2026.1.5',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 26.rpx,
|
||||
|
||||
@@ -142,22 +142,6 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
|
||||
isValid = false;
|
||||
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) {
|
||||
@@ -890,10 +874,10 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
|
||||
// 补齐并追加
|
||||
list.add(newCity);
|
||||
}
|
||||
controller.model
|
||||
.peopleList[
|
||||
index]['UTC'] =
|
||||
list[index].UTC;
|
||||
// controller.model
|
||||
// .peopleList[
|
||||
// index]['UTC'] =
|
||||
// list[index].UTC;
|
||||
controller.model
|
||||
.peopleList[
|
||||
index]
|
||||
@@ -952,14 +936,17 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
|
||||
: "请选择城市".tr,
|
||||
style: TextStyle(
|
||||
color: getCityModel(
|
||||
index) !=
|
||||
null
|
||||
index) !=
|
||||
null &&
|
||||
getCityModel(
|
||||
index)!
|
||||
.id !=
|
||||
null
|
||||
? themeController
|
||||
.currentColor
|
||||
.sc3
|
||||
: themeController
|
||||
.currentColor
|
||||
.sc4,
|
||||
: Color(
|
||||
0xFF9EA4B7),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
),
|
||||
@@ -981,6 +968,160 @@ class PeopleInfoPage extends GetView<PeopleInfoController> {
|
||||
),
|
||||
),
|
||||
getLine(),
|
||||
Container(
|
||||
height: 90.rpx,
|
||||
margin: EdgeInsets.only(
|
||||
left: 40.rpx,
|
||||
right: 35.rpx,
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// if (widget.status ==
|
||||
// BindType.share.code) {
|
||||
// TopSlideNotification.show(
|
||||
// context,
|
||||
// text: "被分享用户只能修改用户名称",
|
||||
// textColor:
|
||||
// themeController
|
||||
// .currentColor
|
||||
// .sc9);
|
||||
// return;
|
||||
// }
|
||||
FocusScope.of(context)
|
||||
.requestFocus(
|
||||
FocusNode());
|
||||
Future.delayed(
|
||||
Duration(
|
||||
milliseconds: 250),
|
||||
() {
|
||||
// 获取当前时区
|
||||
String? currentTimeZone;
|
||||
if (controller
|
||||
.model
|
||||
.peopleList
|
||||
.isNotEmpty &&
|
||||
index <
|
||||
controller
|
||||
.model
|
||||
.peopleList
|
||||
.length &&
|
||||
controller.model
|
||||
.peopleList[
|
||||
index]['UTC'] !=
|
||||
null) {
|
||||
currentTimeZone =
|
||||
controller.model
|
||||
.peopleList[
|
||||
index]['UTC'];
|
||||
}
|
||||
|
||||
showTimeMHTZonePickerDialog(
|
||||
context,
|
||||
title: "请选择时区".tr,
|
||||
initialTimeZone:
|
||||
currentTimeZone ?? "",
|
||||
onConfirm: (String
|
||||
selectedTimeZone) {
|
||||
controller.model
|
||||
.peopleList[
|
||||
index]['UTC'] =
|
||||
selectedTimeZone;
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'请选择时区'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily:
|
||||
'Readex Pro',
|
||||
color:
|
||||
Color(0xFF9EA4B7),
|
||||
fontSize: 30.rpx,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
controller
|
||||
.model
|
||||
.peopleList
|
||||
.isNotEmpty &&
|
||||
index <
|
||||
controller
|
||||
.model
|
||||
.peopleList
|
||||
.length &&
|
||||
controller.model
|
||||
.peopleList[index]
|
||||
[
|
||||
'UTC'] !=
|
||||
null &&
|
||||
controller
|
||||
.model
|
||||
.peopleList[
|
||||
index]
|
||||
[
|
||||
'UTC']!
|
||||
.isNotEmpty
|
||||
? controller.model
|
||||
.peopleList[
|
||||
index]['UTC']!
|
||||
: "请选择时区".tr,
|
||||
style: TextStyle(
|
||||
color: controller
|
||||
.model
|
||||
.peopleList
|
||||
.isNotEmpty &&
|
||||
index <
|
||||
controller
|
||||
.model
|
||||
.peopleList
|
||||
.length &&
|
||||
controller.model
|
||||
.peopleList[index]
|
||||
[
|
||||
'UTC'] !=
|
||||
null &&
|
||||
controller
|
||||
.model
|
||||
.peopleList[
|
||||
index]
|
||||
[
|
||||
'UTC']!
|
||||
.isNotEmpty
|
||||
? themeController
|
||||
.currentColor
|
||||
.sc3
|
||||
: Color(
|
||||
0xFF9EA4B7),
|
||||
fontSize: AppConstants()
|
||||
.title_text_fontSize,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16.rpx),
|
||||
Container(
|
||||
height: 30.rpx,
|
||||
width: 30.rpx,
|
||||
child:
|
||||
SvgPicture.asset(
|
||||
'assets/img/icon/expand_more.svg',
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
getLine(),
|
||||
Container(
|
||||
height: 90.rpx,
|
||||
margin: EdgeInsets.only(
|
||||
|
||||
@@ -60,6 +60,13 @@ class _EPageState extends State<PersonPage> {
|
||||
personController.weight.value = "";
|
||||
personController.height.value = "";
|
||||
personController.dateTime = null;
|
||||
personController.cityModel = null;
|
||||
personController.timeZone.value = "";
|
||||
|
||||
personController.getTimeZoneByLocalTime().then((value) {
|
||||
personController.timeZone.value = value;
|
||||
personController.updateAll();
|
||||
});
|
||||
|
||||
cityDataFuture = cityController.loadAndSetCityData().then((success) {
|
||||
return cityController.cityList;
|
||||
@@ -172,7 +179,7 @@ class _EPageState extends State<PersonPage> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
70.rpx, 141.rpx, 70.rpx, 0),
|
||||
70.rpx, 70.rpx, 70.rpx, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 100.rpx,
|
||||
@@ -404,30 +411,77 @@ class _EPageState extends State<PersonPage> {
|
||||
}, title: "选择生日".tr);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
personController.dateTime != null
|
||||
? DateFormat("yyyy/MM/dd").format(
|
||||
personController.dateTime!)
|
||||
: '人员资料.生日输入提示'.tr,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.dateTime != null
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: personController
|
||||
.dateTime !=
|
||||
null
|
||||
? DateFormat(
|
||||
"yyyy/MM/dd")
|
||||
.format(
|
||||
personController
|
||||
.dateTime!)
|
||||
: '人员资料.生日输入提示'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController
|
||||
.dateTime !=
|
||||
null
|
||||
? 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, 50.rpx, 70.rpx, 0),
|
||||
70.rpx, 25.rpx, 70.rpx, 0),
|
||||
child: Container(
|
||||
height: 100.rpx,
|
||||
decoration: BoxDecoration(
|
||||
@@ -464,31 +518,76 @@ class _EPageState extends State<PersonPage> {
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
personController.height.value != ""
|
||||
? personController.height.value +
|
||||
"cm".tr
|
||||
: '身高输入提示'.tr,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.height.value !=
|
||||
""
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: personController
|
||||
.height.value !=
|
||||
""
|
||||
? personController
|
||||
.height.value +
|
||||
"cm".tr
|
||||
: '身高输入提示'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController
|
||||
.height
|
||||
.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, 50.rpx, 70.rpx, 0),
|
||||
70.rpx, 25.rpx, 70.rpx, 0),
|
||||
child: Container(
|
||||
height: 100.rpx,
|
||||
decoration: BoxDecoration(
|
||||
@@ -512,38 +611,184 @@ class _EPageState extends State<PersonPage> {
|
||||
personController.weight.value ?? "",
|
||||
onConfirm: (int selectedWeight) {
|
||||
personController.weight.value =
|
||||
selectedWeight
|
||||
.toString(); // ✅ 转成字符串
|
||||
selectedWeight.toString();
|
||||
personController.updateAll();
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
personController.weight.value != ""
|
||||
? personController.weight.value +
|
||||
"kg".tr
|
||||
: '人员资料.体重输入提示'.tr,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.weight.value !=
|
||||
""
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: personController
|
||||
.weight.value !=
|
||||
""
|
||||
? personController
|
||||
.weight.value +
|
||||
"kg".tr
|
||||
: '人员资料.体重输入提示'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController
|
||||
.weight
|
||||
.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, 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(
|
||||
height: 100.rpx,
|
||||
decoration: BoxDecoration(
|
||||
@@ -577,32 +822,77 @@ class _EPageState extends State<PersonPage> {
|
||||
title: "选择城市".tr,
|
||||
cityDataFuture:
|
||||
cityDataFuture, // 传入预加载的数据
|
||||
colors: CitySelectionColors(
|
||||
// pickerBackgroundColor:
|
||||
// stringToColor("#003058"),
|
||||
// confirmTextColor:
|
||||
// stringToColor("#84F5FF"),
|
||||
selectedCityColor:
|
||||
themeController.currentColor.sc2,
|
||||
selectedTextColor: Colors.white,
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
_getDetailedCityDisplayText(
|
||||
personController.cityModel),
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.cityModel !=
|
||||
null
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
_getDetailedCityDisplayText(
|
||||
personController.cityModel),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color:
|
||||
personController
|
||||
.cityModel !=
|
||||
null
|
||||
? themeController
|
||||
.currentColor.sc3
|
||||
: themeController
|
||||
.currentColor.sc4,
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
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: EdgeInsetsDirectional.fromSTEB(
|
||||
0, 117.rpx, 0, 0),
|
||||
0, 60.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
|
||||
@@ -3,9 +3,11 @@ import 'dart:convert';
|
||||
import 'package:ef/ef.dart';
|
||||
import 'package:flutter/material.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/util/FitTool.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/controller/person/person_controller.dart';
|
||||
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
|
||||
@@ -666,7 +668,7 @@ Widget _buildCityPickerContent(
|
||||
Get.find();
|
||||
cityModelController.tmp;
|
||||
ef.log("${cityModelController.tmp.value}");
|
||||
return getOnePickers(
|
||||
return getOnePickersCity(
|
||||
context,
|
||||
countries,
|
||||
countryIndex,
|
||||
@@ -684,7 +686,7 @@ Widget _buildCityPickerContent(
|
||||
Get.find();
|
||||
cityModelController.tmp;
|
||||
ef.log("${cityModelController.tmp.value}");
|
||||
return getOnePickers(
|
||||
return getOnePickersCity(
|
||||
context,
|
||||
provinces,
|
||||
provinceIndex,
|
||||
@@ -702,7 +704,7 @@ Widget _buildCityPickerContent(
|
||||
Get.find();
|
||||
cityModelController.tmp;
|
||||
ef.log("${cityModelController.tmp.value}");
|
||||
return getOnePickers(
|
||||
return getOnePickersCity(
|
||||
context,
|
||||
cities,
|
||||
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"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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: "", // 时区不需要单位
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
70.rpx, 141.rpx, 70.rpx, 0),
|
||||
70.rpx, 70.rpx, 70.rpx, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 100.rpx,
|
||||
@@ -204,7 +204,12 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
letterSpacing: 0.0,
|
||||
color: themeController.currentColor.sc3,
|
||||
),
|
||||
hintText: '人员资料.名字输入提示'.tr,
|
||||
hintText: (personController.name.value
|
||||
as String?)
|
||||
?.isNotEmpty ==
|
||||
true
|
||||
? personController.name.value
|
||||
: '体征检测设备'.tr,
|
||||
hintStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 26.rpx,
|
||||
@@ -432,30 +437,77 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
personController.dateTime != null
|
||||
? DateFormat("yyyy/MM/dd").format(
|
||||
personController.dateTime!)
|
||||
: '人员资料.生日输入提示'.tr,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.dateTime != null
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: personController
|
||||
.dateTime !=
|
||||
null
|
||||
? DateFormat(
|
||||
"yyyy/MM/dd")
|
||||
.format(
|
||||
personController
|
||||
.dateTime!)
|
||||
: '人员资料.生日输入提示'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController
|
||||
.dateTime !=
|
||||
null
|
||||
? 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, 50.rpx, 70.rpx, 0),
|
||||
70.rpx, 25.rpx, 70.rpx, 0),
|
||||
child: Container(
|
||||
height: 100.rpx,
|
||||
decoration: BoxDecoration(
|
||||
@@ -500,31 +552,76 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
personController.height.value != ""
|
||||
? personController.height.value +
|
||||
"cm".tr
|
||||
: '身高输入提示'.tr,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.height.value !=
|
||||
""
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: personController
|
||||
.height.value !=
|
||||
""
|
||||
? personController
|
||||
.height.value +
|
||||
"cm".tr
|
||||
: '身高输入提示'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController
|
||||
.height
|
||||
.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, 50.rpx, 70.rpx, 0),
|
||||
70.rpx, 25.rpx, 70.rpx, 0),
|
||||
child: Container(
|
||||
height: 100.rpx,
|
||||
decoration: BoxDecoration(
|
||||
@@ -555,38 +652,193 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
personController.weight.value ?? "",
|
||||
onConfirm: (int selectedWeight) {
|
||||
personController.weight.value =
|
||||
selectedWeight
|
||||
.toString(); // ✅ 转成字符串
|
||||
selectedWeight.toString();
|
||||
personController.updateAll();
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
personController.weight.value != ""
|
||||
? personController.weight.value +
|
||||
"kg".tr
|
||||
: '人员资料.体重输入提示'.tr,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.weight.value !=
|
||||
""
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: personController
|
||||
.weight.value !=
|
||||
""
|
||||
? personController
|
||||
.weight.value +
|
||||
"kg".tr
|
||||
: '人员资料.体重输入提示'.tr,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController
|
||||
.weight
|
||||
.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, 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(
|
||||
height: 100.rpx,
|
||||
decoration: BoxDecoration(
|
||||
@@ -627,33 +879,80 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
title: "选择城市".tr,
|
||||
cityDataFuture:
|
||||
cityDataFuture, // 传入预加载的数据
|
||||
colors: CitySelectionColors(
|
||||
// pickerBackgroundColor:
|
||||
// stringToColor("#003058"),
|
||||
// confirmTextColor:
|
||||
// stringToColor("#84F5FF"),
|
||||
selectedCityColor:
|
||||
themeController.currentColor.sc2,
|
||||
selectedTextColor: Colors.white,
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Center(
|
||||
child: Text(
|
||||
MyUtils.getDetailedCityDisplayText(
|
||||
personController.cityModel),
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color: personController.cityModel !=
|
||||
null
|
||||
? themeController.currentColor.sc3
|
||||
: themeController.currentColor.sc4,
|
||||
fontSize:
|
||||
AppConstants().normal_text_fontSize,
|
||||
letterSpacing: 0,
|
||||
child: Stack(
|
||||
children: [
|
||||
// 文字居中
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
MyUtils
|
||||
.getDetailedCityDisplayText(
|
||||
personController
|
||||
.cityModel),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: 'Readex Pro',
|
||||
color:
|
||||
personController
|
||||
.cityModel !=
|
||||
null
|
||||
? themeController
|
||||
.currentColor.sc3
|
||||
: themeController
|
||||
.currentColor.sc4,
|
||||
fontSize: AppConstants()
|
||||
.normal_text_fontSize,
|
||||
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: EdgeInsetsDirectional.fromSTEB(
|
||||
0, 117.rpx, 0, 0),
|
||||
0, 60.rpx, 0, 0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(),
|
||||
@@ -858,5 +1157,4 @@ class _UpdatePageState extends State<UpdatePersonPage> {
|
||||
onFailure: (res) {},
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -127,18 +127,66 @@ class BarChartPainter extends CustomPainter {
|
||||
final textPainter = TextPainter(textDirection: ui.TextDirection.ltr);
|
||||
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轴刻度
|
||||
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;
|
||||
// 判断是否是基线(i == 0)
|
||||
final bool isBaseline = i == 0;
|
||||
|
||||
drawDashedLine(
|
||||
canvas, Offset(leftPadding, y), Offset(size.width, y), dashPaint);
|
||||
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()
|
||||
..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(
|
||||
@@ -163,14 +211,14 @@ class BarChartPainter extends CustomPainter {
|
||||
final startHour = startDate.hour;
|
||||
|
||||
// 绘制X轴主线(实线)
|
||||
final xAxisPaint = Paint()
|
||||
..color = Colors.grey.withOpacity(0.4)
|
||||
..strokeWidth = 1.rpx;
|
||||
canvas.drawLine(
|
||||
Offset(leftPadding, xAxisY),
|
||||
Offset(size.width, xAxisY),
|
||||
xAxisPaint,
|
||||
);
|
||||
// final xAxisPaint = Paint()
|
||||
// ..color = Colors.grey.withOpacity(0.4)
|
||||
// ..strokeWidth = 1.rpx;
|
||||
// canvas.drawLine(
|
||||
// Offset(leftPadding, xAxisY),
|
||||
// Offset(size.width, xAxisY),
|
||||
// xAxisPaint,
|
||||
// );
|
||||
|
||||
// 绘制左右两侧时间标签(HH:mm格式)
|
||||
final leftLabel = DateFormat('HH:mm').format(startDate);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -98,8 +98,9 @@ class _BreatheCardState extends State<BreatheCard>
|
||||
BorderRadius.circular(AppConstants().normal_container_radius),
|
||||
),
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
|
||||
// padding:
|
||||
// EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Wrap(
|
||||
spacing: 23.rpx,
|
||||
runSpacing: 25.rpx,
|
||||
@@ -110,7 +111,8 @@ class _BreatheCardState extends State<BreatheCard>
|
||||
_shouldAnimate && item['id'] == _highlightedId;
|
||||
|
||||
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(
|
||||
animation: _animationController ?? AlwaysStoppedAnimation(0),
|
||||
builder: (context, child) {
|
||||
@@ -137,7 +139,7 @@ class _BreatheCardState extends State<BreatheCard>
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
es.EasyDartModule.logger.error("呼吸监测绘制异常${e}");
|
||||
es.EasyDartModule.logger.error("呼吸卡片绘制异常${e}");
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,15 +100,17 @@ class _HeartRateCardState extends State<HeartRateCard>
|
||||
}).toList(); // 添加 .toList()
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: themeController.currentColor.sc5,
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConstants().normal_container_radius),
|
||||
),
|
||||
// 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),
|
||||
// padding:
|
||||
// EdgeInsetsDirectional.fromSTEB(26.rpx, 29.rpx, 26.rpx, 45.rpx),
|
||||
padding: EdgeInsets.all(0),
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
spacing: 23.rpx,
|
||||
runSpacing: 25.rpx,
|
||||
children: List.generate(data.length, (index) {
|
||||
@@ -118,7 +120,7 @@ class _HeartRateCardState extends State<HeartRateCard>
|
||||
_shouldAnimate && item['id'] == _highlightedId;
|
||||
|
||||
return SizedBox(
|
||||
width: (MediaQuery.of(context).size.width - 160.rpx) / 3,
|
||||
width: (MediaQuery.of(context).size.width - 120.rpx) / 3,
|
||||
child: AnimatedBuilder(
|
||||
animation: _animationController ?? AlwaysStoppedAnimation(0),
|
||||
builder: (context, child) {
|
||||
@@ -145,7 +147,7 @@ class _HeartRateCardState extends State<HeartRateCard>
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
es.EasyDartModule.logger.error("心率监测绘制异常${e}");
|
||||
es.EasyDartModule.logger.error("心率卡片绘制异常${e}");
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,8 @@ class _HeartRateStandardWidgetState extends State<HeartRateStandardWidget> {
|
||||
14.rpx, 10.rpx, 14.rpx, 10.rpx), //
|
||||
borderRadius: 0.rpx, // 圆形点击区域
|
||||
onTap: () {
|
||||
if (AppConstants().ent_type == APPPackageType.MHT.code) {
|
||||
if (AppConstants().ent_type ==
|
||||
APPPackageType.MHT.code) {
|
||||
showTipDialog(
|
||||
context,
|
||||
Container(
|
||||
|
||||
@@ -104,54 +104,41 @@ class _SleepCardState extends State<SleepCard> with TickerProviderStateMixin {
|
||||
.where((item) => item['show'] != false)
|
||||
.toList();
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
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,
|
||||
runSpacing: 25.rpx,
|
||||
children: List.generate(data.length, (index) {
|
||||
final item = data[index];
|
||||
item['showTip'] = true;
|
||||
final bool isHighlighted =
|
||||
_shouldAnimate && item['id'] == _highlightedId;
|
||||
return SizedBox(
|
||||
width: (MediaQuery.of(context).size.width - 160.rpx) / num,
|
||||
child: AnimatedBuilder(
|
||||
animation: _animationController ?? AlwaysStoppedAnimation(0),
|
||||
builder: (context, child) {
|
||||
return Container(
|
||||
key: isHighlighted ? _highlightKey : null,
|
||||
decoration: isHighlighted
|
||||
? BoxDecoration(
|
||||
border: Border.all(
|
||||
color: themeController.currentColor.sc2
|
||||
.withOpacity(
|
||||
_animationController?.value ?? 0),
|
||||
width: 1.rpx,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
)
|
||||
: null,
|
||||
child: SleepDataModuleWidget(
|
||||
data: item,
|
||||
sleepReportData: widget.sleepReport,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
return Wrap(
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
spacing: 23.rpx,
|
||||
runSpacing: 25.rpx,
|
||||
children: List.generate(data.length, (index) {
|
||||
final item = data[index];
|
||||
item['showTip'] = true;
|
||||
final bool isHighlighted =
|
||||
_shouldAnimate && item['id'] == _highlightedId;
|
||||
return SizedBox(
|
||||
width: (MediaQuery.of(context).size.width - 120.rpx) / num,
|
||||
child: AnimatedBuilder(
|
||||
animation: _animationController ?? AlwaysStoppedAnimation(0),
|
||||
builder: (context, child) {
|
||||
return Container(
|
||||
key: isHighlighted ? _highlightKey : null,
|
||||
decoration: isHighlighted
|
||||
? BoxDecoration(
|
||||
border: Border.all(
|
||||
color: themeController.currentColor.sc2
|
||||
.withOpacity(_animationController?.value ?? 0),
|
||||
width: 1.rpx,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
)
|
||||
: null,
|
||||
child: SleepDataModuleWidget(
|
||||
data: item,
|
||||
sleepReportData: widget.sleepReport,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
} catch (e) {
|
||||
es.EasyDartModule.logger.error("数据卡片渲染异常${e}");
|
||||
|
||||
@@ -70,6 +70,22 @@ class _SleepViewWidgetState extends State<SleepViewWidget> {
|
||||
// "name": "rem",
|
||||
// "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(
|
||||
width: double.infinity,
|
||||
@@ -306,7 +322,7 @@ class _SleepViewWidgetState extends State<SleepViewWidget> {
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 49.rpx,
|
||||
height: 70.rpx,
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsetsDirectional.fromSTEB(
|
||||
@@ -359,8 +375,13 @@ class _SleepViewWidgetState extends State<SleepViewWidget> {
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
es.EasyDartModule.logger.error("打鼾监测绘制异常${e}");
|
||||
es.EasyDartModule.logger.error("睡眠规律性异常${e}");
|
||||
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')}';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user