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
e9fe298f
Commit
e9fe298f
authored
Jun 12, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
11
parent
9db068bb
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
277 additions
and
164 deletions
+277
-164
main.dart
lib/main.dart
+2
-6
inspection_device_repository.dart
lib/repositories/inspection_device_repository.dart
+8
-2
inspection_device_service.dart
lib/services/inspection_device_service.dart
+6
-1
toast_utils.dart
lib/utils/toast_utils.dart
+16
-0
abnormal_detail_view.dart
lib/views/home/abnormal/abnormal_detail_view.dart
+3
-6
device_state.dart
lib/views/home/device/cubit/device_state.dart
+42
-8
device_detail_view.dart
lib/views/home/device/device_detail_view.dart
+6
-7
index_view.dart
lib/views/home/index/index_view.dart
+1
-0
temperature_block.dart
lib/views/home/index/widget/temperature_block.dart
+3
-6
voltage_operate_block.dart
lib/views/home/index/widget/voltage_operate_block.dart
+3
-6
inspection_cubit.dart
lib/views/home/inspection/cubit/inspection_cubit.dart
+68
-10
inspection_state.dart
lib/views/home/inspection/cubit/inspection_state.dart
+27
-0
inspection_detail_view.dart
lib/views/home/inspection/inspection_detail_view.dart
+9
-3
filter_panel.dart
lib/views/home/inspection/widget/filter_panel.dart
+60
-66
start_inspection_button.dart
...ome/inspection_device/widget/start_inspection_button.dart
+2
-3
room_report_cubit.dart
lib/views/report/room/cubit/room_report_cubit.dart
+1
-1
room_management_block.dart
lib/views/service/index/widget/room_management_block.dart
+5
-12
room_detail_view.dart
lib/views/service/room/room_detail_view.dart
+8
-21
pubspec.lock
pubspec.lock
+4
-4
pubspec.yaml
pubspec.yaml
+1
-1
对接方案.md
对接方案.md
+2
-1
No files found.
lib/main.dart
View file @
e9fe298f
...
...
@@ -10,6 +10,7 @@ import 'package:smart_hotel_app/services/auth_service.dart';
import
'package:smart_hotel_app/utils/http/dio_request.dart'
;
import
'package:smart_hotel_app/utils/event_bus.dart'
;
import
'package:smart_hotel_app/utils/storage/storage_service.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
...
...
@@ -98,12 +99,7 @@ class _MyAppState extends State<MyApp> {
_appRouter
.
replaceAll
([
const
DefaultLayoutRoute
()]);
}
if
(
state
is
AuthTokenExpired
)
{
_scaffoldMessengerKey
.
currentState
?.
showSnackBar
(
const
SnackBar
(
content:
Text
(
'登录已过期,请重新登录'
),
backgroundColor:
Colors
.
red
,
),
);
showToast
(
'登录已过期,请重新登录'
);
_appRouter
.
replaceAll
([
LoginRoute
()]);
}
if
(
state
is
AuthLoggedOut
)
{
...
...
lib/repositories/inspection_device_repository.dart
View file @
e9fe298f
...
...
@@ -6,11 +6,17 @@ class InspectionDeviceRepository {
Future
<
ResponseModel
<
InspectionDeviceListBO
>>
getList
({
required
int
pageSize
,
required
int
pageNum
,
int
?
roomId
int
?
roomId
,
String
?
runStatus
,
})
{
return
DioRequest
.
instance
.
get
<
InspectionDeviceListBO
>(
'/app/device/inspection'
,
queryParameters:
{
'pageSize'
:
pageSize
,
'pageNum'
:
pageNum
,
"roomId"
:
roomId
},
queryParameters:
{
'pageSize'
:
pageSize
,
'pageNum'
:
pageNum
,
'roomId'
:
roomId
,
'runStatus'
:
runStatus
,
},
fromJsonT:
(
data
)
=>
InspectionDeviceListBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
...
...
lib/services/inspection_device_service.dart
View file @
e9fe298f
...
...
@@ -11,9 +11,14 @@ class InspectionDeviceService {
required
int
pageSize
,
required
int
pageNum
,
int
?
roomId
,
String
?
runStatus
,
})
async
{
final
result
=
await
_repository
.
getList
(
pageSize:
pageSize
,
pageNum:
pageNum
,
roomId:
roomId
);
pageSize:
pageSize
,
pageNum:
pageNum
,
roomId:
roomId
,
runStatus:
runStatus
,
);
if
(
result
.
success
&&
result
.
data
!=
null
)
{
return
result
.
data
!;
}
...
...
lib/utils/toast_utils.dart
0 → 100644
View file @
e9fe298f
import
'dart:ui'
;
import
'package:fluttertoast/fluttertoast.dart'
;
void
showToast
(
String
msg
)
{
Fluttertoast
.
showToast
(
msg:
msg
,
toastLength:
Toast
.
LENGTH_SHORT
,
gravity:
ToastGravity
.
CENTER
,
timeInSecForIosWeb:
2
,
backgroundColor:
const
Color
(
0xDD000000
),
textColor:
const
Color
(
0xFFFFFFFF
),
fontSize:
16.0
,
);
}
\ No newline at end of file
lib/views/home/abnormal/abnormal_detail_view.dart
View file @
e9fe298f
...
...
@@ -8,6 +8,7 @@ import 'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_state.dart';
import
'package:smart_hotel_app/views/home/abnormal/widget/alarm_info_block.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/widget/temperature_block.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/widget/temperature_char_block.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
@RoutePage
()
class
AbnormalDetailView
extends
StatelessWidget
{
...
...
@@ -169,15 +170,11 @@ class AbnormalDetailView extends StatelessWidget {
try
{
await
cubit
.
handleConfirm
();
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'操作成功'
)),
);
showToast
(
'操作成功'
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'操作失败:
$e
'
)),
);
showToast
(
'操作失败:
$e
'
);
}
}
}
...
...
lib/views/home/device/cubit/device_state.dart
View file @
e9fe298f
class
DeviceInfo
{
import
'package:equatable/equatable.dart'
;
class
DeviceInfo
extends
Equatable
{
final
String
deviceName
;
final
String
deviceId
;
final
String
location
;
...
...
@@ -22,9 +24,26 @@ class DeviceInfo {
required
this
.
powerData
,
required
this
.
tempData
,
});
@override
List
<
Object
?>
get
props
=>
[
deviceName
,
deviceId
,
location
,
status
,
voltage
,
current
,
power
,
temperature
,
powerData
,
tempData
,
];
}
class
DeviceState
{
/// copyWith 中用作 "未传参" 哨兵,区分 "保持原值" 和 "显式设为 null"。
const
Object
_unset
=
Object
();
class
DeviceState
extends
Equatable
{
final
bool
isLoading
;
final
String
?
error
;
final
DeviceInfo
?
deviceInfo
;
...
...
@@ -43,19 +62,33 @@ class DeviceState {
DeviceState
copyWith
({
bool
?
isLoading
,
String
?
error
,
DeviceInfo
?
deviceInfo
,
Object
?
error
=
_unset
,
Object
?
deviceInfo
=
_unset
,
bool
?
isPoweringOn
,
bool
?
isPoweringOff
,
String
?
operationMessage
,
Object
?
operationMessage
=
_unset
,
})
{
return
DeviceState
(
isLoading:
isLoading
??
this
.
isLoading
,
error:
error
??
this
.
error
,
deviceInfo:
deviceInfo
??
this
.
deviceInfo
,
error:
identical
(
error
,
_unset
)
?
this
.
error
:
error
as
String
?,
deviceInfo:
identical
(
deviceInfo
,
_unset
)
?
this
.
deviceInfo
:
deviceInfo
as
DeviceInfo
?,
isPoweringOn:
isPoweringOn
??
this
.
isPoweringOn
,
isPoweringOff:
isPoweringOff
??
this
.
isPoweringOff
,
operationMessage:
operationMessage
??
this
.
operationMessage
,
operationMessage:
identical
(
operationMessage
,
_unset
)
?
this
.
operationMessage
:
operationMessage
as
String
?,
);
}
@override
List
<
Object
?>
get
props
=>
[
isLoading
,
error
,
deviceInfo
,
isPoweringOn
,
isPoweringOff
,
operationMessage
,
];
}
\ No newline at end of file
lib/views/home/device/device_detail_view.dart
View file @
e9fe298f
...
...
@@ -7,6 +7,7 @@ import 'package:smart_hotel_app/views/home/device/cubit/device_state.dart';
import
'package:smart_hotel_app/views/home/device/widget/device_parms_block.dart'
;
import
'package:smart_hotel_app/views/home/device/widget/power_char_block.dart'
;
import
'package:smart_hotel_app/views/home/device/widget/state_info_block.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
@RoutePage
()
class
DeviceDetailView
extends
StatelessWidget
{
...
...
@@ -19,14 +20,12 @@ class DeviceDetailView extends StatelessWidget {
return
BlocProvider
(
create:
(
_
)
=>
DeviceCubit
(
deviceId:
deviceId
),
child:
BlocListener
<
DeviceCubit
,
DeviceState
>(
listenWhen:
(
prev
,
curr
)
=>
curr
.
operationMessage
!=
null
&&
prev
.
operationMessage
!=
curr
.
operationMessage
,
listener:
(
context
,
state
)
{
final
message
=
state
.
operationMessage
;
if
(
message
!=
null
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
message
)),
);
context
.
read
<
DeviceCubit
>().
clearOperationMessage
();
}
showToast
(
state
.
operationMessage
!);
context
.
read
<
DeviceCubit
>().
clearOperationMessage
();
},
child:
Scaffold
(
backgroundColor:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
...
...
lib/views/home/index/index_view.dart
View file @
e9fe298f
...
...
@@ -106,6 +106,7 @@ class _HomeViewState extends State<HomeView> with AutoRouteAwareStateMixin<HomeV
]);
case
'voltage'
:
case
'current'
:
case
'device'
:
case
'power'
:
blocks
.
addAll
([
SizedBox
(
height:
20
.
h
),
...
...
lib/views/home/index/widget/temperature_block.dart
View file @
e9fe298f
...
...
@@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import
'package:smart_hotel_app/repositories/alert_detail_repository.dart'
;
import
'package:smart_hotel_app/services/alert_detail_service.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
class
TemperatureBlock
extends
StatelessWidget
{
final
int
alertId
;
...
...
@@ -339,16 +340,12 @@ class TemperatureBlock extends StatelessWidget {
AlertDetailService
(
repository:
AlertDetailRepository
());
await
service
.
handleAlert
(
alertId:
alertId
);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'操作成功'
)),
);
showToast
(
'操作成功'
);
context
.
read
<
HomeIndexCubit
>().
reloadDashboard
();
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'操作失败:
$e
'
)),
);
showToast
(
'操作失败:
$e
'
);
}
}
}
...
...
lib/views/home/index/widget/voltage_operate_block.dart
View file @
e9fe298f
...
...
@@ -6,6 +6,7 @@ import 'package:smart_hotel_app/repositories/alert_detail_repository.dart';
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:smart_hotel_app/services/alert_detail_service.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
class
VoltageOperateBlock
extends
StatelessWidget
{
final
int
alertId
;
...
...
@@ -278,16 +279,12 @@ class VoltageOperateBlock extends StatelessWidget {
AlertDetailService
(
repository:
AlertDetailRepository
());
await
service
.
handleAlert
(
alertId:
alertId
);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'操作成功'
)),
);
showToast
(
'操作成功'
);
context
.
read
<
HomeIndexCubit
>().
reloadDashboard
();
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'操作失败:
$e
'
)),
);
showToast
(
'操作失败:
$e
'
);
}
}
}
...
...
lib/views/home/inspection/cubit/inspection_cubit.dart
View file @
e9fe298f
...
...
@@ -10,7 +10,10 @@ class InspectionCubit extends Cubit<InspectionState> {
final
InspectionRoomService
_roomService
;
final
InspectionDeviceService
_deviceService
;
static
const
int
_pageSize
=
20
;
static
const
int
pageSize
=
20
;
/// 完整房间列表缓存,用于在切换 Tab 时按 runStatus 重新过滤
List
<
InspectionRoomBO
>
_allRoomsRaw
=
const
[];
InspectionCubit
({
InspectionRoomService
?
roomService
,
...
...
@@ -27,19 +30,21 @@ class InspectionCubit extends Cubit<InspectionState> {
Future
<
void
>
initData
()
async
{
try
{
final
rooms
=
await
_roomService
.
getRooms
();
final
roomsMap
=
<
int
,
String
>{};
for
(
final
r
in
rooms
)
{
roomsMap
[
r
.
roomId
]
=
r
.
roomNumber
;
}
_allRoomsRaw
=
rooms
;
final
tabCounts
=
_computeTabCounts
(
rooms
);
final
filteredRooms
=
_filterRooms
(
rooms
,
state
.
selectedTab
);
final
firstRoomIds
=
rooms
.
isNotEmpty
?
[
rooms
.
first
.
roomId
]
:
<
int
>[];
// 仅当首次进入(之前没有选过房间)时,默认选中过滤后的第一个房间
final
initialRoomIds
=
filteredRooms
.
isNotEmpty
?
[
filteredRooms
.
entries
.
first
.
key
]
:
<
int
>[];
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
null
,
allRooms:
roomsMap
,
selectedRoomIds:
first
RoomIds
,
allRooms:
filteredRooms
,
selectedRoomIds:
initial
RoomIds
,
tabCounts:
tabCounts
,
));
}
catch
(
e
)
{
...
...
@@ -57,10 +62,17 @@ class InspectionCubit extends Cubit<InspectionState> {
:
null
;
final
result
=
await
_deviceService
.
getList
(
pageSize:
_
pageSize
,
pageSize:
pageSize
,
pageNum:
pageKey
,
roomId:
roomId
,
runStatus:
state
.
selectedTab
.
runStatus
,
);
// 首页时记录总数,供翻页判断是否到底
if
(
pageKey
==
1
)
{
emit
(
state
.
copyWith
(
totalCount:
result
.
total
));
}
return
result
.
data
.
map
((
e
)
=>
InspectionDevice
.
fromInspectionDeviceBO
(
e
))
.
toList
();
...
...
@@ -89,8 +101,54 @@ class InspectionCubit extends Cubit<InspectionState> {
};
}
/// 根据 Tab 的 runStatus 过滤房间:
/// - total / runStatus 为 null → 返回全部
/// - 其他 → 仅保留对应状态计数 > 0 的房间
Map
<
int
,
String
>
_filterRooms
(
List
<
InspectionRoomBO
>
rooms
,
DeviceStatusTab
tab
)
{
final
result
=
<
int
,
String
>{};
for
(
final
room
in
rooms
)
{
if
(
_roomMatchesTab
(
room
,
tab
))
{
result
[
room
.
roomId
]
=
room
.
roomNumber
;
}
}
return
result
;
}
bool
_roomMatchesTab
(
InspectionRoomBO
room
,
DeviceStatusTab
tab
)
{
switch
(
tab
)
{
case
DeviceStatusTab
.
total
:
return
true
;
case
DeviceStatusTab
.
on
:
return
room
.
runStatus
.
normal
>
0
;
case
DeviceStatusTab
.
off
:
case
DeviceStatusTab
.
offline
:
return
room
.
runStatus
.
offline
>
0
;
case
DeviceStatusTab
.
alarm
:
return
room
.
runStatus
.
warning
>
0
;
case
DeviceStatusTab
.
fault
:
return
room
.
runStatus
.
fault
>
0
;
}
}
void
selectTab
(
DeviceStatusTab
tab
)
{
emit
(
state
.
copyWith
(
selectedTab:
tab
));
final
filteredRooms
=
_filterRooms
(
_allRoomsRaw
,
tab
);
// 过滤后剔除已不存在的已选房间;若全被剔除则默认选第一个
final
keptSelection
=
state
.
selectedRoomIds
.
where
(
filteredRooms
.
containsKey
)
.
toList
();
final
newSelectedRoomIds
=
keptSelection
.
isNotEmpty
?
keptSelection
:
(
filteredRooms
.
isNotEmpty
?
[
filteredRooms
.
entries
.
first
.
key
]
:
<
int
>[]);
emit
(
state
.
copyWith
(
selectedTab:
tab
,
allRooms:
filteredRooms
,
selectedRoomIds:
newSelectedRoomIds
,
));
}
void
toggleRoom
(
int
roomId
)
{
...
...
lib/views/home/inspection/cubit/inspection_state.dart
View file @
e9fe298f
...
...
@@ -4,6 +4,27 @@ import 'package:smart_hotel_app/models/bo/inspection_device_bo.dart';
enum
DeviceStatusTab
{
total
,
on
,
off
,
offline
,
alarm
,
fault
}
extension
DeviceStatusTabRunStatus
on
DeviceStatusTab
{
/// 映射为接口 runStatus 入参:
/// online=开启(绿) offline=关闭/离线(灰) warning=告警(黄) fault=故障(红)
String
?
get
runStatus
{
switch
(
this
)
{
case
DeviceStatusTab
.
total
:
return
null
;
case
DeviceStatusTab
.
on
:
return
'online'
;
case
DeviceStatusTab
.
off
:
return
'offline'
;
case
DeviceStatusTab
.
offline
:
return
'offline'
;
case
DeviceStatusTab
.
alarm
:
return
'warning'
;
case
DeviceStatusTab
.
fault
:
return
'fault'
;
}
}
}
class
InspectionDevice
{
final
String
id
;
final
IconData
icon
;
...
...
@@ -89,6 +110,7 @@ class InspectionState extends Equatable {
final
List
<
int
>
selectedRoomIds
;
final
Map
<
int
,
String
>
allRooms
;
final
Map
<
DeviceStatusTab
,
int
>
tabCounts
;
final
int
totalCount
;
const
InspectionState
({
this
.
isLoading
=
false
,
...
...
@@ -104,6 +126,7 @@ class InspectionState extends Equatable {
DeviceStatusTab
.
alarm
:
0
,
DeviceStatusTab
.
fault
:
0
,
},
this
.
totalCount
=
0
,
});
InspectionState
copyWith
({
...
...
@@ -113,6 +136,7 @@ class InspectionState extends Equatable {
List
<
int
>?
selectedRoomIds
,
Map
<
int
,
String
>?
allRooms
,
Map
<
DeviceStatusTab
,
int
>?
tabCounts
,
int
?
totalCount
,
})
{
return
InspectionState
(
isLoading:
isLoading
??
this
.
isLoading
,
...
...
@@ -121,6 +145,7 @@ class InspectionState extends Equatable {
selectedRoomIds:
selectedRoomIds
??
this
.
selectedRoomIds
,
allRooms:
allRooms
??
this
.
allRooms
,
tabCounts:
tabCounts
??
this
.
tabCounts
,
totalCount:
totalCount
??
this
.
totalCount
,
);
}
...
...
@@ -132,5 +157,6 @@ class InspectionState extends Equatable {
selectedRoomIds
,
allRooms
,
tabCounts
,
totalCount
,
];
}
\ No newline at end of file
lib/views/home/inspection/inspection_detail_view.dart
View file @
e9fe298f
...
...
@@ -31,19 +31,25 @@ class _InspectionDetailBody extends StatefulWidget {
class
_InspectionDetailBodyState
extends
State
<
_InspectionDetailBody
>
{
late
final
PagingController
<
int
,
InspectionDevice
>
_pagingController
;
late
final
InspectionCubit
_cubit
;
DeviceStatusTab
?
_lastTab
;
List
<
int
>?
_lastRoomIds
;
@override
void
initState
()
{
super
.
initState
();
_cubit
=
context
.
read
<
InspectionCubit
>();
_pagingController
=
PagingController
<
int
,
InspectionDevice
>(
getNextPageKey:
(
state
)
{
if
(
state
.
keys
==
null
||
state
.
keys
!.
isEmpty
)
return
1
;
return
state
.
lastPageIsEmpty
?
null
:
state
.
nextIntPageKey
;
final
total
=
_cubit
.
state
.
totalCount
;
final
nextKey
=
state
.
nextIntPageKey
;
if
((
nextKey
-
1
)
*
InspectionCubit
.
pageSize
>=
total
)
{
return
null
;
}
return
nextKey
;
},
fetchPage:
(
pageKey
)
=>
context
.
read
<
InspectionCubit
>().
fetchPage
(
pageKey
),
fetchPage:
(
pageKey
)
=>
_cubit
.
fetchPage
(
pageKey
),
);
}
...
...
lib/views/home/inspection/widget/filter_panel.dart
View file @
e9fe298f
...
...
@@ -40,88 +40,82 @@ class FilterPanel extends StatelessWidget {
}
Widget
_buildStatusTabs
()
{
return
Column
(
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
DeviceStatusTab
.
values
.
map
((
tab
)
{
final
isSelected
=
selectedTab
==
tab
;
final
count
=
tabCounts
[
tab
]
??
0
;
return
Expanded
(
child:
GestureDetector
(
onTap:
()
=>
onTabSelected
(
tab
),
child:
Stack
(
clipBehavior:
Clip
.
none
,
alignment:
Alignment
.
center
,
children:
[
Padding
(
padding:
EdgeInsets
.
only
(
top:
8
.
h
),
child:
Text
(
_getTabLabel
(
tab
),
style:
TextStyle
(
fontSize:
28
.
sp
,
fontWeight:
isSelected
?
FontWeight
.
bold
:
FontWeight
.
normal
,
color:
isSelected
?
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
)
:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
DeviceStatusTab
.
values
.
map
((
tab
)
{
final
isSelected
=
selectedTab
==
tab
;
final
count
=
tabCounts
[
tab
]
??
0
;
return
Expanded
(
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
=>
onTabSelected
(
tab
),
child:
Padding
(
padding:
EdgeInsets
.
symmetric
(
vertical:
8
.
h
),
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Stack
(
clipBehavior:
Clip
.
none
,
children:
[
Padding
(
padding:
EdgeInsets
.
only
(
right:
16
.
w
),
child:
Text
(
_getTabLabel
(
tab
),
style:
TextStyle
(
fontSize:
isSelected
?
32
.
sp
:
28
.
sp
,
fontWeight:
isSelected
?
FontWeight
.
bold
:
FontWeight
.
normal
,
color:
isSelected
?
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
)
:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
height:
1.0
,
),
),
),
),
if
(
count
>
0
)
Positioned
(
top:
0
,
right:
-
8
.
w
,
top:
-
20
.
h
,
right:
-
18
.
h
,
child:
Container
(
width:
28
.
w
,
height:
28
.
h
,
constraints:
BoxConstraints
(
minWidth:
32
.
w
,
minHeight:
32
.
w
,
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
6
.
w
),
decoration:
BoxDecoration
(
color:
_getTabColor
(
tab
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
)
,
shape:
BoxShape
.
circle
,
),
child:
Center
(
child:
Text
(
count
.
toString
(),
style:
TextStyle
(
fontSize:
20
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
Colors
.
white
,
),
alignment:
Alignment
.
center
,
child:
Text
(
count
.
toString
(),
style:
TextStyle
(
fontSize:
14
.
sp
,
color:
Colors
.
white
,
height:
1.0
,
),
),
),
),
],
),
),
);
}).
toList
(),
),
SizedBox
(
height:
12
.
h
),
Container
(
height:
4
.
h
,
width:
double
.
infinity
,
color:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
child:
Stack
(
children:
[
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
final
segmentWidth
=
constraints
.
maxWidth
/
DeviceStatusTab
.
values
.
length
;
final
selectedIndex
=
DeviceStatusTab
.
values
.
indexOf
(
selectedTab
);
return
AnimatedPositioned
(
],
),
SizedBox
(
height:
12
.
h
),
AnimatedContainer
(
duration:
const
Duration
(
milliseconds:
200
),
left:
selectedIndex
*
segmentWidth
,
width:
segmentWidth
,
child:
Container
(
height:
4
.
h
,
height:
4
.
h
,
width:
isSelected
?
48
.
w
:
0
,
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
borderRadius:
BorderRadius
.
circular
(
2
.
r
),
),
)
;
}
,
)
,
]
,
),
]
,
)
,
),
)
,
]
,
)
;
}).
toList
()
,
);
}
...
...
lib/views/home/inspection_device/widget/start_inspection_button.dart
View file @
e9fe298f
...
...
@@ -8,6 +8,7 @@ import 'package:smart_hotel_app/blocs/auth/auth_state.dart';
import
'package:smart_hotel_app/repositories/inspection_device_repository.dart'
;
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:smart_hotel_app/services/inspection_device_service.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
class
StartInspectionButton
extends
StatelessWidget
{
final
String
deviceId
;
...
...
@@ -75,9 +76,7 @@ class StartInspectionButton extends StatelessWidget {
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
context
.
popRoute
();
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'巡检失败:
$e
'
)),
);
showToast
(
'巡检失败:
$e
'
);
}
}
},
...
...
lib/views/report/room/cubit/room_report_cubit.dart
View file @
e9fe298f
...
...
@@ -12,7 +12,7 @@ class RoomReportCubit extends Cubit<RoomReportState> {
loadData
();
}
Future
<
void
>
loadData
({
int
?
floorId
})
async
{
Future
<
void
>
loadData
({
int
floorId
=
1
})
async
{
emit
(
state
.
copyWith
(
isLoading:
true
,
error:
null
));
try
{
final
overview
=
await
_service
.
getOverview
(
floorId
);
...
...
lib/views/service/index/widget/room_management_block.dart
View file @
e9fe298f
...
...
@@ -6,6 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:smart_hotel_app/views/service/index/cubit/service_index_state.dart'
;
import
'package:smart_hotel_app/views/service/index/widget/area_device_list.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
class
RoomManagementBlock
extends
StatefulWidget
{
const
RoomManagementBlock
({
super
.
key
});
...
...
@@ -517,15 +518,11 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
try
{
await
cubit
.
powerOnRoom
(
_selectedRoom
!);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'送电成功'
)),
);
showToast
(
'送电成功'
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'送电失败:
$e
'
)),
);
showToast
(
'送电失败:
$e
'
);
}
}
}
...
...
@@ -561,15 +558,11 @@ class _RoomManagementBlockState extends State<RoomManagementBlock> {
try
{
await
cubit
.
powerOffRoom
(
_selectedRoom
!);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'断电成功'
)),
);
showToast
(
'断电成功'
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'断电失败:
$e
'
)),
);
showToast
(
'断电失败:
$e
'
);
}
}
}
...
...
lib/views/service/room/room_detail_view.dart
View file @
e9fe298f
...
...
@@ -9,6 +9,7 @@ import 'package:smart_hotel_app/views/service/room/widget/room_overview_card.dar
import
'package:smart_hotel_app/views/service/room/widget/room_device_status_card.dart'
;
import
'package:smart_hotel_app/views/service/room/widget/device_control_card.dart'
;
import
'package:smart_hotel_app/views/service/room/widget/room_bottom_buttons.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
@RoutePage
()
class
ServiceRoomDetailView
extends
StatelessWidget
{
...
...
@@ -105,24 +106,18 @@ class ServiceRoomDetailView extends StatelessWidget {
try
{
await
cubit
.
toggleMainPowerForSwitch
(
value
);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
value
?
'送电成功'
:
'断电成功'
),
),
);
showToast
(
value
?
'送电成功'
:
'断电成功'
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'操作失败:
$e
'
)),
);
showToast
(
'操作失败:
$e
'
);
}
}
},
onDeviceToggle:
(
index
,
value
)
=>
cubit
.
toggleControlDevice
(
index
,
value
),
onDeviceTap:
(
index
,
device
)
{
if
(
device
.
deviceTypeName
==
'空调'
||
device
.
deviceTypeN
ame
?.
contains
(
'空调'
)
==
true
)
{
if
(
device
.
name
==
'空调'
||
device
.
n
ame
?.
contains
(
'空调'
)
==
true
)
{
context
.
pushRoute
(
ServiceDeviceDetailRoute
(
deviceId:
device
.
deviceId
));
}
},
...
...
@@ -134,15 +129,11 @@ class ServiceRoomDetailView extends StatelessWidget {
try
{
await
cubit
.
toggleMainPower
(
true
);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'送电成功'
)),
);
showToast
(
'送电成功'
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'送电失败:
$e
'
)),
);
showToast
(
'送电失败:
$e
'
);
}
}
},
...
...
@@ -150,15 +141,11 @@ class ServiceRoomDetailView extends StatelessWidget {
try
{
await
cubit
.
toggleMainPower
(
false
);
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'断电成功'
)),
);
showToast
(
'断电成功'
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'断电失败:
$e
'
)),
);
showToast
(
'断电失败:
$e
'
);
}
}
},
...
...
pubspec.lock
View file @
e9fe298f
...
...
@@ -404,10 +404,10 @@ packages:
dependency: "direct main"
description:
name: fluttertoast
sha256: "
90778fe0497fe3a09166e8cf2e0867310ff434b794526589e77ec03cf08ba8e8
"
sha256: "
7903c9d5339173497bfecbc23bc4212f5a87e0edfac2e1693fb74465ea67da7e
"
url: "https://pub.dev"
source: hosted
version: "
8.2.14
"
version: "
9.1.0
"
frontend_server_client:
dependency: transitive
description:
...
...
@@ -942,5 +942,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.1
0.3
<4.0.0"
flutter: ">=3.
38.4
"
dart: ">=3.1
1.0
<4.0.0"
flutter: ">=3.
41.0
"
pubspec.yaml
View file @
e9fe298f
...
...
@@ -42,7 +42,7 @@ dependencies:
flutter_bloc
:
^8.1.5
equatable
:
^2.0.5
flutter_screenutil
:
^5.9.3
fluttertoast
:
^
8.2.5
fluttertoast
:
^
9.1.0
loading_animation_widget
:
^1.3.0
# fl_chart: ^1.2.0
flutter_switch
:
^0.3.2
...
...
对接方案.md
View file @
e9fe298f
# 智慧酒
店 App 接口对接方案
# 智慧酒
店 App 接口对接方案
...
...
@@ -1240,6 +1240,7 @@ class xxxBO extends Equatable {
请
求体:
{
"roomId":0,
"runStatus":String,// 运行状态码,与入参保持一致:online=开启(绿) offline=关闭/离线(灰) warning=告警(黄) fault=故障(红)
"pageSize": 20,
"pageNum": 1
}
...
...
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