Commit 7e849e9f authored by 张宏's avatar 张宏

智能酒店相关页面

parent 3a517340
......@@ -46,4 +46,7 @@ app.*.map.json
/android/app/release
# FVM Version Cache
.fvm/
\ No newline at end of file
.fvm/
# ai相关
ai_work/
\ No newline at end of file
{
"dart.flutterSdkPath": ".fvm/versions/3.38.10"
"dart.flutterSdkPath": ".fvm/versions/3.41.9"
}
\ No newline at end of file
buildscript {
ext.kotlin_version = '1.9.22'
ext.kotlin_version = '2.2.20'
repositories {
google()
maven { url uri('https://maven.aliyun.com/repository/google') }
......
......@@ -3,5 +3,5 @@ distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
# distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.10.2-bin.zip
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.13-bin.zip
import 'package:auto_route/auto_route.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
import 'package:smart_hotel_app/views/report/rule/rule_management_view.dart';
import 'package:smart_hotel_app/views/report/device/device_list_view.dart';
@AutoRouterConfig(replaceInRouteName: 'View,Route')
class AppRouter extends $AppRouter {
......@@ -29,5 +31,8 @@ class AppRouter extends $AppRouter {
AutoRoute(page: InspectionDetailRoute.page),
AutoRoute(page: InspectionDeviceRoute.page),
AutoRoute(page: InspectionHistoryRoute.page),
AutoRoute(page: AbnormalListRoute.page),
AutoRoute(page: ReportRuleManagementRoute.page),
AutoRoute(page: ReportDeviceListRoute.page),
];
}
This diff is collapsed.
......@@ -133,7 +133,7 @@ class EquipmentListBlock extends StatelessWidget {
),
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Column(
children: equipmentList.take(3).map((item) => _buildEquipmentItem(item)).toList(),
children: equipmentList.take(5).map((item) => _buildEquipmentItem(item)).toList(),
),
),
],
......
......@@ -66,7 +66,7 @@ class FilterPanel extends StatelessWidget {
child: Text(
_getTabLabel(tab),
style: TextStyle(
fontSize: 36.sp,
fontSize: 28.sp,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
color: isSelected
? const Color.fromRGBO(66, 165, 245, 1.0)
......@@ -78,17 +78,17 @@ class FilterPanel extends StatelessWidget {
top: 0,
right: -8.w,
child: Container(
width: 56.w,
height: 56.h,
width: 28.w,
height: 28.h,
decoration: BoxDecoration(
color: _getTabColor(tab),
borderRadius: BorderRadius.circular(28.r),
borderRadius: BorderRadius.circular(12.r),
),
child: Center(
child: Text(
count.toString(),
style: TextStyle(
fontSize: 24.sp,
fontSize: 20.sp,
fontWeight: FontWeight.bold,
color: Colors.white,
),
......@@ -163,13 +163,13 @@ class FilterPanel extends StatelessWidget {
color: isSelected
? const Color.fromRGBO(66, 165, 245, 1.0)
: const Color.fromRGBO(200, 208, 220, 1.0),
width: 2.w,
width: 1.w,
),
),
child: Text(
room,
style: TextStyle(
fontSize: 28.sp,
fontSize: 24.sp,
color: isSelected
? const Color.fromRGBO(66, 165, 245, 1.0)
: const Color.fromRGBO(100, 116, 139, 1.0),
......
......@@ -42,10 +42,10 @@ class InspectionDeviceView extends StatelessWidget {
fontWeight: FontWeight.w200,
),
),
Icon(
Icons.arrow_forward,
color: const Color.fromRGBO(100, 116, 139, 1),
),
// Icon(
// Icons.arrow_forward,
// color: const Color.fromRGBO(100, 116, 139, 1),
// ),
],
),
centerTitle: true,
......@@ -71,7 +71,7 @@ class InspectionDeviceView extends StatelessWidget {
InspectionHistoryCard(
historyList: state.inspectionHistory,
),
SizedBox(height: 20.h),
// SizedBox(height: 20.h),
InspectionItemsCard(
items: state.inspectionItems,
),
......
......@@ -15,9 +15,12 @@ class InspectionHistoryCard extends StatelessWidget {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.r),
topRight: Radius.circular(20.r),
),
),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
padding: EdgeInsets.only(left: 20.w, right: 20.w, top: 16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......
......@@ -15,7 +15,10 @@ class InspectionItemsCard extends StatelessWidget {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20.r),
bottomRight: Radius.circular(20.r),
),
),
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
child: Column(
......
......@@ -60,7 +60,7 @@ class _DefaultLayoutViewState extends State<DefaultLayoutView> {
width: 48.w,
height: 48.h,
),
label: "服务",
label: "管理",
),
BottomNavigationBarItem(
icon: Image.asset(
......@@ -73,7 +73,7 @@ class _DefaultLayoutViewState extends State<DefaultLayoutView> {
width: 48.w,
height: 48.h,
),
label: "看板",
label: "能耗",
),
BottomNavigationBarItem(
icon: Image.asset(
......
......@@ -105,7 +105,7 @@ class LoginView extends StatelessWidget {
'智能酒店管理系统',
style: TextStyle(
color: Color(0xFF333333),
fontSize: 36,
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
......@@ -114,7 +114,7 @@ class LoginView extends StatelessWidget {
'Intelligent Hotel Management System',
style: TextStyle(
color: Color(0xFF999999),
fontSize: 24,
fontSize: 14,
),
),
],
......
......@@ -15,7 +15,7 @@ class BtnLogin extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 96.h,
height: 104.h,
decoration: BoxDecoration(
color: Color.fromRGBO(73, 149, 234, 1),
borderRadius: BorderRadius.circular(40.w),
......@@ -40,7 +40,7 @@ class BtnLogin extends StatelessWidget {
"登录",
style: TextStyle(
color: Colors.white,
fontSize: 32.sp,
fontSize: 40.sp,
fontWeight: FontWeight.bold,
),
),
......
......@@ -16,7 +16,7 @@ class ProfileHeaderBlock extends StatelessWidget {
return Container(
width: double.infinity,
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 28.w, vertical: 32.h),
padding: EdgeInsets.only(left: 28.w, right: 28.w, top: ScreenUtil().statusBarHeight + 32.h, bottom: 32.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
import 'package:smart_hotel_app/views/profile/index/cubit/profile_state.dart';
class ProfileMenuBlock extends StatelessWidget {
......@@ -7,9 +9,15 @@ class ProfileMenuBlock extends StatelessWidget {
const ProfileMenuBlock({super.key, required this.menuList});
Widget _buildMenuItem(MenuItem item) {
Widget _buildMenuItem(BuildContext context, MenuItem item) {
return GestureDetector(
onTap: () => item.onTap?.call(),
onTap: () {
if (item.onTap != null) {
item.onTap!();
} else {
_handleMenuTap(context, item.title);
}
},
child: Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 28.h),
......@@ -38,7 +46,7 @@ class ProfileMenuBlock extends StatelessWidget {
child: Text(
item.title,
style: TextStyle(
fontSize: 30.sp,
fontSize: 28.sp,
fontWeight: FontWeight.w500,
color: const Color.fromRGBO(100, 116, 139, 1.0),
),
......@@ -55,13 +63,23 @@ class ProfileMenuBlock extends StatelessWidget {
);
}
void _handleMenuTap(BuildContext context, String title) {
switch (title) {
case '告警信息':
context.pushRoute(const AbnormalListRoute());
break;
default:
break;
}
}
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: Column(
children: [
...menuList.map((item) => _buildMenuItem(item)).toList(),
...menuList.map((item) => _buildMenuItem(context, item)).toList(),
],
),
);
......
......@@ -17,12 +17,12 @@ class ReportEnergyDetailView extends StatelessWidget {
return BlocProvider(
create: (_) => EnergyCubit(),
child: Scaffold(
backgroundColor: const Color.fromRGBO(15, 23, 42, 1),
backgroundColor: const Color.fromRGBO(245, 245, 247, 1),
appBar: AppBar(
backgroundColor: const Color.fromRGBO(15, 23, 42, 1),
backgroundColor: Colors.white,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
icon: const Icon(Icons.arrow_back, color: Colors.black87),
onPressed: () {
context.popRoute();
},
......@@ -30,8 +30,8 @@ class ReportEnergyDetailView extends StatelessWidget {
title: Text(
'能耗分析',
style: TextStyle(
color: Colors.white,
fontSize: 18.sp,
color: Colors.black87,
fontSize: 32.sp,
fontWeight: FontWeight.bold,
),
),
......@@ -42,7 +42,7 @@ class ReportEnergyDetailView extends StatelessWidget {
builder: (context, state) {
return Column(
children: [
SizedBox(height: 10.h),
SizedBox(height: 16.h),
EnergyStatsCardBlock(
todayEnergy: state.todayEnergy,
todayEnergyChange: state.todayEnergyChange,
......@@ -50,9 +50,9 @@ class ReportEnergyDetailView extends StatelessWidget {
monthEnergyChange: state.monthEnergyChange,
monthBill: state.monthBill,
),
SizedBox(height: 20.h),
SizedBox(height: 16.h),
HourlyChartBlock(hourlyData: state.hourlyData),
SizedBox(height: 20.h),
SizedBox(height: 16.h),
ZoneChartBlock(zoneData: state.zoneData),
SizedBox(height: 20.h),
],
......
......@@ -26,9 +26,10 @@ class EnergyStatsCardBlock extends StatelessWidget {
Expanded(
child: _buildCard(
'${todayEnergy.toInt()}',
'今日(kWh)',
'今日(kwh)',
'${todayEnergyChange.toInt()}%',
true,
const Color.fromRGBO(59, 130, 246, 1),
),
),
SizedBox(width: 12.w),
......@@ -38,6 +39,7 @@ class EnergyStatsCardBlock extends StatelessWidget {
'本月(kWh)',
'${monthEnergyChange.toInt()}%',
true,
const Color.fromRGBO(59, 130, 246, 1),
),
),
SizedBox(width: 12.w),
......@@ -47,6 +49,7 @@ class EnergyStatsCardBlock extends StatelessWidget {
'本月电费预估',
null,
null,
const Color.fromRGBO(16, 185, 129, 1),
),
),
],
......@@ -54,56 +57,56 @@ class EnergyStatsCardBlock extends StatelessWidget {
);
}
Widget _buildCard(String value, String label, String? change, bool? isDown) {
Widget _buildCard(String value, String label, String? change, bool? isDown, Color valueColor) {
return Container(
padding: EdgeInsets.symmetric(vertical: 16.h, horizontal: 12.w),
padding: EdgeInsets.symmetric(vertical: 24.h, horizontal: 16.w),
decoration: BoxDecoration(
color: const Color.fromRGBO(30, 41, 59, 1),
borderRadius: BorderRadius.circular(12.r),
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
value,
style: TextStyle(
color: Colors.white,
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: valueColor,
fontSize: 40.sp,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 4.h),
Text(
label,
style: TextStyle(
color: const Color.fromRGBO(148, 163, 184, 1),
fontSize: 12.sp,
color: Colors.black54,
fontSize: 24.sp,
),
),
SizedBox(height: 4.h),
if (change != null)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
isDown! ? Icons.arrow_drop_down : Icons.arrow_drop_up,
isDown! ? Icons.arrow_downward : Icons.arrow_upward,
color: isDown
? const Color.fromRGBO(34, 197, 94, 1)
? const Color.fromRGBO(16, 185, 129, 1)
: const Color.fromRGBO(239, 68, 68, 1),
size: 16.sp,
size: 24.sp,
),
Text(
change,
style: TextStyle(
color: isDown
? const Color.fromRGBO(34, 197, 94, 1)
? const Color.fromRGBO(16, 185, 129, 1)
: const Color.fromRGBO(239, 68, 68, 1),
fontSize: 12.sp,
fontSize: 24.sp,
),
),
],
)
else
SizedBox(height: 20.h),
SizedBox(height: 24.h),
],
),
);
......
......@@ -11,10 +11,10 @@ class HourlyChartBlock extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 16.w),
padding: EdgeInsets.all(16.w),
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
color: const Color.fromRGBO(30, 41, 59, 1),
borderRadius: BorderRadius.circular(12.r),
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
......@@ -22,39 +22,55 @@ class HourlyChartBlock extends StatelessWidget {
Text(
'今日逐时用电',
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: Colors.black87,
fontSize: 24.sp,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 16.h),
SizedBox(height: 100.h),
SizedBox(
height: 200.h,
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceBetween,
maxY: 200,
alignment: BarChartAlignment.spaceAround,
maxY: 100,
barTouchData: BarTouchData(enabled: false),
titlesData: const FlTitlesData(
titlesData: FlTitlesData(
show: true,
rightTitles: AxisTitles(
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 20,
reservedSize: 30,
getTitlesWidget: _getBottomTitleWidget,
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
getTitlesWidget: _getLeftTitleWidget,
),
),
),
borderData: FlBorderData(show: false),
gridData: const FlGridData(show: false),
gridData: FlGridData(
show: true,
drawVerticalLine: false,
horizontalInterval: 20,
getDrawingHorizontalLine: (value) {
return FlLine(
color: const Color.fromRGBO(200, 200, 200, 1),
strokeWidth: 1,
dashArray: [5, 5],
);
},
),
barGroups: _buildBarGroups(),
),
),
......@@ -64,6 +80,57 @@ class HourlyChartBlock extends StatelessWidget {
);
}
Widget _getBottomTitleWidget(double value, TitleMeta meta) {
const style = TextStyle(
color: Colors.black54,
fontSize: 14,
);
String text;
final index = value.toInt();
if (index % 4 == 0) {
if (index == 0) {
text = '00:00';
} else if (index == 24) {
text = '24:00';
} else {
text = '$index:04';
}
} else {
text = '';
}
return SideTitleWidget(
meta: meta,
child: Text(text, style: style),
);
}
Widget _getLeftTitleWidget(double value, TitleMeta meta) {
const style = TextStyle(
color: Colors.black54,
fontSize: 14,
);
String text;
if (value == 0) {
text = '0';
} else if (value == 20) {
text = '20';
} else if (value == 40) {
text = '40';
} else if (value == 60) {
text = '60';
} else if (value == 80) {
text = '80';
} else if (value == 100) {
text = '100';
} else {
text = '';
}
return SideTitleWidget(
meta: meta,
child: Text(text, style: style),
);
}
List<BarChartGroupData> _buildBarGroups() {
return hourlyData.asMap().entries.map((entry) {
final index = entry.key;
......@@ -73,10 +140,8 @@ class HourlyChartBlock extends StatelessWidget {
barRods: [
BarChartRodData(
toY: value,
color: index >= 8 && index <= 12
? const Color.fromRGBO(59, 130, 246, 1)
: const Color.fromRGBO(37, 99, 235, 1),
width: 10.w,
color: const Color.fromRGBO(59, 130, 246, 1),
width: 12.w,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(4),
topRight: Radius.circular(4),
......
......@@ -11,10 +11,10 @@ class ZoneChartBlock extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 16.w),
padding: EdgeInsets.all(16.w),
padding: EdgeInsets.all(24.w),
decoration: BoxDecoration(
color: const Color.fromRGBO(30, 41, 59, 1),
borderRadius: BorderRadius.circular(12.r),
color: Colors.white,
borderRadius: BorderRadius.circular(20.r),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
......@@ -22,59 +22,76 @@ class ZoneChartBlock extends StatelessWidget {
Text(
'分区用电占比',
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: Colors.black87,
fontSize: 24.sp,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 16.h),
SizedBox(height: 24.h),
...zoneData.asMap().entries.map((entry) {
final index = entry.key;
final data = entry.value;
return Padding(
padding: EdgeInsets.only(
bottom: index < zoneData.length - 1 ? 16.h : 0),
bottom: index < zoneData.length - 1 ? 20.h : 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
data.name,
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
),
Row(
children: [
Container(
width: 12.w,
height: 12.h,
decoration: BoxDecoration(
color: index == 0
? const Color.fromRGBO(59, 130, 246, 1)
: const Color.fromRGBO(107, 114, 128, 1),
borderRadius: BorderRadius.circular(3.r),
),
),
SizedBox(width: 8.w),
Text(
data.name,
style: TextStyle(
color: Colors.black87,
fontSize: 24.sp,
),
),
],
),
Text(
'${data.percentage.toInt()}% (${data.energy.toInt()} kWh)',
style: TextStyle(
color: const Color.fromRGBO(148, 163, 184, 1),
fontSize: 14.sp,
color: index == 0
? const Color.fromRGBO(59, 130, 246, 1)
: Colors.black54,
fontSize: 24.sp,
),
),
],
),
SizedBox(height: 8.h),
SizedBox(height: 12.h),
Stack(
children: [
Container(
height: 12.h,
height: 16.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(51, 65, 85, 1),
borderRadius: BorderRadius.circular(6.r),
color: const Color.fromRGBO(229, 231, 235, 1),
borderRadius: BorderRadius.circular(8.r),
),
),
FractionallySizedBox(
widthFactor: data.percentage / 100,
child: Container(
height: 12.h,
height: 16.h,
decoration: BoxDecoration(
color: index == 0
? const Color.fromRGBO(59, 130, 246, 1)
: const Color.fromRGBO(71, 85, 105, 1),
borderRadius: BorderRadius.circular(6.r),
: const Color.fromRGBO(107, 114, 128, 1),
borderRadius: BorderRadius.circular(8.r),
),
),
),
......
......@@ -31,7 +31,7 @@ class ReportIndexView extends StatelessWidget {
child: Container(
width: double.infinity,
color: const Color.fromRGBO(242, 243, 245, 1),
padding: EdgeInsets.symmetric(horizontal: 28.w),
padding: EdgeInsets.only(left: 28.w, right: 28.w, top: ScreenUtil().statusBarHeight),
child: Column(
children: [
ReportHeaderBlock(
......
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:smart_hotel_app/routes/app_router.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
class DeviceOnlineRate extends StatelessWidget {
final Map<String, dynamic> deviceOnlineRate;
......@@ -15,108 +18,124 @@ class DeviceOnlineRate extends StatelessWidget {
devices.fold<int>(0, (sum, device) => sum + (device['count'] as int));
final rate = deviceOnlineRate['rate'] as double;
return Container(
width: double.infinity,
padding: EdgeInsets.all(28.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
deviceOnlineRate['title'] as String,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.normal,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
Text(
'共 $totalDevices 台',
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
return GestureDetector(
onTap: () {
context.pushRoute(const ReportDeviceListRoute());
},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(28.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
deviceOnlineRate['title'] as String,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.normal,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
),
],
),
SizedBox(height: 20.h),
Row(
children: [
SizedBox(
width: 120.w,
height: 120.h,
child: Stack(
alignment: Alignment.center,
Row(
children: [
PieChart(
PieChartData(
sections: [
PieChartSectionData(
value: rate,
color: const Color.fromRGBO(34, 197, 94, 1),
title: '',
radius: 50.w,
),
PieChartSectionData(
value: 1 - rate,
color: const Color.fromRGBO(229, 231, 235, 1),
title: '',
radius: 50.w,
),
],
sectionsSpace: 0,
centerSpaceRadius: 38.w,
),
),
Text(
deviceOnlineRate['rateText'] as String,
'共 $totalDevices 台',
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(31, 41, 55, 1),
fontSize: 22.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
),
),
SizedBox(width: 8.w),
Icon(
Icons.chevron_right,
size: 24.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
),
],
),
),
SizedBox(width: 24.w),
Expanded(
child: Column(
children: devices.map((device) {
return Padding(
padding: EdgeInsets.only(bottom: 8.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
device['name'] as String,
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(107, 114, 128, 1),
],
),
SizedBox(height: 20.h),
Row(
children: [
SizedBox(
width: 120.w,
height: 120.h,
child: Stack(
alignment: Alignment.center,
children: [
PieChart(
PieChartData(
sections: [
PieChartSectionData(
value: rate,
color: const Color.fromRGBO(34, 197, 94, 1),
title: '',
radius: 30.w,
),
),
Text(
'${device['count']} 台',
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(55, 65, 81, 1),
PieChartSectionData(
// value: 1 - rate,
value: 1 - rate,
color: const Color.fromRGBO(229, 231, 235, 1),
title: '',
radius: 30.w,
),
),
],
],
sectionsSpace: 0,
centerSpaceRadius: 38.w,
),
),
);
}).toList(),
Text(
deviceOnlineRate['rateText'] as String,
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(31, 41, 55, 1),
),
),
],
),
),
SizedBox(width: 24.w),
Expanded(
child: Column(
children: devices.map((device) {
return Padding(
padding: EdgeInsets.only(bottom: 8.h),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
device['name'] as String,
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
Text(
'${device['count']} 台',
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(55, 65, 81, 1),
),
),
],
),
);
}).toList(),
),
),
),
],
),
],
],
),
],
),
),
);
}
......
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/routes/app_router.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
class QuickActionsBlock extends StatelessWidget {
final Map<String, dynamic> quickActions;
......@@ -31,32 +34,42 @@ class QuickActionsBlock extends StatelessWidget {
SizedBox(height: 28.h),
Row(
children: actions.map((action) {
final name = action['name'] as String;
return Padding(
padding: EdgeInsets.only(right: 60.w),
child: Column(
children: [
Container(
width: 80.w,
height: 80.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(239, 246, 255, 1),
borderRadius: BorderRadius.circular(16.r),
child: GestureDetector(
onTap: () {
if (name == '联动规则') {
context.pushRoute(const ReportRuleManagementRoute());
} else if (name == '告警记录') {
context.pushRoute(const AbnormalListRoute());
}
},
child: Column(
children: [
Container(
width: 80.w,
height: 80.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(239, 246, 255, 1),
borderRadius: BorderRadius.circular(16.r),
),
child: Icon(
action['icon'] as IconData,
color: const Color.fromRGBO(59, 130, 246, 1),
size: 36.sp,
),
),
child: Icon(
action['icon'] as IconData,
color: const Color.fromRGBO(59, 130, 246, 1),
size: 36.sp,
SizedBox(height: 8.h),
Text(
name,
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
),
SizedBox(height: 8.h),
Text(
action['name'] as String,
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
],
],
),
),
);
}).toList(),
......
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
class RoomStatusDistribution extends StatelessWidget {
final Map<String, dynamic> roomStatusDistribution;
......@@ -13,108 +15,123 @@ class RoomStatusDistribution extends StatelessWidget {
roomStatusDistribution['statuses'] as List<Map<String, dynamic>>;
final totalRooms = roomStatusDistribution['totalRooms'] as int;
return Container(
width: double.infinity,
padding: EdgeInsets.all(28.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
roomStatusDistribution['title'] as String,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.normal,
color: const Color.fromRGBO(107, 114, 128, 1),
return GestureDetector(
onTap: () {
context.pushRoute(const ReportRoomDetailRoute());
},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(28.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
roomStatusDistribution['title'] as String,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.normal,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
),
Text(
'共 $totalRooms 间',
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
Row(
children: [
Text(
'共 $totalRooms 间',
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
),
),
SizedBox(width: 8.w),
Icon(
Icons.arrow_forward_ios,
size: 20.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
),
],
),
),
],
),
SizedBox(height: 20.h),
...statuses.map((status) {
final count = status['count'] as int;
final color = status['color'] as Color;
final name = status['name'] as String;
final percentage = totalRooms > 0 ? count / totalRooms : 0.0;
],
),
SizedBox(height: 20.h),
...statuses.map((status) {
final count = status['count'] as int;
final color = status['color'] as Color;
final name = status['name'] as String;
final percentage = totalRooms > 0 ? count / totalRooms : 0.0;
return Padding(
padding: EdgeInsets.only(bottom: 16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 12.w,
height: 12.h,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
return Padding(
padding: EdgeInsets.only(bottom: 16.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 12.w,
height: 12.h,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
),
SizedBox(width: 8.w),
Text(
name,
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(55, 65, 81, 1),
SizedBox(width: 8.w),
Text(
name,
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(55, 65, 81, 1),
),
),
),
],
),
Text(
'$count 间',
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(55, 65, 81, 1),
],
),
),
],
),
SizedBox(height: 8.h),
Stack(
children: [
Container(
height: 8.h,
decoration: BoxDecoration(
color: const Color.fromRGBO(229, 231, 235, 1),
borderRadius: BorderRadius.circular(4.r),
Text(
'$count 间',
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(55, 65, 81, 1),
),
),
),
FractionallySizedBox(
widthFactor: percentage,
child: Container(
],
),
SizedBox(height: 8.h),
Stack(
children: [
Container(
height: 8.h,
decoration: BoxDecoration(
color: color,
color: const Color.fromRGBO(229, 231, 235, 1),
borderRadius: BorderRadius.circular(4.r),
),
),
),
],
),
],
),
);
}).toList(),
],
FractionallySizedBox(
widthFactor: percentage,
child: Container(
height: 8.h,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(4.r),
),
),
),
],
),
],
),
);
}).toList(),
],
),
),
);
}
}
\ No newline at end of file
}
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
class WeeklyPowerChart extends StatelessWidget {
final Map<String, dynamic> weeklyPowerUsage;
......@@ -11,36 +13,50 @@ class WeeklyPowerChart extends StatelessWidget {
Widget build(BuildContext context) {
final data = weeklyPowerUsage['data'] as List<Map<String, dynamic>>;
return Container(
width: double.infinity,
padding: EdgeInsets.all(28.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${weeklyPowerUsage['title']} (${weeklyPowerUsage['unit']})',
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.normal,
color: const Color.fromRGBO(107, 114, 128, 1),
return GestureDetector(
onTap: () {
context.pushRoute(const ReportEnergyDetailRoute());
},
child: Container(
width: double.infinity,
padding: EdgeInsets.all(28.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${weeklyPowerUsage['title']} (${weeklyPowerUsage['unit']})',
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.normal,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
),
Text(
weeklyPowerUsage['dateRange'] as String,
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
Row(
children: [
Text(
weeklyPowerUsage['dateRange'] as String,
style: TextStyle(
fontSize: 22.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
),
),
SizedBox(width: 8.w),
Icon(
Icons.arrow_forward_ios,
size: 20.sp,
color: const Color.fromRGBO(156, 163, 175, 1),
),
],
),
),
],
),
],
),
SizedBox(height: 20.h),
SizedBox(
height: 200.h,
......@@ -108,6 +124,7 @@ class WeeklyPowerChart extends StatelessWidget {
),
],
),
),
);
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/views/report/room/cubit/room_report_state.dart';
class RoomReportCubit extends Cubit<RoomReportState> {
RoomReportCubit() : super(const RoomReportState());
RoomReportCubit() : super(const RoomReportState()) {
_initData();
}
void _initData() {
final floors = [
FloorInfo(
floorName: '一楼',
rooms: List.generate(10, (index) => _createRoom(101 + index)),
),
FloorInfo(
floorName: '二楼',
rooms: List.generate(10, (index) => _createRoom(201 + index)),
),
FloorInfo(
floorName: '三楼',
rooms: List.generate(10, (index) => _createRoom(301 + index)),
),
FloorInfo(
floorName: '四楼',
rooms: List.generate(10, (index) => _createRoom(401 + index)),
),
FloorInfo(
floorName: '五楼',
rooms: List.generate(10, (index) => _createRoom(501 + index)),
),
FloorInfo(
floorName: '六楼',
rooms: List.generate(10, (index) => _createRoom(601 + index)),
),
];
final statusStats = [
const StatusStat(
label: '入住',
count: 45,
color: Color.fromRGBO(59, 130, 246, 1),
),
const StatusStat(
label: '空闲',
count: 7,
color: Color.fromRGBO(156, 163, 175, 1),
),
const StatusStat(
label: '预订',
count: 5,
color: Color.fromRGBO(147, 197, 253, 1),
),
const StatusStat(
label: '告警',
count: 3,
color: Color.fromRGBO(251, 191, 36, 1),
),
];
final detailRooms = [
RoomInfo(
roomNumber: '302',
status: RoomStatus.occupied,
statusText: '入住中',
deviceStatus: const RoomDeviceStatus(
hasPerson: true,
powerOn: true,
wifiNormal: true,
acOn: true,
acTemperature: '24',
lightOn: false,
tvOn: true,
curtainOn: false,
),
),
];
emit(state.copyWith(
floors: floors,
statusStats: statusStats,
detailRooms: detailRooms,
));
}
RoomInfo _createRoom(int number) {
RoomStatus status;
String statusText;
if (number == 303) {
status = RoomStatus.warning;
statusText = '告警';
} else if (number == 309) {
status = RoomStatus.temperature;
statusText = '温度';
} else if ([302, 304, 308].contains(number)) {
status = RoomStatus.occupied;
statusText = number == 308 ? '入住·勿扰' : '入住·在房';
} else if (number == 307) {
status = RoomStatus.reserved;
statusText = '预定';
} else {
status = RoomStatus.vacant;
statusText = '空闲';
}
return RoomInfo(
roomNumber: number.toString(),
status: status,
statusText: statusText,
);
}
void selectFloor(int index) {
emit(state.copyWith(selectedFloorIndex: index));
}
}
\ No newline at end of file
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
enum RoomStatus {
vacant,
occupied,
reserved,
warning,
temperature,
}
class RoomDeviceStatus {
final bool hasPerson;
final bool powerOn;
final bool wifiNormal;
final bool acOn;
final String acTemperature;
final bool lightOn;
final bool tvOn;
final bool curtainOn;
const RoomDeviceStatus({
this.hasPerson = true,
this.powerOn = true,
this.wifiNormal = true,
this.acOn = false,
this.acTemperature = '24',
this.lightOn = false,
this.tvOn = false,
this.curtainOn = false,
});
RoomDeviceStatus copyWith({
bool? hasPerson,
bool? powerOn,
bool? wifiNormal,
bool? acOn,
String? acTemperature,
bool? lightOn,
bool? tvOn,
bool? curtainOn,
}) {
return RoomDeviceStatus(
hasPerson: hasPerson ?? this.hasPerson,
powerOn: powerOn ?? this.powerOn,
wifiNormal: wifiNormal ?? this.wifiNormal,
acOn: acOn ?? this.acOn,
acTemperature: acTemperature ?? this.acTemperature,
lightOn: lightOn ?? this.lightOn,
tvOn: tvOn ?? this.tvOn,
curtainOn: curtainOn ?? this.curtainOn,
);
}
}
class RoomInfo {
final String roomNumber;
final RoomStatus status;
final String statusText;
final RoomDeviceStatus deviceStatus;
const RoomInfo({
required this.roomNumber,
required this.status,
required this.statusText,
this.deviceStatus = const RoomDeviceStatus(),
});
RoomInfo copyWith({
String? roomNumber,
RoomStatus? status,
String? statusText,
RoomDeviceStatus? deviceStatus,
}) {
return RoomInfo(
roomNumber: roomNumber ?? this.roomNumber,
status: status ?? this.status,
statusText: statusText ?? this.statusText,
deviceStatus: deviceStatus ?? this.deviceStatus,
);
}
}
class FloorInfo {
final String floorName;
final List<RoomInfo> rooms;
const FloorInfo({
required this.floorName,
required this.rooms,
});
FloorInfo copyWith({
String? floorName,
List<RoomInfo>? rooms,
}) {
return FloorInfo(
floorName: floorName ?? this.floorName,
rooms: rooms ?? this.rooms,
);
}
}
class StatusStat {
final String label;
final int count;
final Color color;
const StatusStat({
required this.label,
required this.count,
required this.color,
});
}
class RoomReportState extends Equatable {
const RoomReportState();
final List<FloorInfo> floors;
final int selectedFloorIndex;
final List<StatusStat> statusStats;
final List<RoomInfo> detailRooms;
const RoomReportState({
this.floors = const [],
this.selectedFloorIndex = 2,
this.statusStats = const [],
this.detailRooms = const [],
});
RoomReportState copyWith() {
return const RoomReportState();
RoomReportState copyWith({
List<FloorInfo>? floors,
int? selectedFloorIndex,
List<StatusStat>? statusStats,
List<RoomInfo>? detailRooms,
}) {
return RoomReportState(
floors: floors ?? this.floors,
selectedFloorIndex: selectedFloorIndex ?? this.selectedFloorIndex,
statusStats: statusStats ?? this.statusStats,
detailRooms: detailRooms ?? this.detailRooms,
);
}
@override
List<Object?> get props => [];
List<Object?> get props => [
floors,
selectedFloorIndex,
statusStats,
detailRooms,
];
}
\ No newline at end of file
......@@ -37,12 +37,12 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
Map<String, List<Map<String, dynamic>>> _buildRoomCache() {
return {
'1楼': _generateRooms(1, 80),
'2楼': _generateRooms(2, Random().nextInt(41) + 10),
'3楼': _generateRooms(3, Random().nextInt(41) + 10),
'4楼': _generateRooms(4, Random().nextInt(41) + 10),
'1楼': _generateRooms(1, 20),
'2楼': _generateRooms(2, Random().nextInt(21) + 10),
'3楼': _generateRooms(3, Random().nextInt(21) + 10),
'4楼': _generateRooms(4, Random().nextInt(21) + 10),
'5楼': _generateRooms(5, Random().nextInt(5) + 10),
'6楼': _generateRooms(6, Random().nextInt(41) + 10),
'6楼': _generateRooms(6, Random().nextInt(21) + 10),
};
}
......
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/views/service/index/cubit/service_index_cubit.dart';
import 'package:smart_hotel_app/views/service/index/cubit/service_index_state.dart';
......@@ -18,15 +19,17 @@ class ServiceIndexView extends StatelessWidget {
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 28.w),
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: Container(
color: const Color.fromRGBO(242, 243, 245, 1),
// color: const Color.fromRGBO(242, 243, 245, 1),
color: Color.fromRGBO(242, 243, 245, 1.0),
child: BlocBuilder<ServiceIndexCubit, ServiceIndexState>(
builder: (context, state) {
return Column(
children: [
ServiceHeadBlock(pendingCount: state.pendingCount),
const ServiceHeadBlock(),
ServiceStatsBlock(
pendingCount: state.pendingCount,
occupiedCount: state.occupiedRooms,
......
......@@ -525,4 +525,4 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
],
);
}
}
\ No newline at end of file
}
......@@ -2,76 +2,47 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ServiceHeadBlock extends StatelessWidget {
final int pendingCount;
const ServiceHeadBlock({super.key, required this.pendingCount});
const ServiceHeadBlock({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: EdgeInsets.fromLTRB(28.w, 20.h, 28.w, 20.h),
color: Color.fromRGBO(73, 149, 234, 1),
child: Stack(
height: 150.h,
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight, left: 20.w, right: 20.w),
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(20.r),
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.emoji_emotions_outlined,
color: Color.fromRGBO(255, 255, 255, 1), size: 40.sp),
SizedBox(width: 10.w),
Text(
'早安,张先生',
style: TextStyle(
fontSize: 40.sp,
fontWeight: FontWeight.bold,
color: Colors.white,
fontFamily: 'FZLTXH',
),
),
],
),
SizedBox(height: 15.h),
Text(
'今日天气:晴 25°C ~ 35°C',
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: Color.fromRGBO(255, 255, 255, 1),
fontFamily: 'FZLTXH',
),
),
],
Text(
'客房服务看板',
style: TextStyle(
fontSize: 32.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(0, 0, 0, 1),
fontFamily: 'FZLTXH',
),
),
Positioned(
right: 0,
bottom: 0,
child: GestureDetector(
onTap: () {},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 3.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.r),
color: const Color.fromRGBO(1, 1, 1, 0.1),
),
child: Row(
children: [
Icon(Icons.notifications_outlined,
color: Colors.white, size: 38.sp),
SizedBox(width: 5.w),
Text(
'待响应需求 $pendingCount',
style: TextStyle(
fontSize: 24.sp,
fontWeight: FontWeight.bold,
color: Colors.white,
fontFamily: 'FZLTXH',
),
),
],
),
Container(
width: 64.w,
height: 64.w,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: const Color.fromRGBO(73, 149, 234, 1),
width: 1.w,
),
),
child: CircleAvatar(
radius: 40.w,
backgroundColor: Colors.white,
child: Icon(
Icons.person,
color: const Color.fromRGBO(73, 149, 234, 1),
size: 48.sp,
),
),
),
......@@ -79,4 +50,4 @@ class ServiceHeadBlock extends StatelessWidget {
),
);
}
}
\ No newline at end of file
}
......@@ -19,21 +19,21 @@ class ServiceStatsBlock extends StatelessWidget {
width: double.infinity,
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.r),
color: Colors.white,
// borderRadius: BorderRadius.circular(24.r),
color: Color.fromRGBO(242, 243, 245, 1.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'服务概览',
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(31, 41, 55, 1),
),
),
SizedBox(height: 20.h),
// Text(
// '服务概览',
// style: TextStyle(
// fontSize: 28.sp,
// fontWeight: FontWeight.bold,
// color: const Color.fromRGBO(31, 41, 55, 1),
// ),
// ),
// SizedBox(height: 20.h),
Row(
children: [
_buildStatCard(
......@@ -74,12 +74,12 @@ class ServiceStatsBlock extends StatelessWidget {
),
child: Column(
children: [
Icon(icon, color: color, size: 28.sp),
// Icon(icon, color: color, size: 28.sp),
SizedBox(height: 8.h),
Text(
value,
style: TextStyle(
fontSize: 32.sp,
fontSize: 60.sp,
fontWeight: FontWeight.bold,
color: color,
),
......@@ -88,7 +88,7 @@ class ServiceStatsBlock extends StatelessWidget {
Text(
label,
style: TextStyle(
fontSize: 20.sp,
fontSize: 24.sp,
color: const Color.fromRGBO(107, 114, 128, 1),
),
),
......@@ -97,4 +97,4 @@ class ServiceStatsBlock extends StatelessWidget {
),
);
}
}
\ No newline at end of file
}
......@@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:smart_hotel_app/routes/app_router.gr.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_cubit.dart';
import 'package:smart_hotel_app/views/service/room/cubit/service_room_state.dart';
import 'package:smart_hotel_app/views/service/room/widget/room_overview_card.dart';
......@@ -64,6 +65,11 @@ class ServiceRoomDetailView extends StatelessWidget {
controlDevices: state.controlDevices,
onMainPowerToggle: (value) => cubit.toggleMainPower(value),
onDeviceToggle: (index, value) => cubit.toggleControlDevice(index, value),
onDeviceTap: (index, device) {
if (device.name == '空调') {
context.pushRoute(const ServiceDeviceDetailRoute());
}
},
),
SizedBox(height: 20.h),
const RoomBottomButtons(),
......
......@@ -8,6 +8,7 @@ class DeviceControlCard extends StatelessWidget {
final List<ControlDevice> controlDevices;
final Function(bool) onMainPowerToggle;
final Function(int, bool) onDeviceToggle;
final Function(int, ControlDevice)? onDeviceTap;
const DeviceControlCard({
super.key,
......@@ -15,6 +16,7 @@ class DeviceControlCard extends StatelessWidget {
required this.controlDevices,
required this.onMainPowerToggle,
required this.onDeviceToggle,
this.onDeviceTap,
});
@override
......@@ -107,14 +109,21 @@ class DeviceControlCard extends StatelessWidget {
],
),
FlutterSwitch(
width: 48.0,
height: 25.0,
value: mainPowerOn,
onToggle: onMainPowerToggle,
activeColor: const Color.fromRGBO(59, 130, 246, 1),
inactiveColor: const Color.fromRGBO(209, 213, 219, 1),
width: 60.w,
height: 30.h,
toggleSize: 26,
showOnOff: false,
onToggle: onMainPowerToggle
),
// FlutterSwitch(
// value: mainPowerOn,
// onToggle: onMainPowerToggle,
// activeColor: const Color.fromRGBO(59, 130, 246, 1),
// inactiveColor: const Color.fromRGBO(209, 213, 219, 1),
// width: 50.w,
// height: 28.h,
// // toggleSize: 26,
// ),
],
),
SizedBox(height: 20.h),
......@@ -134,49 +143,62 @@ class DeviceControlCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: onDeviceTap != null ? () => onDeviceTap!(index, device) : null,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(
device.icon,
color: const Color.fromRGBO(66, 165, 245, 1.0),
size: 36.sp,
Row(
children: [
Icon(
device.icon,
color: const Color.fromRGBO(66, 165, 245, 1.0),
size: 36.sp,
),
SizedBox(width: 8.w),
Text(
device.name,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
),
),
],
),
SizedBox(width: 8.w),
Text(
device.name,
style: TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.bold,
color: const Color.fromRGBO(10, 13, 20, 1.0),
if (device.detailText != null) ...[
SizedBox(height: 8.h),
Text(
device.detailText!,
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(100, 116, 139, 1.0),
),
),
),
],
],
),
if (device.detailText != null) ...[
SizedBox(height: 8.h),
Text(
device.detailText!,
style: TextStyle(
fontSize: 24.sp,
color: const Color.fromRGBO(100, 116, 139, 1.0),
),
),
],
],
),
),
),
FlutterSwitch(
width: 48.0,
height: 25.0,
value: device.isOn,
showOnOff: false,
onToggle: (value) => onDeviceToggle(index, value),
activeColor: const Color.fromRGBO(66, 165, 245, 1.0),
inactiveColor: const Color.fromRGBO(200, 208, 220, 1.0),
width: 60.w,
height: 30.h,
toggleSize: 26,
),
// FlutterSwitch(
// value: device.isOn,
// onToggle: (value) => onDeviceToggle(index, value),
// activeColor: const Color.fromRGBO(66, 165, 245, 1.0),
// inactiveColor: const Color.fromRGBO(200, 208, 220, 1.0),
// width: 60.w,
// height: 30.h,
// toggleSize: 26,
// ),
],
),
if (index < controlDevices.length - 1) ...[
......
......@@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)
set(PLUGIN_BUNDLED_LIBRARIES)
......
......@@ -6,9 +6,7 @@ import FlutterMacOS
import Foundation
import flutter_secure_storage_macos
import path_provider_foundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
}
This diff is collapsed.
......@@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
jni
)
set(PLUGIN_BUNDLED_LIBRARIES)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment