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
165f6cbb
Commit
165f6cbb
authored
May 22, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
e12f65bf
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1002 additions
and
603 deletions
+1002
-603
launch.json
.vscode/launch.json
+26
-0
jth.png
lib/assets/icon/jth.png
+0
-0
person1.png
lib/assets/icon/person1.png
+0
-0
login_view.dart
lib/views/login/login_view.dart
+127
-106
room_management_block.dart
lib/views/service/index/child/room_management_block.dart
+172
-165
service_head_block.dart
lib/views/service/index/child/service_head_block.dart
+49
-63
service_stats_block.dart
lib/views/service/index/child/service_stats_block.dart
+32
-13
index_view.dart
lib/views/service/index/index_view.dart
+3
-1
bottom_operation_block.dart
lib/views/service/room/child/bottom_operation_block.dart
+81
-0
device_control_block.dart
lib/views/service/room/child/device_control_block.dart
+208
-0
room_info_block.dart
lib/views/service/room/child/room_info_block.dart
+211
-94
room_status_block.dart
lib/views/service/room/child/room_status_block.dart
+0
-149
controller.dart
lib/views/service/room/controller.dart
+65
-0
room_detail_view.dart
lib/views/service/room/room_detail_view.dart
+19
-12
pubspec.lock
pubspec.lock
+8
-0
pubspec.yaml
pubspec.yaml
+1
-0
No files found.
.vscode/launch.json
0 → 100644
View file @
165f6cbb
{
//
使用
IntelliSense
了解相关属性。
//
悬停以查看现有属性的描述。
//
欲了解更多信息,请访问
:
https
:
//go.microsoft.com/fwlink/?linkid=
830387
"version"
:
"0.2.0"
,
"configurations"
:
[
{
"name"
:
"smart_hotel_app"
,
"request"
:
"launch"
,
"type"
:
"dart"
},
{
"name"
:
"smart_hotel_app (profile mode)"
,
"request"
:
"launch"
,
"type"
:
"dart"
,
"flutterMode"
:
"profile"
},
{
"name"
:
"smart_hotel_app (release mode)"
,
"request"
:
"launch"
,
"type"
:
"dart"
,
"flutterMode"
:
"release"
}
]
}
\ No newline at end of file
lib/assets/icon/jth.png
0 → 100644
View file @
165f6cbb
735 Bytes
lib/assets/icon/person1.png
0 → 100644
View file @
165f6cbb
1.64 KB
lib/views/login/login_view.dart
View file @
165f6cbb
import
'dart:io'
;
import
'package:auto_route/auto_route.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:fluttertoast/fluttertoast.dart'
;
import
'package:smart_hotel_app/blocs/auth/auth_bloc.dart'
;
...
...
@@ -40,6 +42,15 @@ class _LoginViewState extends State<LoginView> {
storageService:
StorageService
(),
);
_loadSavedCredentials
();
// 设置状态栏样式
SystemChrome
.
setSystemUIOverlayStyle
(
SystemUiOverlayStyle
(
statusBarColor:
Colors
.
transparent
,
statusBarIconBrightness:
Brightness
.
dark
,
statusBarBrightness:
Brightness
.
light
,
),
);
}
Future
<
void
>
_loadSavedCredentials
()
async
{
...
...
@@ -55,118 +66,129 @@ class _LoginViewState extends State<LoginView> {
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
resizeToAvoidBottomInset:
true
,
body:
Container
(
width:
double
.
infinity
,
height:
double
.
infinity
,
padding:
EdgeInsets
.
only
(
left:
50
.
w
,
right:
50
.
w
),
decoration:
BoxDecoration
(
color:
Color
(
0xFFF5F7FA
),
),
child:
SingleChildScrollView
(
child:
Column
(
children:
[
SizedBox
(
height:
150
.
h
),
Container
(
margin:
EdgeInsets
.
only
(
bottom:
80
.
h
),
child:
Column
(
children:
[
Container
(
width:
160
.
w
,
height:
160
.
w
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
40
.
w
),
gradient:
LinearGradient
(
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
colors:
[
Color
(
0xFF00C6FF
),
Color
(
0xFF0072FF
),
],
return
AnnotatedRegion
<
SystemUiOverlayStyle
>(
value:
SystemUiOverlayStyle
(
statusBarColor:
Colors
.
transparent
,
statusBarIconBrightness:
Brightness
.
dark
,
statusBarBrightness:
Brightness
.
light
,
),
child:
Scaffold
(
backgroundColor:
Color
(
0xFFF5F7FA
),
resizeToAvoidBottomInset:
true
,
body:
SafeArea
(
top:
false
,
child:
Container
(
width:
double
.
infinity
,
height:
double
.
infinity
,
padding:
EdgeInsets
.
only
(
left:
50
.
w
,
right:
50
.
w
),
decoration:
BoxDecoration
(
color:
Color
(
0xFFF5F7FA
),
),
child:
SingleChildScrollView
(
child:
Column
(
children:
[
SizedBox
(
height:
150
.
h
),
Container
(
margin:
EdgeInsets
.
only
(
bottom:
80
.
h
),
child:
Column
(
children:
[
Container
(
width:
160
.
w
,
height:
160
.
w
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
40
.
w
),
gradient:
LinearGradient
(
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
colors:
[
Color
(
0xFF00C6FF
),
Color
(
0xFF0072FF
),
],
),
),
child:
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
40
.
w
),
child:
Image
.
asset
(
'lib/assets/login/logo@2x.png'
,
fit:
BoxFit
.
cover
,
),
),
),
),
child:
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
40
.
w
),
child:
Image
.
asset
(
'lib/assets/login/logo@2x.png'
,
fit:
BoxFit
.
cover
,
SizedBox
(
height:
40
.
h
),
Text
(
"智能酒店管理系统"
,
style:
TextStyle
(
color:
Color
(
0xFF333333
),
fontSize:
36
.
sp
,
fontWeight:
FontWeight
.
bold
,
),
),
),
),
SizedBox
(
height:
40
.
h
),
Text
(
"智能酒店管理系统"
,
style:
TextStyle
(
color:
Color
(
0xFF333333
),
fontSize:
36
.
sp
,
fontWeight:
FontWeight
.
bold
,
),
),
SizedBox
(
height:
10
.
h
),
Text
(
"Intelligent Hotel Management System"
,
style:
TextStyle
(
color:
Color
(
0xFF999999
),
fontSize:
24
.
sp
,
),
),
],
),
),
Form
(
key:
_frmGlobalKey
,
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
UsernameField
(
controller:
_txtUserNameController
,
),
SizedBox
(
height:
20
.
h
),
PasswordField
(
controller:
_txtPwdController
,
),
SizedBox
(
height:
30
.
h
),
RememberPasswordRow
(
value:
_rememberPassword
,
onChanged:
(
val
)
{
setState
(()
{
_rememberPassword
=
val
??
false
;
});
},
onForgotPassword:
_loginController
.
forgotPwd
,
),
SizedBox
(
height:
10
.
h
),
BlocConsumer
<
AuthBloc
,
AuthState
>(
listener:
(
context
,
state
)
{
if
(
state
is
AuthFailure
)
{
Fluttertoast
.
showToast
(
msg:
state
.
error
,
toastLength:
Toast
.
LENGTH_SHORT
,
gravity:
ToastGravity
.
CENTER
,
timeInSecForIosWeb:
2
,
backgroundColor:
Colors
.
red
,
textColor:
Colors
.
white
,
fontSize:
16.0
);
}
},
builder:
(
context
,
state
)
{
return
BtnLogin
(
isLoading:
state
is
AuthLoading
,
onPressed:
()
=>
_loginController
.
login
(
_frmGlobalKey
,
rememberPassword:
_rememberPassword
,
SizedBox
(
height:
10
.
h
),
Text
(
"Intelligent Hotel Management System"
,
style:
TextStyle
(
color:
Color
(
0xFF999999
),
fontSize:
24
.
sp
,
),
);
},
),
],
),
),
Form
(
key:
_frmGlobalKey
,
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
UsernameField
(
controller:
_txtUserNameController
,
),
SizedBox
(
height:
20
.
h
),
PasswordField
(
controller:
_txtPwdController
,
),
SizedBox
(
height:
30
.
h
),
RememberPasswordRow
(
value:
_rememberPassword
,
onChanged:
(
val
)
{
setState
(()
{
_rememberPassword
=
val
??
false
;
});
},
onForgotPassword:
_loginController
.
forgotPwd
,
),
SizedBox
(
height:
10
.
h
),
BlocConsumer
<
AuthBloc
,
AuthState
>(
listener:
(
context
,
state
)
{
if
(
state
is
AuthFailure
)
{
Fluttertoast
.
showToast
(
msg:
state
.
error
,
toastLength:
Toast
.
LENGTH_SHORT
,
gravity:
ToastGravity
.
CENTER
,
timeInSecForIosWeb:
2
,
backgroundColor:
Colors
.
red
,
textColor:
Colors
.
white
,
fontSize:
16.0
);
}
},
builder:
(
context
,
state
)
{
return
BtnLogin
(
isLoading:
state
is
AuthLoading
,
onPressed:
()
=>
_loginController
.
login
(
_frmGlobalKey
,
rememberPassword:
_rememberPassword
,
),
);
},
),
],
),
]
,
)
,
)
,
]
,
),
]
,
)
,
),
),
),
);
}
}
\ No newline at end of file
}
lib/views/service/index/child/room_management_block.dart
View file @
165f6cbb
...
...
@@ -24,7 +24,6 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
_controller
=
ServiceIndexController
(
context
);
}
List
<
Map
<
String
,
dynamic
>>
_getFilteredRooms
()
{
...
...
@@ -69,48 +68,47 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
Widget
build
(
BuildContext
context
)
{
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
,
),
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
color:
Colors
.
white
,
boxShadow:
[
BoxShadow
(
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
0.03
),
blurRadius:
20
.
r
,
offset:
Offset
(
0
,
4
),
),
],
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
// 楼层选择
_buildFloorSelector
(),
SizedBox
(
height:
1
5
.
h
),
SizedBox
(
height:
1
8
.
h
),
// 类型选择
_buildTypeSelector
(),
SizedBox
(
height:
1
5
.
h
),
SizedBox
(
height:
1
8
.
h
),
// 搜索框
_buildSearchBox
(),
SizedBox
(
height:
15
.
h
),
SizedBox
(
height:
32
.
h
),
_buildLine
(),
SizedBox
(
height:
18
.
h
),
// 房间区域
_buildRoomGrid
(),
SizedBox
(
height:
20
.
h
),
// 选中状态提示
if
(
_selectedRoom
!=
null
)
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
.
w
,
vertical:
8
.
h
),
decoration:
BoxDecoration
(
color:
Color
.
fromRGBO
(
15
,
23
,
42
,
1
),
borderRadius:
BorderRadius
.
circular
(
10
.
r
),
),
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
15
.
h
),
child:
Text
(
'已选:
$_selectedRoom
号房'
,
'已选:
$_selectedRoom
号房'
,
style:
TextStyle
(
fontSize:
1
4
.
sp
,
color:
Color
s
.
white
,
fontSize:
2
4
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)
,
),
),
),
SizedBox
(
height:
15
.
h
),
// 底部按钮
_buildBottomButtons
(),
],
...
...
@@ -125,8 +123,9 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
child:
Row
(
children:
floors
.
map
((
floor
)
{
final
isSelected
=
_selectedFloor
==
floor
;
final
displayFloor
=
floor
.
replaceAll
(
'楼'
,
''
);
return
Padding
(
padding:
EdgeInsets
.
only
(
right:
10
.
w
),
padding:
EdgeInsets
.
only
(
right:
24
.
w
),
child:
GestureDetector
(
onTap:
()
{
setState
(()
{
...
...
@@ -139,23 +138,26 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
_searchText
=
''
;
});
},
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
,
vertical:
10
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
10
.
r
),
border:
Border
.
all
(
color:
isSelected
?
Color
.
fromRGBO
(
59
,
130
,
246
,
1
)
:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
2
.
w
,
child:
Column
(
children:
[
Text
(
'
$displayFloor
楼'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
isSelected
?
Color
.
fromRGBO
(
80
,
162
,
255
,
1
)
:
Color
.
fromRGBO
(
0
,
0
,
0
,
1
),
fontWeight:
isSelected
?
FontWeight
.
bold
:
FontWeight
.
normal
,
),
),
),
child:
Text
(
floor
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
isSelected
?
Color
.
fromRGBO
(
59
,
130
,
246
,
1
)
:
Colors
.
white
,
fontWeight:
isSelected
?
FontWeight
.
bold
:
FontWeight
.
normal
,
SizedBox
(
height:
4
.
h
),
Container
(
width:
50
.
w
,
height:
3
.
h
,
decoration:
BoxDecoration
(
color:
isSelected
?
Color
.
fromRGBO
(
80
,
162
,
255
,
1
)
:
Colors
.
transparent
,
borderRadius:
BorderRadius
.
circular
(
2
.
r
),
),
),
)
,
]
,
),
),
);
...
...
@@ -173,7 +175,7 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
final
isSelected
=
_selectedType
==
type
;
return
Expanded
(
child:
Padding
(
padding:
EdgeInsets
.
only
(
right:
index
<
types
.
length
-
1
?
8
.
w
:
0
),
padding:
EdgeInsets
.
only
(
right:
index
<
types
.
length
-
1
?
10
.
w
:
0
),
child:
GestureDetector
(
onTap:
()
{
setState
(()
{
...
...
@@ -185,17 +187,21 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
});
},
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
12
.
h
),
padding:
EdgeInsets
.
symmetric
(
vertical:
8
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
15
.
r
),
color:
isSelected
?
Color
.
fromRGBO
(
59
,
130
,
246
,
1
)
:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
border:
Border
.
all
(
color:
isSelected
?
Color
.
fromRGBO
(
73
,
149
,
234
,
0.5
)
:
Colors
.
transparent
,
width:
1
.
w
,
),
color:
isSelected
?
Color
.
fromRGBO
(
73
,
149
,
234
,
0.2
)
:
Color
.
fromRGBO
(
238
,
238
,
238
,
1
),
),
child:
Center
(
child:
Text
(
type
,
style:
TextStyle
(
fontSize:
1
4
.
sp
,
color:
Colors
.
white
,
fontSize:
2
4
.
sp
,
color:
isSelected
?
Color
.
fromRGBO
(
73
,
149
,
234
,
1
)
:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)
,
fontWeight:
isSelected
?
FontWeight
.
bold
:
FontWeight
.
normal
,
),
),
...
...
@@ -210,14 +216,24 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
Widget
_buildSearchBox
()
{
return
Container
(
height:
55
.
h
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
1
5
.
w
),
height:
80
.
h
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
1
6
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
15
.
r
),
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
borderRadius:
BorderRadius
.
circular
(
86
.
r
),
color:
Colors
.
white
,
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
146
,
191
,
243
,
1
),
width:
1
.
w
,
),
),
child:
Row
(
children:
[
Icon
(
Icons
.
search
,
color:
Color
.
fromRGBO
(
153
,
153
,
153
,
1
),
size:
37
.
sp
,
),
SizedBox
(
width:
26
.
w
),
Expanded
(
child:
TextField
(
controller:
_searchController
,
...
...
@@ -227,40 +243,41 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
});
},
style:
TextStyle
(
fontSize:
1
4
.
sp
,
color:
Color
s
.
white
,
fontSize:
2
4
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)
,
),
decoration:
InputDecoration
(
hintText:
'输入房号快速查找,如
301...'
,
hintText:
'输入房号快速查找,如301...'
,
hintStyle:
TextStyle
(
fontSize:
1
4
.
sp
,
color:
Color
s
.
grey
,
fontSize:
2
4
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)
,
),
border:
InputBorder
.
none
,
contentPadding:
EdgeInsets
.
symmetric
(
vertical:
1
8
.
h
),
contentPadding:
EdgeInsets
.
symmetric
(
vertical:
1
6
.
h
),
isCollapsed:
true
,
),
),
),
Icon
(
Icons
.
keyboard
,
color:
Colors
.
grey
,
size:
24
.
sp
,
),
],
),
);
}
Widget
_buildLine
()
{
return
Container
(
height:
1
.
h
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
);
}
String
_buildFilterLabel
()
{
final
typePart
=
_selectedType
??
'全部类型'
;
final
floorPart
=
_selectedFloor
??
'全部楼层'
;
return
'
$typePart
·
$floorPart
'
;
final
floorPart
=
_selectedFloor
?.
replaceAll
(
'楼'
,
''
)
??
''
;
return
floorPart
.
isNotEmpty
?
'客房
${floorPart}
楼·左右滑动选择'
:
"左右滑动选择"
;
}
Widget
_buildRoomGrid
()
{
final
filteredRooms
=
_getFilteredRooms
();
final
crossAxisCount
=
8
;
// 列
final
crossAxisCount
=
12
;
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
...
...
@@ -271,17 +288,15 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
Text
(
_buildFilterLabel
(),
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
w500
,
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
Text
(
'共
${filteredRooms.length}
间'
,
'共
${filteredRooms.length}
间'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
w500
,
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
),
],
...
...
@@ -293,14 +308,14 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
padding:
EdgeInsets
.
symmetric
(
vertical:
40
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
15
.
r
),
color:
Color
.
fromRGBO
(
51
,
65
,
8
5
,
1
),
color:
Color
.
fromRGBO
(
245
,
245
,
24
5
,
1
),
),
child:
Center
(
child:
Text
(
'未找到匹配的房间'
,
style:
TextStyle
(
fontSize:
1
6
.
sp
,
color:
Color
s
.
grey
,
fontSize:
1
5
.
sp
,
color:
Color
.
fromRGBO
(
153
,
153
,
153
,
1
)
,
),
),
),
...
...
@@ -310,15 +325,15 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
scrollDirection:
Axis
.
horizontal
,
controller:
_scrollController
,
child:
SizedBox
(
// width: (100.w + 10.w) * (filteredRooms.length / crossAxisCount).ceil(),
width:
ScreenUtil
().
screenWidth
,
width:
(
120
.
w
+
12
.
w
)
*
crossAxisCount
,
child:
GridView
.
builder
(
shrinkWrap:
true
,
physics:
NeverScrollableScrollPhysics
(),
padding:
EdgeInsets
.
zero
,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
crossAxisCount
,
crossAxisSpacing:
1
0
.
w
,
mainAxisSpacing:
1
0
.
h
,
crossAxisSpacing:
1
2
.
w
,
mainAxisSpacing:
1
2
.
h
,
childAspectRatio:
1
,
),
itemCount:
filteredRooms
.
length
,
...
...
@@ -339,28 +354,29 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
Color
backgroundColor
;
Color
borderColor
;
Color
textColor
;
Color
statusTextColor
;
IconData
?
statusIcon
;
switch
(
status
)
{
case
'入住'
:
backgroundColor
=
Color
.
fromRGBO
(
59
,
130
,
246
,
0.3
);
borderColor
=
Color
.
fromRGBO
(
59
,
130
,
246
,
1
);
textColor
=
Colors
.
white
;
backgroundColor
=
Color
.
fromRGBO
(
220
,
236
,
255
,
1
);
borderColor
=
isSelected
?
Color
.
fromRGBO
(
64
,
158
,
255
,
1
)
:
Colors
.
transparent
;
textColor
=
Color
.
fromRGBO
(
100
,
116
,
139
,
1
);
statusTextColor
=
Color
.
fromRGBO
(
73
,
149
,
234
,
1
);
break
;
case
'待清洁'
:
backgroundColor
=
Color
.
fromRGBO
(
246
,
158
,
11
,
0.3
);
borderColor
=
Color
.
fromRGBO
(
246
,
158
,
11
,
1
);
textColor
=
Colors
.
white
;
backgroundColor
=
Color
.
fromRGBO
(
238
,
238
,
238
,
1
);
borderColor
=
isSelected
?
Color
.
fromRGBO
(
64
,
158
,
255
,
1
)
:
Colors
.
transparent
;
textColor
=
Color
.
fromRGBO
(
100
,
116
,
139
,
1
);
statusTextColor
=
Color
.
fromRGBO
(
73
,
149
,
234
,
1
);
statusIcon
=
Icons
.
warning_amber_rounded
;
break
;
case
'空闲'
:
default
:
backgroundColor
=
Color
.
fromRGBO
(
51
,
65
,
85
,
1
);
borderColor
=
Color
.
fromRGBO
(
71
,
85
,
105
,
1
);
textColor
=
Colors
.
white
;
}
if
(
isSelected
)
{
backgroundColor
=
Color
.
fromRGBO
(
59
,
130
,
246
,
1
);
borderColor
=
Color
.
fromRGBO
(
59
,
130
,
246
,
1
);
backgroundColor
=
Color
.
fromRGBO
(
238
,
238
,
238
,
1
);
borderColor
=
isSelected
?
Color
.
fromRGBO
(
64
,
158
,
255
,
1
)
:
Colors
.
transparent
;
textColor
=
Color
.
fromRGBO
(
100
,
116
,
139
,
1
);
statusTextColor
=
Color
.
fromRGBO
(
73
,
149
,
234
,
1
);
}
return
GestureDetector
(
...
...
@@ -370,14 +386,12 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
});
},
child:
Container
(
width:
50
.
w
,
height:
50
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
color:
backgroundColor
,
border:
Border
.
all
(
color:
borderColor
,
width:
isSelected
?
2
.
w
:
1
.
w
,
width:
isSelected
?
3
.
w
:
0
,
),
),
child:
Column
(
...
...
@@ -386,20 +400,35 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
Text
(
room
[
'number'
]
as
String
,
style:
TextStyle
(
fontSize:
12
.
sp
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
textColor
,
),
),
if
(
status
!=
'空闲'
)
Padding
(
padding:
EdgeInsets
.
only
(
top:
2
.
h
),
child:
Icon
(
status
==
'入住'
?
Icons
.
person
:
Icons
.
warning
,
size:
10
.
sp
,
color:
status
==
'入住'
?
Colors
.
white
:
Color
.
fromRGBO
(
246
,
158
,
11
,
1
),
),
),
SizedBox
(
height:
6
.
h
),
Builder
(
builder:
(
context
)
{
if
(
status
==
'入住'
)
{
return
Text
(
'入住'
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
statusTextColor
,
),
);
}
else
if
(
status
==
'待清洁'
)
{
return
Image
.
asset
(
"lib/assets/icon/jth.png"
,
width:
24
.
sp
,
height:
30
.
sp
,);
}
else
{
return
Text
(
' '
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
statusTextColor
,
),
);
}
},
),
],
),
),
...
...
@@ -407,97 +436,75 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
}
Widget
_buildBottomButtons
()
{
final
isRoomSelected
=
_selectedRoom
!=
null
;
return
Row
(
children:
[
Expanded
(
child:
ElevatedButton
(
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
Color
.
fromRGBO
(
34
,
197
,
94
,
1
),
minimumSize:
Size
(
double
.
infinity
,
55
.
h
),
backgroundColor:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
disabledBackgroundColor:
Color
.
fromRGBO
(
204
,
204
,
204
,
1
),
minimumSize:
Size
(
double
.
infinity
,
88
.
h
),
padding:
EdgeInsets
.
zero
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
1
5
.
r
),
borderRadius:
BorderRadius
.
circular
(
1
6
.
r
),
),
elevation:
0
,
),
onPressed:
()
{
if
(
_selectedRoom
!=
null
)
{
_controller
.
powerOnRoom
(
_selectedRoom
!);
}
else
{
_showMessage
(
'请先选择房间'
);
}
},
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Icon
(
Icons
.
power
,
color:
Colors
.
white
,
size:
20
.
sp
),
SizedBox
(
width:
8
.
w
),
Text
(
'送电'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
bold
),
),
],
onPressed:
isRoomSelected
?
()
{
_controller
.
powerOnRoom
(
_selectedRoom
!);
}
:
null
,
child:
Text
(
'送电'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
w500
),
),
),
),
SizedBox
(
width:
1
2
.
w
),
SizedBox
(
width:
1
6
.
w
),
Expanded
(
child:
ElevatedButton
(
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
Color
.
fromRGBO
(
239
,
68
,
68
,
1
),
minimumSize:
Size
(
double
.
infinity
,
55
.
h
),
backgroundColor:
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
disabledBackgroundColor:
Color
.
fromRGBO
(
204
,
204
,
204
,
1
),
minimumSize:
Size
(
double
.
infinity
,
88
.
h
),
padding:
EdgeInsets
.
zero
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
15
.
r
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
side:
BorderSide
(
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
width:
1
.
w
,
),
),
elevation:
0
,
),
onPressed:
()
{
if
(
_selectedRoom
!=
null
)
{
_controller
.
powerOffRoom
(
_selectedRoom
!);
}
else
{
_showMessage
(
'请先选择房间'
);
}
},
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Icon
(
Icons
.
power_off
,
color:
Colors
.
white
,
size:
20
.
sp
),
SizedBox
(
width:
8
.
w
),
Text
(
'断电'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
bold
),
),
],
onPressed:
isRoomSelected
?
()
{
_controller
.
powerOffRoom
(
_selectedRoom
!);
}
:
null
,
child:
Text
(
'断电'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
fontWeight:
FontWeight
.
w500
),
),
),
),
SizedBox
(
width:
1
2
.
w
),
SizedBox
(
width:
1
6
.
w
),
Expanded
(
child:
ElevatedButton
(
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
minimumSize:
Size
(
double
.
infinity
,
55
.
h
),
backgroundColor:
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
disabledBackgroundColor:
Color
.
fromRGBO
(
204
,
204
,
204
,
1
),
minimumSize:
Size
(
double
.
infinity
,
88
.
h
),
padding:
EdgeInsets
.
zero
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
1
5
.
r
),
borderRadius:
BorderRadius
.
circular
(
1
6
.
r
),
),
elevation:
0
,
),
onPressed:
()
{
if
(
_selectedRoom
!=
null
)
{
_controller
.
viewRoom
(
_selectedRoom
!);
}
else
{
_showMessage
(
'请先选择房间'
);
}
},
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Icon
(
Icons
.
settings
,
color:
Colors
.
white
,
size:
20
.
sp
),
SizedBox
(
width:
8
.
w
),
Text
(
'查看'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
bold
),
),
],
onPressed:
isRoomSelected
?
()
{
_controller
.
viewRoom
(
_selectedRoom
!);
}
:
null
,
child:
Text
(
'查看'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
fontWeight:
FontWeight
.
w500
),
),
),
),
...
...
lib/views/service/index/child/service_head_block.dart
View file @
165f6cbb
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/service/index/controller.dart'
;
class
ServiceHeadBlock
extends
StatefulWidget
{
const
ServiceHeadBlock
({
super
.
key
});
...
...
@@ -9,80 +10,65 @@ class ServiceHeadBlock extends StatefulWidget {
}
class
_ServiceHeadBlockState
extends
State
<
ServiceHeadBlock
>
{
late
final
ServiceIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ServiceIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
pendingCount
=
_controller
.
getPendingCount
();
return
Container
(
width:
double
.
infinity
,
height:
140
.
h
,
padding:
EdgeInsets
.
only
(
top:
ScreenUtil
().
statusBarHeight
,
left:
20
.
w
,
right:
20
.
w
),
decoration:
BoxDecoration
(
border:
Border
(
bottom:
BorderSide
(
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
width:
1
.
w
,
),
),
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
padding:
EdgeInsets
.
only
(
top:
ScreenUtil
().
statusBarHeight
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Flex
(
direction:
Axis
.
horizontal
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Container
(
width:
4
.
w
,
height:
20
.
h
,
decoration:
BoxDecoration
(
color:
Color
.
fromRGBO
(
239
,
68
,
68
,
1
),
borderRadius:
BorderRadius
.
circular
(
2
.
r
),
),
),
SizedBox
(
width:
10
.
w
),
Text
(
'客房服务看板'
,
style:
TextStyle
(
fontSize:
24
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
],
),
SizedBox
(
height:
8
.
h
),
Text
(
'服务员视角 · 2条待响应需求'
,
style:
TextStyle
(
fontSize:
16
.
sp
,
color:
Color
.
fromRGBO
(
61
,
79
,
106
,
1.0
),
),
),
],
),
Container
(
width:
50
.
w
,
height:
50
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
25
.
r
),
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
71
,
85
,
105
,
1
),
width:
1
.
w
,
),
Text
(
'客房服务看板'
,
style:
TextStyle
(
fontSize:
40
.
sp
,
fontWeight:
FontWeight
.
w200
,
color:
Color
.
fromRGBO
(
10
,
13
,
20
,
1
),
),
child:
Icon
(
Icons
.
person
,
color:
Colors
.
white
,
size:
24
.
sp
,
),
SizedBox
(
height:
8
.
h
),
Text
(
'服务员视角·
$pendingCount
条待响应需求'
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
],
),
Container
(
width:
64
.
w
,
height:
64
.
h
,
margin:
EdgeInsets
.
only
(
top:
5
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
48
.
r
),
color:
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
border:
Border
.
all
(
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
width:
1
.
w
,
),
),
child:
Image
.
asset
(
"lib/assets/icon/person1.png"
,
width:
38
.
w
,
height:
38
.
h
),
// Icon(
// Icons.person,
// color: Color.fromRGBO(64, 158, 255, 1),
// size: 26.sp,
// ),
),
],
),
);
...
...
lib/views/service/index/child/service_stats_block.dart
View file @
165f6cbb
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/service/index/controller.dart'
;
class
ServiceStatsBlock
extends
StatefulWidget
{
const
ServiceStatsBlock
({
super
.
key
});
...
...
@@ -9,34 +10,45 @@ class ServiceStatsBlock extends StatefulWidget {
}
class
_ServiceStatsBlockState
extends
State
<
ServiceStatsBlock
>
{
late
final
ServiceIndexController
_controller
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ServiceIndexController
(
context
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
pendingCount
=
_controller
.
getPendingCount
();
final
occupiedCount
=
_controller
.
getOccupiedRooms
();
final
vacantCount
=
_controller
.
getVacantRooms
();
return
Container
(
width:
double
.
infinity
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
,
vertical:
20
.
h
),
child:
Row
(
children:
[
Expanded
(
child:
_buildStatCard
(
'2'
,
pendingCount
.
toString
()
,
'待响应'
,
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
),
SizedBox
(
width:
12
.
w
),
Expanded
(
child:
_buildStatCard
(
'45'
,
occupiedCount
.
toString
()
,
'入住中'
,
Color
.
fromRGBO
(
34
,
197
,
94
,
1
),
Color
.
fromRGBO
(
20
,
184
,
166
,
1
),
),
),
SizedBox
(
width:
12
.
w
),
Expanded
(
child:
_buildStatCard
(
'7'
,
vacantCount
.
toString
()
,
'空闲可清洁'
,
Color
s
.
white
,
Color
.
fromRGBO
(
10
,
13
,
20
,
1
)
,
),
),
],
...
...
@@ -48,25 +60,32 @@ class _ServiceStatsBlockState extends State<ServiceStatsBlock> {
return
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
20
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
30
,
41
,
59
,
1
),
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
color:
Colors
.
white
,
boxShadow:
[
BoxShadow
(
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
0.05
),
blurRadius:
10
.
r
,
offset:
Offset
(
0
,
2
),
),
],
),
child:
Column
(
children:
[
Text
(
value
,
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
60
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
valueColor
,
),
),
SizedBox
(
height:
8
.
h
),
// SizedBox(height: 5
.h),
Text
(
label
,
style:
TextStyle
(
fontSize:
1
4
.
sp
,
color:
Color
s
.
grey
,
fontSize:
2
4
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)
,
),
),
],
...
...
lib/views/service/index/index_view.dart
View file @
165f6cbb
...
...
@@ -34,10 +34,12 @@ class _ServiceIndexViewState extends State<ServiceIndexView> {
),
child:
Container
(
width:
double
.
infinity
,
color:
Color
.
fromRGBO
(
15
,
23
,
42
,
1
),
color:
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
children:
[
ServiceHeadBlock
(),
SizedBox
(
height:
10
.
h
),
ServiceStatsBlock
(),
SizedBox
(
height:
10
.
h
),
RoomManagementBlock
(),
...
...
lib/views/service/room/child/bottom_operation_block.dart
0 → 100644
View file @
165f6cbb
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
class
BottomOperationBlock
extends
StatefulWidget
{
const
BottomOperationBlock
({
super
.
key
});
@override
State
<
BottomOperationBlock
>
createState
()
=>
_BottomOperationBlockState
();
}
class
_BottomOperationBlockState
extends
State
<
BottomOperationBlock
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
Row
(
children:
[
Expanded
(
child:
_buildOperationButton
(
'送电'
,
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
Colors
.
white
,
null
,
),
),
SizedBox
(
width:
16
.
w
),
Expanded
(
child:
_buildOperationButton
(
'断电'
,
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
BorderSide
(
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
width:
1
.
w
,
),
),
),
SizedBox
(
width:
16
.
w
),
Expanded
(
child:
_buildOperationButton
(
'设备控制'
,
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
null
,
),
),
],
);
}
Widget
_buildOperationButton
(
String
text
,
Color
backgroundColor
,
Color
textColor
,
BorderSide
?
borderSide
,
)
{
return
ElevatedButton
(
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
backgroundColor
,
minimumSize:
Size
(
double
.
infinity
,
88
.
h
),
padding:
EdgeInsets
.
zero
,
shape:
borderSide
!=
null
?
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
side:
borderSide
,
)
:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
),
elevation:
0
,
),
onPressed:
()
{},
child:
Text
(
text
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
textColor
,
fontWeight:
FontWeight
.
w500
,
),
),
);
}
}
lib/views/service/room/child/device_control_block.dart
0 → 100644
View file @
165f6cbb
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:flutter_switch/flutter_switch.dart'
;
import
'package:smart_hotel_app/views/service/room/controller.dart'
;
class
DeviceControlBlock
extends
StatefulWidget
{
const
DeviceControlBlock
({
super
.
key
});
@override
State
<
DeviceControlBlock
>
createState
()
=>
_DeviceControlBlockState
();
}
class
_DeviceControlBlockState
extends
State
<
DeviceControlBlock
>
{
late
final
ServiceRoomController
_controller
;
late
bool
_mainPowerOn
;
late
List
<
bool
>
_devicePowerStates
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ServiceRoomController
(
context
);
_mainPowerOn
=
_controller
.
getMainPowerOn
();
final
deviceControls
=
_controller
.
getDeviceControls
();
_devicePowerStates
=
deviceControls
.
map
((
d
)
=>
d
[
'isOn'
]
as
bool
).
toList
();
}
@override
Widget
build
(
BuildContext
context
)
{
final
deviceControls
=
_controller
.
getDeviceControls
();
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
'设备控制'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
1
),
fontWeight:
FontWeight
.
bold
,
),
),
SizedBox
(
height:
20
.
h
),
Container
(
width:
double
.
infinity
,
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
color:
Colors
.
white
,
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
_buildMainPowerControl
(),
SizedBox
(
height:
20
.
h
),
_buildDivider
(),
SizedBox
(
height:
20
.
h
),
_buildSubDeviceTitle
(),
SizedBox
(
height:
20
.
h
),
...
deviceControls
.
asMap
().
entries
.
map
((
entry
)
{
final
index
=
entry
.
key
;
final
device
=
entry
.
value
;
return
Column
(
children:
[
_buildDeviceControlItem
(
device
,
index
),
if
(
index
<
deviceControls
.
length
-
1
)
SizedBox
(
height:
20
.
h
),
if
(
index
<
deviceControls
.
length
-
1
)
_buildDivider
(),
if
(
index
<
deviceControls
.
length
-
1
)
SizedBox
(
height:
20
.
h
),
],
);
}).
toList
(),
],
),
),
],
);
}
Widget
_buildMainPowerControl
()
{
return
Row
(
children:
[
Container
(
width:
60
.
w
,
height:
60
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
color:
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
),
child:
Icon
(
Icons
.
power_settings_new_outlined
,
size:
36
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
),
SizedBox
(
width:
16
.
w
),
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
'房间总电源'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
1
),
fontWeight:
FontWeight
.
bold
,
),
),
SizedBox
(
height:
4
.
h
),
Text
(
'控制整个房间供电'
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
],
),
),
FlutterSwitch
(
value:
_mainPowerOn
,
onToggle:
(
value
)
{
setState
(()
{
_mainPowerOn
=
value
;
});
},
width:
60
.
w
,
height:
30
.
h
,
toggleSize:
26
.
sp
,
borderRadius:
16
.
r
,
padding:
3
.
r
,
activeColor:
Color
.
fromRGBO
(
80
,
162
,
255
,
1
),
inactiveColor:
Color
.
fromRGBO
(
200
,
200
,
200
,
1
),
toggleColor:
Colors
.
white
,
),
],
);
}
Widget
_buildDivider
()
{
return
Container
(
height:
1
.
h
,
color:
Color
.
fromRGBO
(
229
,
231
,
235
,
1
),
);
}
Widget
_buildSubDeviceTitle
()
{
return
Text
(
'分设备控制'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
1
),
fontWeight:
FontWeight
.
bold
,
),
);
}
Widget
_buildDeviceControlItem
(
Map
<
String
,
dynamic
>
device
,
int
index
)
{
return
Row
(
children:
[
Icon
(
device
[
'icon'
]
as
IconData
,
size:
40
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
SizedBox
(
width:
16
.
w
),
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
device
[
'name'
]
as
String
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
1
),
),
),
if
(
device
[
'status'
]
!=
null
)
...[
SizedBox
(
height:
4
.
h
),
Text
(
device
[
'status'
]
as
String
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
],
],
),
),
FlutterSwitch
(
value:
_devicePowerStates
[
index
],
onToggle:
(
value
)
{
setState
(()
{
_devicePowerStates
[
index
]
=
value
;
});
},
width:
60
.
w
,
height:
30
.
h
,
toggleSize:
26
.
sp
,
borderRadius:
16
.
r
,
padding:
3
.
r
,
activeColor:
Color
.
fromRGBO
(
80
,
162
,
255
,
1
),
inactiveColor:
Color
.
fromRGBO
(
200
,
200
,
200
,
1
),
toggleColor:
Colors
.
white
,
),
],
);
}
}
lib/views/service/room/child/room_info_block.dart
View file @
165f6cbb
...
...
@@ -3,123 +3,240 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import
'package:smart_hotel_app/views/service/room/controller.dart'
;
class
RoomInfoBlock
extends
StatefulWidget
{
final
ServiceRoomController
controller
;
const
RoomInfoBlock
({
super
.
key
,
required
this
.
controller
,
});
const
RoomInfoBlock
({
super
.
key
});
@override
State
<
RoomInfoBlock
>
createState
()
=>
_RoomInfoBlockState
();
}
class
_RoomInfoBlockState
extends
State
<
RoomInfoBlock
>
{
@override
Widget
build
(
BuildContext
context
)
{
final
roomDetail
=
widget
.
controller
.
getRoomDetail
();
final
guestName
=
roomDetail
[
'guestName'
]
as
String
?;
final
checkInDate
=
roomDetail
[
'checkInDate'
]
as
String
?;
final
checkOutDate
=
roomDetail
[
'checkOutDate'
]
as
String
?;
final
status
=
roomDetail
[
'status'
]
as
String
;
late
final
ServiceRoomController
_controller
;
Color
statusColor
;
Color
statusBgColor
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
ServiceRoomController
(
context
);
}
switch
(
status
)
{
case
'入住中'
:
statusColor
=
Color
.
fromRGBO
(
59
,
130
,
246
,
1
);
statusBgColor
=
Color
.
fromRGBO
(
59
,
130
,
246
,
0.2
);
break
;
case
'待清洁'
:
statusColor
=
Color
.
fromRGBO
(
246
,
158
,
11
,
1
);
statusBgColor
=
Color
.
fromRGBO
(
246
,
158
,
11
,
0.2
);
break
;
case
'空闲'
:
default
:
statusColor
=
Color
.
fromRGBO
(
34
,
197
,
94
,
1
);
statusBgColor
=
Color
.
fromRGBO
(
34
,
197
,
94
,
0.2
);
break
;
}
@override
Widget
build
(
BuildContext
context
)
{
final
roomDetail
=
_controller
.
getRoomDetail
();
final
roomStatus
=
_controller
.
getRoomStatus
();
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
,
),
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
color:
Colors
.
white
,
),
child:
Row
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Container
(
width:
80
.
w
,
height:
80
.
w
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
color:
Color
.
fromRGBO
(
51
,
65
,
85
,
1
),
),
child:
Icon
(
Icons
.
bed
,
color:
statusColor
,
size:
40
.
sp
,
),
_buildRoomHeader
(
roomDetail
),
SizedBox
(
height:
20
.
h
),
_buildStatusTags
(
roomStatus
),
SizedBox
(
height:
20
.
h
),
_buildDivider
(),
SizedBox
(
height:
20
.
h
),
_buildDeviceStatusTitle
(),
SizedBox
(
height:
20
.
h
),
_buildDeviceGrid
(),
],
),
);
}
Widget
_buildRoomHeader
(
Map
<
String
,
dynamic
>
roomDetail
)
{
return
Row
(
children:
[
Container
(
width:
64
.
w
,
height:
66
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
color:
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
),
SizedBox
(
width:
20
.
w
),
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Text
(
roomDetail
[
'roomNumber'
]
as
String
,
style:
TextStyle
(
fontSize:
24
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
),
SizedBox
(
width:
15
.
w
),
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
.
w
,
vertical:
5
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
color:
statusBgColor
,
),
child:
Text
(
status
,
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
statusColor
,
fontWeight:
FontWeight
.
w500
,
),
),
),
],
),
SizedBox
(
height:
10
.
h
),
if
(
guestName
!=
null
&&
checkInDate
!=
null
&&
checkOutDate
!=
null
)
child:
Icon
(
Icons
.
bed_outlined
,
size:
36
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
),
SizedBox
(
width:
16
.
w
),
Expanded
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Text
(
'
$guestName
·
$checkInDate
-
$checkOutDate
·
${roomDetail['roomType']}
'
,
roomDetail
[
'roomNumber'
]
as
String
,
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
Colors
.
grey
,
fontSize:
32
.
sp
,
color:
Colors
.
black
,
fontWeight:
FontWeight
.
bold
,
),
)
else
)
,
SizedBox
(
width:
12
.
w
),
Text
(
roomDetail
[
'
roomType
'
]
as
String
,
roomDetail
[
'
status
'
]
as
String
,
style:
TextStyle
(
fontSize:
1
4
.
sp
,
color:
Color
s
.
grey
,
fontSize:
2
4
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
)
,
),
),
],
],
),
SizedBox
(
height:
6
.
h
),
Text
(
_buildGuestInfo
(
roomDetail
),
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
],
),
),
],
);
}
String
_buildGuestInfo
(
Map
<
String
,
dynamic
>
roomDetail
)
{
final
guestName
=
roomDetail
[
'guestName'
]
as
String
?;
final
checkInDate
=
roomDetail
[
'checkInDate'
]
as
String
?;
final
checkOutDate
=
roomDetail
[
'checkOutDate'
]
as
String
?;
final
roomType
=
roomDetail
[
'roomType'
]
as
String
;
if
(
guestName
!=
null
&&
checkInDate
!=
null
&&
checkOutDate
!=
null
)
{
return
'
$guestName
·
$checkInDate
-
$checkOutDate
·
$roomType
'
;
}
return
roomType
;
}
Widget
_buildStatusTags
(
Map
<
String
,
dynamic
>
roomStatus
)
{
return
Wrap
(
spacing:
12
.
w
,
children:
[
_buildStatusTag
(
'有人'
,
roomStatus
[
'hasGuest'
]
as
bool
,
),
_buildStatusTag
(
'通电中'
,
roomStatus
[
'powerOn'
]
as
bool
,
),
_buildStatusTag
(
'wifi正常'
,
roomStatus
[
'wifiNormal'
]
as
bool
,
),
],
);
}
Widget
_buildStatusTag
(
String
text
,
bool
isActive
)
{
return
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
8
.
h
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
color:
Color
.
fromRGBO
(
20
,
184
,
166
,
0.2
),
),
child:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Icon
(
Icons
.
check
,
size:
20
.
sp
,
color:
Color
.
fromRGBO
(
16
,
185
,
129
,
1
),
),
SizedBox
(
width:
6
.
w
),
Text
(
text
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
Color
.
fromRGBO
(
20
,
184
,
166
,
1
),
),
),
],
),
);
}
Widget
_buildDivider
()
{
return
Container
(
height:
1
.
h
,
color:
Color
.
fromRGBO
(
229
,
231
,
235
,
1
),
);
}
Widget
_buildDeviceStatusTitle
()
{
return
Text
(
'房间设备状态'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
0
,
0
,
0
,
1
),
fontWeight:
FontWeight
.
bold
,
),
);
}
Widget
_buildDeviceGrid
()
{
final
devices
=
_controller
.
getDevices
();
return
GridView
.
builder
(
shrinkWrap:
true
,
physics:
NeverScrollableScrollPhysics
(),
padding:
EdgeInsets
.
zero
,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
2
,
crossAxisSpacing:
16
.
w
,
mainAxisSpacing:
16
.
h
,
childAspectRatio:
2.2
,
),
itemCount:
devices
.
length
,
itemBuilder:
(
context
,
index
)
{
return
_buildDeviceItem
(
devices
[
index
]);
},
);
}
Widget
_buildDeviceItem
(
Map
<
String
,
dynamic
>
device
)
{
return
Container
(
padding:
EdgeInsets
.
all
(
20
.
w
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
color:
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Row
(
children:
[
Icon
(
device
[
'icon'
]
as
IconData
,
size:
32
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
SizedBox
(
width:
10
.
w
),
Text
(
device
[
'name'
]
as
String
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
fontWeight:
FontWeight
.
bold
,
),
),
],
),
SizedBox
(
height:
10
.
h
),
Text
(
device
[
'status'
]
as
String
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
(
device
[
'isOn'
]
as
bool
)
?
Color
.
fromRGBO
(
20
,
184
,
166
,
1
)
:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
],
...
...
lib/views/service/room/child/room_status_block.dart
deleted
100644 → 0
View file @
e12f65bf
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 @
165f6cbb
...
...
@@ -48,4 +48,68 @@ class ServiceRoomController {
'wifiSignal'
:
'-45dBm'
,
};
}
bool
getMainPowerOn
()
{
final
num
=
roomNumber
??
'302'
;
final
numInt
=
int
.
tryParse
(
num
)
??
302
;
return
numInt
%
2
==
0
;
}
List
<
Map
<
String
,
dynamic
>>
getDevices
()
{
final
num
=
roomNumber
??
'302'
;
final
numInt
=
int
.
tryParse
(
num
)
??
302
;
return
[
{
'name'
:
'空调'
,
'icon'
:
Icons
.
air_outlined
,
'status'
:
'24°C·开'
,
'isOn'
:
true
,
},
{
'name'
:
'照明'
,
'icon'
:
Icons
.
light_outlined
,
'status'
:
'关'
,
'isOn'
:
false
,
},
{
'name'
:
'电视'
,
'icon'
:
Icons
.
tv_outlined
,
'status'
:
'开'
,
'isOn'
:
true
,
},
{
'name'
:
'窗帘'
,
'icon'
:
Icons
.
curtains_closed_outlined
,
'status'
:
'关'
,
'isOn'
:
false
,
},
];
}
List
<
Map
<
String
,
dynamic
>>
getDeviceControls
()
{
final
num
=
roomNumber
??
'302'
;
final
numInt
=
int
.
tryParse
(
num
)
??
302
;
return
[
{
'name'
:
'空调'
,
'icon'
:
Icons
.
air_outlined
,
'status'
:
'当前:制冷24°C·风速:自动'
,
'isOn'
:
true
,
},
{
'name'
:
'主照明'
,
'icon'
:
Icons
.
light_outlined
,
'status'
:
null
,
'isOn'
:
false
,
},
{
'name'
:
'电视'
,
'icon'
:
Icons
.
tv_outlined
,
'status'
:
null
,
'isOn'
:
true
,
},
];
}
}
\ No newline at end of file
lib/views/service/room/room_detail_view.dart
View file @
165f6cbb
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:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/views/service/room/controller.dart'
;
import
'package:smart_hotel_app/views/service/room/child/room_info_block.dart'
;
import
'package:smart_hotel_app/views/service/room/child/device_control_block.dart'
;
import
'package:smart_hotel_app/views/service/room/child/bottom_operation_block.dart'
;
@RoutePage
()
class
ServiceRoomDetailView
extends
StatefulWidget
{
...
...
@@ -28,32 +29,38 @@ class _ServiceRoomDetailViewState extends State<ServiceRoomDetailView> {
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
backgroundColor:
Color
.
fromRGBO
(
15
,
23
,
42
,
1
),
backgroundColor:
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
appBar:
AppBar
(
backgroundColor:
Color
.
fromRGBO
(
15
,
23
,
42
,
1
)
,
backgroundColor:
Color
s
.
white
,
elevation:
0
,
leading:
IconButton
(
icon:
Icon
(
Icons
.
arrow_back
,
color:
Colors
.
white
),
icon:
Icon
(
Icons
.
arrow_back
_ios
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
onPressed:
()
{
context
.
popRoute
();
},
),
title:
Text
(
'
${widget.roomNumber ?? '客房'}
详情'
,
// '${widget.roomNumber ?? '客房'}详情',
'客房详情'
,
style:
TextStyle
(
color:
Color
s
.
white
,
fontSize:
18
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Color
.
fromRGBO
(
10
,
13
,
20
,
1
)
,
fontSize:
32
.
sp
,
fontWeight:
FontWeight
.
w200
,
),
),
centerTitle:
true
,
),
body:
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
children:
[
SizedBox
(
height:
20
.
h
),
RoomInfoBlock
(),
SizedBox
(
height:
20
.
h
),
DeviceControlBlock
(),
SizedBox
(
height:
20
.
h
),
BottomOperationBlock
(),
SizedBox
(
height:
20
.
h
),
RoomInfoBlock
(
controller:
_controller
),
RoomStatusBlock
(
controller:
_controller
),
],
),
),
...
...
pubspec.lock
View file @
165f6cbb
...
...
@@ -350,6 +350,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.2"
flutter_switch:
dependency: "direct main"
description:
name: flutter_switch
sha256: b91477f926bba135d2d203d7b24367492662d8d9c3aa6adb960b14c1087d3c41
url: "https://pub.dev"
source: hosted
version: "0.3.2"
flutter_test:
dependency: "direct dev"
description: flutter
...
...
pubspec.yaml
View file @
165f6cbb
...
...
@@ -44,6 +44,7 @@ dependencies:
fluttertoast
:
^8.2.5
loading_animation_widget
:
^1.3.0
fl_chart
:
^1.2.0
flutter_switch
:
^0.3.2
dev_dependencies
:
flutter_test
:
...
...
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