Files
tuiche/lib/pages/mh_page/homepage/new_Home_page.dart
2025-11-13 09:56:02 +08:00

1157 lines
57 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:easyweb/utils/appmanger.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/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/JPushUtil.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/sleep/sleep_report_controller.dart';
import 'package:vbvs_app/controller/user_info_controller.dart';
import 'package:vbvs_app/controller/weather/weather_controller.dart';
import 'package:vbvs_app/enum/APPPackageType.dart';
import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart';
import 'package:vbvs_app/pages/mh_page/FloatingSvgIcon.dart';
import 'package:vbvs_app/pages/mh_page/component/mht_bind_dialog.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<NewHomePage> createState() => _NewHomePageState();
}
class _NewHomePageState extends State<NewHomePage> {
SleepReportController sleepReportController = Get.find();
UserInfoController userInfoController = Get.find();
MHTHomeController deviceController = Get.find();
MHTHomeController homeController = Get.find();
double borderRadius = 16.rpx;
var formFieldController = FormFieldController<String>(null);
var personInfo = {}.obs;
// GlobalController gloablController = Get.find();
WeatherModelController weatherModelController = Get.find();
// var selectedDayIndex = (6).obs;
StreamSubscription? _newVersionSubscription;
@override
void initState() {
super.initState();
if (userInfoController.model.login == 1) {
//查询人员信息列表
deviceController.getPersonList();
//请求绑定设备列表
// 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();
}
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (homeController.homeSleepDays.value.isNotEmpty) {
homeController.selectedDayIndex.value =
homeController.homeSleepDays.value.length - 1;
}
});
WidgetsBinding.instance.addPostFrameCallback((_) {
_onReady();
});
try {
_newVersionSubscription =
ef.kvRoot.appmanger.onAppUpdate.listen((MiniAppPkg pkg) {
if (AppConstants().ent_type != APPPackageType.MHT.code) {
return;
}
if (userInfoController.model.login! == null ||
userInfoController.model.login! == 0) {
//未登录
return;
}
showTipUpgradeDialog(
context,
Column(
children: [
SizedBox(
width: 94.rpx,
height: 70.rpx,
child: SvgPicture.asset(
'assets/img/icon/upgrade.svg',
fit: BoxFit.cover,
// color: themeController.currentColor.sc3, // 若你想加颜色控制可取消注释
),
),
Text(
"web控制更新".tr,
style: TextStyle(
color: stringToColor("#333333"),
fontSize: AppConstants().title_text_fontSize,
),
),
Text("新版本号".tr +
"" +
"${pkg.version}" +
"" +
"点击确认退出app重新进入".tr),
].divide(SizedBox(
height: 37.rpx,
)),
));
});
} catch (e) {
print(e);
}
}
getWeekName(int i) {
String v = "";
switch (i) {
case 1:
v = "周一".tr;
break;
case 2:
v = "周二".tr;
break;
case 3:
v = "周三".tr;
break;
case 4:
v = "周四".tr;
break;
case 5:
v = "周五".tr;
break;
case 6:
v = "周六".tr;
break;
case 7:
v = "周日".tr;
break;
}
return v;
}
@override
Widget build(BuildContext context) {
weatherModelController.getCurrentWeather();
deviceController.getDeviceList(group: 'room').then((apiResponse) {
if (apiResponse.code != HttpStatusCodes.ok) {
// TopSlideNotification.show(
// context,
// text: apiResponse.msg!,
// textColor: themeController.currentColor.sc9,
// );
} else {
//请求睡眠报告
// deviceController.getSleepReport();
}
});
if (userInfoController.model.login == 1) {
//查询人员信息列表
deviceController.getPersonList();
//请求绑定设备列表
// 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();
}
});
}
WidgetsBinding.instance.addPostFrameCallback((_) {
if (homeController.homeSleepDays.value.isNotEmpty) {
homeController.selectedDayIndex.value =
homeController.homeSleepDays.value.length - 1;
}
});
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 InkWell(
onTap: () {
if (userInfoController.model.login == 0) {
Get.toNamed("/loginPage");
}
},
child: userInfo(userInfoController.model.login),
);
}),
const Spacer(), // 左右分隔
if (userInfoController.model.login != null &&
userInfoController.model.login != 0 &&
userInfoController.model.user!.phone != null &&
userInfoController.model.user!.phone != "17649984946")
FloatingSvgIcon(
assetPath: 'assets/img/icon/xiaoyi.svg',
width: 60.rpx,
height: 60.rpx,
onTap: () {
// print("点击了小鹅图标");
if (userInfoController.model.login == 0) {
Get.toNamed("/loginPage");
}
Get.toNamed("/xiaoEPage",
arguments: "https://xiaoe.he-info.cn/");
},
),
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: SvgPicture.asset(
"assets/images/weather/${weatherModelController.model.weatherIconurl}-fill.svg",
// fit: BoxFit.cover,
color: themeController
.currentColor.sc4,
),
),
].divide(SizedBox(
width: 20.rpx,
)),
);
}),
],
),
),
],
),
),
),
//未登录
Obx(() {
if (userInfoController.model.login! == null ||
userInfoController.model.login! == 0) {
return 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"),
// ),
SvgPicture.asset(
'assets/images/icon/add.svg',
width: 42.rpx,
height: 42.rpx,
),
SizedBox(width: 20.rpx),
Text(
'添加新设备'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: stringToColor("#85F5FF"),
letterSpacing: 0,
fontSize: 26.rpx,
),
),
],
),
),
),
);
}
return Container();
}),
//已登录
Obx(() {
if (userInfoController.model.login! != null &&
userInfoController.model.login! == 1) {
final list = deviceController.personnelList.value;
// 当数据第一次到达时自动赋值
if (list.isNotEmpty &&
formFieldController.value == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
formFieldController.value = list[0]["mac"];
personInfo.value = list[0];
homeController.selectPerson.value = list[0];
homeController.selectDevcie.value = list[0]["mac"];
deviceController.getHomeSleeps(
formFieldController.value, context);
homeController.updateAll();
});
}
return SingleChildScrollView(
child: Column(
children: [
if (homeController.personnelList.value.length != 0)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 40.rpx, 30.rpx, 10.rpx),
child: Container(
width: MediaQuery.sizeOf(context).width,
height:
MediaQuery.sizeOf(context).height * 0.184,
constraints: BoxConstraints(
minHeight: 354.rpx,
),
decoration: BoxDecoration(
color: stringToColor("#003058"),
borderRadius: BorderRadius.circular(20.rpx),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
20.rpx, 20.rpx, 16.rpx, 25.rpx),
child: Container(
width:
MediaQuery.sizeOf(context).width,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
ScrollbarTheme(
data: ScrollbarThemeData(
thumbColor:
MaterialStateProperty.all(
Colors.transparent),
trackColor:
MaterialStateProperty.all(
Colors.transparent),
trackBorderColor:
MaterialStateProperty.all(
Colors.transparent),
),
child: ValueListenableBuilder(
valueListenable:
formFieldController,
builder: (c, a, s) =>
FlutterFlowDropDown<
String>(
controller:
formFieldController,
options: deviceController
.personnelList.value
.map<String>((d) =>
"${d["mac"]}")
.toList(),
optionLabels:
deviceController
.personnelList.value
.map<String>((d) {
var s =
d["name"] ?? d["mac"];
if (s == null) {
return "";
} else {
return "$s";
}
}).toList(),
onChanged: (val) {
final list =
deviceController
.personnelList
.value;
final selectedPerson =
list.firstWhere(
(element) =>
element['mac'] ==
val,
orElse: () =>
null, // 防止找不到时报错
);
homeController
.selectPerson
.value =
selectedPerson;
personInfo.value =
selectedPerson;
// homeController
// .selectedDayIndex =
// (6).obs;
homeController
.selectedDayIndex
.value = 6;
print("$val");
if (val == null) {
homeController
.homeSleepDays
.value = [];
} else {
homeController
.selectDevcie
.value =
formFieldController
.value!;
deviceController
.getHomeSleeps(
formFieldController
.value,
context);
homeController
.updateAll();
}
},
width: 300.rpx,
height: 81.rpx,
maxHeight: 300.rpx,
textStyle: TextStyle(
fontSize: 28.rpx,
overflow:
TextOverflow.ellipsis,
color: Colors.white,
),
hintText: '',
icon: Icon(
Icons
.keyboard_arrow_down_rounded,
color: stringToColor(
"#FFFFFF"),
size: 30.rpx,
),
fillColor: stringToColor(
"#011D33"),
elevation: 2,
borderColor:
Colors.transparent,
borderWidth: 2,
borderRadius: 100.rpx,
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(
// "/newSleepReportPage",
// arguments: {
// 'mac':
// formFieldController
// .value!,
// 'type': 1,
// "person":
// personInfo.value,
// 'backgroundImg':
// 'assets/images/new_background.png',
// 'date': DateTime.now()
// .millisecondsSinceEpoch,
// 'person_show': false,
// 'reportPadding': false,
// },
// );
sleepReportController
.initParams(
macValue:
formFieldController
.value!,
dateValue: DateTime.now()
.millisecondsSinceEpoch,
);
sleepReportController
.sleepReport.value = {};
sleepReportController
.loadSleepReport(
MyUtils.formatDate(
DateTime.now()),
formFieldController
.value!,
context);
// 切换导航栏到报告页
MainPageBBottomChange
.jumpTo(1);
}
},
child: Row(
mainAxisSize:
MainAxisSize.max,
children: [
SizedBox(
width: 12.rpx,
),
SvgPicture.asset(
"assets/images/table.svg",
width: 28.rpx,
height: 28.rpx,
color: stringToColor(
"#FFFFFF"),
),
SizedBox(
width: 20.rpx,
),
],
),
),
],
),
),
),
if (homeController
.homeSleepDays.value.length ==
0)
Expanded(
child: Center(
child: SizedBox(
width: 40.rpx, // 宽度
height: 40.rpx, // 高度
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<
Color>(
Colors.white,
),
),
),
),
),
if (homeController
.homeSleepDays.value.length !=
0)
Container(
padding: EdgeInsets.only(
top: 0.rpx,
bottom: 20.rpx,
left: 16.rpx,
right: 16.rpx,
),
width: double.infinity,
decoration: BoxDecoration(),
child: Obx(() => Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
...List.generate(
homeController
.homeSleepDays
.value
.length, (index) {
var day = homeController
.homeSleepDays[index];
bool isSelected =
homeController
.selectedDayIndex
.value ==
index;
return Expanded(
child: GestureDetector(
onTap: () {
homeController
.selectedDayIndex
.value = index;
int? timeMillis =
parseToInt(
day['time']);
sleepReportController
.initParams(
macValue:
formFieldController
.value!,
dateValue:
timeMillis,
);
sleepReportController
.sleepReport
.value = {};
sleepReportController.loadSleepReport(
MyUtils.formatDate(
DateTime.fromMillisecondsSinceEpoch(
timeMillis!)),
formFieldController
.value!,
context);
// 切换导航栏到报告页
MainPageBBottomChange
.jumpTo(1);
},
child: Container(
padding:
EdgeInsets.only(
top: 10.rpx,
bottom: 20.rpx,
),
width: 90.rpx,
decoration:
BoxDecoration(
color: isSelected
? stringToColor(
"#011D33")
: Colors
.transparent,
borderRadius:
BorderRadius
.circular(
8.rpx),
),
child: Column(
mainAxisSize:
MainAxisSize
.max,
mainAxisAlignment:
MainAxisAlignment
.start,
crossAxisAlignment:
CrossAxisAlignment
.center,
children: [
Text(
day['week'],
style:
TextStyle(
fontFamily:
'Readex Pro',
fontSize:
30.rpx,
letterSpacing:
0,
color: stringToColor(
"#FFFFFF"),
),
),
SizedBox(
height:
12.rpx),
Text(
day['date'],
// "哈哈",
style:
TextStyle(
fontFamily:
'Readex Pro',
letterSpacing:
0,
fontSize:
22.rpx,
color: stringToColor(
"#929699"),
),
),
SizedBox(
height:
39.rpx),
buildScoreOrIcon(
day['score']),
],
),
),
),
);
})
],
)),
),
],
),
),
),
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.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"),
// ),
SvgPicture.asset(
'assets/images/icon/add.svg',
width: 42.rpx,
height: 42.rpx,
),
SizedBox(width: 20.rpx),
Text(
'添加新设备'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: stringToColor("#85F5FF"),
letterSpacing: 0,
fontSize: 26.rpx,
),
),
],
),
),
),
),
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"),
// ),
SvgPicture.asset(
'assets/images/icon/add.svg',
width: 42.rpx,
height: 42.rpx,
),
SizedBox(width: 20.rpx),
Text(
'添加新设备'.tr,
style: TextStyle(
fontFamily: 'Readex Pro',
color: stringToColor("#85F5FF"),
letterSpacing: 0,
fontSize: 26.rpx,
),
),
],
),
),
),
),
],
),
);
}
return Container();
}),
],
),
),
),
),
),
));
}
//1 :登录 0未登录
Widget userInfo(int? login) {
return Row(
children: (login == 1)
? [
SizedBox(width: 40.rpx),
CircleAvatar(
radius: 27.rpx, // 可根据需求调整
backgroundColor: Colors.transparent,
backgroundImage: login == 1
? (userInfoController.model.user!.avatar == null ||
userInfoController.model.user!.avatar!.isEmpty
? const AssetImage(
"assets/images/mine_avatar.png",
)
: NetworkImage(
userInfoController.model.user!.avatar!,
))
: const AssetImage(
"assets/images/mine_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, // 可根据需求调整
backgroundColor: Colors.transparent,
backgroundImage: login == 1
? (userInfoController.model.user!.avatar == null ||
userInfoController.model.user!.avatar!.isEmpty
? const AssetImage(
"assets/images/mine_avatar.png",
)
: NetworkImage(
userInfoController.model.user!.avatar!,
))
: const AssetImage(
"assets/images/mine_avatar.png",
),
),
SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距
Text(
'未命名'.tr,
style: TextStyle(fontSize: 30.rpx, color: Colors.white),
)
],
);
}
Widget buildScoreOrIcon(dynamic score) {
return SizedBox(
width: 50.rpx,
height: 50.rpx,
child: Center(
child: (score != null)
? FittedBox(
child: Text(
'${score['socre']}',
style: TextStyle(
fontFamily: 'Readex Pro',
fontSize: 40.rpx,
letterSpacing: 0,
color: Colors.white,
),
),
)
: SvgPicture.asset(
'assets/img/icon/close.svg',
width: 25.rpx,
height: 25.rpx,
color: themeController.currentColor.sc3,
),
),
);
}
int? parseToInt(dynamic value) {
if (value == null) return null;
if (value is int) return value;
if (value is String) return int.tryParse(value);
return null;
}
void _onReady() {
// 页面渲染完成后执行的逻辑,比如处理通知跳转
_handlePendingRoute();
}
void _handlePendingRoute() {
var pending = JPushUtil.box.read("pendingRoute");
if (pending != null) {
String route = pending["route"];
var args = pending["arguments"];
Future.delayed(const Duration(milliseconds: 300), () {
Get.toNamed(route, arguments: args);
});
JPushUtil.box.remove("pendingRoute");
}
}
}
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<ScoreItem> scoreList;
final ValueChanged<String?>? 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<String>(
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,
),
),
],
),
);
},
),
)
],
),
);
}
}