Files
tuiche/lib/pages/device_control/new_Home_page.dart
2025-06-03 09:34:31 +08:00

855 lines
44 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/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/mh/muser_info_controller.dart';
class NewHomePage extends StatefulWidget {
const NewHomePage({super.key});
@override
State<NewHomePage> createState() => _NewHomePageState();
}
class _NewHomePageState extends State<NewHomePage> {
MUserInfoController userInfoController = Get.find();
BodyDeviceController deviceController = Get.find();
double borderRadius = 16.rpx;
var formFieldController = FormFieldController<String>(null);
get gloablController => Get.find<GlobalController>();
// get userInfoController => Get.find<UserInfoController>();
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();
}
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) {
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: Row(
children: [
// 左侧头像
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/people_avatar.png",
)
: NetworkImage(
userInfoController.model.user!.avatar!,
))
: const AssetImage(
"assets/images/people_avatar.png",
),
),
SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距
Text(
'Eason Chan',
style: TextStyle(fontSize: 30.rpx, color: Colors.white),
),
const Spacer(), // 左右分隔
// Container(
// width: 61.rpx,
// height: 78.rpx,
// alignment: const Alignment(0, 0),
// child: Image.asset(
// "assets/images/xiaoe.png",
// fit: BoxFit.cover,
// ),
// ),
// SizedBox(width: 46.rpx), // icon 之间的间距
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 0),
onTap: () {},
child: Container(
height: 60.rpx,
width: 75.rpx,
child: SvgPicture.asset(
'assets/img/icon/xiaoe.svg',
// color: Colors.white,
))),
// SizedBox(width: 40.rpx),
],
),
centerTitle: false,
),
body: SafeArea(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1.123,
// decoration: BoxDecoration(
// color: AppColors.bg_color,
// image: DecorationImage(
// image: AssetImage("assets/images/background.png"),
// fit: BoxFit.cover,
// ),
// ),
decoration: BoxDecoration(
),
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: 30.rpx),
child: Column(
children: [
Padding(
padding:
EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0),
child: Row(
children: [
Text('上海 22° 多云',
style: TextStyle(
fontSize: 26.rpx,
color: Colors.white)),
Icon(Icons.cloud,
size: 30.rpx, color: Colors.white),
],
),
),
],
))),
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<String>((d) =>
"${d["mac"]}")
.toList(),
optionLabels:
gloablController
.model.JunheDevices
.map<String>((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: '添加新设备',
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: Container(
width: MediaQuery.sizeOf(context).width,
padding: EdgeInsets.only(
top: 90.rpx, bottom: 80.rpx),
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(borderRadius),
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'检测到您当前暂无设备!',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 32.rpx,
letterSpacing: 0,
),
),
SizedBox(
height:
MediaQuery.sizeOf(context).height *
0.037,
),
Container(
width: MediaQuery.sizeOf(context).width *
0.54,
height: 90.rpx,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
borderRadius: BorderRadius.circular(0),
),
child: FFButtonWidget(
onPressed: () {
// print('Button pressed ...');
Get.toNamed("/homeDeviceType");
},
text: '立即添加一台',
icon: Icon(
Icons.add,
color: FlutterFlowTheme.of(context)
.primaryText,
size: 60.rpx,
),
options: FFButtonOptions(
iconPadding:
EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 0),
color: Colors.white,
textStyle:
FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color:
FlutterFlowTheme.of(
context)
.primaryText,
letterSpacing: 0,
fontSize: 30.rpx),
elevation: 3,
borderSide: BorderSide(
color: Color(0xFFABB0C0),
width: 1,
),
borderRadius:
BorderRadius.circular(45.rpx),
),
),
),
],
),
),
),
],
),
)
],
),
),
)
// Padding(
// padding: EdgeInsets.symmetric(horizontal: 30.rpx),
// child: Column(
// children: [
// Padding(
// padding: EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0),
// child: Row(
// children: [
// Text('上海 22° 多云',
// style: TextStyle(
// fontSize: 26.rpx, color: Colors.white)),
// Icon(Icons.cloud,
// size: 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<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,
),
),
],
),
);
},
),
)
],
),
);
}
}