1257 lines
66 KiB
Dart
1257 lines
66 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: [
|
|
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");
|
|
}
|
|
}
|
|
}
|