Files
tuiche/lib/pages/main_bottom/home_page.dart
2025-07-11 15:55:59 +08:00

1338 lines
71 KiB
Dart

import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/common/util/requestWithLog.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/home_page/DynamicReportDetailWidget.dart';
import 'package:vbvs_app/component/home_page/SleepDataModuleWidget.dart';
import 'package:vbvs_app/component/home_page/SleepDateWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/device/blueteeth_bind_controller.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/home/home_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_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/user_info_controller.dart';
import 'package:vbvs_app/controller/weather/weather_controller.dart';
import 'package:vbvs_app/enum/LoginStatus.dart';
import 'package:vbvs_app/pages/device_bind/componnet/bind_dialog.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
UserInfoController userInfoController = Get.find();
ThemeController themeController = Get.find();
BodyDeviceController deviceController = Get.find();
HomeController homeController = Get.find();
WeatherModelController weatherModelController = Get.find();
final GlobalKey addIconKey = GlobalKey();
OverlayEntry? _popupEntry;
void _showPopup() {
final renderBox =
addIconKey.currentContext?.findRenderObject() as RenderBox?;
if (renderBox == null) return;
final position = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
double popupWidth = 190.rpx;
_popupEntry?.remove(); // 清除旧弹窗
_popupEntry = OverlayEntry(
builder: (context) => Stack(
children: [
// 空白区域点击关闭
Positioned.fill(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
_popupEntry?.remove();
_popupEntry = null;
},
child: Container(), // 透明区域,必须加上确保能响应点击
),
),
// 弹窗本体
Positioned(
top: position.dy + size.height + 26.rpx,
left: position.dx + size.width - popupWidth - 40.rpx,
child: Material(
color: Colors.transparent,
child: Container(
width: popupWidth,
padding: EdgeInsets.all(20.rpx),
decoration: BoxDecoration(
color: themeController.currentColor.sc17,
borderRadius: BorderRadius.circular(12.rpx),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 12.rpx,
spreadRadius: 2.rpx,
offset: Offset(0, 6.rpx),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 11.rpx),
ClickableContainer(
padding: EdgeInsets.symmetric(vertical: 10.rpx),
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc16.withOpacity(0.1),
borderRadius: 0.rpx,
onTap: () {
_popupEntry?.remove();
_popupEntry = null;
TopSlideNotification.show(
context,
text: "待开发功能".tr,
);
},
child: Container(
width: double.infinity,
child: Center(
child: Text(
'扫一扫.标题'.tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
),
),
),
SizedBox(height: 35.rpx),
ClickableContainer(
padding: EdgeInsets.symmetric(vertical: 10.rpx),
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc16.withOpacity(0.1),
borderRadius: 0.rpx,
onTap: () {
_popupEntry?.remove();
_popupEntry = null;
BlueteethBindController blueteethBindController =
Get.find();
blueteethBindController.returnPage = 0;
Get.toNamed("/deviceType");
},
child: Container(
width: double.infinity,
child: Center(
child: Text(
'蓝牙绑定.标题'.tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
),
),
),
SizedBox(height: 13.rpx),
],
),
),
),
),
],
),
);
Overlay.of(context)!.insert(_popupEntry!);
}
void _hidePopup() {
_popupEntry?.remove();
_popupEntry = null;
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// 页面返回时重新判断是否当前路由是HomePage
WidgetsBinding.instance.addPostFrameCallback((_) {
if (ModalRoute.of(context)?.isCurrent ?? false) {
checkAndShowBindProcess();
}
});
}
@override
initState() {
super.initState();
if (userInfoController.model.login == 1) {
homeController.getSleepReport();
deviceController.getDeviceNum().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
}
});
deviceController.getDeviceList().then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController.currentColor.sc9,
);
} else {
//请求睡眠报告
deviceController.getSleepReport();
}
});
}
if (userInfoController.device_bind_flag == 0) {
dealBindProcess().then((value) {
WidgetsBinding.instance.addPostFrameCallback((_) {
userInfoController.device_bind_flag = 1;
checkAndShowBindProcess();
});
});
}
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
if (_popupEntry != null) {
_hidePopup();
}
},
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgImage.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
top: true,
// child: Text("首页"),
child: Container(
height: bodySize.maxHeight,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
AppConstants().main_left_right_padding,
47.rpx,
AppConstants().main_left_right_padding,
0),
child: Column(
children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Padding(
//用户信息
padding: EdgeInsetsDirectional.fromSTEB(
AppConstants().content_left_right_padding,
0,
0,
0),
child: Container(
// color: Colors.red,
width: double.infinity,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
if (userInfoController.model.login == 0)
Obx(() {
return Visibility(
visible:
userInfoController.model.login ==
0,
child: CustomCard(
borderRadius: 20.rpx,
onTap: () async {
Get.toNamed("/loginPage");
},
colors: [
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
// width: 100.rpx,
height: 60.rpx,
alignment: Alignment.center,
padding: EdgeInsetsDirectional
.fromSTEB(
16.rpx, 0, 16.rpx, 0),
child: Text(
'首页.登录'.tr,
style: TextStyle(
fontFamily: 'Inter Tight',
color: themeController
.currentColor.sc19,
letterSpacing: 0.0,
),
),
),
),
);
}),
if (userInfoController.model.login == 1)
Obx(() {
return Visibility(
visible:
userInfoController.model.login ==
1,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Text(
userInfoController.model.user!
.nick_name ??
'未命名'.tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
fontSize: AppConstants()
.normal_text_fontSize,
),
),
Obx(() {
return Row(
children: [
Text(
"${weatherModelController.model.cityName ?? '未知数据'.tr}",
style: TextStyle(
color: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
),
),
Text(
"${(weatherModelController.model.current_temperature != null && weatherModelController.model.current_temperature! > 0) ? weatherModelController.model.current_temperature : '未知数据'.tr}" +
"°C",
style: TextStyle(
color: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
),
),
Text(
"${(weatherModelController.model.weather_info?.isNotEmpty ?? false) ? weatherModelController.model.weather_info : '未知数据'.tr}",
style: TextStyle(
color: themeController
.currentColor.sc4,
fontSize: AppConstants()
.normal_text_fontSize,
),
),
if (weatherModelController
.model
.weatherIconurl !=
null &&
weatherModelController
.model
.weatherIconurl!
.isNotEmpty)
Container(
width: 35.rpx,
height: 26.rpx,
clipBehavior:
Clip.antiAlias,
decoration:
BoxDecoration(
shape: BoxShape
.circle),
child: Image.network(
weatherModelController
.model
.weatherIconurl!,
fit: BoxFit.cover,
),
),
].divide(SizedBox(
width: 20.rpx,
)),
);
}),
],
),
);
}),
ClickableContainer(
key: addIconKey,
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc16,
padding: EdgeInsets.all(0.rpx),
onTap: () {
UserInfoController userInfoController =
Get.find();
if (userInfoController.model.login !=
LoginStatus.LOGIN.code) {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor: themeController
.currentColor.sc9,
);
_hidePopup();
Get.toNamed("/loginPage");
} else {
// 点击图标时,展示弹窗
if (_popupEntry == null) {
_showPopup();
} else {
_hidePopup();
}
}
},
child: SvgPicture.asset(
'assets/img/icon/add.svg',
width: 39.rpx,
height: 39.rpx,
color:
themeController.currentColor.sc16,
),
),
],
),
),
),
Padding(
//绑定数量
padding: EdgeInsetsDirectional.fromSTEB(
19.rpx, 34.rpx, 0, 21.rpx),
child: ClickableContainer(
backgroundColor: Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
onTap: () async {
print('点击了容器');
if (userInfoController.model.login ==
LoginStatus.LOGIN.code) {
await Get.toNamed("/bodyDevice");
} else {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor:
themeController.currentColor.sc9,
);
Get.toNamed("/loginPage");
}
},
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 10.rpx, 0, 10.rpx),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Container(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'首页.已关联体征监测设备'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
//todo 颜色
color: themeController
.currentColor.sc3,
),
),
Obx(() {
return Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
0, 4.rpx, 0.rpx, 0.rpx),
child: Text(
"${deviceController.bindDeviceNum.value}",
style: TextStyle(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
color: themeController
.currentColor.sc8,
),
),
);
}),
].divide(SizedBox(
width: 6.rpx,
)),
)),
Obx(() {
return Visibility(
visible: userInfoController
.model.deviceBindNum! >=
0,
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
0, 0.rpx, 8.rpx, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 14.rpx,
height:
14.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
),
);
}),
],
),
),
),
Obx(() {
return Visibility(
visible:
deviceController.bindDeviceNum.value == 0,
child: Container(
//未绑定布局
width: MediaQuery.sizeOf(context).width,
height:
MediaQuery.sizeOf(context).height * 0.277,
constraints: BoxConstraints(
minWidth: 690.rpx,
minHeight: 450.rpx,
),
decoration: BoxDecoration(
color: themeController.currentColor.sc5,
borderRadius: BorderRadius.circular(
AppConstants()
.normal_container_radius), // 圆角半径
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomCard(
borderRadius: AppConstants()
.button_container_radius, // 圆角半径
onTap: () {
// Get.toNamed("/qrView");
if (userInfoController.model.login ==
LoginStatus.LOGIN.code) {
// Get.toNamed("/deviceType");
TopSlideNotification.show(
context,
text: "待开发功能".tr,
);
} else {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor: themeController
.currentColor.sc9,
);
Get.toNamed("/loginPage");
}
},
colors: [
// 渐变色
themeController.currentColor.sc1,
themeController.currentColor.sc2,
],
child: Container(
width:
MediaQuery.sizeOf(context).width *
0.66,
height: MediaQuery.sizeOf(context)
.height *
0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/img/icon/scan.svg',
width: 25.rpx,
height: 25.rpx, // SVG 的固定大小
color: themeController
.currentColor.sc16, // 颜色设置
),
Text(
'首页.扫一扫绑定'.tr,
style: TextStyle(
color: themeController
.currentColor.sc19,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(width: 17.rpx)),
),
),
),
CustomCard(
borderRadius: AppConstants()
.button_container_radius, // 圆角半径
onTap: () async {
if (userInfoController.model.login ==
LoginStatus.LOGIN.code) {
await Get.toNamed("/deviceType");
homeController.getSleepReport();
deviceController
.getDeviceNum()
.then((apiResponse) {
if (apiResponse.code !=
HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController
.currentColor.sc9,
);
}
});
deviceController
.getDeviceList()
.then((apiResponse) {
if (apiResponse.code !=
HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: apiResponse.msg!,
textColor: themeController
.currentColor.sc9,
);
} else {
//请求睡眠报告
deviceController
.getSleepReport();
}
});
} else {
TopSlideNotification.show(
context,
text: "必须登录提示".tr,
textColor: themeController
.currentColor.sc9,
);
Get.toNamed("/loginPage");
}
},
colors: [
//todo 颜色
themeController.currentColor.sc1,
themeController.currentColor.sc2,
], // 渐变色是同一个色,也可以根据需要调整
child: Container(
width:
MediaQuery.sizeOf(context).width *
0.66,
height: MediaQuery.sizeOf(context)
.height *
0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/img/icon/bluetooth.svg',
width: 25.rpx,
height: 25
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
//todo 颜色
color: themeController
.currentColor.sc16,
),
Text(
'首页.蓝牙绑定'.tr,
style: TextStyle(
//todo 颜色
color: themeController
.currentColor.sc19,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
)
].divide(SizedBox(
height: 60.rpx,
)),
),
),
);
}),
Obx(() {
return Visibility(
visible: userInfoController.model.login == 0 ||
deviceController.bindDeviceNum.value == 0,
child: Padding(
//未绑定标语
padding: EdgeInsetsDirectional.fromSTEB(
0, 26.rpx, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: themeController.currentColor.sc6,
borderRadius: BorderRadius.circular(
AppConstants()
.normal_container_radius), // 圆角半径
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
25.rpx, 25.rpx, 25.rpx, 25.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
0.rpx, 5.rpx, 0.rpx, 0.rpx),
child: SvgPicture.asset(
'assets/img/icon/sound.svg',
width: 30.rpx,
height: 30
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color:
stringToColor("#FF9F66"), //固定
),
),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'首页.提示标题'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
fontWeight: FontWeight.w600,
color: stringToColor(
"#916D46"), //固定
),
),
Text(
'首页.提示内容1'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
//todo 配置颜色
color: stringToColor(
"#916D46"), //固定
),
),
Text(
'首页.提示内容2'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
color: stringToColor(
"#916D46"), //固定
),
),
Text(
'首页.提示内容3'.tr,
style: TextStyle(
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
//todo 配置颜色
color: stringToColor(
"#916D46"), //固定
),
),
].divide(SizedBox(
height: AppConstants()
.text_padding_up_dowm_p)),
),
)
].divide(SizedBox(width: 20.rpx)),
),
),
),
),
);
}),
Obx(() {
return Visibility(
visible: userInfoController.model.login == 1 &&
deviceController.bindDeviceNum.value != 0,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 26.rpx, 0, 0),
child: Container(
width: bodySize.maxWidth,
height: bodySize.maxHeight * 0.107,
constraints: BoxConstraints(
minHeight: 240.rpx,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
ClickableContainer(
backgroundColor:
themeController.currentColor.sc5,
highlightColor:
themeController.currentColor.sc21,
borderRadius: AppConstants()
.normal_container_radius,
padding: EdgeInsets
.zero, // 原始Container没有padding
onTap: () async {
// BodyDeviceController
// bodyDeviceController = Get.find();
// bodyDeviceController.model.type = 1;
// Get.toNamed("/bodyDevice");
homeController.model.type = 1;
deviceController.model.type = 1;
await deviceController
.getDeviceList();
await deviceController
.getSleepReport();
homeController.updateAll();
},
child: Container(
decoration: BoxDecoration(
border:
homeController.model.type == 1
? Border.all(
color: themeController
.currentColor
.sc2, // 边框颜色
width: 1, // 边框宽度
)
: null,
borderRadius:
BorderRadius.circular(
12), // 可选:圆角
),
width: bodySize.maxWidth * 0.445,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SizedBox(height: 32.rpx),
Container(
width: 120.rpx,
height: 120.rpx,
child: Image.asset(
"assets/img/netlove.png",
fit: BoxFit.cover,
),
),
Text(
"首页.我的e护".tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
),
),
SizedBox(height: 32.rpx),
],
),
),
),
ClickableContainer(
backgroundColor:
themeController.currentColor.sc5,
highlightColor:
themeController.currentColor.sc21,
borderRadius: AppConstants()
.normal_container_radius,
padding: EdgeInsets.zero,
onTap: () async {
homeController.model.type = 2;
deviceController.model.type = 2;
await deviceController
.getDeviceList();
await deviceController
.getSleepReport();
homeController.updateAll();
},
child: Container(
decoration: BoxDecoration(
border:
homeController.model.type == 2
? Border.all(
color: themeController
.currentColor
.sc2, // 边框颜色
width: 1, // 边框宽度
)
: null,
borderRadius:
BorderRadius.circular(
12), // 可选:圆角
),
width: bodySize.maxWidth * 0.445,
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Container(
width: 120.rpx,
height: 120.rpx,
child: Image.asset(
"assets/img/mye.png",
fit: BoxFit.cover,
),
),
Text(
"首页.云关爱".tr,
style: TextStyle(
color: themeController
.currentColor.sc3,
),
),
]
.addToStart(
SizedBox(height: 32.rpx))
.addToEnd(
SizedBox(height: 32.rpx)),
),
),
),
],
),
),
),
);
}),
],
),
),
Obx(() {
Map<String, List<dynamic>> reportData =
deviceController.sleepReportData.value;
var deviceList = deviceController.deviceList.value
.where((device) => device['show'] == true)
.toList();
if (deviceList.isEmpty) {
return Expanded(child: NullDataWidget());
}
if (reportData.isEmpty) {
return Expanded(child: NullDataWidget());
}
List<String> macList = reportData.keys.toList();
macList = macList
.where(
(mac) => deviceList
.any((device) => device['mac'] == mac),
)
.toList();
if (macList.length != deviceList.length) {
return Expanded(
child: Center(
child: CircularProgressIndicator(
color: themeController.currentColor.sc1,
)),
);
}
// return Expanded(
// child: SingleChildScrollView(
// child: Column(
// children: List.generate(
// deviceList.length,
// (i) {
// String mac = macList[i];
// List<dynamic> dailyDataList =
// reportData[mac]!;
// Map? targetDevice =
// deviceList.firstWhereOrNull(
// (device) => device['mac'] == mac,
// );
// List stateModule = [];
// String currentTime = "";
// String goalMac = targetDevice?['mac'];
// var person = targetDevice?['person'];
// return DynamicReportDetailWidget(
// key: ValueKey(
// '${targetDevice!['mac']}_${homeController.model.type}'), // 添加唯一key
// targetDevice: targetDevice!,
// sleepDateWidgets: List.generate(
// dailyDataList.length,
// (j) {
// var dayData = dailyDataList[j];
// DateTime date =
// DateTime.fromMillisecondsSinceEpoch(
// dayData['time'] is String
// ? int.parse(dayData['time'])
// : dayData['time'],
// );
// if (dayData['selected'] != null &&
// dayData['selected'] == true &&
// dayData['state'] != null) {
// stateModule = dayData['state'];
// currentTime = dayData['time'];
// }
// return SleepDateWidget(
// mac: mac,
// time: dayData['time'],
// date: date,
// score: dayData['score']?['socre']
// ?.toString() ??
// '',
// comment: dayData['score']?['name'],
// textColor: dayData['score']
// ?['color'] ==
// null
// ? null
// : stringToColor(
// dayData['score']?['color']),
// isSelected: dayData['selected'],
// );
// },
// ),
// sleepDataModuleWidgets: stateModule
// .isNotEmpty
// ? List.generate(
// stateModule.length,
// (j) {
// stateModule[j]['onto'] = true;
// stateModule[j]['time'] =
// currentTime;
// stateModule[j]['mac'] = goalMac;
// stateModule[j]['person'] = person;
// return SleepDataModuleWidget(
// data: stateModule[j],
// );
// },
// )
// : [],
// );
// },
// ),
// ),
// ),
// );
return Expanded(
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 26.rpx), // 第一个上方间距
...List.generate(deviceList.length, (i) {
String mac = macList[i];
List<dynamic> dailyDataList =
reportData[mac]!;
Map? targetDevice =
deviceList.firstWhereOrNull(
(device) => device['mac'] == mac,
);
List stateModule = [];
String currentTime = "";
String goalMac = targetDevice?['mac'];
var person = targetDevice?['person'];
return Column(
children: [
DynamicReportDetailWidget(
key: ValueKey(
'${targetDevice!['mac']}_${homeController.model.type}'),
targetDevice: targetDevice!,
sleepDateWidgets: List.generate(
dailyDataList.length, (j) {
var dayData = dailyDataList[j];
DateTime date = DateTime
.fromMillisecondsSinceEpoch(
dayData['time'] is String
? int.parse(dayData['time'])
: dayData['time'],
);
if (dayData['selected'] == true &&
dayData['state'] != null) {
stateModule = dayData['state'];
currentTime = dayData['time'];
}
return SleepDateWidget(
mac: mac,
time: dayData['time'],
date: date,
score: dayData['score']?['socre']
?.toString() ??
'',
comment: dayData['score']?['name'],
textColor: dayData['score']
?['color'] ==
null
? null
: stringToColor(
dayData['score']?['color']),
isSelected: dayData['selected'],
);
}),
sleepDataModuleWidgets: stateModule
.isNotEmpty
? List.generate(stateModule.length,
(j) {
stateModule[j]['onto'] = true;
stateModule[j]['time'] =
currentTime;
stateModule[j]['mac'] = goalMac;
stateModule[j]['person'] =
person;
return SleepDataModuleWidget(
data: stateModule[j]);
})
: [],
),
SizedBox(
height:
26.rpx), // 每个 widget 下方间距(包括最后一个)
],
);
}),
],
),
),
);
}),
],
),
),
),
),
),
),
),
);
}
void checkAndShowBindProcess() {
UserInfoController userInfoController = Get.find();
List device_bind_process = userInfoController.device_bind_status;
if (device_bind_process != null && device_bind_process.isNotEmpty) {
int currentIndex = 0;
void showNextDialog() {
if (currentIndex >= device_bind_process.length) return;
String code = device_bind_process[currentIndex]['mac'];
showUnBindTipDialog(
context,
Column(
children: [
Text(
"发现".tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
SizedBox(height: 20.rpx),
Text.rich(
TextSpan(
children: [
TextSpan(
text: "检测到".tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
TextSpan(
text: code,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc8,
),
),
TextSpan(
text: "绑定流程未走完是否继续?".tr,
style: TextStyle(
fontSize: AppConstants().normal_text_fontSize,
color: themeController.currentColor.sc3,
),
),
],
),
),
],
),
onConfirm: () async {
var data = device_bind_process[currentIndex];
PersonController personController = Get.find();
personController.after_deveice = data['device_info'];
BlueteethBindController blueteethBindController = Get.find();
blueteethBindController.currentDeviceMac!.value =
data['device_info']['mac'];
// 判断逻辑...
if (data['wifi'] == false) {
await Get.toNamed("/afterWifiPagePerson",
arguments: data['device_info']);
return;
}
if (data['celibration'] == false) {
await Get.toNamed("/afterCalibrationPersonPage");
return;
}
if (data['person_info'] == false) {
PersonController personController = Get.find();
if (data['device_info']['person'] != null) {
personController.currentPersonId.value =
data['device_info']['_id'];
personController.name.value =
data['device_info']['person']['name'];
personController.update_person_mac.value =
data['device_info']['mac'];
personController.gender.value =
data['device_info']['person']['gender'] ?? 1;
personController.weight?.value =
data['device_info']['person']['weight']?.toString() ?? '';
personController.height.value =
data['device_info']['person']['height']?.toString() ?? '';
personController.selectedDiseaseIds.value =
data['device_info']['person']['disease'] ?? [];
personController.birthday.value =
data['device_info']['person']['birthday'] ?? '';
personController.dateTime = MyUtils.formatBirthdayTime(
data['device_info']['person']['birthday']);
} else {
personController.update_person_mac.value =
data['device_info']['mac'];
personController.currentPersonId.value =
data['device_info']['_id'];
personController.name.value = "";
personController.gender.value = 1;
personController.dateTime = null;
personController.height.value = "";
personController.weight.value = "";
personController.diseaseList.value = [];
}
await Get.toNamed("/afterUpdatePersonPage");
return;
}
currentIndex++;
showNextDialog();
},
onCancel: () {
device_bind_process.removeAt(currentIndex);
showNextDialog();
},
);
}
showNextDialog();
}
}
//处理绑定未完成的数据
Future<void> dealBindProcess() async {
UserInfoController userInfoController = Get.find();
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.device_list;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}?bindType=1";
userInfoController.device_bind_status = [];
try {
final res = await requestWithLog(
logTitle: "查询设备绑定列表",
method: MyHttpMethod.get,
queryUrl: queryUrl,
);
List data = res.data ?? [];
if (data.isNotEmpty) {
// 使用 Future.wait 等待所有设备的查询完成
await Future.wait(
data.map((element) async {
String mac = element['mac'];
String type = "device_bind_status_$mac";
String queryUrl =
"${serviceAddress}${serviceName}${ServiceConstant.user_setting}?type=${type}";
try {
final res = await requestWithLog(
logTitle: "查询绑定流程",
method: MyHttpMethod.get,
queryUrl: queryUrl,
);
if (res.data != null && res.data.isNotEmpty) {
bool celibration = res.data['celibration'];
bool person_info = res.data['person_info'];
bool wifi = res.data['wifi'];
if (!celibration || !person_info || !wifi) {
res.data['device_info'] = element;
userInfoController.device_bind_status.add(res.data);
}
}
} catch (e) {
print("查询绑定流程失败: $e");
}
}),
);
}
} catch (e) {
print("查询设备绑定列表失败: $e");
}
}
}