Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
smart_hotel_app
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张宏
smart_hotel_app
Commits
2421f3e8
Commit
2421f3e8
authored
May 20, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
1bfb3cc9
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1069 additions
and
37 deletions
+1069
-37
app_router.dart
lib/routes/app_router.dart
+1
-1
app_router.gr.dart
lib/routes/app_router.gr.dart
+16
-16
default_view.dart
lib/views/layout/default_view.dart
+1
-1
index_view.dart
lib/views/message/index_view.dart
+0
-19
device_online_rate.dart
lib/views/report/index/child/device_online_rate.dart
+131
-0
quick_actions_block.dart
lib/views/report/index/child/quick_actions_block.dart
+85
-0
report_header_block.dart
lib/views/report/index/child/report_header_block.dart
+71
-0
report_metrics_block.dart
lib/views/report/index/child/report_metrics_block.dart
+149
-0
room_status_distribution.dart
lib/views/report/index/child/room_status_distribution.dart
+132
-0
weekly_power_chart.dart
lib/views/report/index/child/weekly_power_chart.dart
+159
-0
controller.dart
lib/views/report/index/controller.dart
+96
-0
index_view.dart
lib/views/report/index/index_view.dart
+56
-0
room_status_block.dart
lib/views/service/room/child/room_status_block.dart
+149
-0
controller.dart
lib/views/service/room/controller.dart
+21
-0
room_detail_view.dart
lib/views/service/room/room_detail_view.dart
+2
-0
No files found.
lib/routes/app_router.dart
View file @
2421f3e8
...
...
@@ -15,7 +15,7 @@ class AppRouter extends $AppRouter {
children:
[
AutoRoute
(
page:
HomeRoute
.
page
,
initial:
true
),
AutoRoute
(
page:
ServiceIndexRoute
.
page
),
AutoRoute
(
page:
Message
Route
.
page
),
AutoRoute
(
page:
ReportIndex
Route
.
page
),
AutoRoute
(
page:
ProfileRoute
.
page
),
],
),
...
...
lib/routes/app_router.gr.dart
View file @
2421f3e8
...
...
@@ -17,8 +17,8 @@ import 'package:smart_hotel_app/views/home/device/device_detail_view.dart'
import
'package:smart_hotel_app/views/home/index/index_view.dart'
as
_i4
;
import
'package:smart_hotel_app/views/layout/default_view.dart'
as
_i2
;
import
'package:smart_hotel_app/views/login/login_view.dart'
as
_i5
;
import
'package:smart_hotel_app/views/
messag
e/index_view.dart'
as
_i6
;
import
'package:smart_hotel_app/views/
profile
/index_view.dart'
as
_i7
;
import
'package:smart_hotel_app/views/
profil
e/index_view.dart'
as
_i6
;
import
'package:smart_hotel_app/views/
report/index
/index_view.dart'
as
_i7
;
import
'package:smart_hotel_app/views/search/index_view.dart'
as
_i8
;
import
'package:smart_hotel_app/views/service/index/index_view.dart'
as
_i9
;
import
'package:smart_hotel_app/views/service/room/room_detail_view.dart'
...
...
@@ -59,16 +59,16 @@ abstract class $AppRouter extends _i11.RootStackRouter {
child:
const
_i5
.
LoginView
(),
);
},
Messag
eRoute
.
name
:
(
routeData
)
{
Profil
eRoute
.
name
:
(
routeData
)
{
return
_i11
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
child:
const
_i6
.
Messag
eView
(),
child:
const
_i6
.
Profil
eView
(),
);
},
Profile
Route
.
name
:
(
routeData
)
{
ReportIndex
Route
.
name
:
(
routeData
)
{
return
_i11
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
child:
const
_i7
.
Profile
View
(),
child:
const
_i7
.
ReportIndex
View
(),
);
},
SearchRoute
.
name
:
(
routeData
)
{
...
...
@@ -173,29 +173,29 @@ class LoginRoute extends _i11.PageRouteInfo<void> {
}
/// generated route for
/// [_i6.
Messag
eView]
class
Messag
eRoute
extends
_i11
.
PageRouteInfo
<
void
>
{
const
Messag
eRoute
({
List
<
_i11
.
PageRouteInfo
>?
children
})
/// [_i6.
Profil
eView]
class
Profil
eRoute
extends
_i11
.
PageRouteInfo
<
void
>
{
const
Profil
eRoute
({
List
<
_i11
.
PageRouteInfo
>?
children
})
:
super
(
Messag
eRoute
.
name
,
Profil
eRoute
.
name
,
initialChildren:
children
,
);
static
const
String
name
=
'
Messag
eRoute'
;
static
const
String
name
=
'
Profil
eRoute'
;
static
const
_i11
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
/// generated route for
/// [_i7.
Profile
View]
class
Profile
Route
extends
_i11
.
PageRouteInfo
<
void
>
{
const
Profile
Route
({
List
<
_i11
.
PageRouteInfo
>?
children
})
/// [_i7.
ReportIndex
View]
class
ReportIndex
Route
extends
_i11
.
PageRouteInfo
<
void
>
{
const
ReportIndex
Route
({
List
<
_i11
.
PageRouteInfo
>?
children
})
:
super
(
Profile
Route
.
name
,
ReportIndex
Route
.
name
,
initialChildren:
children
,
);
static
const
String
name
=
'
Profile
Route'
;
static
const
String
name
=
'
ReportIndex
Route'
;
static
const
_i11
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
...
...
lib/views/layout/default_view.dart
View file @
2421f3e8
...
...
@@ -14,7 +14,7 @@ class _DefaultLayoutViewState extends State<DefaultLayoutView> {
@override
Widget
build
(
BuildContext
context
)
{
return
AutoTabsScaffold
(
routes:
const
[
HomeRoute
(),
ServiceIndexRoute
(),
Message
Route
(),
ProfileRoute
()],
routes:
const
[
HomeRoute
(),
ServiceIndexRoute
(),
ReportIndex
Route
(),
ProfileRoute
()],
transitionBuilder:
(
context
,
child
,
animation
)
=>
child
,
bottomNavigationBuilder:
(
context
,
tabsRouter
)
{
return
Container
(
...
...
lib/views/message/index_view.dart
deleted
100644 → 0
View file @
1bfb3cc9
import
'package:auto_route/auto_route.dart'
;
import
'package:flutter/material.dart'
;
@RoutePage
()
class
MessageView
extends
StatefulWidget
{
const
MessageView
({
super
.
key
});
@override
State
<
MessageView
>
createState
()
=>
_MessageViewState
();
}
class
_MessageViewState
extends
State
<
MessageView
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
const
Center
(
child:
Text
(
'MessageView'
),
);
}
}
lib/views/report/index/child/device_online_rate.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:fl_chart/fl_chart.dart'
;
import
'package:smart_hotel_app/views/report/index/controller.dart'
;
class
DeviceOnlineRate
extends
StatefulWidget
{
const
DeviceOnlineRate
({
super
.
key
});
@override
State
<
DeviceOnlineRate
>
createState
()
=>
_DeviceOnlineRateState
();
}
class
_DeviceOnlineRateState
extends
State
<
DeviceOnlineRate
>
{
late
final
ReportIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ReportIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
rateData
=
_controller
.
getDeviceOnlineRate
();
final
devices
=
rateData
[
'devices'
]
as
List
<
Map
<
String
,
dynamic
>>;
return
Container
(
width:
double
.
infinity
,
margin:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
),
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
rateData
[
'title'
]
as
String
,
style:
TextStyle
(
fontSize:
18
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
Text
(
rateData
[
'rateText'
]
as
String
,
style:
TextStyle
(
fontSize:
18
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Color
.
fromRGBO
(
34
,
197
,
94
,
1
),
),
),
],
),
SizedBox
(
height:
20
.
h
),
Row
(
children:
[
SizedBox
(
height:
150
.
w
,
child:
Stack
(
alignment:
Alignment
.
center
,
children:
[
SizedBox
(
width:
150
.
w
,
height:
150
.
w
,
child:
PieChart
(
PieChartData
(
sections:
[
PieChartSectionData
(
value:
rateData
[
'rate'
]
as
double
,
color:
Color
.
fromRGBO
(
34
,
197
,
94
,
1
),
radius:
15
,
),
PieChartSectionData
(
value:
1
-
(
rateData
[
'rate'
]
as
double
),
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
radius:
15
,
),
],
centerSpaceRadius:
50
.
w
,
sectionsSpace:
0
,
startDegreeOffset:
-
90
,
),
),
),
Text
(
rateData
[
'rateText'
].
toString
().
replaceAll
(
'%'
,
''
),
style:
TextStyle
(
fontSize:
32
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Color
.
fromRGBO
(
34
,
197
,
94
,
1
),
),
),
],
),
),
SizedBox
(
width:
30
.
w
),
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
...
devices
.
map
((
device
)
{
return
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
12
.
h
),
child:
Text
(
'
${device['name']}
${device['count']}
台'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
),
),
);
}).
toList
(),
],
),
),
],
),
],
),
);
}
}
lib/views/report/index/child/quick_actions_block.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/report/index/controller.dart'
;
class
QuickActionsBlock
extends
StatefulWidget
{
const
QuickActionsBlock
({
super
.
key
});
@override
State
<
QuickActionsBlock
>
createState
()
=>
_QuickActionsBlockState
();
}
class
_QuickActionsBlockState
extends
State
<
QuickActionsBlock
>
{
late
final
ReportIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ReportIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
actionsData
=
_controller
.
getQuickActions
();
final
actions
=
actionsData
[
'actions'
]
as
List
<
Map
<
String
,
dynamic
>>;
return
Container
(
width:
double
.
infinity
,
margin:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
),
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
actionsData
[
'title'
]
as
String
,
style:
TextStyle
(
fontSize:
18
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
SizedBox
(
height:
20
.
h
),
Row
(
children:
actions
.
map
((
action
)
{
return
Expanded
(
child:
Column
(
children:
[
Container
(
width:
80
.
w
,
height:
80
.
w
,
decoration:
BoxDecoration
(
color:
action
[
'backgroundColor'
]
as
Color
,
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
child:
Icon
(
action
[
'icon'
]
as
IconData
,
color:
action
[
'iconColor'
]
as
Color
,
size:
36
.
sp
,
),
),
SizedBox
(
height:
12
.
h
),
Text
(
action
[
'name'
]
as
String
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
),
),
],
),
);
}).
toList
(),
),
],
),
);
}
}
lib/views/report/index/child/report_header_block.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/report/index/controller.dart'
;
class
ReportHeaderBlock
extends
StatefulWidget
{
const
ReportHeaderBlock
({
super
.
key
});
@override
State
<
ReportHeaderBlock
>
createState
()
=>
_ReportHeaderBlockState
();
}
class
_ReportHeaderBlockState
extends
State
<
ReportHeaderBlock
>
{
late
final
ReportIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ReportIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
headerData
=
_controller
.
getReportHeader
();
return
Container
(
width:
double
.
infinity
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
,
vertical:
24
.
h
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
headerData
[
'title'
]
as
String
,
style:
TextStyle
(
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
SizedBox
(
height:
8
.
h
),
Text
(
headerData
[
'subtitle'
]
as
String
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
grey
,
),
),
],
),
),
Container
(
width:
56
.
w
,
height:
56
.
w
,
decoration:
BoxDecoration
(
shape:
BoxShape
.
circle
,
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
),
child:
Icon
(
Icons
.
star
,
color:
Color
.
fromRGBO
(
251
,
191
,
36
,
1
),
size:
28
.
sp
,
),
),
],
),
);
}
}
lib/views/report/index/child/report_metrics_block.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/report/index/controller.dart'
;
class
ReportMetricsBlock
extends
StatefulWidget
{
const
ReportMetricsBlock
({
super
.
key
});
@override
State
<
ReportMetricsBlock
>
createState
()
=>
_ReportMetricsBlockState
();
}
class
_ReportMetricsBlockState
extends
State
<
ReportMetricsBlock
>
{
late
final
ReportIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ReportIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
metricsData
=
_controller
.
getReportMetrics
();
final
powerUsage
=
metricsData
[
'powerUsage'
]
as
Map
<
String
,
dynamic
>;
final
pendingAlerts
=
metricsData
[
'pendingAlerts'
]
as
Map
<
String
,
dynamic
>;
return
Container
(
width:
double
.
infinity
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
),
child:
Row
(
children:
[
Expanded
(
child:
_buildMetricCard
(
title:
'今日用电'
,
value:
powerUsage
[
'value'
],
unit:
powerUsage
[
'unit'
]
as
String
,
changeText:
powerUsage
[
'changeText'
]
as
String
,
changeColor:
Color
.
fromRGBO
(
34
,
197
,
94
,
1
),
progress:
powerUsage
[
'progress'
]
as
double
,
progressColor:
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
),
),
SizedBox
(
width:
16
.
w
),
Expanded
(
child:
_buildMetricCard
(
title:
'待处理告警'
,
value:
pendingAlerts
[
'value'
],
unit:
pendingAlerts
[
'unit'
]
as
String
,
changeText:
pendingAlerts
[
'changeText'
]
as
String
,
changeColor:
Color
.
fromRGBO
(
246
,
158
,
11
,
1
),
progress:
pendingAlerts
[
'progress'
]
as
double
,
progressColor:
Color
.
fromRGBO
(
249
,
115
,
22
,
1
),
),
),
],
),
);
}
Widget
_buildMetricCard
({
required
String
title
,
required
num
value
,
required
String
unit
,
required
String
changeText
,
required
Color
changeColor
,
required
double
progress
,
required
Color
progressColor
,
})
{
return
Container
(
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
title
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
grey
,
),
),
Text
(
changeText
,
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
changeColor
,
fontWeight:
FontWeight
.
w500
,
),
),
],
),
SizedBox
(
height:
16
.
h
),
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
baseline
,
textBaseline:
TextBaseline
.
alphabetic
,
children:
[
Text
(
value
.
toString
().
replaceAllMapped
(
RegExp
(
r'(\d)(?=(\d{3})+(?!\d))'
),
(
Match
match
)
=>
'
${match[1]}
,'
,
),
style:
TextStyle
(
fontSize:
36
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
SizedBox
(
width:
4
.
w
),
Text
(
unit
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
grey
,
),
),
],
),
SizedBox
(
height:
16
.
h
),
Container
(
height:
8
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
4
.
r
),
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
),
child:
FractionallySizedBox
(
widthFactor:
progress
,
child:
Container
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
4
.
r
),
color:
progressColor
,
),
),
),
),
],
),
);
}
}
lib/views/report/index/child/room_status_distribution.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/report/index/controller.dart'
;
class
RoomStatusDistribution
extends
StatefulWidget
{
const
RoomStatusDistribution
({
super
.
key
});
@override
State
<
RoomStatusDistribution
>
createState
()
=>
_RoomStatusDistributionState
();
}
class
_RoomStatusDistributionState
extends
State
<
RoomStatusDistribution
>
{
late
final
ReportIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ReportIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
distributionData
=
_controller
.
getRoomStatusDistribution
();
final
statuses
=
distributionData
[
'statuses'
]
as
List
<
Map
<
String
,
dynamic
>>;
final
totalRooms
=
distributionData
[
'totalRooms'
]
as
int
;
return
Container
(
width:
double
.
infinity
,
margin:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
),
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
distributionData
[
'title'
]
as
String
,
style:
TextStyle
(
fontSize:
18
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
Text
(
'共
$totalRooms
间'
,
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
Colors
.
grey
,
),
),
],
),
SizedBox
(
height:
20
.
h
),
...
statuses
.
map
((
status
)
{
final
count
=
status
[
'count'
]
as
int
;
final
color
=
status
[
'color'
]
as
Color
;
final
percentage
=
(
count
/
totalRooms
*
100
).
toStringAsFixed
(
0
);
return
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
16
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Container
(
width:
12
.
w
,
height:
12
.
w
,
decoration:
BoxDecoration
(
color:
color
,
borderRadius:
BorderRadius
.
circular
(
6
.
r
),
),
),
SizedBox
(
width:
10
.
w
),
Expanded
(
child:
Text
(
status
[
'name'
]
as
String
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
),
),
),
Text
(
'
$count
间 (
$percentage
%)'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
color
,
fontWeight:
FontWeight
.
bold
,
),
),
],
),
SizedBox
(
height:
8
.
h
),
Container
(
width:
double
.
infinity
,
height:
12
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
6
.
r
),
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
),
child:
Align
(
alignment:
Alignment
.
centerLeft
,
child:
FractionallySizedBox
(
widthFactor:
count
/
totalRooms
,
child:
Container
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
6
.
r
),
color:
color
,
),
),
),
),
),
],
),
);
}).
toList
(),
],
),
);
}
}
lib/views/report/index/child/weekly_power_chart.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:fl_chart/fl_chart.dart'
;
import
'package:smart_hotel_app/views/report/index/controller.dart'
;
class
WeeklyPowerChart
extends
StatefulWidget
{
const
WeeklyPowerChart
({
super
.
key
});
@override
State
<
WeeklyPowerChart
>
createState
()
=>
_WeeklyPowerChartState
();
}
class
_WeeklyPowerChartState
extends
State
<
WeeklyPowerChart
>
{
late
final
ReportIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ReportIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
chartData
=
_controller
.
getWeeklyPowerUsage
();
final
data
=
chartData
[
'data'
]
as
List
<
Map
<
String
,
dynamic
>>;
return
Container
(
width:
double
.
infinity
,
margin:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
),
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
'
${chartData['title']}
(
${chartData['unit']}
)'
,
style:
TextStyle
(
fontSize:
18
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
Text
(
chartData
[
'dateRange'
]
as
String
,
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
Colors
.
grey
,
),
),
],
),
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
200
.
h
,
child:
LineChart
(
LineChartData
(
gridData:
FlGridData
(
show:
true
,
drawVerticalLine:
false
,
drawHorizontalLine:
true
,
getDrawingHorizontalLine:
(
value
)
{
return
FlLine
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
strokeWidth:
1
,
);
},
),
titlesData:
FlTitlesData
(
show:
true
,
bottomTitles:
AxisTitles
(
sideTitles:
SideTitles
(
showTitles:
true
,
getTitlesWidget:
(
value
,
meta
)
{
final
index
=
value
.
toInt
();
if
(
index
>=
0
&&
index
<
data
.
length
)
{
return
Padding
(
padding:
EdgeInsets
.
only
(
top:
8
.
h
),
child:
Text
(
data
[
index
][
'day'
]
as
String
,
style:
TextStyle
(
color:
Colors
.
grey
,
fontSize:
14
.
sp
,
),
),
);
}
return
const
SizedBox
.
shrink
();
},
reservedSize:
30
.
h
,
),
),
leftTitles:
AxisTitles
(
sideTitles:
SideTitles
(
showTitles:
false
,
),
),
topTitles:
AxisTitles
(
sideTitles:
SideTitles
(
showTitles:
false
),
),
rightTitles:
AxisTitles
(
sideTitles:
SideTitles
(
showTitles:
false
),
),
),
borderData:
FlBorderData
(
show:
false
,
),
minX:
0
,
maxX:
(
data
.
length
-
1
).
toDouble
(),
minY:
0
,
maxY:
300
,
lineBarsData:
[
LineChartBarData
(
spots:
data
.
asMap
().
entries
.
map
((
entry
)
{
final
index
=
entry
.
key
;
final
item
=
entry
.
value
;
return
FlSpot
(
index
.
toDouble
(),
(
item
[
'value'
]
as
num
).
toDouble
(),
);
}).
toList
(),
isCurved:
true
,
color:
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
barWidth:
3
,
isStrokeCapRound:
true
,
dotData:
FlDotData
(
show:
true
,
getDotPainter:
(
spot
,
percent
,
barData
,
index
)
{
return
FlDotCirclePainter
(
radius:
4
,
color:
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
strokeWidth:
2
,
strokeColor:
Colors
.
white
,
);
},
),
belowBarData:
BarAreaData
(
show:
true
,
color:
Color
.
fromRGBO
(
59
,
130
,
246
,
0.2
),
),
),
],
),
),
),
],
),
);
}
}
lib/views/report/index/controller.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
class
ReportIndexController
{
final
BuildContext
context
;
ReportIndexController
(
this
.
context
);
Map
<
String
,
dynamic
>
getReportHeader
()
{
return
{
'title'
:
'经营概览看板'
,
'subtitle'
:
'管理层视角 · 关键指标一览'
,
};
}
Map
<
String
,
dynamic
>
getReportMetrics
()
{
return
{
'powerUsage'
:
{
'value'
:
1284
,
'unit'
:
'kWh'
,
'change'
:
-
8
,
'changeText'
:
'↓ 8%'
,
'progress'
:
0.6
,
},
'pendingAlerts'
:
{
'value'
:
3
,
'unit'
:
'条'
,
'change'
:
null
,
'changeText'
:
'需关注'
,
'progress'
:
0.3
,
},
};
}
Map
<
String
,
dynamic
>
getWeeklyPowerUsage
()
{
return
{
'title'
:
'本周用电趋势'
,
'unit'
:
'kWh'
,
'dateRange'
:
'5.7 - 5.13'
,
'data'
:
[
{
'day'
:
'一'
,
'value'
:
120
},
{
'day'
:
'二'
,
'value'
:
180
},
{
'day'
:
'三'
,
'value'
:
150
},
{
'day'
:
'四'
,
'value'
:
200
},
{
'day'
:
'五'
,
'value'
:
250
},
{
'day'
:
'六'
,
'value'
:
220
},
{
'day'
:
'日'
,
'value'
:
164
},
],
};
}
Map
<
String
,
dynamic
>
getRoomStatusDistribution
()
{
return
{
'title'
:
'客房状态分布'
,
'totalRooms'
:
52
,
'statuses'
:
[
{
'name'
:
'入住中'
,
'count'
:
45
,
'color'
:
Color
.
fromRGBO
(
59
,
130
,
246
,
1
)},
{
'name'
:
'空闲'
,
'count'
:
7
,
'color'
:
Color
.
fromRGBO
(
148
,
163
,
184
,
1
)},
{
'name'
:
'已预订'
,
'count'
:
5
,
'color'
:
Color
.
fromRGBO
(
96
,
165
,
250
,
1
)},
{
'name'
:
'设备告警'
,
'count'
:
3
,
'color'
:
Color
.
fromRGBO
(
249
,
115
,
22
,
1
)},
],
};
}
Map
<
String
,
dynamic
>
getDeviceOnlineRate
()
{
return
{
'title'
:
'设备在线率'
,
'rate'
:
1.0
,
'rateText'
:
'100%'
,
'devices'
:
[
{
'name'
:
'智能空开'
,
'count'
:
16
},
{
'name'
:
'客控设备'
,
'count'
:
24
},
{
'name'
:
'网络设备'
,
'count'
:
8
},
],
};
}
Map
<
String
,
dynamic
>
getQuickActions
()
{
return
{
'title'
:
'快捷操作'
,
'actions'
:
[
{
'name'
:
'告警记录'
,
'icon'
:
Icons
.
warning_amber
,
'backgroundColor'
:
Color
.
fromRGBO
(
125
,
96
,
87
,
1
),
'iconColor'
:
Color
.
fromRGBO
(
255
,
152
,
0
,
1
),
},
{
'name'
:
'联动规则'
,
'icon'
:
Icons
.
account_tree
,
'backgroundColor'
:
Color
.
fromRGBO
(
68
,
109
,
98
,
1
),
'iconColor'
:
Color
.
fromRGBO
(
76
,
175
,
80
,
1
),
},
],
};
}
}
\ No newline at end of file
lib/views/report/index/index_view.dart
0 → 100644
View file @
2421f3e8
import
'package:auto_route/auto_route.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/report/index/child/report_header_block.dart'
;
import
'package:smart_hotel_app/views/report/index/child/report_metrics_block.dart'
;
import
'package:smart_hotel_app/views/report/index/child/weekly_power_chart.dart'
;
import
'package:smart_hotel_app/views/report/index/child/room_status_distribution.dart'
;
import
'package:smart_hotel_app/views/report/index/child/device_online_rate.dart'
;
import
'package:smart_hotel_app/views/report/index/child/quick_actions_block.dart'
;
@RoutePage
()
class
ReportIndexView
extends
StatefulWidget
{
const
ReportIndexView
({
super
.
key
});
@override
State
<
ReportIndexView
>
createState
()
=>
_ReportIndexViewState
();
}
class
_ReportIndexViewState
extends
State
<
ReportIndexView
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
return
SingleChildScrollView
(
child:
ConstrainedBox
(
constraints:
BoxConstraints
(
minHeight:
constraints
.
maxHeight
,
),
child:
Container
(
width:
double
.
infinity
,
color:
Color
.
fromRGBO
(
15
,
23
,
42
,
1
),
child:
Column
(
children:
[
ReportHeaderBlock
(),
SizedBox
(
height:
10
.
h
),
ReportMetricsBlock
(),
SizedBox
(
height:
10
.
h
),
WeeklyPowerChart
(),
SizedBox
(
height:
10
.
h
),
RoomStatusDistribution
(),
SizedBox
(
height:
10
.
h
),
DeviceOnlineRate
(),
SizedBox
(
height:
10
.
h
),
QuickActionsBlock
(),
SizedBox
(
height:
10
.
h
),
],
),
),
),
);
},
);
}
}
\ No newline at end of file
lib/views/service/room/child/room_status_block.dart
0 → 100644
View file @
2421f3e8
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/service/room/controller.dart'
;
class
RoomStatusBlock
extends
StatefulWidget
{
final
ServiceRoomController
controller
;
const
RoomStatusBlock
({
super
.
key
,
required
this
.
controller
,
});
@override
State
<
RoomStatusBlock
>
createState
()
=>
_RoomStatusBlockState
();
}
class
_RoomStatusBlockState
extends
State
<
RoomStatusBlock
>
{
@override
Widget
build
(
BuildContext
context
)
{
final
roomStatus
=
widget
.
controller
.
getRoomStatus
();
final
hasGuest
=
roomStatus
[
'hasGuest'
]
as
bool
;
final
guestRefreshTime
=
roomStatus
[
'guestRefreshTime'
]
as
String
;
final
powerOn
=
roomStatus
[
'powerOn'
]
as
bool
;
final
currentPower
=
roomStatus
[
'currentPower'
]
as
String
;
final
wifiNormal
=
roomStatus
[
'wifiNormal'
]
as
bool
;
final
wifiSignal
=
roomStatus
[
'wifiSignal'
]
as
String
;
return
Container
(
width:
double
.
infinity
,
margin:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
),
child:
Column
(
children:
[
SizedBox
(
height:
20
.
h
),
Row
(
children:
[
Expanded
(
child:
_buildStatusCard
(
icon:
Icons
.
person_outline
,
title:
'有客人'
,
subtitle:
hasGuest
?
'有人在房内'
:
'无人在房内'
,
extraInfo:
'感应器刷新 ·
$guestRefreshTime
'
,
isActive:
hasGuest
,
),
),
SizedBox
(
width:
12
.
w
),
Expanded
(
child:
_buildStatusCard
(
icon:
Icons
.
flash_on
,
title:
'没有电'
,
subtitle:
powerOn
?
'通电运行中'
:
'断电中'
,
extraInfo:
'当前功率
$currentPower
'
,
isActive:
powerOn
,
),
),
],
),
SizedBox
(
height:
12
.
h
),
Row
(
children:
[
Expanded
(
child:
_buildStatusCard
(
icon:
Icons
.
wifi
,
title:
'没有网'
,
subtitle:
wifiNormal
?
'WiFi正常'
:
'WiFi异常'
,
extraInfo:
'信号强度
$wifiSignal
'
,
isActive:
wifiNormal
,
),
),
SizedBox
(
width:
12
.
w
),
Expanded
(
child:
Container
()),
],
),
],
),
);
}
Widget
_buildStatusCard
({
required
IconData
icon
,
required
String
title
,
required
String
subtitle
,
required
String
extraInfo
,
required
bool
isActive
,
})
{
final
activeColor
=
Color
.
fromRGBO
(
34
,
197
,
94
,
1
);
final
inactiveColor
=
Color
.
fromRGBO
(
148
,
163
,
184
,
1
);
final
bgColor
=
isActive
?
Color
.
fromRGBO
(
34
,
197
,
94
,
0.1
)
:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
);
final
color
=
isActive
?
activeColor
:
inactiveColor
;
return
Container
(
padding:
EdgeInsets
.
all
(
16
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Icon
(
icon
,
color:
color
,
size:
20
.
sp
),
SizedBox
(
width:
8
.
w
),
Text
(
title
,
style:
TextStyle
(
fontSize:
12
.
sp
,
color:
Colors
.
grey
,
),
),
],
),
SizedBox
(
height:
12
.
h
),
Row
(
children:
[
Icon
(
isActive
?
Icons
.
check_circle
:
Icons
.
cancel
,
color:
color
,
size:
18
.
sp
,
),
SizedBox
(
width:
6
.
w
),
Text
(
subtitle
,
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
color
,
fontWeight:
FontWeight
.
w500
,
),
),
],
),
SizedBox
(
height:
8
.
h
),
Text
(
extraInfo
,
style:
TextStyle
(
fontSize:
11
.
sp
,
color:
Colors
.
grey
,
),
),
],
),
);
}
}
lib/views/service/room/controller.dart
View file @
2421f3e8
...
...
@@ -28,4 +28,24 @@ class ServiceRoomController {
'roomType'
:
roomTypes
[
typeIndex
],
};
}
Map
<
String
,
dynamic
>
getRoomStatus
()
{
final
num
=
roomNumber
??
'302'
;
final
numInt
=
int
.
tryParse
(
num
)
??
302
;
final
hasGuest
=
numInt
%
2
==
0
;
final
powerOn
=
true
;
final
wifiNormal
=
true
;
final
now
=
DateTime
.
now
();
final
refreshTime
=
'
${now.hour.toString().padLeft(2, '0')}
:
${now.minute.toString().padLeft(2, '0')}
'
;
return
{
'hasGuest'
:
hasGuest
,
'guestRefreshTime'
:
refreshTime
,
'powerOn'
:
powerOn
,
'currentPower'
:
'1.24kW'
,
'wifiNormal'
:
wifiNormal
,
'wifiSignal'
:
'-45dBm'
,
};
}
}
\ No newline at end of file
lib/views/service/room/room_detail_view.dart
View file @
2421f3e8
...
...
@@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/service/room/child/room_info_block.dart'
;
import
'package:smart_hotel_app/views/service/room/child/room_status_block.dart'
;
import
'package:smart_hotel_app/views/service/room/controller.dart'
;
@RoutePage
()
...
...
@@ -52,6 +53,7 @@ class _ServiceRoomDetailViewState extends State<ServiceRoomDetailView> {
children:
[
SizedBox
(
height:
20
.
h
),
RoomInfoBlock
(
controller:
_controller
),
RoomStatusBlock
(
controller:
_controller
),
],
),
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment