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/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/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; import 'package:vbvs_app/controller/user_info_controller.dart'; import 'package:vbvs_app/controller/weather/weather_controller.dart'; import 'package:vbvs_app/pages/mh_page/FloatingSvgIcon.dart'; import 'package:vbvs_app/pages/mh_page/homepage/component/HomeDeviceWidget.dart'; import 'package:vbvs_app/pages/mh_page/homepage/controller/mht_home_controller.dart'; class NewHomePage extends StatefulWidget { const NewHomePage({super.key}); @override State createState() => _NewHomePageState(); } class _NewHomePageState extends State { UserInfoController userInfoController = Get.find(); MHTHomeController deviceController = Get.find(); MHTHomeController homeController = Get.find(); double borderRadius = 16.rpx; var formFieldController = FormFieldController(null); GlobalController gloablController = Get.find(); WeatherModelController weatherModelController = Get.find(); var sleepDays = [].obs; var sleep_mac = "".obs; Map scoreColor = { "-1": "#d3d3d3", "1": "#4e8408", "2": "#7bbb33", "3": "#e15b8d", "4": "#ff0000", }; Map scoreName = { "-1": "暂无", "1": "优秀", "2": "良好", "3": "合格", "4": "注意", }; @override void 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(group: 'room').then((apiResponse) { if (apiResponse.code != HttpStatusCodes.ok) { TopSlideNotification.show( Get.context!, text: apiResponse.msg!, textColor: themeController.currentColor.sc9, ); } else { //请求睡眠报告 deviceController.getSleepReport(); } }); } } getWeekName(int i) { String v = ""; switch (i) { case 1: v = "周一"; break; case 2: v = "周二"; break; case 3: v = "周三"; break; case 4: v = "周四"; break; case 5: v = "周五"; break; case 6: v = "周六"; break; case 7: v = "周日"; break; } return v; } @override Widget build(BuildContext context) { deviceController.getDeviceList(group: 'room').then((apiResponse) { if (apiResponse.code != HttpStatusCodes.ok) { TopSlideNotification.show( Get.context!, text: apiResponse.msg!, textColor: themeController.currentColor.sc9, ); } else { //请求睡眠报告 deviceController.getSleepReport(); } }); int login = userInfoController.model.login!; return GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/new_background.png'), // 本地图片 fit: BoxFit.fill, // 填满整个 Container ), ), child: Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( iconTheme: IconThemeData(color: themeController.currentColor.sc3), backgroundColor: Colors.transparent, automaticallyImplyLeading: false, titleSpacing: 0, title: Container( height: 180.rpx, child: Row( children: [ // 左侧头像 Obx(() { return userInfo(userInfoController.model.login); }), const Spacer(), // 左右分隔 FloatingSvgIcon( assetPath: 'assets/img/icon/xiaoe.svg', width: 60.rpx, height: 60.rpx, onTap: () { print("点击了小鹅图标"); }, ), SizedBox(width: 40.rpx), ], ), ), ), body: SafeArea( child: Container( width: MediaQuery.sizeOf(context).width, height: MediaQuery.sizeOf(context).height * 1.123, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.max, children: [ //天气 Container( padding: EdgeInsets.fromLTRB(26.rpx, 10.rpx, 26.rpx, 40.rpx), width: double.infinity, child: Padding( padding: EdgeInsets.symmetric(horizontal: 0.rpx), child: Column( children: [ Padding( padding: EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0), child: Row( children: [ Obx(() { return Row( children: [ Text( "${weatherModelController.model.cityName ?? '未知数据'.tr}", style: TextStyle( color: Colors.white, 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: Colors.white, fontSize: AppConstants() .normal_text_fontSize, ), ), Text( "${(weatherModelController.model.weather_info?.isNotEmpty ?? false) ? weatherModelController.model.weather_info : '未知数据'.tr}", style: TextStyle( color: Colors.white, 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, )), ); }), ], ), ), ], ), ), ), // Obx(() { // return Container( // padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), // child: Column( // children: [ // if (gloablController.model.deviceList.length > 0) // Container( // child: Column( // children: [ // Container( // width: MediaQuery.sizeOf(context).width, // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular( // borderRadius), // ), // child: Column( // mainAxisSize: MainAxisSize.max, // children: [ // Padding( // padding: EdgeInsetsDirectional // .fromSTEB(30.rpx, 16.rpx, // 16.rpx, 8.rpx), // child: Container( // width: // MediaQuery.sizeOf(context) // .width, // height: // MediaQuery.sizeOf(context) // .height * // 0.065, // decoration: BoxDecoration( // color: FlutterFlowTheme.of( // context) // .secondaryBackground, // ), // child: Row( // mainAxisSize: // MainAxisSize.max, // mainAxisAlignment: // MainAxisAlignment // .spaceBetween, // children: [ // ValueListenableBuilder( // valueListenable: // formFieldController, // builder: (c, a, s) => // FlutterFlowDropDown< // String>( // controller: // formFieldController, // options: gloablController // .model.JunheDevices // .map((d) => // "${d["mac"]}") // .toList(), // optionLabels: // gloablController // .model // .JunheDevices // .map( // (d) { // var s = d["name"] ?? // d["mac"]; // if (s == null) { // return ""; // } else { // return "$s"; // } // }).toList(), // onChanged: (val) { // // print("$val"); // // if (val == null) { // // sleepDays.value = []; // // } else { // // getSleeps( // // formFieldController // // .value); // // } // // // sleep_mac.value = val!; // }, // width: 360.rpx, // height: 72.rpx, // maxHeight: 200.rpx, // textStyle: TextStyle( // fontSize: 28.rpx, // overflow: // TextOverflow // .ellipsis), // hintText: '', // icon: Icon( // Icons // .keyboard_arrow_down_rounded, // color: FlutterFlowTheme // .of(context) // .secondaryText, // size: 48.rpx, // ), // fillColor: // stringToColor( // "#F3F5F6"), // elevation: 2, // borderColor: // stringToColor( // "#F3F5F6"), // borderWidth: 2, // borderRadius: 18, // margin: // EdgeInsetsDirectional // .fromSTEB( // 32.rpx, // 8.rpx, // 32.rpx, // 8.rpx), // hidesUnderline: true, // isOverButton: false, // isSearchable: false, // isMultiSelect: false, // ), // ), // InkWell( // onTap: () { // // if (formFieldController // // .value != // // null) { // // Get.toNamed( // // "/sleepWebview", // // arguments: [ // // formFieldController // // .value // // ]); // // } // }, // child: Row( // mainAxisSize: // MainAxisSize.max, // children: [ // Text( // '睡眠报告', // style: FlutterFlowTheme // .of(context) // .bodyMedium // .override( // fontFamily: // 'Readex Pro', // letterSpacing: // 0, // fontSize: // 30.rpx), // ), // SizedBox( // width: 12.rpx, // ), // SvgPicture.asset( // "assets/images/table.svg", // width: 28.rpx, // height: 28.rpx), // SizedBox( // width: 20.rpx, // ), // ], // ), // ), // ], // ), // ), // ), // Container( // padding: EdgeInsets.only( // top: 0.rpx, // bottom: 20.rpx, // left: 16.rpx, // right: 16.rpx), // width: double.infinity, // decoration: BoxDecoration(), // child: Row( // mainAxisSize: MainAxisSize.max, // crossAxisAlignment: // CrossAxisAlignment.start, // children: [ // ...List.generate( // sleepDays.value.length, // (index) { // var day = sleepDays[index]; // return Expanded( // child: Container( // padding: // EdgeInsets.only( // top: 10.rpx, // bottom: 20.rpx), // width: 100, // // decoration: BoxDecoration( // // color: index == 2 // // ? stringToColor("#F3F5F6") // // : Colors.white, // // borderRadius: // // BorderRadius.circular( // // borderRadius), // // ), // child: Column( // mainAxisSize: // MainAxisSize.max, // mainAxisAlignment: // MainAxisAlignment // .start, // crossAxisAlignment: // CrossAxisAlignment // .center, // children: [ // Text( // day['week'], // style: FlutterFlowTheme // .of(context) // .bodyMedium // .override( // fontFamily: // 'Readex Pro', // fontSize: // 30.rpx, // letterSpacing: // 0, // ), // ), // Text( // day['date'], // style: FlutterFlowTheme // .of(context) // .bodyMedium // .override( // fontFamily: // 'Readex Pro', // letterSpacing: // 0, // fontSize: // 24.rpx, // ), // ), // SizedBox( // height: 6.rpx, // ), // Column( // children: [ // Row( // mainAxisSize: // MainAxisSize // .max, // mainAxisAlignment: // MainAxisAlignment // .center, // children: [ // Text( // '${day['score'] ?? "-"}', // style: FlutterFlowTheme.of( // context) // .bodyMedium // .override( // fontFamily: // 'Readex Pro', // fontSize: // 48.rpx, // letterSpacing: // 0, // ), // ), // if (day['score'] != // null) // SizedBox( // width: 2 // .rpx, // ), // if (day['score'] != // null) // Text( // '分', // style: FlutterFlowTheme.of(context) // .bodyMedium // .override( // fontFamily: 'Readex Pro', // letterSpacing: 0, // fontSize: 26.rpx, // ), // ), // ], // ), // Container( // width: // 120.rpx, // height: // 52.rpx, // decoration: // BoxDecoration( // color: stringToColor( // day['scoreColor'] ?? // "#f3f5f6"), // borderRadius: // BorderRadius.circular( // 26.rpx), // shape: BoxShape // .rectangle, // ), // alignment: // Alignment // .center, // child: Text( // '${day['scoreType'] ?? "暂无"}', // style: FlutterFlowTheme.of( // context) // .bodyMedium // .override( // fontFamily: // 'Readex Pro', // color: day['scoreType'] != null // ? Colors.white // : stringToColor("#ced1d7"), // letterSpacing: // 0, // fontSize: // 28.rpx, // ), // ), // ) // ], // ) // ], // ), // ), // ); // }) // ], // ), // ), // ], // ), // ), // ...List.generate( // gloablController.model.deviceList // .length, (index) { // var device = gloablController // .model.deviceList[index]; // String rname = device['roomName']; // if (index != 0) { // String lrname = gloablController // .model.deviceList[index - 1] // ["roomName"]; // if (lrname == rname) { // rname = ""; // } // } // return Column(children: [ // Padding( // padding: // EdgeInsetsDirectional.fromSTEB( // 20.rpx, 20.rpx, 0, 0), // child: Container( // decoration: BoxDecoration(), // alignment: // AlignmentDirectional(-1, 0), // child: rname.isNotEmpty // ? Text( // "$rname", // style: FlutterFlowTheme // .of(context) // .bodyMedium // .override( // fontFamily: // 'Readex Pro', // color: Colors.white, // fontSize: 32.rpx, // letterSpacing: 0, // ), // ) // : SizedBox( // height: 10.rpx, // ), // ), // ), // // getDeviceList(context, device) // ]); // }), // Padding( // padding: EdgeInsetsDirectional.fromSTEB( // 0, 40.rpx, 0, 100.rpx), // child: Container( // width: // MediaQuery.sizeOf(context).width, // height: 84.rpx, // decoration: BoxDecoration(), // child: FFButtonWidget( // onPressed: () { // // print('Button pressed ...'); // // Get.toNamed("/homeDeviceType"); // }, // text: '添加新设备'.tr, // icon: Icon( // Icons.add, // size: 60.rpx, // ), // options: FFButtonOptions( // height: 80.rpx, // padding: EdgeInsetsDirectional // .fromSTEB( // 48.rpx, 0, 48.rpx, 0), // iconPadding: EdgeInsetsDirectional // .fromSTEB(0, 0, 0, 0), // color: stringToColor("#182B7C"), // textStyle: // FlutterFlowTheme.of(context) // .titleSmall // .override( // fontFamily: // 'Readex Pro', // color: Colors.white, // letterSpacing: 0, // fontSize: 30.rpx), // elevation: 3, // borderSide: BorderSide( // color: Colors.transparent, // width: 1, // ), // borderRadius: // BorderRadius.circular( // borderRadius), // ), // ), // ), // ), // ], // ), // ), // if (gloablController.model.deviceList.length == 0) // Padding( // padding: EdgeInsetsDirectional.fromSTEB( // 0, 0, 0, 80.rpx), // child: ClickableContainer( // backgroundColor: Colors.transparent, // highlightColor: Colors.transparent, // padding: EdgeInsets.all(0), // onTap: () { // if (userInfoController.model.login == // null || // userInfoController.model.login == 0) { // TopSlideNotification.show(context, // text: "请先登录".tr, // textColor: themeController // .currentColor.sc9); // Get.toNamed("/loginPage"); // } else { // Get.toNamed("/mHTDeviceTypePage"); // } // }, // child: Container( // width: MediaQuery.sizeOf(context).width, // height: 302.rpx, // padding: EdgeInsets.only( // top: 90.rpx, bottom: 80.rpx), // decoration: BoxDecoration( // borderRadius: // BorderRadius.circular(borderRadius), // border: Border.all( // color: // stringToColor("#85F5FF"), // 边框颜色 // width: 1.rpx, // 边框宽度 // ), // ), // child: Column( // mainAxisSize: MainAxisSize.max, // mainAxisAlignment: // MainAxisAlignment.center, // children: [ // SvgPicture.asset( // 'assets/images/icon/add.svg', // width: 42.rpx, // height: 42.rpx, // ), // SizedBox( // height: 32.rpx, // ), // Text( // '添加一台新设备'.tr, // style: TextStyle( // color: stringToColor("#85F5FF"), // fontSize: AppConstants() // .normal_text_fontSize, // letterSpacing: 0, // ), // ), // ], // ), // ), // ), // ), // ], // ), // ); // }), //未登录 Obx(() { if (userInfoController.model.login! == null || userInfoController.model.login! == 0) { return Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0, 30.rpx, 80.rpx), child: ClickableContainer( backgroundColor: Colors.transparent, highlightColor: Colors.transparent, padding: EdgeInsets.all(0), onTap: () { if (userInfoController.model.login == null || userInfoController.model.login == 0) { TopSlideNotification.show(context, text: "请先登录".tr, textColor: themeController.currentColor.sc9); Get.toNamed("/loginPage"); } else { Get.toNamed("/mHTDeviceTypePage"); } }, child: Container( width: MediaQuery.sizeOf(context).width, height: 302.rpx, padding: EdgeInsets.only( top: 90.rpx, bottom: 80.rpx), decoration: BoxDecoration( borderRadius: BorderRadius.circular(borderRadius), border: Border.all( color: stringToColor("#85F5FF"), // 边框颜色 width: 1.rpx, // 边框宽度 ), ), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/images/icon/add.svg', width: 42.rpx, height: 42.rpx, ), SizedBox( height: 32.rpx, ), Text( '添加一台新设备'.tr, style: TextStyle( color: stringToColor("#85F5FF"), fontSize: AppConstants().normal_text_fontSize, letterSpacing: 0, ), ), ], ), ), ), ); } return Container(); }), //已登录 Obx(() { if (userInfoController.model.login! != null && userInfoController.model.login! == 1) { return SingleChildScrollView( child: Column( children: [ if (homeController.bindDeviceNum.value != 0) Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 40.rpx, 30.rpx, 100.rpx), child: Column( children: homeController .deviceList.entries .map((entry) => HomeDeviceWidget( roomName: entry.key, deviceStatusList: entry.value, )) .toList() .divide(SizedBox(height: 30.rpx)), ), ), if (homeController.bindDeviceNum.value == 0) Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0, 30.rpx, 80.rpx), child: ClickableContainer( backgroundColor: Colors.transparent, highlightColor: Colors.transparent, padding: EdgeInsets.all(0), onTap: () { if (userInfoController.model.login == null || userInfoController.model.login == 0) { TopSlideNotification.show(context, text: "请先登录".tr, textColor: themeController .currentColor.sc9); Get.toNamed("/loginPage"); } else { Get.toNamed("/mHTDeviceTypePage"); } }, child: Container( width: MediaQuery.sizeOf(context).width, height: 302.rpx, padding: EdgeInsets.only( top: 90.rpx, bottom: 80.rpx), decoration: BoxDecoration( borderRadius: BorderRadius.circular( borderRadius), border: Border.all( color: stringToColor( "#85F5FF"), // 边框颜色 width: 1.rpx, // 边框宽度 ), ), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/images/icon/add.svg', width: 42.rpx, height: 42.rpx, ), SizedBox( height: 32.rpx, ), Text( '添加一台新设备'.tr, style: TextStyle( color: stringToColor("#85F5FF"), fontSize: AppConstants() .normal_text_fontSize, letterSpacing: 0, ), ), ], ), ), ), ), if (homeController.bindDeviceNum.value != 0) Padding( padding: EdgeInsetsDirectional.fromSTEB( 30.rpx, 0.rpx, 30.rpx, 100.rpx), child: ClickableContainer( onTap: () { // 点击逻辑 Get.toNamed("/mHTDeviceTypePage"); }, backgroundColor: Colors.transparent, highlightColor: themeController .currentColor .sc21, // 这里可以自定义高亮色,透明就用 Colors.transparent borderRadius: borderRadius, padding: EdgeInsetsDirectional.fromSTEB( 0.rpx, 0, 0.rpx, 0), child: Container( height: 92.rpx, alignment: Alignment.center, decoration: BoxDecoration( border: Border.all( color: stringToColor( "#85F5FF"), // 边框颜色 width: 1.rpx, // 边框宽度 ), borderRadius: BorderRadius.circular( borderRadius), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.add, size: 60.rpx, color: stringToColor("#85F5FF"), ), SizedBox(width: 20.rpx), Text( '添加新设备'.tr, style: FlutterFlowTheme.of(context) .titleSmall .override( fontFamily: 'Readex Pro', color: stringToColor( "#85F5FF"), letterSpacing: 0, fontSize: 30.rpx, ), ), ], ), ), ), ), ], ), ); } return Container(); }), ], ), ), ), ), ), )); } //1 :登录 0:未登录 Widget userInfo(int? login) { return Row( children: (login == 1) ? [ SizedBox(width: 40.rpx), CircleAvatar( radius: 27.rpx, // 可根据需求调整 backgroundImage: login == 1 ? (userInfoController.model.user!.avatar == null || userInfoController.model.user!.avatar!.isEmpty ? const AssetImage( "assets/images/default_avatar.png", ) : NetworkImage( userInfoController.model.user!.avatar!, )) : const AssetImage( "assets/images/default_avatar.png", ), ), SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距 Text( '${userInfoController.model.user?.nick_name?.isNotEmpty == true ? userInfoController.model.user!.nick_name : '未命名'.tr}', style: TextStyle(fontSize: 30.rpx, color: Colors.white), ) ] : [ SizedBox(width: 40.rpx), CircleAvatar( radius: 27.rpx, // 可根据需求调整 backgroundImage: login == 1 ? (userInfoController.model.user!.avatar == null || userInfoController.model.user!.avatar!.isEmpty ? const AssetImage( "assets/images/default_avatar.png", ) : NetworkImage( userInfoController.model.user!.avatar!, )) : const AssetImage( "assets/images/default_avatar.png", ), ), SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距 Text( '未命名'.tr, style: TextStyle(fontSize: 30.rpx, color: Colors.white), ) ], ); } } class ScoreItem { final String weekday; // 如“周四” final String dateStr; // 如“07/03” final int score; final bool isToday; ScoreItem({ required this.weekday, required this.dateStr, required this.score, this.isToday = false, }); } class ScoreCard extends StatelessWidget { final String selectedUser; final List scoreList; final ValueChanged? onUserChanged; final VoidCallback? onChartPressed; const ScoreCard({ super.key, required this.selectedUser, required this.scoreList, this.onUserChanged, this.onChartPressed, }); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: const Color(0xff0F2B44), borderRadius: BorderRadius.circular(16), ), padding: const EdgeInsets.all(12), child: Column( children: [ // 顶部用户选择 + 图标按钮 Row( children: [ DropdownButtonHideUnderline( child: DropdownButton( value: selectedUser, borderRadius: BorderRadius.circular(12), dropdownColor: const Color(0xff0F2B44), iconEnabledColor: Colors.white, style: const TextStyle(color: Colors.white), items: ['Eason Chan', 'Jay Chou', 'G.E.M.'] .map((user) => DropdownMenuItem( value: user, child: Text(user), )) .toList(), onChanged: onUserChanged, ), ), const Spacer(), IconButton( onPressed: onChartPressed, icon: const Icon(Icons.bar_chart, color: Colors.white), ), ], ), const SizedBox(height: 12), // 日期+分数 横向滚动展示 SizedBox( height: 70, child: ListView.separated( scrollDirection: Axis.horizontal, itemCount: scoreList.length, separatorBuilder: (_, __) => const SizedBox(width: 12), itemBuilder: (context, index) { final item = scoreList[index]; final isToday = item.isToday; return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: isToday ? Colors.white.withOpacity(0.1) : Colors.transparent, borderRadius: BorderRadius.circular(12), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(item.weekday, style: const TextStyle( color: Colors.white70, fontSize: 12)), Text(item.dateStr, style: const TextStyle( color: Colors.white54, fontSize: 10)), const SizedBox(height: 4), Text( item.score.toString(), style: TextStyle( color: Colors.white, fontWeight: isToday ? FontWeight.bold : FontWeight.normal, fontSize: 16, ), ), ], ), ); }, ), ) ], ), ); } }