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
9474420e
Commit
9474420e
authored
Jun 22, 2026
by
huqu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix bugs
parent
7566c742
Show whitespace changes
Inline
Side-by-side
Showing
61 changed files
with
958 additions
and
734 deletions
+958
-734
alert_bg.png
lib/assets/icon/alert_bg.png
+0
-0
current_bg.png
lib/assets/icon/current_bg.png
+0
-0
info_dcl_bg.png
lib/assets/icon/info_dcl_bg.png
+0
-0
info_wb_bg.png
lib/assets/icon/info_wb_bg.png
+0
-0
info_ycl_bg.png
lib/assets/icon/info_ycl_bg.png
+0
-0
offline_bg.png
lib/assets/icon/offline_bg.png
+0
-0
thermostat_bg.png
lib/assets/icon/thermostat_bg.png
+0
-0
voltage_bg.png
lib/assets/icon/voltage_bg.png
+0
-0
alert_dashboard_bo.dart
lib/models/bo/alert_dashboard_bo.dart
+17
-0
inspection_room_bo.dart
lib/models/bo/inspection_room_bo.dart
+54
-7
alert_list_repository.dart
lib/repositories/alert_list_repository.dart
+3
-3
inspection_room_repository.dart
lib/repositories/inspection_room_repository.dart
+5
-8
inspection_room_service.dart
lib/services/inspection_room_service.dart
+1
-1
abnormal_detail_view.dart
lib/views/home/abnormal/abnormal_detail_view.dart
+12
-10
abnormal_cubit.dart
lib/views/home/abnormal/cubit/abnormal_cubit.dart
+3
-13
abnormal_state.dart
lib/views/home/abnormal/cubit/abnormal_state.dart
+2
-0
alarm_info_block.dart
lib/views/home/abnormal/widget/alarm_info_block.dart
+10
-3
temperature_block.dart
lib/views/home/abnormal/widget/temperature_block.dart
+97
-35
abnormal_list_cubit.dart
lib/views/home/abnormal_list/cubit/abnormal_list_cubit.dart
+6
-5
abnormal_list_state.dart
lib/views/home/abnormal_list/cubit/abnormal_list_state.dart
+5
-24
alarm_list_item.dart
lib/views/home/abnormal_list/widget/alarm_list_item.dart
+109
-63
device_cubit.dart
lib/views/home/device/cubit/device_cubit.dart
+1
-2
device_state.dart
lib/views/home/device/cubit/device_state.dart
+3
-3
power_char_block.dart
lib/views/home/device/widget/power_char_block.dart
+24
-20
state_info_block.dart
lib/views/home/device/widget/state_info_block.dart
+6
-6
home_index_cubit.dart
lib/views/home/index/cubit/home_index_cubit.dart
+9
-7
index_view.dart
lib/views/home/index/index_view.dart
+1
-1
temperature_block.dart
lib/views/home/index/widget/temperature_block.dart
+11
-17
voltage_operate_block.dart
lib/views/home/index/widget/voltage_operate_block.dart
+5
-12
inspection_cubit.dart
lib/views/home/inspection/cubit/inspection_cubit.dart
+37
-96
inspection_state.dart
lib/views/home/inspection/cubit/inspection_state.dart
+18
-10
inspection_detail_view.dart
lib/views/home/inspection/inspection_detail_view.dart
+8
-6
device_list_item.dart
lib/views/home/inspection/widget/device_list_item.dart
+1
-1
filter_panel.dart
lib/views/home/inspection/widget/filter_panel.dart
+95
-77
inspection_device_view.dart
lib/views/home/inspection_device/inspection_device_view.dart
+10
-0
device_overview_card.dart
...s/home/inspection_device/widget/device_overview_card.dart
+14
-15
inspection_history_card.dart
...ome/inspection_device/widget/inspection_history_card.dart
+8
-14
inspection_items_card.dart
.../home/inspection_device/widget/inspection_items_card.dart
+2
-1
inspection_topology_cubit.dart
.../inspection_topology/cubit/inspection_topology_cubit.dart
+2
-2
device_detail_dialog.dart
...home/inspection_topology/widget/device_detail_dialog.dart
+9
-9
device_header_widget.dart
...home/inspection_topology/widget/device_header_widget.dart
+1
-1
network_topology_widget.dart
...e/inspection_topology/widget/network_topology_widget.dart
+54
-37
device_list_cubit.dart
lib/views/report/device/cubit/device_list_cubit.dart
+1
-0
device_list_state.dart
lib/views/report/device/cubit/device_list_state.dart
+3
-1
device_card.dart
lib/views/report/device/widget/device_card.dart
+18
-59
device_filter_tab.dart
lib/views/report/device/widget/device_filter_tab.dart
+2
-1
energy_stats_card_block.dart
lib/views/report/energy/widget/energy_stats_card_block.dart
+4
-6
hourly_chart_block.dart
lib/views/report/energy/widget/hourly_chart_block.dart
+34
-10
weekly_power_chart.dart
lib/views/report/index/widget/weekly_power_chart.dart
+15
-2
room_report_cubit.dart
lib/views/report/room/cubit/room_report_cubit.dart
+21
-2
room_report_state.dart
lib/views/report/room/cubit/room_report_state.dart
+7
-0
room_detail_view.dart
lib/views/report/room/room_detail_view.dart
+29
-18
room_detail_card.dart
lib/views/report/room/widget/room_detail_card.dart
+6
-2
room_grid.dart
lib/views/report/room/widget/room_grid.dart
+24
-22
service_index_cubit.dart
lib/views/service/index/cubit/service_index_cubit.dart
+39
-6
room_management_block.dart
lib/views/service/index/widget/room_management_block.dart
+40
-40
service_stats_block.dart
lib/views/service/index/widget/service_stats_block.dart
+2
-3
service_room_cubit.dart
lib/views/service/room/cubit/service_room_cubit.dart
+28
-28
room_detail_view.dart
lib/views/service/room/room_detail_view.dart
+27
-1
device_control_card.dart
lib/views/service/room/widget/device_control_card.dart
+10
-23
room_device_status_card.dart
lib/views/service/room/widget/room_device_status_card.dart
+5
-1
No files found.
lib/assets/icon/alert_bg.png
0 → 100644
View file @
9474420e
978 Bytes
lib/assets/icon/current_bg.png
0 → 100644
View file @
9474420e
541 Bytes
lib/assets/icon/info_dcl_bg.png
0 → 100644
View file @
9474420e
264 Bytes
lib/assets/icon/info_wb_bg.png
0 → 100644
View file @
9474420e
337 Bytes
lib/assets/icon/info_ycl_bg.png
0 → 100644
View file @
9474420e
318 Bytes
lib/assets/icon/offline_bg.png
0 → 100644
View file @
9474420e
696 Bytes
lib/assets/icon/thermostat_bg.png
0 → 100644
View file @
9474420e
1 KB
lib/assets/icon/voltage_bg.png
0 → 100644
View file @
9474420e
737 Bytes
lib/models/bo/alert_dashboard_bo.dart
View file @
9474420e
...
@@ -97,6 +97,8 @@ class AlertItemBO extends Equatable {
...
@@ -97,6 +97,8 @@ class AlertItemBO extends Equatable {
final
String
waitingDurationDesc
;
final
String
waitingDurationDesc
;
final
String
alertTime
;
final
String
alertTime
;
final
String
alertCategory
;
final
String
alertCategory
;
final
String
deviceCode
;
final
String
deviceLocation
;
const
AlertItemBO
({
const
AlertItemBO
({
required
this
.
alertId
,
required
this
.
alertId
,
...
@@ -117,6 +119,8 @@ class AlertItemBO extends Equatable {
...
@@ -117,6 +119,8 @@ class AlertItemBO extends Equatable {
required
this
.
waitingDurationDesc
,
required
this
.
waitingDurationDesc
,
required
this
.
alertTime
,
required
this
.
alertTime
,
required
this
.
alertCategory
,
required
this
.
alertCategory
,
required
this
.
deviceCode
,
required
this
.
deviceLocation
,
});
});
factory
AlertItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
factory
AlertItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
...
@@ -139,6 +143,8 @@ class AlertItemBO extends Equatable {
...
@@ -139,6 +143,8 @@ class AlertItemBO extends Equatable {
waitingDurationDesc:
json
[
'waitingDurationDesc'
]
as
String
?
??
''
,
waitingDurationDesc:
json
[
'waitingDurationDesc'
]
as
String
?
??
''
,
alertTime:
json
[
'alertTime'
]
as
String
?
??
''
,
alertTime:
json
[
'alertTime'
]
as
String
?
??
''
,
alertCategory:
json
[
'alertCategory'
]
as
String
?
??
''
,
alertCategory:
json
[
'alertCategory'
]
as
String
?
??
''
,
deviceCode:
json
[
'deviceCode'
]
as
String
?
??
''
,
deviceLocation:
json
[
'deviceLocation'
]
as
String
?
??
''
,
);
);
}
}
...
@@ -162,6 +168,8 @@ class AlertItemBO extends Equatable {
...
@@ -162,6 +168,8 @@ class AlertItemBO extends Equatable {
waitingDurationDesc
,
waitingDurationDesc
,
alertTime
,
alertTime
,
alertCategory
,
alertCategory
,
deviceCode
,
deviceLocation
,
];
];
}
}
...
@@ -181,6 +189,8 @@ class DeviceItemBO extends Equatable {
...
@@ -181,6 +189,8 @@ class DeviceItemBO extends Equatable {
final
String
current
;
final
String
current
;
final
String
onlineStatus
;
final
String
onlineStatus
;
final
String
lastHeartbeat
;
final
String
lastHeartbeat
;
final
String
deviceCode
;
final
String
deviceLocation
;
const
DeviceItemBO
({
const
DeviceItemBO
({
required
this
.
deviceId
,
required
this
.
deviceId
,
...
@@ -196,6 +206,8 @@ class DeviceItemBO extends Equatable {
...
@@ -196,6 +206,8 @@ class DeviceItemBO extends Equatable {
required
this
.
current
,
required
this
.
current
,
required
this
.
onlineStatus
,
required
this
.
onlineStatus
,
required
this
.
lastHeartbeat
,
required
this
.
lastHeartbeat
,
required
this
.
deviceCode
,
required
this
.
deviceLocation
,
});
});
factory
DeviceItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
factory
DeviceItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
...
@@ -213,6 +225,8 @@ class DeviceItemBO extends Equatable {
...
@@ -213,6 +225,8 @@ class DeviceItemBO extends Equatable {
current:
json
[
'current'
]
as
String
?
??
''
,
current:
json
[
'current'
]
as
String
?
??
''
,
onlineStatus:
json
[
'onlineStatus'
]
as
String
?
??
'0'
,
onlineStatus:
json
[
'onlineStatus'
]
as
String
?
??
'0'
,
lastHeartbeat:
json
[
'lastHeartbeat'
]
as
String
?
??
''
,
lastHeartbeat:
json
[
'lastHeartbeat'
]
as
String
?
??
''
,
deviceCode:
json
[
'deviceCode'
]
as
String
?
??
''
,
deviceLocation:
json
[
'deviceLocation'
]
as
String
?
??
''
,
);
);
}
}
...
@@ -231,5 +245,7 @@ class DeviceItemBO extends Equatable {
...
@@ -231,5 +245,7 @@ class DeviceItemBO extends Equatable {
current
,
current
,
onlineStatus
,
onlineStatus
,
lastHeartbeat
,
lastHeartbeat
,
deviceCode
,
deviceLocation
,
];
];
}
}
\ No newline at end of file
lib/models/bo/inspection_room_bo.dart
View file @
9474420e
import
'package:equatable/equatable.dart'
;
import
'package:equatable/equatable.dart'
;
class
InspectionRoomBO
extends
Equatable
{
class
InspectionRoomBO
extends
Equatable
{
final
int
roomId
;
final
String
roomNumber
;
final
InspectionRoomRunStatusBO
runStatus
;
final
InspectionRoomRunStatusBO
runStatus
;
final
List
<
InspectionRoomGroupsBO
>
roomGroups
;
const
InspectionRoomBO
({
const
InspectionRoomBO
({
required
this
.
roomId
,
required
this
.
roomNumber
,
required
this
.
runStatus
,
required
this
.
runStatus
,
required
this
.
roomGroups
,
});
});
factory
InspectionRoomBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
factory
InspectionRoomBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
final
roomGroups
=
json
[
'roomGroups'
]
as
List
<
dynamic
>?
??
[];
return
InspectionRoomBO
(
return
InspectionRoomBO
(
roomId:
int
.
tryParse
(
json
[
'roomId'
]?.
toString
()
??
''
)
??
0
,
roomNumber:
json
[
'roomNumber'
]
as
String
?
??
''
,
runStatus:
InspectionRoomRunStatusBO
.
fromJson
(
runStatus:
InspectionRoomRunStatusBO
.
fromJson
(
json
[
'runStatus'
]
as
Map
<
String
,
dynamic
>?
??
{},
json
[
'runStatus'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
),
roomGroups:
roomGroups
.
map
((
e
)
=>
InspectionRoomGroupsBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
(),
);
);
}
}
@override
@override
List
<
Object
?>
get
props
=>
[
r
oomId
,
roomNumber
,
runStatu
s
];
List
<
Object
?>
get
props
=>
[
r
unStatus
,
roomGroup
s
];
}
}
class
InspectionRoomRunStatusBO
extends
Equatable
{
class
InspectionRoomRunStatusBO
extends
Equatable
{
...
@@ -50,3 +50,49 @@ class InspectionRoomRunStatusBO extends Equatable {
...
@@ -50,3 +50,49 @@ class InspectionRoomRunStatusBO extends Equatable {
@override
@override
List
<
Object
?>
get
props
=>
[
normal
,
warning
,
offline
,
fault
];
List
<
Object
?>
get
props
=>
[
normal
,
warning
,
offline
,
fault
];
}
}
class
InspectionRoomGroupsBO
extends
Equatable
{
final
String
areaTypeName
;
final
List
<
InspectionRoomsBO
>
rooms
;
const
InspectionRoomGroupsBO
({
required
this
.
areaTypeName
,
required
this
.
rooms
,
});
factory
InspectionRoomGroupsBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
final
rooms
=
json
[
'rooms'
]
as
List
<
dynamic
>?
??
[];
return
InspectionRoomGroupsBO
(
areaTypeName:
json
[
'areaTypeName'
]?.
toString
()
??
''
,
rooms:
rooms
.
map
((
e
)
=>
InspectionRoomsBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
(),
);
}
@override
List
<
Object
?>
get
props
=>
[
areaTypeName
,
rooms
];
}
class
InspectionRoomsBO
extends
Equatable
{
final
int
roomId
;
final
String
roomNumber
;
final
String
areaTypeName
;
const
InspectionRoomsBO
({
required
this
.
roomId
,
required
this
.
roomNumber
,
required
this
.
areaTypeName
,
});
factory
InspectionRoomsBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
InspectionRoomsBO
(
roomId:
int
.
tryParse
(
json
[
'roomId'
]?.
toString
()
??
''
)
??
0
,
roomNumber:
json
[
'roomNumber'
]?.
toString
()
??
''
,
areaTypeName:
json
[
'areaTypeName'
]?.
toString
()
??
''
,
);
}
@override
List
<
Object
?>
get
props
=>
[
roomId
,
roomNumber
,
areaTypeName
];
}
\ No newline at end of file
lib/repositories/alert_list_repository.dart
View file @
9474420e
...
@@ -4,7 +4,7 @@ import '../models/bo/alert_list_bo.dart';
...
@@ -4,7 +4,7 @@ import '../models/bo/alert_list_bo.dart';
class
AlertListRepository
{
class
AlertListRepository
{
/// 获取告警列表
/// 获取告警列表
/// [alertStatus] 告警状态码:0=待处理 2=已处理
3
=误报,不传则查询全部
/// [alertStatus] 告警状态码:0=待处理 2=已处理
4
=误报,不传则查询全部
Future
<
ResponseModel
<
AlertListBO
>>
getList
({
Future
<
ResponseModel
<
AlertListBO
>>
getList
({
required
int
pageSize
,
required
int
pageSize
,
required
int
pageNum
,
required
int
pageNum
,
...
@@ -20,8 +20,7 @@ class AlertListRepository {
...
@@ -20,8 +20,7 @@ class AlertListRepository {
return
DioRequest
.
instance
.
get
<
AlertListBO
>(
return
DioRequest
.
instance
.
get
<
AlertListBO
>(
'/app/alert/list'
,
'/app/alert/list'
,
queryParameters:
params
,
queryParameters:
params
,
fromJsonT:
(
data
)
=>
fromJsonT:
(
data
)
=>
AlertListBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
AlertListBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
);
}
}
}
}
\ No newline at end of file
lib/repositories/inspection_room_repository.dart
View file @
9474420e
...
@@ -4,15 +4,11 @@ import '../models/bo/inspection_room_bo.dart';
...
@@ -4,15 +4,11 @@ import '../models/bo/inspection_room_bo.dart';
class
InspectionRoomRepository
{
class
InspectionRoomRepository
{
/// 获取设备巡检房间列表
/// 获取设备巡检房间列表
Future
<
ResponseModel
<
List
<
InspectionRoomBO
>
>>
getRooms
()
{
Future
<
ResponseModel
<
InspectionRoomBO
>>
getRooms
()
{
return
DioRequest
.
instance
.
get
<
List
<
InspectionRoomBO
>
>(
return
DioRequest
.
instance
.
get
<
InspectionRoomBO
>(
'/app/device/inspection/rooms'
,
'/app/device/inspection/rooms'
,
fromJsonT:
(
data
)
{
fromJsonT:
(
data
)
=>
final
list
=
data
as
List
<
dynamic
>;
InspectionRoomBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
return
list
.
map
((
e
)
=>
InspectionRoomBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
();
},
);
);
}
}
}
}
\ No newline at end of file
lib/services/inspection_room_service.dart
View file @
9474420e
...
@@ -7,7 +7,7 @@ class InspectionRoomService {
...
@@ -7,7 +7,7 @@ class InspectionRoomService {
InspectionRoomService
({
required
InspectionRoomRepository
repository
})
InspectionRoomService
({
required
InspectionRoomRepository
repository
})
:
_repository
=
repository
;
:
_repository
=
repository
;
Future
<
List
<
InspectionRoomBO
>
>
getRooms
()
async
{
Future
<
InspectionRoomBO
>
getRooms
()
async
{
final
result
=
await
_repository
.
getRooms
();
final
result
=
await
_repository
.
getRooms
();
if
(
result
.
success
&&
result
.
data
!=
null
)
{
if
(
result
.
success
&&
result
.
data
!=
null
)
{
return
result
.
data
!;
return
result
.
data
!;
...
...
lib/views/home/abnormal/abnormal_detail_view.dart
View file @
9474420e
...
@@ -54,6 +54,7 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -54,6 +54,7 @@ class AbnormalDetailView extends StatelessWidget {
if
(
state
.
isLoading
)
{
if
(
state
.
isLoading
)
{
return
const
Center
(
child:
CircularProgressIndicator
(
color:
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
)));
return
const
Center
(
child:
CircularProgressIndicator
(
color:
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
)));
}
}
if
(
state
.
error
!=
null
)
{
if
(
state
.
error
!=
null
)
{
return
Center
(
return
Center
(
child:
Text
(
child:
Text
(
...
@@ -65,10 +66,12 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -65,10 +66,12 @@ class AbnormalDetailView extends StatelessWidget {
),
),
);
);
}
}
final
alarmInfo
=
state
.
alarmInfo
;
final
alarmInfo
=
state
.
alarmInfo
;
if
(
alarmInfo
==
null
)
{
if
(
alarmInfo
==
null
)
{
return
const
SizedBox
.
shrink
();
return
const
SizedBox
.
shrink
();
}
}
final
cubit
=
context
.
read
<
AbnormalCubit
>();
final
cubit
=
context
.
read
<
AbnormalCubit
>();
return
SingleChildScrollView
(
return
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
...
@@ -94,11 +97,12 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -94,11 +97,12 @@ class AbnormalDetailView extends StatelessWidget {
Widget
_buildBottomButtons
(
BuildContext
context
,
AbnormalCubit
cubit
)
{
Widget
_buildBottomButtons
(
BuildContext
context
,
AbnormalCubit
cubit
)
{
return
Container
(
return
Container
(
width:
double
.
infinity
,
width:
double
.
infinity
,
padding:
EdgeInsets
.
symmetric
(
vertical:
15
.
h
),
padding:
EdgeInsets
.
symmetric
(
vertical:
20
.
h
),
child:
Column
(
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
spacing:
20
.
h
,
children:
[
children:
[
if
(
alarmStatus
!=
AlarmStatus
.
processed
)
...[
if
(
alarmStatus
!=
AlarmStatus
.
processed
)
BlocBuilder
<
AbnormalCubit
,
AbnormalState
>(
BlocBuilder
<
AbnormalCubit
,
AbnormalState
>(
builder:
(
context
,
state
)
{
builder:
(
context
,
state
)
{
final
isDisabled
=
state
.
isHandling
||
state
.
isHandled
;
final
isDisabled
=
state
.
isHandling
||
state
.
isHandled
;
...
@@ -109,7 +113,7 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -109,7 +113,7 @@ class AbnormalDetailView extends StatelessWidget {
color:
isDisabled
color:
isDisabled
?
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.4
)
?
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.4
)
:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
),
child:
TextButton
(
child:
TextButton
(
onPressed:
isDisabled
onPressed:
isDisabled
...
@@ -127,7 +131,7 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -127,7 +131,7 @@ class AbnormalDetailView extends StatelessWidget {
:
Text
(
:
Text
(
state
.
isHandled
?
'已处理'
:
'确认处理'
,
state
.
isHandled
?
'已处理'
:
'确认处理'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
36
.
sp
,
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
),
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
),
),
),
),
),
...
@@ -135,14 +139,12 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -135,14 +139,12 @@ class AbnormalDetailView extends StatelessWidget {
);
);
},
},
),
),
SizedBox
(
height:
20
.
h
),
],
Container
(
Container
(
width:
double
.
infinity
,
width:
double
.
infinity
,
height:
88
.
h
,
height:
88
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
),
child:
TextButton
(
child:
TextButton
(
onPressed:
()
{
onPressed:
()
{
...
@@ -156,15 +158,15 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -156,15 +158,15 @@ class AbnormalDetailView extends StatelessWidget {
Text
(
Text
(
'设备控制'
,
'设备控制'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
36
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
),
),
SizedBox
(
width:
8
.
w
),
SizedBox
(
width:
8
.
w
),
Image
.
asset
(
Image
.
asset
(
"lib/assets/icon/right.png"
,
"lib/assets/icon/right.png"
,
width:
24
.
w
,
width:
40
.
w
,
height:
2
1
.
h
,
height:
2
4
.
h
,
),
),
],
],
),
),
...
...
lib/views/home/abnormal/cubit/abnormal_cubit.dart
View file @
9474420e
...
@@ -39,8 +39,8 @@ class AbnormalCubit extends Cubit<AbnormalState> {
...
@@ -39,8 +39,8 @@ class AbnormalCubit extends Cubit<AbnormalState> {
return
AlarmInfo
(
return
AlarmInfo
(
alarmType:
basic
.
alertTitle
,
alarmType:
basic
.
alertTitle
,
deviceInfo:
basic
.
alertDeviceLocation
,
deviceInfo:
basic
.
alertDeviceLocation
,
alertLevelText:
basic
.
alertLevel
Text
,
alertLevelText:
basic
.
alertLevel
,
urgency:
_mapUrgency
(
basic
.
alertLevel
)
,
urgency:
''
,
currentTemp:
info
.
alertValue
,
currentTemp:
info
.
alertValue
,
voltage:
''
,
voltage:
''
,
current:
''
,
current:
''
,
...
@@ -60,20 +60,10 @@ class AbnormalCubit extends Cubit<AbnormalState> {
...
@@ -60,20 +60,10 @@ class AbnormalCubit extends Cubit<AbnormalState> {
}).
toList
(),
}).
toList
(),
alertDeviceId:
basic
.
alertDeviceId
,
alertDeviceId:
basic
.
alertDeviceId
,
alertCount:
basic
.
alertCount
,
alertCount:
basic
.
alertCount
,
alertIcon:
basic
.
alertIcon
,
);
);
}
}
String
_mapUrgency
(
String
level
)
{
switch
(
level
)
{
case
'danger'
:
return
'高警'
;
case
'warning'
:
return
'中警'
;
default
:
return
'普通'
;
}
}
Future
<
void
>
handleConfirm
()
async
{
Future
<
void
>
handleConfirm
()
async
{
if
(
state
.
isHandling
||
state
.
isHandled
)
return
;
if
(
state
.
isHandling
||
state
.
isHandled
)
return
;
emit
(
state
.
copyWith
(
isHandling:
true
));
emit
(
state
.
copyWith
(
isHandling:
true
));
...
...
lib/views/home/abnormal/cubit/abnormal_state.dart
View file @
9474420e
...
@@ -22,6 +22,7 @@ class AlarmInfo {
...
@@ -22,6 +22,7 @@ class AlarmInfo {
final
List
<
FlSpot
>
temperatureSpots
;
final
List
<
FlSpot
>
temperatureSpots
;
final
String
alertDeviceId
;
final
String
alertDeviceId
;
final
int
alertCount
;
final
int
alertCount
;
final
String
alertIcon
;
const
AlarmInfo
({
const
AlarmInfo
({
required
this
.
alarmType
,
required
this
.
alarmType
,
...
@@ -45,6 +46,7 @@ class AlarmInfo {
...
@@ -45,6 +46,7 @@ class AlarmInfo {
required
this
.
temperatureSpots
,
required
this
.
temperatureSpots
,
required
this
.
alertDeviceId
,
required
this
.
alertDeviceId
,
required
this
.
alertCount
,
required
this
.
alertCount
,
required
this
.
alertIcon
,
});
});
}
}
...
...
lib/views/home/abnormal/widget/alarm_info_block.dart
View file @
9474420e
...
@@ -33,7 +33,9 @@ class AlarmInfoBlock extends StatelessWidget {
...
@@ -33,7 +33,9 @@ class AlarmInfoBlock extends StatelessWidget {
SizedBox
(
height:
25
.
h
),
SizedBox
(
height:
25
.
h
),
_buildInfoRow
(
_buildInfoRow
(
'告警级别'
,
'告警级别'
,
alarmInfo
.
alertLevelText
,
alarmInfo
.
alertLevelText
==
'3'
?
'高警(Level 3)'
:
alarmInfo
.
alertLevelText
==
'2'
?
'中警(Level 2)'
:
alarmInfo
.
alertLevelText
==
'1'
?
'低警(Level 1)'
:
''
,
valueColor:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
valueColor:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
SizedBox
(
height:
25
.
h
),
SizedBox
(
height:
25
.
h
),
...
@@ -65,7 +67,6 @@ class AlarmInfoBlock extends StatelessWidget {
...
@@ -65,7 +67,6 @@ class AlarmInfoBlock extends StatelessWidget {
Widget
_buildInfoRow
(
String
label
,
String
value
,
{
Color
?
valueColor
})
{
Widget
_buildInfoRow
(
String
label
,
String
value
,
{
Color
?
valueColor
})
{
final
displayValue
=
_truncateText
(
value
);
final
displayValue
=
_truncateText
(
value
);
return
Row
(
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
Text
(
Text
(
label
,
label
,
...
@@ -74,12 +75,18 @@ class AlarmInfoBlock extends StatelessWidget {
...
@@ -74,12 +75,18 @@ class AlarmInfoBlock extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
),
),
Text
(
SizedBox
(
width:
20
.
w
),
Expanded
(
child:
Text
(
displayValue
,
displayValue
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
valueColor
??
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
valueColor
??
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
textAlign:
TextAlign
.
end
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
),
),
),
],
],
);
);
...
...
lib/views/home/abnormal/widget/temperature_block.dart
View file @
9474420e
...
@@ -18,65 +18,53 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -18,65 +18,53 @@ class TemperatureBlock extends StatelessWidget {
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
child:
Column
(
child:
Column
(
spacing:
5
.
h
,
children:
[
children:
[
Row
(
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
20
.
w
,
children:
[
children:
[
Container
(
_buildIcon
(),
width:
70
.
w
,
height:
66
.
h
,
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
),
child:
Icon
(
Icons
.
thermostat_outlined
,
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
size:
40
.
sp
,
),
),
SizedBox
(
width:
15
.
w
),
Expanded
(
Expanded
(
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
5
.
h
,
children:
[
children:
[
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
Text
(
Expanded
(
child:
Text
(
alarmInfo
.
alarmType
,
alarmInfo
.
alarmType
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
28
.
sp
,
color:
Colors
.
black
,
color:
Colors
.
black
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
),
),
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
),
),
),
Row
(
children:
[
Text
(
Text
(
'
${alarmInfo.alertLevelText}
· '
,
alarmInfo
.
alertLevelText
==
'3'
?
'高警'
:
alarmInfo
.
alertLevelText
==
'2'
?
'中警'
:
alarmInfo
.
alertLevelText
==
'1'
?
'低警'
:
''
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
fontWeight:
FontWeight
.
bold
,
),
),
),
),
if
(
alarmInfo
.
alertLevelText
==
'3'
)
...[
Container
(
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
.
w
,
vertical:
5
.
h
),
width:
5
.
w
,
decoration:
BoxDecoration
(
height:
5
.
h
,
color:
const
Color
.
fromRGBO
(
255
,
158
,
159
,
0.5
),
margin:
EdgeInsets
.
symmetric
(
horizontal:
5
.
w
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
decoration:
const
BoxDecoration
(
),
color:
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
child:
Text
(
shape:
BoxShape
.
circle
alarmInfo
.
urgency
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
),
),
),
_buildLevelBadge
()
],
],
),
],
],
),
),
Text
(
Text
(
...
@@ -91,21 +79,20 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -91,21 +79,20 @@ class TemperatureBlock extends StatelessWidget {
),
),
],
],
),
),
SizedBox
(
height:
5
.
h
),
Row
(
Row
(
children:
[
children:
[
SizedBox
(
width:
85
.
w
),
SizedBox
(
width:
85
.
w
),
Text
(
Text
(
'告警数量:'
,
'告警数量:'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
2
8
.
sp
,
fontSize:
2
4
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
),
),
Text
(
Text
(
alarmInfo
.
alertCount
.
toString
(),
alarmInfo
.
alertCount
.
toString
(),
style:
TextStyle
(
style:
TextStyle
(
fontSize:
2
8
.
sp
,
fontSize:
2
4
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
),
),
...
@@ -115,4 +102,78 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -115,4 +102,78 @@ class TemperatureBlock extends StatelessWidget {
)
)
);
);
}
}
Widget
_buildIcon
()
{
Color
?
bgColor
;
String
icon
=
''
;
double
iconW
=
0
;
double
iconH
=
0
;
switch
(
alarmInfo
.
alertIcon
)
{
case
'temperature'
:
//温度
bgColor
=
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
);
icon
=
'lib/assets/icon/thermostat_bg.png'
;
iconW
=
20
.
w
;
iconH
=
38
.
h
;
break
;
case
'voltage'
:
//电压
bgColor
=
const
Color
.
fromRGBO
(
255
,
211
,
213
,
1
);
icon
=
'lib/assets/icon/voltage_bg.png'
;
iconW
=
40
.
w
;
iconH
=
30
.
h
;
break
;
case
'current'
:
//电流
bgColor
=
const
Color
.
fromRGBO
(
255
,
161
,
72
,
1
);
icon
=
'lib/assets/icon/current_bg.png'
;
iconW
=
30
.
w
;
iconH
=
38
.
h
;
break
;
case
'alert'
:
//漏电
bgColor
=
const
Color
.
fromRGBO
(
255
,
128
,
114
,
1
);
icon
=
'lib/assets/icon/alert_bg.png'
;
iconW
=
46
.
w
;
iconH
=
32
.
h
;
break
;
case
'offline'
:
//离线
bgColor
=
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
);
icon
=
'lib/assets/icon/offline_bg.png'
;
iconW
=
44
.
w
;
iconH
=
32
.
h
;
break
;
}
return
Container
(
width:
64
.
w
,
height:
53
.
h
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
bgColor
,
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
),
child:
icon
.
isNotEmpty
?
Image
.
asset
(
icon
,
width:
iconW
,
height:
iconH
)
:
const
SizedBox
.
shrink
(),
);
}
Widget
_buildLevelBadge
()
{
return
Container
(
width:
73
.
w
,
height:
32
.
h
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
0.2
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
border:
Border
.
all
(
color:
const
Color
.
fromRGBO
(
255
,
158
,
159
,
0.5
),
width:
1
.
w
,
)
),
child:
Text
(
'紧急'
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
);
}
}
}
\ No newline at end of file
lib/views/home/abnormal_list/cubit/abnormal_list_cubit.dart
View file @
9474420e
...
@@ -8,8 +8,8 @@ import 'package:smart_hotel_app/services/alert_list_service.dart';
...
@@ -8,8 +8,8 @@ import 'package:smart_hotel_app/services/alert_list_service.dart';
import
'package:smart_hotel_app/views/home/abnormal_list/cubit/abnormal_list_state.dart'
;
import
'package:smart_hotel_app/views/home/abnormal_list/cubit/abnormal_list_state.dart'
;
/// AlarmStatus → 告警状态码: 0=待处理 1=处理中 2=已确认 3=已关闭 4=误报关闭
/// AlarmStatus → 告警状态码: 0=待处理 1=处理中 2=已确认 3=已关闭 4=误报关闭
String
?
alarmStatusToApi
(
AlarmStatus
filter
)
{
String
?
alarmStatusToApi
(
AlarmStatus
status
)
{
switch
(
filter
)
{
switch
(
status
)
{
case
AlarmStatus
.
all
:
case
AlarmStatus
.
all
:
return
null
;
return
null
;
case
AlarmStatus
.
pending
:
case
AlarmStatus
.
pending
:
...
@@ -28,8 +28,7 @@ class AbnormalListCubit extends Cubit<AbnormalListState> {
...
@@ -28,8 +28,7 @@ class AbnormalListCubit extends Cubit<AbnormalListState> {
PagingController
<
int
,
AlarmItem
>?
_pagingController
;
PagingController
<
int
,
AlarmItem
>?
_pagingController
;
AbnormalListCubit
()
AbnormalListCubit
():
_service
=
AlertListService
(
:
_service
=
AlertListService
(
repository:
AlertListRepository
(),
repository:
AlertListRepository
(),
),
),
super
(
const
AbnormalListState
());
super
(
const
AbnormalListState
());
...
@@ -71,12 +70,14 @@ class AbnormalListCubit extends Cubit<AbnormalListState> {
...
@@ -71,12 +70,14 @@ class AbnormalListCubit extends Cubit<AbnormalListState> {
/// 切换筛选 Tab,触发重新请求
/// 切换筛选 Tab,触发重新请求
void
setFilter
(
AlarmStatus
filter
)
{
void
setFilter
(
AlarmStatus
filter
)
{
if
(
state
.
currentFilter
==
filter
)
return
;
if
(
state
.
currentFilter
==
filter
)
return
;
emit
(
state
.
copyWith
(
currentFilter:
filter
));
emit
(
state
.
copyWith
(
currentFilter:
filter
));
_pagingController
?.
refresh
();
_pagingController
?.
refresh
();
}
}
void
onAlarmItemTap
(
AlarmItem
item
,
BuildContext
context
)
{
void
onAlarmItemTap
(
AlarmItem
item
,
BuildContext
context
)
{
final
alertId
=
int
.
tryParse
(
item
.
id
)
??
0
;
final
alertId
=
int
.
tryParse
(
item
.
id
)
??
0
;
context
.
pushRoute
(
AbnormalDetailRoute
(
alertId:
alertId
,
alarmStatus:
item
.
status
));
context
.
pushRoute
(
AbnormalDetailRoute
(
alertId:
alertId
,
alarmStatus:
item
.
status
));
}
}
}
}
lib/views/home/abnormal_list/cubit/abnormal_list_state.dart
View file @
9474420e
...
@@ -11,7 +11,7 @@ class AlarmItem extends Equatable {
...
@@ -11,7 +11,7 @@ class AlarmItem extends Equatable {
final
String
processTime
;
final
String
processTime
;
final
AlarmStatus
status
;
final
AlarmStatus
status
;
final
String
level
;
final
String
level
;
final
String
urgency
;
final
String
alertIcon
;
const
AlarmItem
({
const
AlarmItem
({
required
this
.
id
,
required
this
.
id
,
...
@@ -21,7 +21,7 @@ class AlarmItem extends Equatable {
...
@@ -21,7 +21,7 @@ class AlarmItem extends Equatable {
required
this
.
processTime
,
required
this
.
processTime
,
required
this
.
status
,
required
this
.
status
,
required
this
.
level
,
required
this
.
level
,
required
this
.
urgency
,
required
this
.
alertIcon
,
});
});
factory
AlarmItem
.
fromAlertListItemBO
(
AlertListItemBO
item
)
{
factory
AlarmItem
.
fromAlertListItemBO
(
AlertListItemBO
item
)
{
...
@@ -32,8 +32,8 @@ class AlarmItem extends Equatable {
...
@@ -32,8 +32,8 @@ class AlarmItem extends Equatable {
alarmTime:
item
.
alertTime
.
isEmpty
?
'--'
:
item
.
alertTime
,
alarmTime:
item
.
alertTime
.
isEmpty
?
'--'
:
item
.
alertTime
,
processTime:
item
.
handleTime
.
isEmpty
?
'--'
:
item
.
handleTime
,
processTime:
item
.
handleTime
.
isEmpty
?
'--'
:
item
.
handleTime
,
status:
_mapAlertStatus
(
item
.
alertStatus
),
status:
_mapAlertStatus
(
item
.
alertStatus
),
level:
_mapAlertLevel
(
item
.
alertLevel
)
,
level:
item
.
alertLevel
,
urgency:
''
,
alertIcon:
item
.
alertIcon
,
);
);
}
}
...
@@ -51,28 +51,9 @@ class AlarmItem extends Equatable {
...
@@ -51,28 +51,9 @@ class AlarmItem extends Equatable {
}
}
}
}
static
String
_mapAlertLevel
(
String
alertLevel
)
{
switch
(
alertLevel
)
{
case
'3'
:
case
'danger'
:
return
'高警'
;
case
'2'
:
case
'warning'
:
return
'中警'
;
case
'1'
:
case
'info'
:
return
'普通'
;
default
:
return
''
;
}
}
@override
@override
List
<
Object
?>
get
props
=>
List
<
Object
?>
get
props
=>
[
id
,
title
,
deviceInfo
,
alarmTime
,
processTime
,
status
,
level
,
urgency
];
[
id
,
title
,
deviceInfo
,
alarmTime
,
processTime
,
status
,
level
,
alertIcon
];
}
}
class
AbnormalListState
extends
Equatable
{
class
AbnormalListState
extends
Equatable
{
...
...
lib/views/home/abnormal_list/widget/alarm_list_item.dart
View file @
9474420e
...
@@ -15,6 +15,7 @@ class AlarmListItem extends StatelessWidget {
...
@@ -15,6 +15,7 @@ class AlarmListItem extends StatelessWidget {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
GestureDetector
(
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
=>
onTap
(
item
),
onTap:
()
=>
onTap
(
item
),
child:
Container
(
child:
Container
(
width:
double
.
infinity
,
width:
double
.
infinity
,
...
@@ -26,35 +27,52 @@ class AlarmListItem extends StatelessWidget {
...
@@ -26,35 +27,52 @@ class AlarmListItem extends StatelessWidget {
),
),
child:
Row
(
child:
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
20
.
w
,
children:
[
children:
[
_buildIcon
(),
_buildIcon
(),
SizedBox
(
width:
20
.
w
),
Expanded
(
Expanded
(
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
10
.
h
,
children:
[
children:
[
_buildTitleRow
(),
_buildTitleRow
(),
SizedBox
(
height:
15
.
h
),
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
Text
(
Expanded
(
child:
Text
(
item
.
deviceInfo
,
item
.
deviceInfo
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
),
),
),
SizedBox
(
width:
15
.
w
),
Text
(
Text
(
item
.
level
,
item
.
level
==
'3'
?
'高警'
:
item
.
level
==
'2'
?
'中警'
:
item
.
level
==
'1'
?
'低警'
:
''
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
),
),
if
(
item
.
level
==
'3'
)
...[
Container
(
width:
5
.
w
,
height:
5
.
h
,
margin:
EdgeInsets
.
symmetric
(
horizontal:
5
.
w
),
decoration:
const
BoxDecoration
(
color:
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
shape:
BoxShape
.
circle
),
),
_buildLevelBadge
()
],
],
],
),
),
SizedBox
(
height:
10
.
h
),
Text
(
Text
(
'告警时间:
${item.alarmTime}
'
,
'告警时间:
${item.alarmTime}
'
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -62,7 +80,6 @@ class AlarmListItem extends StatelessWidget {
...
@@ -62,7 +80,6 @@ class AlarmListItem extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
),
),
SizedBox
(
height:
10
.
h
),
Text
(
Text
(
'处理时间:
${item.processTime}
'
,
'处理时间:
${item.processTime}
'
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -80,89 +97,128 @@ class AlarmListItem extends StatelessWidget {
...
@@ -80,89 +97,128 @@ class AlarmListItem extends StatelessWidget {
}
}
Widget
_buildIcon
()
{
Widget
_buildIcon
()
{
Color
?
bgColor
;
String
icon
=
''
;
double
iconW
=
0
;
double
iconH
=
0
;
switch
(
item
.
alertIcon
)
{
case
'temperature'
:
//温度
bgColor
=
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
);
icon
=
'lib/assets/icon/thermostat_bg.png'
;
iconW
=
20
.
w
;
iconH
=
38
.
h
;
break
;
case
'voltage'
:
//电压
bgColor
=
const
Color
.
fromRGBO
(
255
,
211
,
213
,
1
);
icon
=
'lib/assets/icon/voltage_bg.png'
;
iconW
=
40
.
w
;
iconH
=
30
.
h
;
break
;
case
'current'
:
//电流
bgColor
=
const
Color
.
fromRGBO
(
255
,
161
,
72
,
1
);
icon
=
'lib/assets/icon/current_bg.png'
;
iconW
=
30
.
w
;
iconH
=
38
.
h
;
break
;
case
'alert'
:
//漏电
bgColor
=
const
Color
.
fromRGBO
(
255
,
128
,
114
,
1
);
icon
=
'lib/assets/icon/alert_bg.png'
;
iconW
=
46
.
w
;
iconH
=
32
.
h
;
break
;
case
'offline'
:
//离线
bgColor
=
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
);
icon
=
'lib/assets/icon/offline_bg.png'
;
iconW
=
44
.
w
;
iconH
=
32
.
h
;
break
;
}
return
Container
(
return
Container
(
width:
96
.
w
,
width:
80
.
w
,
height:
96
.
w
,
height:
64
.
h
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
)
,
color:
bgColor
,
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
),
),
child:
Icon
(
child:
icon
.
isNotEmpty
?
Image
.
asset
(
icon
,
width:
iconW
,
height:
iconH
)
:
Icons
.
thermostat
,
const
SizedBox
.
shrink
(),
size:
48
.
w
,
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
),
);
);
}
}
Widget
_buildTitleRow
()
{
Widget
_buildTitleRow
()
{
return
Row
(
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
Text
(
Expanded
(
child:
Text
(
item
.
title
,
item
.
title
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
28
.
sp
,
color:
Colors
.
black
,
color:
Colors
.
black
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
),
),
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
),
),
),
_buildStatusBadge
(),
_buildStatusBadge
(),
// Row(
// children: [
// _buildStatusBadge(),
// SizedBox(width: 12.w),
// _buildLevelBadge(),
// SizedBox(width: 8.w),
// _buildUrgencyBadge(),
// ],
// ),
],
],
);
);
}
}
Widget
_buildStatusBadge
()
{
Widget
_buildStatusBadge
()
{
Color
bgColor
;
Color
?
bgColor
;
Color
textColor
;
Color
?
textColor
;
String
text
;
String
text
=
''
;
IconData
?
icon
;
String
icon
=
''
;
double
iconW
=
0
;
double
iconH
=
0
;
switch
(
item
.
status
)
{
switch
(
item
.
status
)
{
case
AlarmStatus
.
pending
:
case
AlarmStatus
.
pending
:
bgColor
=
const
Color
.
fromRGBO
(
254
,
247
,
217
,
1
);
bgColor
=
const
Color
.
fromRGBO
(
254
,
247
,
217
,
1
);
textColor
=
const
Color
.
fromRGBO
(
250
,
204
,
21
,
1
);
textColor
=
const
Color
.
fromRGBO
(
250
,
204
,
21
,
1
);
text
=
'待处理'
;
text
=
'待处理'
;
icon
=
Icons
.
error_outline
;
icon
=
'lib/assets/icon/info_dcl_bg.png'
;
iconW
=
4
.
w
;
iconH
=
15
.
h
;
break
;
break
;
case
AlarmStatus
.
processed
:
case
AlarmStatus
.
processed
:
bgColor
=
const
Color
.
fromRGBO
(
84
,
214
,
120
,
0.15
);
bgColor
=
const
Color
.
fromRGBO
(
209
,
250
,
229
,
1
);
textColor
=
const
Color
.
fromRGBO
(
84
,
214
,
120
,
1
);
textColor
=
const
Color
.
fromRGBO
(
20
,
184
,
166
,
1
);
text
=
'已处理'
;
text
=
'已处理'
;
icon
=
Icons
.
check_circle_outline
;
icon
=
'lib/assets/icon/info_ycl_bg.png'
;
iconW
=
18
.
w
;
iconH
=
11
.
h
;
break
;
break
;
case
AlarmStatus
.
falseAlarm
:
case
AlarmStatus
.
falseAlarm
:
bgColor
=
const
Color
.
fromRGBO
(
255
,
100
,
101
,
0.15
);
bgColor
=
const
Color
.
fromRGBO
(
255
,
224
,
224
,
1
);
textColor
=
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
);
textColor
=
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
);
text
=
'误报'
;
text
=
'误报'
;
icon
=
Icons
.
cancel_outlined
;
icon
=
'lib/assets/icon/info_wb_bg.png'
;
iconW
=
14
.
w
;
iconH
=
11
.
h
;
break
;
break
;
default
:
default
:
bgColor
=
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.0
);
//完全透明
break
;
textColor
=
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
);
}
text
=
''
;
if
(
text
.
isEmpty
)
{
return
const
SizedBox
.
shrink
();
}
}
return
Container
(
return
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
4
.
h
),
width:
132
.
w
,
height:
32
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
bgColor
,
color:
bgColor
,
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
),
child:
Row
(
child:
Row
(
mainAxis
Size:
MainAxisSize
.
min
,
mainAxis
Alignment:
MainAxisAlignment
.
center
,
spacing:
6
.
w
,
spacing:
6
.
w
,
children:
[
children:
[
I
con
(
icon
,
size:
30
.
w
,
color:
textColor
),
I
mage
.
asset
(
icon
,
width:
iconW
,
height:
iconH
),
Text
(
Text
(
text
,
text
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -178,35 +234,25 @@ class AlarmListItem extends StatelessWidget {
...
@@ -178,35 +234,25 @@ class AlarmListItem extends StatelessWidget {
Widget
_buildLevelBadge
()
{
Widget
_buildLevelBadge
()
{
return
Container
(
return
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
8
.
h
),
width:
73
.
w
,
height:
32
.
h
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
0.15
),
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
0.2
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
border:
Border
.
all
(
color:
const
Color
.
fromRGBO
(
255
,
158
,
159
,
0.5
),
width:
1
.
w
,
)
),
),
child:
Text
(
child:
Text
(
item
.
level
,
'紧急'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
2
2
.
sp
,
fontSize:
2
4
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
),
),
);
);
}
}
Widget
_buildUrgencyBadge
()
{
return
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
8
.
h
),
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
0.15
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
),
child:
Text
(
item
.
urgency
,
style:
TextStyle
(
fontSize:
22
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
);
}
}
}
lib/views/home/device/cubit/device_cubit.dart
View file @
9474420e
...
@@ -48,8 +48,7 @@ class DeviceCubit extends Cubit<DeviceState> {
...
@@ -48,8 +48,7 @@ class DeviceCubit extends Cubit<DeviceState> {
return
DeviceInfo
(
return
DeviceInfo
(
deviceName:
basic
.
deviceName
,
deviceName:
basic
.
deviceName
,
deviceId:
basic
.
deviceCode
,
deviceCode:
basic
.
deviceCode
,
// location: basic.roomName,
location:
basic
.
deviceLocation
,
location:
basic
.
deviceLocation
,
status:
status
,
status:
status
,
voltage:
params
.
voltage
,
voltage:
params
.
voltage
,
...
...
lib/views/home/device/cubit/device_state.dart
View file @
9474420e
...
@@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart';
...
@@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart';
class
DeviceInfo
extends
Equatable
{
class
DeviceInfo
extends
Equatable
{
final
String
deviceName
;
final
String
deviceName
;
final
String
device
Id
;
final
String
device
Code
;
final
String
location
;
final
String
location
;
final
String
status
;
final
String
status
;
final
String
voltage
;
final
String
voltage
;
...
@@ -15,7 +15,7 @@ class DeviceInfo extends Equatable {
...
@@ -15,7 +15,7 @@ class DeviceInfo extends Equatable {
const
DeviceInfo
({
const
DeviceInfo
({
required
this
.
deviceName
,
required
this
.
deviceName
,
required
this
.
device
Id
,
required
this
.
device
Code
,
required
this
.
location
,
required
this
.
location
,
required
this
.
status
,
required
this
.
status
,
required
this
.
voltage
,
required
this
.
voltage
,
...
@@ -30,7 +30,7 @@ class DeviceInfo extends Equatable {
...
@@ -30,7 +30,7 @@ class DeviceInfo extends Equatable {
@override
@override
List
<
Object
?>
get
props
=>
[
List
<
Object
?>
get
props
=>
[
deviceName
,
deviceName
,
device
Id
,
device
Code
,
location
,
location
,
status
,
status
,
voltage
,
voltage
,
...
...
lib/views/home/device/widget/power_char_block.dart
View file @
9474420e
...
@@ -28,6 +28,7 @@ class PowerCharBlock extends StatelessWidget {
...
@@ -28,6 +28,7 @@ class PowerCharBlock extends StatelessWidget {
),
),
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
20
.
h
,
children:
[
children:
[
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
...
@@ -39,25 +40,14 @@ class PowerCharBlock extends StatelessWidget {
...
@@ -39,25 +40,14 @@ class PowerCharBlock extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
),
),
Container
(
Row
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
color:
Colors
.
transparent
,
border:
Border
.
all
(
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.5
),
width:
1.5
.
w
,
),
),
child:
Row
(
children:
[
children:
[
_buildTab
(
'功率'
,
0
),
_buildTab
(
'功率'
,
0
),
_buildTab
(
'温度'
,
1
),
_buildTab
(
'温度'
,
1
),
],
],
),
),
),
],
],
),
),
SizedBox
(
height:
20
.
h
),
SizedBox
(
SizedBox
(
height:
250
.
h
,
height:
250
.
h
,
child:
BarChart
(
child:
BarChart
(
...
@@ -93,13 +83,15 @@ class PowerCharBlock extends StatelessWidget {
...
@@ -93,13 +83,15 @@ class PowerCharBlock extends StatelessWidget {
getTitlesWidget:
(
value
,
meta
)
{
getTitlesWidget:
(
value
,
meta
)
{
return
Text
(
return
Text
(
'
${value.toInt()}
'
,
'
${value.toInt()}
'
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
style:
TextStyle
(
color:
const
Color
.
fromRGBO
(
156
,
163
,
175
,
1
),
color:
const
Color
.
fromRGBO
(
156
,
163
,
175
,
1
),
fontSize:
2
4
.
sp
,
fontSize:
2
2
.
sp
,
),
),
);
);
},
},
reservedSize:
40
,
reservedSize:
_leftReservedSize
,
),
),
),
),
bottomTitles:
AxisTitles
(
bottomTitles:
AxisTitles
(
...
@@ -143,15 +135,20 @@ class PowerCharBlock extends StatelessWidget {
...
@@ -143,15 +135,20 @@ class PowerCharBlock extends StatelessWidget {
Widget
_buildTab
(
String
title
,
int
index
)
{
Widget
_buildTab
(
String
title
,
int
index
)
{
final
isSelected
=
selectedTabIndex
==
index
;
final
isSelected
=
selectedTabIndex
==
index
;
return
GestureDetector
(
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
=>
onTabChanged
(
index
),
onTap:
()
=>
onTabChanged
(
index
),
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
8
.
h
),
width:
72
.
w
,
decoration:
BoxDecoration
(
height:
34
.
h
,
alignment:
Alignment
.
center
,
decoration:
isSelected
?
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
color:
isSelected
color:
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
),
?
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
)
border:
Border
.
all
(
:
Colors
.
transparent
,
width:
1
.
w
,
),
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.5
),
)
)
:
null
,
child:
Text
(
child:
Text
(
title
,
title
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -236,4 +233,10 @@ class PowerCharBlock extends StatelessWidget {
...
@@ -236,4 +233,10 @@ class PowerCharBlock extends StatelessWidget {
return
_calcMaxY
(
index
)
/
5
;
return
_calcMaxY
(
index
)
/
5
;
}
}
/// 根据最大数值的位数动态计算左侧保留宽度
double
get
_leftReservedSize
{
final
maxLabel
=
_calcMaxY
(
selectedTabIndex
).
toInt
().
toString
();
return
maxLabel
.
length
*
8
;
}
}
}
\ No newline at end of file
lib/views/home/device/widget/state_info_block.dart
View file @
9474420e
...
@@ -20,8 +20,8 @@ class StateInfoBlock extends StatelessWidget {
...
@@ -20,8 +20,8 @@ class StateInfoBlock extends StatelessWidget {
child:
Row
(
child:
Row
(
children:
[
children:
[
Container
(
Container
(
width:
80
.
w
,
width:
64
.
w
,
height:
70
.
h
,
height:
53
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
15
.
r
),
borderRadius:
BorderRadius
.
circular
(
15
.
r
),
color:
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
),
color:
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
),
...
@@ -29,25 +29,25 @@ class StateInfoBlock extends StatelessWidget {
...
@@ -29,25 +29,25 @@ class StateInfoBlock extends StatelessWidget {
child:
Icon
(
child:
Icon
(
Icons
.
power
,
Icons
.
power
,
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
size:
3
2
.
sp
,
size:
3
8
.
sp
,
),
),
),
),
SizedBox
(
width:
15
.
w
),
SizedBox
(
width:
15
.
w
),
Expanded
(
Expanded
(
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
8
.
h
,
children:
[
children:
[
Text
(
Text
(
deviceInfo
.
deviceName
,
'
${deviceInfo.location}
${deviceInfo.deviceName}
'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
28
.
sp
,
color:
Colors
.
black
,
color:
Colors
.
black
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
),
),
),
),
SizedBox
(
height:
8
.
h
),
Text
(
Text
(
deviceInfo
.
location
,
'
${deviceInfo.deviceCode}${deviceInfo.deviceName}
·
${deviceInfo.location}
'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
...
...
lib/views/home/index/cubit/home_index_cubit.dart
View file @
9474420e
...
@@ -72,7 +72,7 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
...
@@ -72,7 +72,7 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
EquipmentItem
_mapDeviceToEquipment
(
DeviceItemBO
d
)
{
EquipmentItem
_mapDeviceToEquipment
(
DeviceItemBO
d
)
{
return
EquipmentItem
(
return
EquipmentItem
(
icon:
_mapDeviceIcon
(
d
.
deviceTypeIcon
),
icon:
_mapDeviceIcon
(
d
.
deviceTypeIcon
),
title:
d
.
deviceName
,
title:
d
.
device
Location
+
d
.
device
Name
,
subtitle:
_buildDeviceSubtitle
(
d
),
subtitle:
_buildDeviceSubtitle
(
d
),
// status: d.onlineStatus == '1' ? d.runStatusText : '离线',
// status: d.onlineStatus == '1' ? d.runStatusText : '离线',
status:
d
.
runStatusText
,
status:
d
.
runStatusText
,
...
@@ -82,14 +82,16 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
...
@@ -82,14 +82,16 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
IconData
_mapDeviceIcon
(
String
icon
)
{
IconData
_mapDeviceIcon
(
String
icon
)
{
switch
(
icon
)
{
switch
(
icon
)
{
case
'power'
:
case
'ac'
:
return
Icons
.
power
;
return
Icons
.
air_outlined
;
case
'light'
:
return
Icons
.
light_outlined
;
case
'tv'
:
return
Icons
.
tv_outlined
;
case
'curtain'
:
return
Icons
.
blinds_outlined
;
case
'wifi'
:
case
'wifi'
:
return
Icons
.
wifi
;
return
Icons
.
wifi
;
case
'thermostat'
:
return
Icons
.
thermostat
;
case
'light'
:
return
Icons
.
light
;
default
:
default
:
return
Icons
.
devices_other
;
return
Icons
.
devices_other
;
}
}
...
...
lib/views/home/index/index_view.dart
View file @
9474420e
...
@@ -92,7 +92,7 @@ class _HomeViewState extends State<HomeView> with AutoRouteAwareStateMixin<HomeV
...
@@ -92,7 +92,7 @@ class _HomeViewState extends State<HomeView> with AutoRouteAwareStateMixin<HomeV
List
<
Widget
>
_buildAlertBlocks
(
List
<
AlertItemBO
>
alerts
)
{
List
<
Widget
>
_buildAlertBlocks
(
List
<
AlertItemBO
>
alerts
)
{
final
blocks
=
<
Widget
>[];
final
blocks
=
<
Widget
>[];
for
(
final
alert
in
alerts
)
{
for
(
final
alert
in
alerts
)
{
final
location
=
[
alert
.
roomName
,
alert
.
deviceName
]
final
location
=
[
alert
.
deviceLocation
,
alert
.
deviceCode
+
alert
.
deviceName
]
.
where
((
s
)
=>
s
.
isNotEmpty
)
.
where
((
s
)
=>
s
.
isNotEmpty
)
.
join
(
'·'
);
.
join
(
'·'
);
...
...
lib/views/home/index/widget/temperature_block.dart
View file @
9474420e
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/utils/deal_utils.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
import
'package:smart_hotel_app/utils/toast_utils.dart'
;
...
@@ -46,15 +47,13 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -46,15 +47,13 @@ class TemperatureBlock extends StatelessWidget {
Container
(
Container
(
width:
66
.
w
,
width:
66
.
w
,
height:
54
.
h
,
height:
54
.
h
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
),
color:
const
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
),
),
child:
Icon
(
child:
Image
.
asset
(
'lib/assets/icon/thermostat_bg.png'
,
Icons
.
thermostat_outlined
,
width:
16
.
w
,
height:
32
.
h
),
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
size:
40
.
sp
,
),
),
),
SizedBox
(
width:
16
.
w
),
SizedBox
(
width:
16
.
w
),
Expanded
(
Expanded
(
...
@@ -107,7 +106,8 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -107,7 +106,8 @@ class TemperatureBlock extends StatelessWidget {
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
children:
[
Text
(
Text
(
currentTemperature
.
isNotEmpty
?
currentTemperature
:
'--℃'
,
currentTemperature
.
isNotEmpty
?
DealUtils
.
cleanNumber
(
currentTemperature
)
:
'--℃'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
40
.
sp
,
fontSize:
40
.
sp
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
...
@@ -130,7 +130,8 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -130,7 +130,8 @@ class TemperatureBlock extends StatelessWidget {
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
children:
[
Text
(
Text
(
currentVoltage
.
isNotEmpty
?
currentVoltage
:
'--V'
,
currentVoltage
.
isNotEmpty
?
DealUtils
.
cleanNumber
(
currentVoltage
)
:
'--V'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
40
.
sp
,
fontSize:
40
.
sp
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
...
@@ -153,7 +154,8 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -153,7 +154,8 @@ class TemperatureBlock extends StatelessWidget {
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
children:
[
Text
(
Text
(
currentCurrent
.
isNotEmpty
?
currentCurrent
:
'--A'
,
currentCurrent
.
isNotEmpty
?
DealUtils
.
cleanNumber
(
currentCurrent
)
:
'--A'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
40
.
sp
,
fontSize:
40
.
sp
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
...
@@ -187,20 +189,12 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -187,20 +189,12 @@ class TemperatureBlock extends StatelessWidget {
),
),
SizedBox
(
width:
8
.
w
),
SizedBox
(
width:
8
.
w
),
Text
(
Text
(
waitTime
,
waitTime
.
isNotEmpty
?
waitTime
:
'--'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
),
),
),
),
// Text(
// alarmLevel,
// style: TextStyle(
// fontSize: 24.sp,
// fontWeight: FontWeight.bold,
// color: const Color.fromRGBO(255, 77, 79, 1.0),
// ),
// ),
],
],
),
),
GestureDetector
(
GestureDetector
(
...
...
lib/views/home/index/widget/voltage_operate_block.dart
View file @
9474420e
...
@@ -46,22 +46,15 @@ class VoltageOperateBlock extends StatelessWidget {
...
@@ -46,22 +46,15 @@ class VoltageOperateBlock extends StatelessWidget {
crossAxisAlignment:
CrossAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
children:
[
Container
(
Container
(
width:
6
4
.
w
,
width:
6
6
.
w
,
height:
54
.
h
,
height:
54
.
h
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
),
color:
const
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
borderRadius:
BorderRadius
.
circular
(
12
.
r
),
// border: Border.all(
// color: const Color.fromRGBO(66, 165, 245, 1.0),
// width: 2.w,
// style: BorderStyle.solid,
// ),
),
child:
Icon
(
Icons
.
thermostat_outlined
,
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
size:
40
.
sp
,
),
),
child:
Image
.
asset
(
'lib/assets/icon/thermostat_bg.png'
,
width:
16
.
w
,
height:
32
.
h
),
),
),
SizedBox
(
width:
16
.
w
),
SizedBox
(
width:
16
.
w
),
Expanded
(
Expanded
(
...
@@ -103,7 +96,7 @@ class VoltageOperateBlock extends StatelessWidget {
...
@@ -103,7 +96,7 @@ class VoltageOperateBlock extends StatelessWidget {
width:
double
.
infinity
,
width:
double
.
infinity
,
margin:
EdgeInsets
.
only
(
left:
80
.
w
,
bottom:
20
.
h
),
margin:
EdgeInsets
.
only
(
left:
80
.
w
,
bottom:
20
.
h
),
child:
Text
(
child:
Text
(
'电压
${voltageValue}
V
(正常≤
${normalVoltage}
V)·
$voltageWaitTime
'
,
'电压
${voltageValue}
(正常≤
${normalVoltage}
V)·
$voltageWaitTime
'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
...
...
lib/views/home/inspection/cubit/inspection_cubit.dart
View file @
9474420e
...
@@ -12,9 +12,6 @@ class InspectionCubit extends Cubit<InspectionState> {
...
@@ -12,9 +12,6 @@ class InspectionCubit extends Cubit<InspectionState> {
static
const
int
pageSize
=
20
;
static
const
int
pageSize
=
20
;
/// 完整房间列表缓存,用于在切换 Tab 时按 runStatus 重新过滤
List
<
InspectionRoomBO
>
_allRoomsRaw
=
const
[];
InspectionCubit
({
InspectionCubit
({
InspectionRoomService
?
roomService
,
InspectionRoomService
?
roomService
,
InspectionDeviceService
?
deviceService
,
InspectionDeviceService
?
deviceService
,
...
@@ -30,21 +27,22 @@ class InspectionCubit extends Cubit<InspectionState> {
...
@@ -30,21 +27,22 @@ class InspectionCubit extends Cubit<InspectionState> {
Future
<
void
>
initData
()
async
{
Future
<
void
>
initData
()
async
{
try
{
try
{
final
rooms
=
await
_roomService
.
getRooms
();
final
rooms
=
await
_roomService
.
getRooms
();
_allRoomsRaw
=
rooms
;
final
tabCounts
=
_computeTabCounts
(
rooms
.
runStatus
)
;
final
roomGroups
=
rooms
.
roomGroups
;
final
tabCounts
=
_computeTabCounts
(
rooms
);
final
filteredRooms
=
_filterRooms
(
rooms
,
state
.
selectedTab
);
// 默认选中第一个区域、第一个房间
final
defaultAreaIndex
=
roomGroups
.
isNotEmpty
?
0
:
0
;
// 仅当首次进入(之前没有选过房间)时,默认选中过滤后的第一个房间
final
defaultRoomId
=
roomGroups
.
isNotEmpty
&&
final
initialRoomIds
=
filteredR
ooms
.
isNotEmpty
roomGroups
[
defaultAreaIndex
].
r
ooms
.
isNotEmpty
?
[
filteredRooms
.
entries
.
first
.
key
]
?
roomGroups
[
defaultAreaIndex
].
rooms
.
first
.
roomId
:
<
int
>[]
;
:
null
;
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
isLoading:
false
,
isLoading:
false
,
error:
null
,
error:
null
,
allRooms:
filteredRooms
,
roomGroups:
roomGroups
,
selectedRoomIds:
initialRoomIds
,
selectedAreaIndex:
defaultAreaIndex
,
selectedRoomId:
defaultRoomId
,
tabCounts:
tabCounts
,
tabCounts:
tabCounts
,
));
));
}
catch
(
e
)
{
}
catch
(
e
)
{
...
@@ -55,20 +53,30 @@ class InspectionCubit extends Cubit<InspectionState> {
...
@@ -55,20 +53,30 @@ class InspectionCubit extends Cubit<InspectionState> {
}
}
}
}
/// 从顶层 runStatus 汇总计算各 tab 数量
Map
<
DeviceStatusTab
,
int
>
_computeTabCounts
(
InspectionRoomRunStatusBO
runStatus
)
{
final
total
=
runStatus
.
normal
+
runStatus
.
warning
+
runStatus
.
offline
+
runStatus
.
fault
;
return
{
DeviceStatusTab
.
total
:
total
,
DeviceStatusTab
.
on
:
runStatus
.
normal
,
DeviceStatusTab
.
off
:
0
,
DeviceStatusTab
.
offline
:
runStatus
.
offline
,
DeviceStatusTab
.
alarm
:
runStatus
.
warning
,
DeviceStatusTab
.
fault
:
runStatus
.
fault
,
};
}
/// 供 PagingController.fetchPage 回调使用
/// 供 PagingController.fetchPage 回调使用
Future
<
List
<
InspectionDevice
>>
fetchPage
(
int
pageKey
)
async
{
Future
<
List
<
InspectionDevice
>>
fetchPage
(
int
pageKey
)
async
{
final
roomId
=
state
.
selectedRoomIds
.
length
==
1
?
state
.
selectedRoomIds
.
first
:
null
;
final
result
=
await
_deviceService
.
getList
(
final
result
=
await
_deviceService
.
getList
(
pageSize:
pageSize
,
pageSize:
pageSize
,
pageNum:
pageKey
,
pageNum:
pageKey
,
roomId:
r
oomId
,
roomId:
state
.
selectedR
oomId
,
runStatus:
state
.
selectedTab
.
runStatus
,
runStatus:
state
.
selectedTab
.
runStatus
,
);
);
// 首页时记录总数,供翻页判断是否到底
if
(
pageKey
==
1
)
{
if
(
pageKey
==
1
)
{
emit
(
state
.
copyWith
(
totalCount:
result
.
total
));
emit
(
state
.
copyWith
(
totalCount:
result
.
total
));
}
}
...
@@ -78,87 +86,20 @@ class InspectionCubit extends Cubit<InspectionState> {
...
@@ -78,87 +86,20 @@ class InspectionCubit extends Cubit<InspectionState> {
.
toList
();
.
toList
();
}
}
Map
<
DeviceStatusTab
,
int
>
_computeTabCounts
(
List
<
InspectionRoomBO
>
rooms
)
{
int
normal
=
0
;
int
warning
=
0
;
int
offline
=
0
;
int
fault
=
0
;
for
(
final
room
in
rooms
)
{
normal
+=
room
.
runStatus
.
normal
;
warning
+=
room
.
runStatus
.
warning
;
offline
+=
room
.
runStatus
.
offline
;
fault
+=
room
.
runStatus
.
fault
;
}
return
{
DeviceStatusTab
.
total
:
normal
+
warning
+
offline
+
fault
,
DeviceStatusTab
.
on
:
normal
,
DeviceStatusTab
.
off
:
0
,
DeviceStatusTab
.
offline
:
offline
,
DeviceStatusTab
.
alarm
:
warning
,
DeviceStatusTab
.
fault
:
fault
,
};
}
/// 根据 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
)
{
void
selectTab
(
DeviceStatusTab
tab
)
{
final
filteredRooms
=
_filterRooms
(
_allRoomsRaw
,
tab
);
emit
(
state
.
copyWith
(
selectedTab:
tab
));
}
// 过滤后剔除已不存在的已选房间;若全被剔除则默认选第一个
final
keptSelection
=
state
.
selectedRoomIds
.
where
(
filteredRooms
.
containsKey
)
.
toList
();
final
newSelectedRoomIds
=
keptSelection
.
isNotEmpty
?
keptSelection
:
(
filteredRooms
.
isNotEmpty
?
[
filteredRooms
.
entries
.
first
.
key
]
:
<
int
>[]);
void
selectArea
(
int
index
)
{
if
(
index
<
0
||
index
>=
state
.
roomGroups
.
length
)
return
;
final
rooms
=
state
.
roomGroups
[
index
].
rooms
;
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
selectedTab:
tab
,
selectedAreaIndex:
index
,
allRooms:
filteredRooms
,
selectedRoomId:
rooms
.
isNotEmpty
?
rooms
.
first
.
roomId
:
null
,
selectedRoomIds:
newSelectedRoomIds
,
));
));
}
}
void
toggleRoom
(
int
roomId
)
{
void
selectRoom
(
int
roomId
)
{
final
List
<
int
>
newSelected
=
List
.
from
(
state
.
selectedRoomIds
);
emit
(
state
.
copyWith
(
selectedRoomId:
roomId
));
if
(
newSelected
.
contains
(
roomId
))
{
newSelected
.
remove
(
roomId
);
}
else
{
newSelected
.
clear
();
newSelected
.
add
(
roomId
);
}
emit
(
state
.
copyWith
(
selectedRoomIds:
newSelected
));
}
}
}
}
lib/views/home/inspection/cubit/inspection_state.dart
View file @
9474420e
import
'package:equatable/equatable.dart'
;
import
'package:equatable/equatable.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:smart_hotel_app/models/bo/inspection_device_bo.dart'
;
import
'package:smart_hotel_app/models/bo/inspection_device_bo.dart'
;
import
'package:smart_hotel_app/models/bo/inspection_room_bo.dart'
;
enum
DeviceStatusTab
{
total
,
on
,
off
,
offline
,
alarm
,
fault
}
enum
DeviceStatusTab
{
total
,
on
,
off
,
offline
,
alarm
,
fault
}
...
@@ -61,6 +62,8 @@ class InspectionDevice {
...
@@ -61,6 +62,8 @@ class InspectionDevice {
static
IconData
_mapIcon
(
String
iconType
)
{
static
IconData
_mapIcon
(
String
iconType
)
{
switch
(
iconType
)
{
switch
(
iconType
)
{
case
'curtain'
:
return
Icons
.
blinds_outlined
;
case
'gateway'
:
case
'gateway'
:
return
Icons
.
wifi
;
return
Icons
.
wifi
;
case
'sensor'
:
case
'sensor'
:
...
@@ -107,8 +110,9 @@ class InspectionState extends Equatable {
...
@@ -107,8 +110,9 @@ class InspectionState extends Equatable {
final
bool
isLoading
;
final
bool
isLoading
;
final
String
?
error
;
final
String
?
error
;
final
DeviceStatusTab
selectedTab
;
final
DeviceStatusTab
selectedTab
;
final
List
<
int
>
selectedRoomIds
;
final
int
selectedAreaIndex
;
final
Map
<
int
,
String
>
allRooms
;
final
int
?
selectedRoomId
;
final
List
<
InspectionRoomGroupsBO
>
roomGroups
;
final
Map
<
DeviceStatusTab
,
int
>
tabCounts
;
final
Map
<
DeviceStatusTab
,
int
>
tabCounts
;
final
int
totalCount
;
final
int
totalCount
;
...
@@ -116,8 +120,9 @@ class InspectionState extends Equatable {
...
@@ -116,8 +120,9 @@ class InspectionState extends Equatable {
this
.
isLoading
=
false
,
this
.
isLoading
=
false
,
this
.
error
,
this
.
error
,
this
.
selectedTab
=
DeviceStatusTab
.
total
,
this
.
selectedTab
=
DeviceStatusTab
.
total
,
this
.
selectedRoomIds
=
const
[],
this
.
selectedAreaIndex
=
0
,
this
.
allRooms
=
const
{},
this
.
selectedRoomId
,
this
.
roomGroups
=
const
[],
this
.
tabCounts
=
const
{
this
.
tabCounts
=
const
{
DeviceStatusTab
.
total
:
0
,
DeviceStatusTab
.
total
:
0
,
DeviceStatusTab
.
on
:
0
,
DeviceStatusTab
.
on
:
0
,
...
@@ -133,8 +138,9 @@ class InspectionState extends Equatable {
...
@@ -133,8 +138,9 @@ class InspectionState extends Equatable {
bool
?
isLoading
,
bool
?
isLoading
,
String
?
error
,
String
?
error
,
DeviceStatusTab
?
selectedTab
,
DeviceStatusTab
?
selectedTab
,
List
<
int
>?
selectedRoomIds
,
int
?
selectedAreaIndex
,
Map
<
int
,
String
>?
allRooms
,
int
?
selectedRoomId
,
List
<
InspectionRoomGroupsBO
>?
roomGroups
,
Map
<
DeviceStatusTab
,
int
>?
tabCounts
,
Map
<
DeviceStatusTab
,
int
>?
tabCounts
,
int
?
totalCount
,
int
?
totalCount
,
})
{
})
{
...
@@ -142,8 +148,9 @@ class InspectionState extends Equatable {
...
@@ -142,8 +148,9 @@ class InspectionState extends Equatable {
isLoading:
isLoading
??
this
.
isLoading
,
isLoading:
isLoading
??
this
.
isLoading
,
error:
error
,
error:
error
,
selectedTab:
selectedTab
??
this
.
selectedTab
,
selectedTab:
selectedTab
??
this
.
selectedTab
,
selectedRoomIds:
selectedRoomIds
??
this
.
selectedRoomIds
,
selectedAreaIndex:
selectedAreaIndex
??
this
.
selectedAreaIndex
,
allRooms:
allRooms
??
this
.
allRooms
,
selectedRoomId:
selectedRoomId
??
this
.
selectedRoomId
,
roomGroups:
roomGroups
??
this
.
roomGroups
,
tabCounts:
tabCounts
??
this
.
tabCounts
,
tabCounts:
tabCounts
??
this
.
tabCounts
,
totalCount:
totalCount
??
this
.
totalCount
,
totalCount:
totalCount
??
this
.
totalCount
,
);
);
...
@@ -154,8 +161,9 @@ class InspectionState extends Equatable {
...
@@ -154,8 +161,9 @@ class InspectionState extends Equatable {
isLoading
,
isLoading
,
error
,
error
,
selectedTab
,
selectedTab
,
selectedRoomIds
,
selectedAreaIndex
,
allRooms
,
selectedRoomId
,
roomGroups
,
tabCounts
,
tabCounts
,
totalCount
,
totalCount
,
];
];
...
...
lib/views/home/inspection/inspection_detail_view.dart
View file @
9474420e
...
@@ -33,7 +33,7 @@ class _InspectionDetailBodyState extends State<_InspectionDetailBody> {
...
@@ -33,7 +33,7 @@ class _InspectionDetailBodyState extends State<_InspectionDetailBody> {
late
final
PagingController
<
int
,
InspectionDevice
>
_pagingController
;
late
final
PagingController
<
int
,
InspectionDevice
>
_pagingController
;
late
final
InspectionCubit
_cubit
;
late
final
InspectionCubit
_cubit
;
DeviceStatusTab
?
_lastTab
;
DeviceStatusTab
?
_lastTab
;
List
<
int
>?
_lastRoomIds
;
int
?
_lastRoomId
;
@override
@override
void
initState
()
{
void
initState
()
{
...
@@ -55,9 +55,9 @@ class _InspectionDetailBodyState extends State<_InspectionDetailBody> {
...
@@ -55,9 +55,9 @@ class _InspectionDetailBodyState extends State<_InspectionDetailBody> {
void
_checkFilterChanged
(
InspectionState
state
)
{
void
_checkFilterChanged
(
InspectionState
state
)
{
if
(
_lastTab
!=
state
.
selectedTab
||
if
(
_lastTab
!=
state
.
selectedTab
||
_lastRoomId
s
!=
state
.
selectedRoomIds
)
{
_lastRoomId
!=
state
.
selectedRoomId
)
{
_lastTab
=
state
.
selectedTab
;
_lastTab
=
state
.
selectedTab
;
_lastRoomId
s
=
state
.
selectedRoomIds
;
_lastRoomId
=
state
.
selectedRoomId
;
_pagingController
.
refresh
();
_pagingController
.
refresh
();
}
}
}
}
...
@@ -138,9 +138,11 @@ class _InspectionDetailBodyState extends State<_InspectionDetailBody> {
...
@@ -138,9 +138,11 @@ class _InspectionDetailBodyState extends State<_InspectionDetailBody> {
selectedTab:
state
.
selectedTab
,
selectedTab:
state
.
selectedTab
,
tabCounts:
state
.
tabCounts
,
tabCounts:
state
.
tabCounts
,
onTabSelected:
cubit
.
selectTab
,
onTabSelected:
cubit
.
selectTab
,
selectedRoomIds:
state
.
selectedRoomIds
,
selectedAreaIndex:
state
.
selectedAreaIndex
,
allRooms:
state
.
allRooms
,
selectedRoomId:
state
.
selectedRoomId
,
onRoomToggle:
cubit
.
toggleRoom
,
roomGroups:
state
.
roomGroups
,
onAreaSelected:
cubit
.
selectArea
,
onRoomSelected:
cubit
.
selectRoom
,
),
),
),
),
),
),
...
...
lib/views/home/inspection/widget/device_list_item.dart
View file @
9474420e
...
@@ -87,7 +87,7 @@ class DeviceListItem extends StatelessWidget {
...
@@ -87,7 +87,7 @@ class DeviceListItem extends StatelessWidget {
),
),
SizedBox
(
width:
4
.
w
),
SizedBox
(
width:
4
.
w
),
Text
(
Text
(
device
.
time
,
device
.
time
.
isNotEmpty
?
device
.
time
:
'--'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
...
...
lib/views/home/inspection/widget/filter_panel.dart
View file @
9474420e
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/models/bo/inspection_room_bo.dart'
;
import
'../cubit/inspection_state.dart'
;
import
'../cubit/inspection_state.dart'
;
class
FilterPanel
extends
StatelessWidget
{
class
FilterPanel
extends
StatelessWidget
{
final
DeviceStatusTab
selectedTab
;
final
DeviceStatusTab
selectedTab
;
final
Map
<
DeviceStatusTab
,
int
>
tabCounts
;
final
Map
<
DeviceStatusTab
,
int
>
tabCounts
;
final
Function
(
DeviceStatusTab
)
onTabSelected
;
final
Function
(
DeviceStatusTab
)
onTabSelected
;
final
List
<
int
>
selectedRoomIds
;
final
int
selectedAreaIndex
;
final
Map
<
int
,
String
>
allRooms
;
final
int
?
selectedRoomId
;
final
Function
(
int
)
onRoomToggle
;
final
List
<
InspectionRoomGroupsBO
>
roomGroups
;
final
Function
(
int
)
onAreaSelected
;
final
Function
(
int
)
onRoomSelected
;
const
FilterPanel
({
const
FilterPanel
({
super
.
key
,
super
.
key
,
required
this
.
selectedTab
,
required
this
.
selectedTab
,
required
this
.
tabCounts
,
required
this
.
tabCounts
,
required
this
.
onTabSelected
,
required
this
.
onTabSelected
,
required
this
.
selectedRoomIds
,
required
this
.
selectedAreaIndex
,
required
this
.
allRooms
,
required
this
.
selectedRoomId
,
required
this
.
onRoomToggle
,
required
this
.
roomGroups
,
required
this
.
onAreaSelected
,
required
this
.
onRoomSelected
,
});
});
@override
@override
...
@@ -32,7 +37,15 @@ class FilterPanel extends StatelessWidget {
...
@@ -32,7 +37,15 @@ class FilterPanel extends StatelessWidget {
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
_buildStatusTabs
(),
_buildStatusTabs
(),
SizedBox
(
height:
32
.
h
),
SizedBox
(
height:
16
.
h
),
Divider
(
height:
0.5
.
h
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
thickness:
0.5
,
),
SizedBox
(
height:
16
.
h
),
_buildAreaTabs
(),
SizedBox
(
height:
16
.
h
),
_buildRoomSelector
(),
_buildRoomSelector
(),
],
],
),
),
...
@@ -75,14 +88,13 @@ class FilterPanel extends StatelessWidget {
...
@@ -75,14 +88,13 @@ class FilterPanel extends StatelessWidget {
),
),
Positioned
(
Positioned
(
top:
-
20
.
h
,
top:
-
20
.
h
,
right:
-
18
.
h
,
right:
-
25
.
w
,
child:
Container
(
child:
Container
(
constraints:
BoxConstraints
(
constraints:
BoxConstraints
(
minWidth:
3
2
.
w
,
minWidth:
3
6
.
w
,
minHeight:
3
2
.
w
,
minHeight:
3
6
.
w
,
),
),
padding:
padding:
EdgeInsets
.
symmetric
(
horizontal:
15
.
w
),
EdgeInsets
.
symmetric
(
horizontal:
6
.
w
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
_getTabColor
(
tab
),
color:
_getTabColor
(
tab
),
shape:
BoxShape
.
circle
,
shape:
BoxShape
.
circle
,
...
@@ -93,7 +105,6 @@ class FilterPanel extends StatelessWidget {
...
@@ -93,7 +105,6 @@ class FilterPanel extends StatelessWidget {
style:
TextStyle
(
style:
TextStyle
(
fontSize:
14
.
sp
,
fontSize:
14
.
sp
,
color:
Colors
.
white
,
color:
Colors
.
white
,
height:
1.0
,
),
),
),
),
),
),
...
@@ -119,71 +130,80 @@ class FilterPanel extends StatelessWidget {
...
@@ -119,71 +130,80 @@ class FilterPanel extends StatelessWidget {
);
);
}
}
Widget
_buildRoomSelector
()
{
/// 区域切换 tab
final
roomEntries
=
allRooms
.
entries
.
toList
();
Widget
_buildAreaTabs
()
{
return
Column
(
if
(
roomGroups
.
isEmpty
)
{
crossAxisAlignment:
CrossAxisAlignment
.
start
,
return
const
SizedBox
.
shrink
();
children:
[
}
Text
(
return
SingleChildScrollView
(
'全部区域'
,
scrollDirection:
Axis
.
horizontal
,
child:
Row
(
children:
roomGroups
.
asMap
().
entries
.
map
((
entry
)
{
final
index
=
entry
.
key
;
final
group
=
entry
.
value
;
final
isSelected
=
index
==
selectedAreaIndex
;
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
=>
onAreaSelected
(
index
),
child:
Container
(
width:
100
.
w
,
height:
40
.
h
,
alignment:
Alignment
.
center
,
margin:
EdgeInsets
.
only
(
right:
16
.
w
),
decoration:
BoxDecoration
(
color:
isSelected
?
const
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
)
:
const
Color
.
fromRGBO
(
238
,
238
,
238
,
1.0
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
border:
isSelected
?
Border
.
all
(
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
width:
1
.
w
,
)
:
null
,
),
child:
Text
(
group
.
areaTypeName
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
24
.
sp
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
isSelected
?
FontWeight
.
w600
:
FontWeight
.
normal
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
color:
isSelected
?
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
)
:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
),
),
),
),
SizedBox
(
height:
16
.
h
),
),
if
(
roomEntries
.
isEmpty
)
);
Text
(
}).
toList
(),
),
);
}
/// 当前选中区域的房间 GridView
Widget
_buildRoomSelector
()
{
if
(
roomGroups
.
isEmpty
||
selectedAreaIndex
>=
roomGroups
.
length
)
{
return
Text
(
'暂无房间数据'
,
'暂无房间数据'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.6
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.6
),
),
),
)
);
else
}
// Wrap(
// spacing: 12.w,
final
rooms
=
roomGroups
[
selectedAreaIndex
].
rooms
;
// runSpacing: 12.h,
// children: roomEntries.map((entry) {
if
(
rooms
.
isEmpty
)
{
// final isSelected = selectedRoomIds.contains(entry.key);
return
Text
(
// return GestureDetector(
'暂无房间数据'
,
// onTap: () => onRoomToggle(entry.key),
style:
TextStyle
(
// child: Container(
fontSize:
24
.
sp
,
// width: 120.w,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.6
),
// height: 60.h,
),
// alignment: Alignment.center,
);
// padding: EdgeInsets.symmetric(horizontal: 5.w),
}
// decoration: BoxDecoration(
// color: isSelected
return
GridView
.
builder
(
// ? const Color.fromRGBO(235, 244, 255, 1.0)
// : Colors.white,
// borderRadius: BorderRadius.circular(12.r),
// border: Border.all(
// color: isSelected
// ? const Color.fromRGBO(66, 165, 245, 1.0)
// : const Color.fromRGBO(200, 208, 220, 1.0),
// width: 1.w,
// ),
// ),
// child: Text(
// entry.value,
// style: TextStyle(
// fontSize: 24.sp,
// color: isSelected
// ? const Color.fromRGBO(66, 165, 245, 1.0)
// : const Color.fromRGBO(100, 116, 139, 1.0),
// fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
// ),
// textAlign: TextAlign.center,
// maxLines: 2,
// overflow: TextOverflow.ellipsis,
// ),
// ),
// );
// }).toList(),
// ),
GridView
.
builder
(
shrinkWrap:
true
,
shrinkWrap:
true
,
physics:
const
NeverScrollableScrollPhysics
(),
physics:
const
NeverScrollableScrollPhysics
(),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount
(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount
(
...
@@ -192,12 +212,12 @@ class FilterPanel extends StatelessWidget {
...
@@ -192,12 +212,12 @@ class FilterPanel extends StatelessWidget {
crossAxisSpacing:
12
.
w
,
crossAxisSpacing:
12
.
w
,
mainAxisSpacing:
12
.
h
,
mainAxisSpacing:
12
.
h
,
),
),
itemCount:
roomEntrie
s
.
length
,
itemCount:
room
s
.
length
,
itemBuilder:
(
context
,
index
)
{
itemBuilder:
(
context
,
index
)
{
final
entry
=
roomEntrie
s
[
index
];
final
room
=
room
s
[
index
];
final
isSelected
=
selectedRoomIds
.
contains
(
entry
.
key
)
;
final
isSelected
=
room
.
roomId
==
selectedRoomId
;
return
GestureDetector
(
return
GestureDetector
(
onTap:
()
=>
onRoomToggle
(
entry
.
key
),
onTap:
()
=>
onRoomSelected
(
room
.
roomId
),
child:
Container
(
child:
Container
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
5
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
5
.
w
),
...
@@ -214,7 +234,7 @@ class FilterPanel extends StatelessWidget {
...
@@ -214,7 +234,7 @@ class FilterPanel extends StatelessWidget {
),
),
),
),
child:
Text
(
child:
Text
(
entry
.
value
,
room
.
roomNumber
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
isSelected
color:
isSelected
...
@@ -229,8 +249,6 @@ class FilterPanel extends StatelessWidget {
...
@@ -229,8 +249,6 @@ class FilterPanel extends StatelessWidget {
),
),
);
);
},
},
),
],
);
);
}
}
...
...
lib/views/home/inspection_device/inspection_device_view.dart
View file @
9474420e
...
@@ -68,6 +68,7 @@ class InspectionDeviceView extends StatelessWidget {
...
@@ -68,6 +68,7 @@ class InspectionDeviceView extends StatelessWidget {
child:
BlocBuilder
<
InspectionDeviceCubit
,
InspectionDeviceState
>(
child:
BlocBuilder
<
InspectionDeviceCubit
,
InspectionDeviceState
>(
builder:
(
context
,
state
)
{
builder:
(
context
,
state
)
{
return
Column
(
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
DeviceOverviewCard
(
DeviceOverviewCard
(
deviceName:
state
.
deviceName
,
deviceName:
state
.
deviceName
,
...
@@ -82,6 +83,15 @@ class InspectionDeviceView extends StatelessWidget {
...
@@ -82,6 +83,15 @@ class InspectionDeviceView extends StatelessWidget {
),
),
if
(
state
.
inspectionHistory
.
isNotEmpty
)
...[
if
(
state
.
inspectionHistory
.
isNotEmpty
)
...[
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
20
.
h
),
Text
(
'巡检历史 (
${state.inspectionHistory.length}
)'
,
style:
TextStyle
(
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
),
),
SizedBox
(
height:
10
.
h
),
InspectionHistoryCard
(
InspectionHistoryCard
(
historyList:
state
.
inspectionHistory
,
historyList:
state
.
inspectionHistory
,
),
),
...
...
lib/views/home/inspection_device/widget/device_overview_card.dart
View file @
9474420e
...
@@ -37,10 +37,11 @@ class DeviceOverviewCard extends StatelessWidget {
...
@@ -37,10 +37,11 @@ class DeviceOverviewCard extends StatelessWidget {
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
Row
(
Row
(
spacing:
20
.
w
,
children:
[
children:
[
Container
(
Container
(
width:
10
0
.
w
,
width:
9
0
.
w
,
height:
10
0
.
h
,
height:
9
0
.
h
,
decoration:
const
BoxDecoration
(
decoration:
const
BoxDecoration
(
color:
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
),
color:
Color
.
fromRGBO
(
235
,
244
,
255
,
1.0
),
shape:
BoxShape
.
circle
,
shape:
BoxShape
.
circle
,
...
@@ -48,13 +49,13 @@ class DeviceOverviewCard extends StatelessWidget {
...
@@ -48,13 +49,13 @@ class DeviceOverviewCard extends StatelessWidget {
child:
Icon
(
child:
Icon
(
icon
,
icon
,
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
size:
5
0
.
sp
,
size:
4
0
.
sp
,
),
),
),
),
SizedBox
(
width:
20
.
w
),
Expanded
(
Expanded
(
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
5
.
h
,
children:
[
children:
[
Text
(
Text
(
deviceName
,
deviceName
,
...
@@ -64,7 +65,6 @@ class DeviceOverviewCard extends StatelessWidget {
...
@@ -64,7 +65,6 @@ class DeviceOverviewCard extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
),
),
),
),
SizedBox
(
height:
12
.
h
),
Text
(
Text
(
deviceType
,
deviceType
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -72,9 +72,14 @@ class DeviceOverviewCard extends StatelessWidget {
...
@@ -72,9 +72,14 @@ class DeviceOverviewCard extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
),
),
),
),
SizedBox
(
height:
16
.
h
),
],
),
),
],
),
Container
(
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
24
.
w
,
vertical:
10
.
h
),
margin:
EdgeInsets
.
only
(
left:
110
.
w
,
top:
5
.
h
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
12
.
w
,
vertical:
4
.
h
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
deviceStatus
==
'1'
color:
deviceStatus
==
'1'
?
const
Color
.
fromRGBO
(
225
,
245
,
238
,
1.0
)
?
const
Color
.
fromRGBO
(
225
,
245
,
238
,
1.0
)
...
@@ -84,18 +89,12 @@ class DeviceOverviewCard extends StatelessWidget {
...
@@ -84,18 +89,12 @@ class DeviceOverviewCard extends StatelessWidget {
child:
Text
(
child:
Text
(
deviceStatus
==
'1'
?
'在线'
:
'离线'
,
deviceStatus
==
'1'
?
'在线'
:
'离线'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
24
.
sp
,
color:
deviceStatus
==
'1'
color:
deviceStatus
==
'1'
?
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)
?
const
Color
.
fromRGBO
(
209
,
250
,
229
,
1.0
)
:
const
Color
.
fromRGBO
(
231
,
76
,
60
,
1.0
),
:
const
Color
.
fromRGBO
(
231
,
76
,
60
,
1.0
),
fontWeight:
FontWeight
.
bold
,
),
),
),
],
),
),
),
),
],
),
),
SizedBox
(
height:
32
.
h
),
SizedBox
(
height:
32
.
h
),
Text
(
Text
(
...
...
lib/views/home/inspection_device/widget/inspection_history_card.dart
View file @
9474420e
...
@@ -24,15 +24,6 @@ class InspectionHistoryCard extends StatelessWidget {
...
@@ -24,15 +24,6 @@ class InspectionHistoryCard extends StatelessWidget {
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
Text
(
'巡检历史 (
${historyList.length}
)'
,
style:
TextStyle
(
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
),
),
SizedBox
(
height:
20
.
h
),
...
historyList
.
map
((
item
)
=>
_buildHistoryItem
(
item
)).
toList
(),
...
historyList
.
map
((
item
)
=>
_buildHistoryItem
(
item
)).
toList
(),
],
],
),
),
...
@@ -77,7 +68,7 @@ class InspectionHistoryCard extends StatelessWidget {
...
@@ -77,7 +68,7 @@ class InspectionHistoryCard extends StatelessWidget {
spacing:
4
.
h
,
spacing:
4
.
h
,
children:
[
children:
[
Text
(
Text
(
item
.
inspectorName
,
item
.
inspectorName
.
isNotEmpty
?
item
.
inspectorName
:
'--'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
26
.
sp
,
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
...
@@ -93,7 +84,7 @@ class InspectionHistoryCard extends StatelessWidget {
...
@@ -93,7 +84,7 @@ class InspectionHistoryCard extends StatelessWidget {
),
),
SizedBox
(
width:
4
.
w
),
SizedBox
(
width:
4
.
w
),
Text
(
Text
(
item
.
inspectionTime
,
item
.
inspectionTime
.
isNotEmpty
?
item
.
inspectionTime
:
'--'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1.0
),
...
@@ -106,21 +97,24 @@ class InspectionHistoryCard extends StatelessWidget {
...
@@ -106,21 +97,24 @@ class InspectionHistoryCard extends StatelessWidget {
],
],
),
),
Container
(
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
4
.
h
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
2
.
h
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
225
,
245
,
238
,
1.0
),
color:
const
Color
.
fromRGBO
(
225
,
245
,
238
,
1.0
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
),
child:
Row
(
child:
Row
(
spacing:
4
.
w
,
children:
[
children:
[
Icon
(
Icon
(
Icons
.
check
,
Icons
.
check
,
color:
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
),
color:
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
),
size:
24
.
sp
,
size:
24
.
sp
,
),
),
SizedBox
(
width:
4
.
w
),
Text
(
Text
(
item
.
result
,
item
.
result
==
'0'
?
'巡检中'
:
item
.
result
==
'1'
?
'不通过'
:
item
.
result
==
'2'
?
'通过'
:
item
.
result
==
'3'
?
'警告'
:
''
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
),
color:
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
),
...
...
lib/views/home/inspection_device/widget/inspection_items_card.dart
View file @
9474420e
...
@@ -79,7 +79,8 @@ class InspectionItemsCard extends StatelessWidget {
...
@@ -79,7 +79,8 @@ class InspectionItemsCard extends StatelessWidget {
),
),
SizedBox
(
width:
4
.
w
),
SizedBox
(
width:
4
.
w
),
Text
(
Text
(
item
.
result
,
// item.result,
'通过'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
),
color:
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
),
...
...
lib/views/home/inspection_topology/cubit/inspection_topology_cubit.dart
View file @
9474420e
...
@@ -49,8 +49,8 @@ class InspectionTopologyCubit extends Cubit<InspectionTopologyState> {
...
@@ -49,8 +49,8 @@ class InspectionTopologyCubit extends Cubit<InspectionTopologyState> {
final
rootNode
=
_buildTopologyTree
(
treeNodes
);
final
rootNode
=
_buildTopologyTree
(
treeNodes
);
emit
(
InspectionTopologyState
(
emit
(
InspectionTopologyState
(
deviceName:
info
.
deviceName
,
deviceName:
'
${info.deviceLocation}
${info.deviceName}
'
,
deviceModel:
'
${info.deviceCode}
·
${info.deviceLocation}
'
,
deviceModel:
'
${info.deviceCode}
${info.deviceName}
·
${info.deviceLocation}
'
,
topologyNodes:
[
rootNode
],
topologyNodes:
[
rootNode
],
deviceCount:
_countAllNodes
(
rootNode
),
deviceCount:
_countAllNodes
(
rootNode
),
connectionCount:
_countConnections
(
rootNode
),
connectionCount:
_countConnections
(
rootNode
),
...
...
lib/views/home/inspection_topology/widget/device_detail_dialog.dart
View file @
9474420e
...
@@ -48,7 +48,7 @@ class DeviceDetailDialog extends StatelessWidget {
...
@@ -48,7 +48,7 @@ class DeviceDetailDialog extends StatelessWidget {
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
children:
[
Container
(
Container
(
margin:
EdgeInsets
.
only
(
top:
2
0
.
h
),
margin:
EdgeInsets
.
only
(
top:
4
0
.
h
),
width:
120
.
w
,
width:
120
.
w
,
height:
8
.
h
,
height:
8
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
...
@@ -65,14 +65,14 @@ class DeviceDetailDialog extends StatelessWidget {
...
@@ -65,14 +65,14 @@ class DeviceDetailDialog extends StatelessWidget {
children:
[
children:
[
Container
(
Container
(
width:
80
.
w
,
width:
80
.
w
,
height:
80
.
h
,
height:
64
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
239
,
246
,
255
,
1
),
color:
const
Color
.
fromRGBO
(
239
,
246
,
255
,
1
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
),
),
child:
Icon
(
child:
Icon
(
_getDeviceIcon
(
node
.
name
),
_getDeviceIcon
(
node
.
name
),
size:
8
0
.
sp
,
size:
4
0
.
sp
,
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
),
),
),
),
...
@@ -102,15 +102,15 @@ class DeviceDetailDialog extends StatelessWidget {
...
@@ -102,15 +102,15 @@ class DeviceDetailDialog extends StatelessWidget {
),
),
Container
(
Container
(
padding:
EdgeInsets
.
symmetric
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
24
.
w
,
horizontal:
16
.
w
,
vertical:
1
2
.
h
,
vertical:
2
.
h
,
),
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
209
,
250
,
229
,
1
),
color:
const
Color
.
fromRGBO
(
209
,
250
,
229
,
1
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
),
child:
Text
(
child:
Text
(
node
.
statusText
??
'-'
,
node
.
statusText
??
'-
-
'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
fontWeight:
FontWeight
.
w500
,
fontWeight:
FontWeight
.
w500
,
...
@@ -145,7 +145,7 @@ class DeviceDetailDialog extends StatelessWidget {
...
@@ -145,7 +145,7 @@ class DeviceDetailDialog extends StatelessWidget {
),
),
),
),
Text
(
Text
(
'
${node.id}
'
,
node
.
id
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
fontWeight:
FontWeight
.
w500
,
fontWeight:
FontWeight
.
w500
,
...
@@ -192,7 +192,7 @@ class DeviceDetailDialog extends StatelessWidget {
...
@@ -192,7 +192,7 @@ class DeviceDetailDialog extends StatelessWidget {
}
}
},
},
style:
ElevatedButton
.
styleFrom
(
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
backgroundColor:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
shape:
RoundedRectangleBorder
(
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
borderRadius:
BorderRadius
.
circular
(
40
.
r
),
),
),
...
...
lib/views/home/inspection_topology/widget/device_header_widget.dart
View file @
9474420e
...
@@ -26,7 +26,7 @@ class DeviceHeaderWidget extends StatelessWidget {
...
@@ -26,7 +26,7 @@ class DeviceHeaderWidget extends StatelessWidget {
children:
[
children:
[
Container
(
Container
(
width:
64
.
w
,
width:
64
.
w
,
height:
64
.
h
,
height:
53
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
),
color:
const
Color
.
fromRGBO
(
219
,
234
,
254
,
1
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
...
...
lib/views/home/inspection_topology/widget/network_topology_widget.dart
View file @
9474420e
import
'dart:math'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'../cubit/inspection_topology_state.dart'
;
import
'../cubit/inspection_topology_state.dart'
;
...
@@ -40,6 +42,14 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -40,6 +42,14 @@ class NetworkTopologyWidget extends StatelessWidget {
final
lastLevelCount
=
depthCounts
[
maxDepth
]
??
0
;
final
lastLevelCount
=
depthCounts
[
maxDepth
]
??
0
;
final
useVerticalLeaf
=
lastLevelCount
>
3
;
final
useVerticalLeaf
=
lastLevelCount
>
3
;
// 计算动态高度:竖向叶子节点文字越多,需要越高
final
maxVerticalChars
=
topologyNodes
.
isNotEmpty
?
_maxVerticalChars
(
topologyNodes
[
0
],
0
,
maxDepth
,
useVerticalLeaf
)
:
0
;
// 基础高度 800.h,每个超出4个字的多余字符增加 30.h
final
extraHeight
=
maxVerticalChars
>
4
?
(
maxVerticalChars
-
4
)
*
30
.
h
:
0.0
;
final
topologyHeight
=
max
(
800
.
h
,
800
.
h
+
extraHeight
);
return
Container
(
return
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
24
.
w
,
vertical:
32
.
h
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
24
.
w
,
vertical:
32
.
h
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
...
@@ -51,6 +61,7 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -51,6 +61,7 @@ class NetworkTopologyWidget extends StatelessWidget {
),
),
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
spacing:
32
.
h
,
children:
[
children:
[
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
...
@@ -72,19 +83,19 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -72,19 +83,19 @@ class NetworkTopologyWidget extends StatelessWidget {
),
),
],
],
),
),
SizedBox
(
height:
32
.
h
),
SizedBox
(
SizedBox
(
width:
double
.
infinity
,
width:
double
.
infinity
,
height:
800
.
h
,
height:
topologyHeight
,
child:
ClipRRect
(
child:
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
32
.
r
),
borderRadius:
BorderRadius
.
circular
(
32
.
r
),
child:
Stack
(
child:
Container
(
children:
[
Container
(
width:
double
.
infinity
,
width:
double
.
infinity
,
height:
double
.
infinity
,
height:
double
.
infinity
,
color:
const
Color
.
fromRGBO
(
241
,
245
,
249
,
1
),
color:
const
Color
.
fromRGBO
(
241
,
245
,
249
,
1
),
),
child:
Padding
(
padding:
EdgeInsets
.
only
(
top:
32
.
h
,
bottom:
32
.
h
),
child:
Stack
(
children:
[
if
(
topologyNodes
.
isNotEmpty
)
if
(
topologyNodes
.
isNotEmpty
)
CustomPaint
(
CustomPaint
(
size:
Size
.
infinite
,
size:
Size
.
infinite
,
...
@@ -110,11 +121,28 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -110,11 +121,28 @@ class NetworkTopologyWidget extends StatelessWidget {
),
),
),
),
),
),
),
),
],
],
),
),
);
);
}
}
/// 找到竖向节点中最长的文字长度
int
_maxVerticalChars
(
TopologyNode
node
,
int
depth
,
int
maxDepth
,
bool
useVerticalLeaf
)
{
int
maxChars
=
0
;
final
isVirtualRoot
=
node
.
id
==
'0'
&&
node
.
name
==
'根节点'
;
final
isVertical
=
depth
>=
3
||
(
depth
==
maxDepth
&&
node
.
children
.
isEmpty
&&
useVerticalLeaf
);
if
(!
isVirtualRoot
&&
isVertical
)
{
maxChars
=
node
.
name
.
length
;
}
for
(
var
child
in
node
.
children
)
{
maxChars
=
max
(
maxChars
,
_maxVerticalChars
(
child
,
depth
+
1
,
maxDepth
,
useVerticalLeaf
));
}
return
maxChars
;
}
void
_collectNodes
(
void
_collectNodes
(
TopologyNode
node
,
TopologyNode
node
,
List
<
Widget
>
nodes
,
List
<
Widget
>
nodes
,
...
@@ -137,38 +165,31 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -137,38 +165,31 @@ class NetworkTopologyWidget extends StatelessWidget {
if
(!
isVirtualRoot
)
{
if
(!
isVirtualRoot
)
{
if
(
isVerticalNode
)
{
if
(
isVerticalNode
)
{
// 竖向椭圆容器
// 竖向椭圆容器
final
vw
=
48
.
w
;
final
vh
=
144
.
h
;
nodes
.
add
(
nodes
.
add
(
Positioned
(
Positioned
(
left:
centerX
-
vw
/
2
,
left:
centerX
,
top:
centerY
-
vh
/
2
,
top:
centerY
-
30
.
h
,
width:
vw
,
child:
FractionalTranslation
(
height:
vh
,
translation:
const
Offset
(-
0.5
,
0
)
,
child:
GestureDetector
(
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
=>
onNodeTap
(
node
),
onTap:
()
=>
onNodeTap
(
node
),
child:
Container
(
child:
Container
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
12
.
w
,
vertical:
12
.
h
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
color:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
border:
Border
.
all
(
border:
Border
.
all
(
color:
const
Color
.
fromRGBO
(
80
,
162
,
255
,
1
),
color:
const
Color
.
fromRGBO
(
80
,
162
,
255
,
1
),
width:
1
.
w
,
width:
1
.
w
,
),
),
borderRadius:
BorderRadius
.
circular
(
vw
/
2
),
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
),
),
child:
Padding
(
padding:
EdgeInsets
.
symmetric
(
vertical:
8
.
h
),
child:
Column
(
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
()
{
children:
node
.
name
const
maxChars
=
4
;
.
split
(
''
)
final
chars
=
node
.
name
.
split
(
''
);
final
display
=
chars
.
length
>
maxChars
?
[...
chars
.
take
(
maxChars
-
1
),
'…'
]
:
chars
;
return
display
.
map
((
char
)
=>
Text
(
.
map
((
char
)
=>
Text
(
char
,
char
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -177,8 +198,7 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -177,8 +198,7 @@ class NetworkTopologyWidget extends StatelessWidget {
fontWeight:
FontWeight
.
w500
,
fontWeight:
FontWeight
.
w500
,
),
),
))
))
.
toList
();
.
toList
(),
}(),
),
),
),
),
),
),
...
@@ -186,19 +206,18 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -186,19 +206,18 @@ class NetworkTopologyWidget extends StatelessWidget {
),
),
);
);
}
else
{
}
else
{
// 普通水平椭圆容器
// 横向椭圆容器
final
nodeWidth
=
140
.
w
;
final
nodeHeight
=
54
.
h
;
nodes
.
add
(
nodes
.
add
(
Positioned
(
Positioned
(
left:
centerX
-
nodeWidth
/
2
,
left:
centerX
,
top:
centerY
-
nodeHeight
/
2
,
top:
centerY
-
54
.
h
/
2
,
width:
nodeWidth
,
child:
FractionalTranslation
(
height:
nodeHeight
,
translation:
const
Offset
(-
0.5
,
0
)
,
child:
GestureDetector
(
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
=>
onNodeTap
(
node
),
onTap:
()
=>
onNodeTap
(
node
),
child:
Container
(
child:
Container
(
alignment:
Alignment
.
center
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
24
.
w
,
vertical:
12
.
h
)
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
color:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
border:
Border
.
all
(
border:
Border
.
all
(
...
@@ -214,9 +233,7 @@ class NetworkTopologyWidget extends StatelessWidget {
...
@@ -214,9 +233,7 @@ class NetworkTopologyWidget extends StatelessWidget {
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
fontWeight:
FontWeight
.
w500
,
fontWeight:
FontWeight
.
w500
,
),
),
textAlign:
TextAlign
.
center
,
),
maxLines:
2
,
overflow:
TextOverflow
.
ellipsis
,
),
),
),
),
),
),
...
@@ -241,8 +258,8 @@ class TopologyPainter extends CustomPainter {
...
@@ -241,8 +258,8 @@ class TopologyPainter extends CustomPainter {
if
(
nodes
.
isEmpty
)
return
;
if
(
nodes
.
isEmpty
)
return
;
final
paint
=
Paint
()
final
paint
=
Paint
()
..
color
=
const
Color
.
fromRGBO
(
2
03
,
213
,
225
,
1
)
..
color
=
const
Color
.
fromRGBO
(
2
14
,
217
,
224
,
1
)
..
strokeWidth
=
3
.
w
..
strokeWidth
=
2
.
w
..
style
=
PaintingStyle
.
stroke
;
..
style
=
PaintingStyle
.
stroke
;
_drawConnections
(
canvas
,
size
,
nodes
[
0
],
paint
);
_drawConnections
(
canvas
,
size
,
nodes
[
0
],
paint
);
...
...
lib/views/report/device/cubit/device_list_cubit.dart
View file @
9474420e
...
@@ -56,6 +56,7 @@ class DeviceListCubit extends Cubit<DeviceListState> {
...
@@ -56,6 +56,7 @@ class DeviceListCubit extends Cubit<DeviceListState> {
:
(
row
.
onlineStatus
==
'1'
?
'正常'
:
'离线'
),
:
(
row
.
onlineStatus
==
'1'
?
'正常'
:
'离线'
),
color:
row
.
statusTag
.
color
,
color:
row
.
statusTag
.
color
,
lastUpdate:
row
.
subtitle
.
text
,
lastUpdate:
row
.
subtitle
.
text
,
deviceTypeIcon:
row
.
deviceTypeIcon
,
);
);
}).
toList
();
}).
toList
();
}
}
...
...
lib/views/report/device/cubit/device_list_state.dart
View file @
9474420e
...
@@ -45,6 +45,7 @@ class DeviceInfo extends Equatable {
...
@@ -45,6 +45,7 @@ class DeviceInfo extends Equatable {
final
String
status
;
final
String
status
;
final
String
lastUpdate
;
final
String
lastUpdate
;
final
String
color
;
final
String
color
;
final
String
deviceTypeIcon
;
const
DeviceInfo
({
const
DeviceInfo
({
this
.
deviceId
=
0
,
this
.
deviceId
=
0
,
...
@@ -55,11 +56,12 @@ class DeviceInfo extends Equatable {
...
@@ -55,11 +56,12 @@ class DeviceInfo extends Equatable {
this
.
status
=
''
,
this
.
status
=
''
,
this
.
lastUpdate
=
''
,
this
.
lastUpdate
=
''
,
this
.
color
=
''
,
this
.
color
=
''
,
this
.
deviceTypeIcon
=
''
,
});
});
@override
@override
List
<
Object
?>
get
props
=>
[
deviceId
,
name
,
room
,
type
,
online
,
List
<
Object
?>
get
props
=>
[
deviceId
,
name
,
room
,
type
,
online
,
status
,
lastUpdate
,
color
];
status
,
lastUpdate
,
color
,
deviceTypeIcon
];
}
}
class
DeviceListState
extends
Equatable
{
class
DeviceListState
extends
Equatable
{
...
...
lib/views/report/device/widget/device_card.dart
View file @
9474420e
...
@@ -10,29 +10,20 @@ class DeviceCard extends StatelessWidget {
...
@@ -10,29 +10,20 @@ class DeviceCard extends StatelessWidget {
required
this
.
device
,
required
this
.
device
,
});
});
IconData
_getIconForType
(
DeviceTypeEnum
type
)
{
IconData
_getIconForType
(
String
deviceTypeIcon
)
{
switch
(
type
)
{
switch
(
deviceTypeIcon
)
{
case
DeviceTypeEnum
.
smartBreaker
:
case
'ac'
:
return
Icons
.
power
;
return
Icons
.
air_outlined
;
case
DeviceTypeEnum
.
guestControl
:
case
'light'
:
return
Icons
.
settings_remote
;
return
Icons
.
light_outlined
;
case
DeviceTypeEnum
.
network
:
case
'tv'
:
return
Icons
.
tv_outlined
;
case
'curtain'
:
return
Icons
.
blinds_outlined
;
case
'wifi'
:
return
Icons
.
wifi
;
return
Icons
.
wifi
;
default
:
default
:
return
Icons
.
devices
;
return
Icons
.
devices_other
;
}
}
Color
_getIconColor
(
DeviceTypeEnum
type
)
{
switch
(
type
)
{
case
DeviceTypeEnum
.
smartBreaker
:
return
const
Color
.
fromRGBO
(
245
,
158
,
11
,
1
);
case
DeviceTypeEnum
.
guestControl
:
return
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
);
case
DeviceTypeEnum
.
network
:
return
const
Color
.
fromRGBO
(
16
,
185
,
129
,
1
);
default
:
return
const
Color
.
fromRGBO
(
107
,
114
,
128
,
1
);
}
}
}
}
...
@@ -62,14 +53,14 @@ class DeviceCard extends StatelessWidget {
...
@@ -62,14 +53,14 @@ class DeviceCard extends StatelessWidget {
children:
[
children:
[
Container
(
Container
(
width:
64
.
w
,
width:
64
.
w
,
height:
5
8
.
h
,
height:
5
3
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
color:
_getIconColor
(
device
.
type
).
withOpacity
(
0.
1
),
color:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1
),
),
),
child:
Icon
(
child:
Icon
(
_getIconForType
(
device
.
type
),
_getIconForType
(
device
.
deviceTypeIcon
),
color:
_getIconColor
(
device
.
type
),
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
size:
36
.
sp
,
size:
36
.
sp
,
),
),
),
),
...
@@ -93,14 +84,14 @@ class DeviceCard extends StatelessWidget {
...
@@ -93,14 +84,14 @@ class DeviceCard extends StatelessWidget {
Text
(
Text
(
_getTypeLabel
(
device
.
type
),
_getTypeLabel
(
device
.
type
),
style:
TextStyle
(
style:
TextStyle
(
fontSize:
2
0
.
sp
,
fontSize:
2
4
.
sp
,
color:
const
Color
.
fromRGBO
(
107
,
114
,
128
,
1
),
color:
const
Color
.
fromRGBO
(
107
,
114
,
128
,
1
),
),
),
),
),
Text
(
Text
(
'房间
${device.room}
'
,
'房间
${device.room}
'
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
2
0
.
sp
,
fontSize:
2
4
.
sp
,
color:
const
Color
.
fromRGBO
(
107
,
114
,
128
,
1
),
color:
const
Color
.
fromRGBO
(
107
,
114
,
128
,
1
),
),
),
),
),
...
@@ -122,38 +113,6 @@ class DeviceCard extends StatelessWidget {
...
@@ -122,38 +113,6 @@ class DeviceCard extends StatelessWidget {
fontWeight:
FontWeight
.
w500
,
fontWeight:
FontWeight
.
w500
,
),
),
),
),
// Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Container(
// padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(12.r),
// color: device.online
// ? const Color.fromRGBO(220, 252, 231, 1)
// : const Color.fromRGBO(254, 226, 226, 1),
// ),
// child: Text(
// device.status,
// style: TextStyle(
// fontSize: 20.sp,
// color: device.online
// ? const Color.fromRGBO(21, 128, 61, 1)
// : const Color.fromRGBO(220, 38, 38, 1),
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// SizedBox(height: 8.h),
// Text(
// device.lastUpdate,
// style: TextStyle(
// fontSize: 18.sp,
// color: const Color.fromRGBO(156, 163, 175, 1),
// ),
// ),
// ],
// ),
],
],
),
),
);
);
...
...
lib/views/report/device/widget/device_filter_tab.dart
View file @
9474420e
...
@@ -35,12 +35,13 @@ class DeviceFilterTab extends StatelessWidget {
...
@@ -35,12 +35,13 @@ class DeviceFilterTab extends StatelessWidget {
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
child:
Row
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
//
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:
tabs
.
map
((
tab
)
{
children:
tabs
.
map
((
tab
)
{
final
isSelected
=
selectedType
==
tab
[
'type'
];
final
isSelected
=
selectedType
==
tab
[
'type'
];
return
GestureDetector
(
return
GestureDetector
(
onTap:
()
=>
onSelect
(
tab
[
'type'
]
as
DeviceTypeEnum
),
onTap:
()
=>
onSelect
(
tab
[
'type'
]
as
DeviceTypeEnum
),
child:
Container
(
child:
Container
(
margin:
EdgeInsets
.
only
(
right:
16
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
,
vertical:
8
.
h
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
20
.
w
,
vertical:
8
.
h
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
...
...
lib/views/report/energy/widget/energy_stats_card_block.dart
View file @
9474420e
...
@@ -66,23 +66,24 @@ class EnergyStatsCardBlock extends StatelessWidget {
...
@@ -66,23 +66,24 @@ class EnergyStatsCardBlock extends StatelessWidget {
Widget
_buildCard
(
String
value
,
String
label
,
String
?
change
,
bool
?
isDown
,
Color
valueColor
)
{
Widget
_buildCard
(
String
value
,
String
label
,
String
?
change
,
bool
?
isDown
,
Color
valueColor
)
{
return
Container
(
return
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
24
.
h
)
,
height:
128
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
Colors
.
white
,
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
),
),
child:
Column
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
spacing:
4
.
h
,
children:
[
children:
[
Text
(
Text
(
value
,
value
,
style:
TextStyle
(
style:
TextStyle
(
color:
valueColor
,
color:
valueColor
,
fontSize:
40
.
sp
,
fontSize:
36
.
sp
,
fontWeight:
FontWeight
.
w500
,
fontWeight:
FontWeight
.
w500
,
),
),
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
center
,
),
),
SizedBox
(
height:
4
.
h
),
Text
(
Text
(
label
,
label
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -90,7 +91,6 @@ class EnergyStatsCardBlock extends StatelessWidget {
...
@@ -90,7 +91,6 @@ class EnergyStatsCardBlock extends StatelessWidget {
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
),
),
),
),
SizedBox
(
height:
4
.
h
),
if
(
change
!=
null
)
if
(
change
!=
null
)
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
...
@@ -113,8 +113,6 @@ class EnergyStatsCardBlock extends StatelessWidget {
...
@@ -113,8 +113,6 @@ class EnergyStatsCardBlock extends StatelessWidget {
),
),
],
],
)
)
else
SizedBox
(
height:
24
.
h
),
],
],
),
),
);
);
...
...
lib/views/report/energy/widget/hourly_chart_block.dart
View file @
9474420e
...
@@ -25,20 +25,40 @@ class HourlyChartBlock extends StatelessWidget {
...
@@ -25,20 +25,40 @@ class HourlyChartBlock extends StatelessWidget {
double
get
_chartInterval
=>
_chartMaxY
/
5
;
double
get
_chartInterval
=>
_chartMaxY
/
5
;
double
get
_bottomInterval
{
Set
<
int
>
get
_visibleLabelIndices
{
final
len
=
hourlyData
.
length
;
final
length
=
hourlyData
.
length
;
if
(
len
<=
1
)
return
1
;
if
(
length
<=
10
)
{
// 最多显示约 5 个标签,按间距计算
return
Set
.
from
(
List
.
generate
(
length
,
(
i
)
=>
i
));
return
(
len
/
5
).
ceilToDouble
();
}
final
isOdd
=
length
%
2
==
1
;
if
(
isOdd
)
{
// 奇数:7 个标签,首尾都显示,中间 5 个均分 6 段
final
step
=
(
length
-
1
)
/
6
;
final
indices
=
<
int
>{};
for
(
int
i
=
0
;
i
<=
6
;
i
++)
{
indices
.
add
((
step
*
i
).
round
());
}
return
indices
;
}
else
{
// 偶数:6 个标签,显示首和倒数第二个,中间 4 个均分 5 段
final
step
=
(
length
-
2
)
/
5
;
final
indices
=
<
int
>{};
for
(
int
i
=
0
;
i
<=
5
;
i
++)
{
indices
.
add
((
step
*
i
).
round
());
}
return
indices
;
}
}
}
String
_formatTimeLabel
(
int
index
)
{
String
_formatTimeLabel
(
int
index
)
{
if
(
index
<
0
||
index
>=
timeLabels
.
length
)
return
''
;
if
(
index
<
0
||
index
>=
timeLabels
.
length
)
return
''
;
final
label
=
timeLabels
[
index
];
final
label
=
timeLabels
[
index
];
return
label
;
// "00:00:00" / "00:00" → 只取整点小时,去掉前导 0
// "00:00:00" / "00:00" → 只取整点小时,去掉前导 0
final
parts
=
label
.
split
(
':'
);
//
final parts = label.split(':');
final
hour
=
parts
.
isNotEmpty
?
parts
[
0
]
:
label
;
//
final hour = parts.isNotEmpty ? parts[0] : label;
return
'
${int.tryParse(hour) ?? 0}
'
;
//
return '${int.tryParse(hour) ?? 0}';
}
}
@override
@override
...
@@ -81,10 +101,14 @@ class HourlyChartBlock extends StatelessWidget {
...
@@ -81,10 +101,14 @@ class HourlyChartBlock extends StatelessWidget {
bottomTitles:
AxisTitles
(
bottomTitles:
AxisTitles
(
sideTitles:
SideTitles
(
sideTitles:
SideTitles
(
showTitles:
true
,
showTitles:
true
,
interval:
_bottomInterval
,
interval:
1
,
reservedSize:
30
,
reservedSize:
30
,
getTitlesWidget:
(
value
,
meta
)
{
getTitlesWidget:
(
value
,
meta
)
{
final
label
=
_formatTimeLabel
(
value
.
toInt
());
final
i
=
value
.
toInt
();
if
(!
_visibleLabelIndices
.
contains
(
i
))
{
return
const
SizedBox
.
shrink
();
}
final
label
=
_formatTimeLabel
(
i
);
return
Padding
(
return
Padding
(
padding:
EdgeInsets
.
only
(
top:
8
.
h
),
padding:
EdgeInsets
.
only
(
top:
8
.
h
),
child:
Text
(
child:
Text
(
...
...
lib/views/report/index/widget/weekly_power_chart.dart
View file @
9474420e
...
@@ -45,6 +45,17 @@ class WeeklyPowerChart extends StatelessWidget {
...
@@ -45,6 +45,17 @@ class WeeklyPowerChart extends StatelessWidget {
return
_timeLabels
[
index
];
return
_timeLabels
[
index
];
}
}
String
_formatLeftTitle
(
double
value
)
{
return
'
${value.toInt()}
'
;
}
/// 根据最大数值的位数动态计算左侧保留宽度
double
get
_leftReservedSize
{
final
maxLabel
=
_maxY
.
toInt
().
toString
();
// 每位数字约 10px(22.sp 字号)
return
maxLabel
.
length
*
8
;
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
GestureDetector
(
return
GestureDetector
(
...
@@ -142,14 +153,16 @@ class WeeklyPowerChart extends StatelessWidget {
...
@@ -142,14 +153,16 @@ class WeeklyPowerChart extends StatelessWidget {
interval:
_horizontalInterval
,
interval:
_horizontalInterval
,
getTitlesWidget:
(
value
,
meta
)
{
getTitlesWidget:
(
value
,
meta
)
{
return
Text
(
return
Text
(
'
${value.toInt()}
'
,
_formatLeftTitle
(
value
),
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
style:
TextStyle
(
color:
const
Color
.
fromRGBO
(
156
,
163
,
175
,
1
),
color:
const
Color
.
fromRGBO
(
156
,
163
,
175
,
1
),
fontSize:
22
.
sp
,
fontSize:
22
.
sp
,
),
),
);
);
},
},
reservedSize:
50
,
reservedSize:
_leftReservedSize
,
),
),
),
),
),
),
...
...
lib/views/report/room/cubit/room_report_cubit.dart
View file @
9474420e
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:smart_hotel_app/models/bo/room_bo.dart'
;
import
'package:smart_hotel_app/repositories/room_repository.dart'
;
import
'package:smart_hotel_app/repositories/room_repository.dart'
;
import
'package:smart_hotel_app/services/room_service.dart'
;
import
'package:smart_hotel_app/services/room_service.dart'
;
import
'package:smart_hotel_app/views/report/room/cubit/room_report_state.dart'
;
import
'package:smart_hotel_app/views/report/room/cubit/room_report_state.dart'
;
...
@@ -17,13 +18,26 @@ class RoomReportCubit extends Cubit<RoomReportState> {
...
@@ -17,13 +18,26 @@ class RoomReportCubit extends Cubit<RoomReportState> {
try
{
try
{
final
overview
=
await
_service
.
getOverview
(
floorId
);
final
overview
=
await
_service
.
getOverview
(
floorId
);
final
activeIndex
=
overview
.
floorList
.
indexWhere
((
f
)
=>
f
.
isActive
);
final
activeIndex
=
overview
.
floorList
.
indexWhere
((
f
)
=>
f
.
isActive
);
// 过滤掉每个房间 deviceList 中名称含"分控"的设备
final
filteredDetailRooms
=
overview
.
roomDetailList
.
map
((
room
)
{
return
RoomDetailListBO
(
roomBasicInfo:
room
.
roomBasicInfo
,
statusTags:
room
.
statusTags
,
deviceList:
room
.
deviceList
.
where
((
d
)
=>
!
d
.
deviceName
.
contains
(
'分控'
))
.
toList
(),
);
}).
toList
();
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
isLoading:
false
,
isLoading:
false
,
summary:
overview
.
summary
,
summary:
overview
.
summary
,
floors:
overview
.
floorList
,
floors:
overview
.
floorList
,
selectedFloorIndex:
activeIndex
>=
0
?
activeIndex
:
0
,
selectedFloorIndex:
activeIndex
>=
0
?
activeIndex
:
0
,
roomGrid:
overview
.
roomGrid
,
roomGrid:
overview
.
roomGrid
,
detailRooms:
overview
.
roomDetailList
,
detailRooms:
filteredDetailRooms
,
selectedRoomId:
null
,
));
));
}
catch
(
e
)
{
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
e
.
toString
()));
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
e
.
toString
()));
...
@@ -34,7 +48,12 @@ class RoomReportCubit extends Cubit<RoomReportState> {
...
@@ -34,7 +48,12 @@ class RoomReportCubit extends Cubit<RoomReportState> {
if
(
state
.
selectedFloorIndex
==
index
)
return
;
if
(
state
.
selectedFloorIndex
==
index
)
return
;
final
floorId
=
state
.
floors
[
index
].
floorId
;
final
floorId
=
state
.
floors
[
index
].
floorId
;
emit
(
state
.
copyWith
(
selectedFloorIndex:
index
));
emit
(
state
.
copyWith
(
selectedFloorIndex:
index
,
selectedRoomId:
null
));
loadData
(
floorId:
floorId
);
loadData
(
floorId:
floorId
);
}
}
void
selectRoom
(
int
roomId
)
{
final
newId
=
state
.
selectedRoomId
==
roomId
?
null
:
roomId
;
emit
(
state
.
copyWith
(
selectedRoomId:
newId
));
}
}
}
lib/views/report/room/cubit/room_report_state.dart
View file @
9474420e
...
@@ -2,6 +2,8 @@ import 'package:equatable/equatable.dart';
...
@@ -2,6 +2,8 @@ import 'package:equatable/equatable.dart';
import
'package:smart_hotel_app/models/bo/room_bo.dart'
;
import
'package:smart_hotel_app/models/bo/room_bo.dart'
;
class
RoomReportState
extends
Equatable
{
class
RoomReportState
extends
Equatable
{
static
const
_nothing
=
Object
();
final
bool
isLoading
;
final
bool
isLoading
;
final
String
?
error
;
final
String
?
error
;
final
RoomOverviewSummaryBO
summary
;
final
RoomOverviewSummaryBO
summary
;
...
@@ -9,6 +11,7 @@ class RoomReportState extends Equatable {
...
@@ -9,6 +11,7 @@ class RoomReportState extends Equatable {
final
int
selectedFloorIndex
;
final
int
selectedFloorIndex
;
final
List
<
RoomGridBO
>
roomGrid
;
final
List
<
RoomGridBO
>
roomGrid
;
final
List
<
RoomDetailListBO
>
detailRooms
;
final
List
<
RoomDetailListBO
>
detailRooms
;
final
int
?
selectedRoomId
;
const
RoomReportState
({
const
RoomReportState
({
this
.
isLoading
=
false
,
this
.
isLoading
=
false
,
...
@@ -18,6 +21,7 @@ class RoomReportState extends Equatable {
...
@@ -18,6 +21,7 @@ class RoomReportState extends Equatable {
this
.
selectedFloorIndex
=
0
,
this
.
selectedFloorIndex
=
0
,
this
.
roomGrid
=
const
[],
this
.
roomGrid
=
const
[],
this
.
detailRooms
=
const
[],
this
.
detailRooms
=
const
[],
this
.
selectedRoomId
,
});
});
RoomReportState
copyWith
({
RoomReportState
copyWith
({
...
@@ -28,6 +32,7 @@ class RoomReportState extends Equatable {
...
@@ -28,6 +32,7 @@ class RoomReportState extends Equatable {
int
?
selectedFloorIndex
,
int
?
selectedFloorIndex
,
List
<
RoomGridBO
>?
roomGrid
,
List
<
RoomGridBO
>?
roomGrid
,
List
<
RoomDetailListBO
>?
detailRooms
,
List
<
RoomDetailListBO
>?
detailRooms
,
Object
?
selectedRoomId
=
_nothing
,
bool
clearError
=
false
,
bool
clearError
=
false
,
})
{
})
{
return
RoomReportState
(
return
RoomReportState
(
...
@@ -38,6 +43,7 @@ class RoomReportState extends Equatable {
...
@@ -38,6 +43,7 @@ class RoomReportState extends Equatable {
selectedFloorIndex:
selectedFloorIndex
??
this
.
selectedFloorIndex
,
selectedFloorIndex:
selectedFloorIndex
??
this
.
selectedFloorIndex
,
roomGrid:
roomGrid
??
this
.
roomGrid
,
roomGrid:
roomGrid
??
this
.
roomGrid
,
detailRooms:
detailRooms
??
this
.
detailRooms
,
detailRooms:
detailRooms
??
this
.
detailRooms
,
selectedRoomId:
identical
(
selectedRoomId
,
_nothing
)
?
this
.
selectedRoomId
:
selectedRoomId
as
int
?,
);
);
}
}
...
@@ -50,5 +56,6 @@ class RoomReportState extends Equatable {
...
@@ -50,5 +56,6 @@ class RoomReportState extends Equatable {
selectedFloorIndex
,
selectedFloorIndex
,
roomGrid
,
roomGrid
,
detailRooms
,
detailRooms
,
selectedRoomId
,
];
];
}
}
lib/views/report/room/room_detail_view.dart
View file @
9474420e
...
@@ -59,53 +59,64 @@ class ReportRoomDetailView extends StatelessWidget {
...
@@ -59,53 +59,64 @@ class ReportRoomDetailView extends StatelessWidget {
}
}
return
SingleChildScrollView
(
return
SingleChildScrollView
(
child:
Column
(
child:
Padding
(
children:
[
Padding
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
child:
Column
(
children:
[
children:
[
SizedBox
(
height:
10
.
h
),
SizedBox
(
height:
10
.
h
),
if
(
state
.
floors
.
isNotEmpty
)
Container
(
Container
(
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
Colors
.
white
,
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
vertical
(
top:
Radius
.
circular
(
24
.
r
)
),
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
),
),
child:
FloorSelector
(
child:
Column
(
children:
[
if
(
state
.
floors
.
isNotEmpty
)
FloorSelector
(
floorNames:
state
.
floors
.
map
((
f
)
=>
f
.
floorName
).
toList
(),
floorNames:
state
.
floors
.
map
((
f
)
=>
f
.
floorName
).
toList
(),
selectedIndex:
state
.
selectedFloorIndex
,
selectedIndex:
state
.
selectedFloorIndex
,
),
),
),
if
(
state
.
floors
.
isNotEmpty
&&
state
.
selectedFloorIndex
<
state
.
floors
.
length
)
if
(
state
.
floors
.
isNotEmpty
&&
state
.
selectedFloorIndex
<
state
.
floors
.
length
)
Container
(
Padding
(
decoration:
BoxDecoration
(
padding:
EdgeInsets
.
only
(
bottom:
28
.
h
),
color:
Colors
.
white
,
child:
RoomGrid
(
borderRadius:
BorderRadius
.
vertical
(
bottom:
Radius
.
circular
(
24
.
r
)),
rooms:
state
.
roomGrid
,
selectedRoomId:
state
.
selectedRoomId
,
onRoomTap:
(
roomId
)
{
context
.
read
<
RoomReportCubit
>().
selectRoom
(
roomId
);
},
),
),
padding:
EdgeInsets
.
only
(
bottom:
28
.
w
),
child:
RoomGrid
(
rooms:
state
.
roomGrid
),
),
),
SizedBox
(
height:
10
.
h
),
Divider
(
height:
1
.
h
,
thickness:
0.5
,
color:
const
Color
.
fromRGBO
(
229
,
231
,
235
,
1
),
indent:
28
.
w
,
endIndent:
28
.
w
,
),
StatusStats
(
summary:
state
.
summary
),
StatusStats
(
summary:
state
.
summary
),
SizedBox
(
height:
10
.
h
),
if
(
state
.
isLoading
)
if
(
state
.
isLoading
)
const
Padding
(
const
Padding
(
padding:
EdgeInsets
.
all
(
16.0
),
padding:
EdgeInsets
.
all
(
16.0
),
child:
Center
(
child:
CircularProgressIndicator
(
color:
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
))),
child:
Center
(
child:
CircularProgressIndicator
(
color:
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
))),
),
),
...
state
.
detailRooms
.
map
((
room
)
{
...
state
.
detailRooms
.
where
((
room
)
=>
state
.
selectedRoomId
==
null
||
room
.
roomBasicInfo
.
roomId
==
state
.
selectedRoomId
)
.
map
((
room
)
{
return
Padding
(
return
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
10
.
h
),
padding:
EdgeInsets
.
only
(
bottom:
10
.
h
),
child:
RoomDetailCard
(
room:
room
),
child:
RoomDetailCard
(
room:
room
),
);
);
}).
toList
(),
}),
SizedBox
(
height:
10
.
h
),
],
],
),
),
),
),
SizedBox
(
height:
10
.
h
),
],
],
),
),
),
);
);
}
}
...
...
lib/views/report/room/widget/room_detail_card.dart
View file @
9474420e
...
@@ -167,7 +167,9 @@ class _DeviceControl extends StatelessWidget {
...
@@ -167,7 +167,9 @@ class _DeviceControl extends StatelessWidget {
case
'tv'
:
case
'tv'
:
return
Icons
.
tv_outlined
;
return
Icons
.
tv_outlined
;
case
'curtain'
:
case
'curtain'
:
return
Icons
.
curtains_outlined
;
return
Icons
.
blinds_outlined
;
case
'wifi'
:
return
Icons
.
wifi
;
default
:
default
:
return
Icons
.
devices_other
;
return
Icons
.
devices_other
;
}
}
...
@@ -191,7 +193,9 @@ class _DeviceControl extends StatelessWidget {
...
@@ -191,7 +193,9 @@ class _DeviceControl extends StatelessWidget {
SizedBox
(
width:
16
.
w
),
SizedBox
(
width:
16
.
w
),
Expanded
(
Expanded
(
child:
Text
(
child:
Text
(
device
.
deviceName
,
device
.
deviceName
.
contains
(
'-'
)
?
device
.
deviceName
.
split
(
'-'
).
last
:
device
.
deviceName
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
color:
const
Color
.
fromRGBO
(
59
,
130
,
246
,
1
),
...
...
lib/views/report/room/widget/room_grid.dart
View file @
9474420e
...
@@ -4,8 +4,15 @@ import 'package:smart_hotel_app/models/bo/room_bo.dart';
...
@@ -4,8 +4,15 @@ import 'package:smart_hotel_app/models/bo/room_bo.dart';
class
RoomGrid
extends
StatelessWidget
{
class
RoomGrid
extends
StatelessWidget
{
final
List
<
RoomGridBO
>
rooms
;
final
List
<
RoomGridBO
>
rooms
;
final
int
?
selectedRoomId
;
final
Function
(
int
)
onRoomTap
;
const
RoomGrid
({
super
.
key
,
required
this
.
rooms
});
const
RoomGrid
({
super
.
key
,
required
this
.
rooms
,
required
this
.
selectedRoomId
,
required
this
.
onRoomTap
,
});
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
...
@@ -18,7 +25,11 @@ class RoomGrid extends StatelessWidget {
...
@@ -18,7 +25,11 @@ class RoomGrid extends StatelessWidget {
crossAxisCount:
5
,
crossAxisCount:
5
,
mainAxisSpacing:
16
.
h
,
mainAxisSpacing:
16
.
h
,
crossAxisSpacing:
16
.
w
,
crossAxisSpacing:
16
.
w
,
children:
rooms
.
map
((
room
)
=>
_RoomItem
(
room:
room
)).
toList
(),
children:
rooms
.
map
((
room
)
=>
_RoomItem
(
room:
room
,
isSelected:
room
.
roomId
==
selectedRoomId
,
onTap:
()
=>
onRoomTap
(
room
.
roomId
),
)).
toList
(),
),
),
);
);
}
}
...
@@ -26,8 +37,14 @@ class RoomGrid extends StatelessWidget {
...
@@ -26,8 +37,14 @@ class RoomGrid extends StatelessWidget {
class
_RoomItem
extends
StatelessWidget
{
class
_RoomItem
extends
StatelessWidget
{
final
RoomGridBO
room
;
final
RoomGridBO
room
;
final
bool
isSelected
;
final
VoidCallback
onTap
;
const
_RoomItem
({
required
this
.
room
});
const
_RoomItem
({
required
this
.
room
,
required
this
.
isSelected
,
required
this
.
onTap
,
});
Color
get
_bgColor
{
Color
get
_bgColor
{
switch
(
room
.
statusColor
)
{
switch
(
room
.
statusColor
)
{
...
@@ -55,34 +72,19 @@ class _RoomItem extends StatelessWidget {
...
@@ -55,34 +72,19 @@ class _RoomItem extends StatelessWidget {
}
}
}
}
Color
?
get
_borderColor
{
switch
(
room
.
statusColor
)
{
case
'blue'
:
return
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
);
case
'yellow'
:
return
const
Color
.
fromRGBO
(
250
,
204
,
21
,
1
);
case
'default'
:
case
'gray'
:
default
:
return
null
;
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
GestureDetector
(
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
onTap:
onTap
,
},
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
12
.
h
),
padding:
EdgeInsets
.
symmetric
(
vertical:
12
.
h
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
_bgColor
,
color:
_bgColor
,
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
// border: _borderColor != null
border:
isSelected
// ? Border.all(color: _borderColor!
, width: 1.w)
?
Border
.
all
(
color:
const
Color
.
fromRGBO
(
80
,
162
,
255
,
1
)
,
width:
1
.
w
)
//
: null,
:
null
,
),
),
child:
Column
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
...
...
lib/views/service/index/cubit/service_index_cubit.dart
View file @
9474420e
...
@@ -64,7 +64,7 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
...
@@ -64,7 +64,7 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
floors:
floors
,
floors:
floors
,
));
));
// 默认选中第一个楼层,加载其全部房间数据
(不选区域类型)
// 默认选中第一个楼层,加载其全部房间数据
,再默认选中第一个区域和房间
if
(
floors
.
isNotEmpty
)
{
if
(
floors
.
isNotEmpty
)
{
final
firstFloor
=
floors
.
first
;
final
firstFloor
=
floors
.
first
;
final
firstFloorId
=
firstFloor
.
keys
.
first
;
final
firstFloorId
=
firstFloor
.
keys
.
first
;
...
@@ -72,6 +72,7 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
...
@@ -72,6 +72,7 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
_updateAreasForFloor
(
firstFloorLabel
);
_updateAreasForFloor
(
firstFloorLabel
);
selectFloor
(
firstFloorLabel
);
selectFloor
(
firstFloorLabel
);
await
_loadAllRooms
(
floorId:
firstFloorId
);
await
_loadAllRooms
(
floorId:
firstFloorId
);
_selectFirstTypeAndRoom
();
}
}
}
catch
(
e
)
{
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
e
.
toString
()));
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
e
.
toString
()));
...
@@ -204,7 +205,7 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
...
@@ -204,7 +205,7 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
}
}
/// UI 层切换楼层(切换时重置类型/房间/搜索,重新加载数据)
/// UI 层切换楼层(切换时重置类型/房间/搜索,重新加载数据)
void
toggleFloor
(
String
floorName
,
int
floorId
)
{
Future
<
void
>
toggleFloor
(
String
floorName
,
int
floorId
)
async
{
final
isSameFloor
=
state
.
selectedFloor
==
floorName
;
final
isSameFloor
=
state
.
selectedFloor
==
floorName
;
final
newFloor
=
isSameFloor
?
null
:
floorName
;
final
newFloor
=
isSameFloor
?
null
:
floorName
;
...
@@ -227,17 +228,30 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
...
@@ -227,17 +228,30 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
));
));
if
(
newFloor
!=
null
)
{
if
(
newFloor
!=
null
)
{
_loadAllRooms
(
floorId:
floorId
);
await
_loadAllRooms
(
floorId:
floorId
);
_selectFirstTypeAndRoom
();
}
}
}
}
/// UI 层切换区域类型(点击切换,再点取消
,重置
房间)
/// UI 层切换区域类型(点击切换,再点取消
;切换后默认选中该类型第一个
房间)
void
toggleType
(
String
type
)
{
void
toggleType
(
String
type
)
{
final
newType
=
state
.
selectedType
!=
type
?
type
:
null
;
final
newType
=
state
.
selectedType
!=
type
?
type
:
null
;
String
?
newRoom
;
int
?
newRoomId
;
if
(
newType
!=
null
)
{
final
matchedRoom
=
state
.
rooms
.
firstWhere
(
(
r
)
=>
r
[
'areaType'
]
==
newType
,
orElse:
()
=>
<
String
,
dynamic
>{},
);
if
(
matchedRoom
.
isNotEmpty
)
{
newRoom
=
matchedRoom
[
'number'
]
as
String
;
newRoomId
=
matchedRoom
[
'roomId'
]
as
int
;
}
}
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
selectedType:
newType
,
selectedType:
newType
,
selectedRoom:
n
ull
,
selectedRoom:
n
ewRoom
,
selectedRoomId:
n
ull
,
selectedRoomId:
n
ewRoomId
,
));
));
}
}
...
@@ -327,4 +341,22 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
...
@@ -327,4 +341,22 @@ class ServiceIndexCubit extends Cubit<ServiceIndexState> {
}
}
return
null
;
return
null
;
}
}
/// 默认选中第一个区域类型和该类型下的第一个房间
void
_selectFirstTypeAndRoom
()
{
final
areas
=
state
.
areas
;
final
rooms
=
state
.
rooms
;
if
(
areas
.
isEmpty
||
rooms
.
isEmpty
)
return
;
final
defaultType
=
areas
.
first
;
final
defaultRoom
=
rooms
.
firstWhere
(
(
r
)
=>
r
[
'areaType'
]
==
defaultType
,
orElse:
()
=>
rooms
.
first
,
);
emit
(
state
.
copyWith
(
selectedType:
defaultType
,
selectedRoom:
defaultRoom
[
'number'
]
as
String
,
selectedRoomId:
defaultRoom
[
'roomId'
]
as
int
,
));
}
}
}
\ No newline at end of file
lib/views/service/index/widget/room_management_block.dart
View file @
9474420e
...
@@ -185,46 +185,6 @@ class RoomManagementBlock extends StatelessWidget {
...
@@ -185,46 +185,6 @@ class RoomManagementBlock extends StatelessWidget {
);
);
}
}
Widget
_buildRoomDetail
(
ServiceIndexState
state
,
ServiceIndexCubit
cubit
)
{
final
room
=
cubit
.
getSelectedRoomDetail
();
if
(
room
==
null
)
return
const
SizedBox
.
shrink
();
final
items
=
[
(
'房间有无人'
,
room
[
'occupancyStatus'
]
==
'1'
?
'有人'
:
'无人'
),
(
'房间状态'
,
room
[
'occupancyStatus'
]
==
'1'
?
'入住'
:
'空闲'
),
(
'清洁灯'
,
room
[
'cleanStatus'
]
==
'2'
?
'已完成'
:
'待清洁'
),
(
'设备开关'
,
room
[
'devicePowerStatus'
]
==
'1'
?
'开'
:
'关'
),
];
return
Column
(
children:
items
.
map
((
item
)
{
return
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
16
.
h
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
item
.
$
1
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
Text
(
item
.
$
2
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
fontWeight:
FontWeight
.
w500
,
),
),
],
),
);
}).
toList
(),
);
}
Widget
_buildRoomGrid
(
ServiceIndexState
state
,
ServiceIndexCubit
cubit
)
{
Widget
_buildRoomGrid
(
ServiceIndexState
state
,
ServiceIndexCubit
cubit
)
{
final
filteredRooms
=
cubit
.
getFilteredRooms
();
final
filteredRooms
=
cubit
.
getFilteredRooms
();
const
crossAxisCount
=
12
;
const
crossAxisCount
=
12
;
...
@@ -397,6 +357,46 @@ class RoomManagementBlock extends StatelessWidget {
...
@@ -397,6 +357,46 @@ class RoomManagementBlock extends StatelessWidget {
);
);
}
}
Widget
_buildRoomDetail
(
ServiceIndexState
state
,
ServiceIndexCubit
cubit
)
{
final
room
=
cubit
.
getSelectedRoomDetail
();
if
(
room
==
null
)
return
const
SizedBox
.
shrink
();
final
items
=
[
(
'房间有无人'
,
room
[
'occupancyStatus'
]
==
'1'
?
'有人'
:
'无人'
),
(
'房间状态'
,
room
[
'occupancyStatus'
]
==
'1'
?
'入住'
:
'空闲'
),
// ('清洁灯', room['cleanStatus'] == '2' ? '已完成' : '待清洁'),
// ('设备开关', room['devicePowerStatus'] == '1' ? '开' : '关'),
];
return
Column
(
children:
items
.
map
((
item
)
{
return
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
16
.
h
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
Text
(
item
.
$
1
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
),
Text
(
item
.
$
2
,
style:
TextStyle
(
fontSize:
24
.
sp
,
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
fontWeight:
FontWeight
.
w500
,
),
),
],
),
);
}).
toList
(),
);
}
Widget
_buildBottomButtons
(
ServiceIndexState
state
,
ServiceIndexCubit
cubit
,
BuildContext
context
)
{
Widget
_buildBottomButtons
(
ServiceIndexState
state
,
ServiceIndexCubit
cubit
,
BuildContext
context
)
{
final
isRoomSelected
=
state
.
selectedRoom
!=
null
;
final
isRoomSelected
=
state
.
selectedRoom
!=
null
;
return
Row
(
return
Row
(
...
...
lib/views/service/index/widget/service_stats_block.dart
View file @
9474420e
...
@@ -19,7 +19,7 @@ class ServiceStatsBlock extends StatelessWidget {
...
@@ -19,7 +19,7 @@ class ServiceStatsBlock extends StatelessWidget {
width:
double
.
infinity
,
width:
double
.
infinity
,
padding:
EdgeInsets
.
only
(
top:
20
.
w
,
bottom:
20
.
w
),
padding:
EdgeInsets
.
only
(
top:
20
.
w
,
bottom:
20
.
w
),
child:
Row
(
child:
Row
(
spacing:
12
.
w
,
spacing:
20
.
w
,
children:
[
children:
[
_buildStatCard
(
_buildStatCard
(
'待响应'
,
'待响应'
,
...
@@ -44,13 +44,12 @@ class ServiceStatsBlock extends StatelessWidget {
...
@@ -44,13 +44,12 @@ class ServiceStatsBlock extends StatelessWidget {
Widget
_buildStatCard
(
String
label
,
String
value
,
Color
color
)
{
Widget
_buildStatCard
(
String
label
,
String
value
,
Color
color
)
{
return
Expanded
(
return
Expanded
(
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
16
.
h
)
,
height:
112
.
h
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
Colors
.
white
,
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
),
),
child:
Column
(
child:
Column
(
spacing:
5
.
h
,
children:
[
children:
[
Text
(
Text
(
value
,
value
,
...
...
lib/views/service/room/cubit/service_room_cubit.dart
View file @
9474420e
...
@@ -38,20 +38,34 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
...
@@ -38,20 +38,34 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
wifiOnlineStatus:
basic
.
wifiOnlineStatus
,
wifiOnlineStatus:
basic
.
wifiOnlineStatus
,
);
);
final
roomDevices
=
detail
.
deviceStatusList
.
map
((
d
)
{
final
roomDevices
=
detail
.
deviceStatusList
.
where
((
d
)
=>
!
d
.
deviceName
.
contains
(
'分控'
))
.
map
((
d
)
{
return
RoomDevice
(
return
RoomDevice
(
name:
d
.
deviceName
,
name:
d
.
deviceName
.
contains
(
'-'
)
icon:
_mapDeviceIcon
(
d
.
deviceTypeName
,
d
.
deviceTypeIcon
),
?
d
.
deviceName
.
split
(
'-'
).
last
:
d
.
deviceName
,
icon:
_mapDeviceIcon
(
d
.
deviceTypeIcon
),
isOn:
d
.
powerStatus
==
'1'
||
d
.
powerStatus
==
'on'
,
isOn:
d
.
powerStatus
==
'1'
||
d
.
powerStatus
==
'on'
,
statusText:
_buildDeviceStatusText
(
d
),
statusText:
_buildDeviceStatusText
(
d
),
);
);
}).
toList
();
}).
toList
();
final
controlDevices
=
detail
.
deviceControl
.
subDeviceControls
.
map
((
c
)
{
// 从 deviceStatusList 建立 deviceId → deviceTypeIcon 的映射
final
iconMap
=
<
int
,
String
>{};
for
(
final
d
in
detail
.
deviceStatusList
)
{
iconMap
[
d
.
deviceId
]
=
d
.
deviceTypeIcon
;
}
final
controlDevices
=
detail
.
deviceControl
.
subDeviceControls
.
where
((
c
)
=>
!
c
.
deviceName
.
contains
(
'分控'
))
.
map
((
c
)
{
return
ControlDevice
(
return
ControlDevice
(
deviceId:
c
.
deviceId
,
deviceId:
c
.
deviceId
,
name:
c
.
deviceName
,
name:
c
.
deviceName
.
contains
(
'-'
)
icon:
_mapDeviceIcon
(
c
.
deviceTypeName
,
''
),
?
c
.
deviceName
.
split
(
'-'
).
last
:
c
.
deviceName
,
icon:
_mapDeviceIcon
(
iconMap
[
c
.
deviceId
]
??
''
),
isOn:
c
.
powerOn
,
isOn:
c
.
powerOn
,
detailText:
c
.
currentParamDisplay
.
isNotEmpty
?
c
.
currentParamDisplay
:
null
,
detailText:
c
.
currentParamDisplay
.
isNotEmpty
?
c
.
currentParamDisplay
:
null
,
deviceTypeName:
c
.
deviceTypeName
,
deviceTypeName:
c
.
deviceTypeName
,
...
@@ -114,44 +128,30 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
...
@@ -114,44 +128,30 @@ class ServiceRoomCubit extends Cubit<ServiceRoomState> {
}
}
}
}
IconData
_mapDeviceIcon
(
String
deviceTypeName
,
String
deviceTypeIcon
)
{
IconData
_mapDeviceIcon
(
String
deviceTypeIcon
)
{
// Try to match by deviceTypeName first
final
name
=
deviceTypeName
.
toLowerCase
();
if
(
name
.
contains
(
'空调'
)
||
name
.
contains
(
'air'
))
{
return
Icons
.
air_outlined
;
}
if
(
name
.
contains
(
'照明'
)
||
name
.
contains
(
'灯'
)
||
name
.
contains
(
'light'
))
{
return
Icons
.
light_outlined
;
}
if
(
name
.
contains
(
'电视'
)
||
name
.
contains
(
'tv'
))
{
return
Icons
.
tv_outlined
;
}
if
(
name
.
contains
(
'窗帘'
)
||
name
.
contains
(
'curtain'
))
{
return
Icons
.
curtains_closed_outlined
;
}
// Fallback: match by deviceTypeIcon string
final
icon
=
deviceTypeIcon
.
toLowerCase
();
final
icon
=
deviceTypeIcon
.
toLowerCase
();
if
(
icon
.
contains
(
'air
'
)
||
icon
.
contains
(
'ac
'
))
{
if
(
icon
.
contains
(
'air
-vent
'
))
{
return
Icons
.
air_outlined
;
return
Icons
.
air_outlined
;
}
}
if
(
icon
.
contains
(
'light'
))
{
if
(
icon
.
contains
(
'light
bulb
'
))
{
return
Icons
.
light_outlined
;
return
Icons
.
light_outlined
;
}
}
if
(
icon
.
contains
(
'tv'
))
{
if
(
icon
.
contains
(
'tv'
))
{
return
Icons
.
tv_outlined
;
return
Icons
.
tv_outlined
;
}
}
if
(
icon
.
contains
(
'
curtain
'
))
{
if
(
icon
.
contains
(
'
panel-top
'
))
{
return
Icons
.
curtains_closed_outlined
;
return
Icons
.
curtains_closed_outlined
;
}
}
if
(
icon
.
contains
(
'wifi'
))
{
return
Icons
.
wifi
;
}
return
Icons
.
devices_other
;
return
Icons
.
devices_other
;
}
}
/// 房间总电源开关
/// 房间总电源开关
Future
<
void
>
toggleMainPowerForSwitch
(
bool
value
)
async
{
Future
<
void
>
toggleMainPowerForSwitch
(
bool
value
)
async
{
if
(
state
.
isPoweringOn
||
state
.
isPoweringOff
)
return
;
if
(
state
.
isPoweringOn
||
state
.
isPoweringOff
)
return
;
final
loadingKey
=
value
?
'isPoweringOn'
:
'isPoweringOff'
;
//
final loadingKey = value ? 'isPoweringOn' : 'isPoweringOff';
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
isPoweringOn:
value
,
isPoweringOn:
value
,
isPoweringOff:
!
value
,
isPoweringOff:
!
value
,
...
...
lib/views/service/room/room_detail_view.dart
View file @
9474420e
...
@@ -87,18 +87,44 @@ class ServiceRoomDetailView extends StatelessWidget {
...
@@ -87,18 +87,44 @@ class ServiceRoomDetailView extends StatelessWidget {
return
SingleChildScrollView
(
return
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
20
.
h
),
Container
(
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
24
.
r
),
),
child:
Column
(
children:
[
RoomOverviewCard
(
RoomOverviewCard
(
roomNumber:
state
.
roomNumber
,
roomNumber:
state
.
roomNumber
,
roomStatus:
state
.
roomStatus
,
roomStatus:
state
.
roomStatus
,
statusTags:
state
.
statusTags
,
statusTags:
state
.
statusTags
,
),
),
SizedBox
(
height:
20
.
h
),
Divider
(
height:
0.5
.
h
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
thickness:
0.5
,
indent:
28
.
w
,
endIndent:
28
.
w
,
),
RoomDeviceStatusCard
(
RoomDeviceStatusCard
(
devices:
state
.
roomDevices
,
devices:
state
.
roomDevices
,
),
),
],
),
),
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
20
.
h
),
Text
(
'设备控制'
,
style:
TextStyle
(
fontSize:
32
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
),
),
SizedBox
(
height:
10
.
h
),
DeviceControlCard
(
DeviceControlCard
(
mainPowerOn:
state
.
mainPowerOn
,
mainPowerOn:
state
.
mainPowerOn
,
controlDevices:
state
.
controlDevices
,
controlDevices:
state
.
controlDevices
,
...
...
lib/views/service/room/widget/device_control_card.dart
View file @
9474420e
...
@@ -30,17 +30,8 @@ class DeviceControlCard extends StatelessWidget {
...
@@ -30,17 +30,8 @@ class DeviceControlCard extends StatelessWidget {
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
children:
[
Text
(
'设备控制'
,
style:
TextStyle
(
fontSize:
32
.
sp
,
fontWeight:
FontWeight
.
bold
,
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
),
),
SizedBox
(
height:
20
.
h
),
_buildMainPowerControl
(),
_buildMainPowerControl
(),
SizedBox
(
height:
24
.
h
),
SizedBox
(
height:
30
.
h
),
Text
(
Text
(
'分设备控制'
,
'分设备控制'
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -49,14 +40,10 @@ class DeviceControlCard extends StatelessWidget {
...
@@ -49,14 +40,10 @@ class DeviceControlCard extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
color:
const
Color
.
fromRGBO
(
10
,
13
,
20
,
1.0
),
),
),
),
),
SizedBox
(
height:
30
.
h
),
...
controlDevices
.
asMap
().
entries
.
map
((
entry
)
{
...
controlDevices
.
asMap
().
entries
.
map
((
entry
)
{
final
index
=
entry
.
key
;
final
index
=
entry
.
key
;
final
device
=
entry
.
value
;
final
device
=
entry
.
value
;
return
Padding
(
return
_buildDeviceControl
(
index
,
device
);
padding:
EdgeInsets
.
only
(
bottom:
index
<
controlDevices
.
length
-
1
?
20
.
h
:
0
),
child:
_buildDeviceControl
(
index
,
device
),
);
}).
toList
(),
}).
toList
(),
],
],
),
),
...
@@ -134,24 +121,25 @@ class DeviceControlCard extends StatelessWidget {
...
@@ -134,24 +121,25 @@ class DeviceControlCard extends StatelessWidget {
Widget
_buildDeviceControl
(
int
index
,
ControlDevice
device
)
{
Widget
_buildDeviceControl
(
int
index
,
ControlDevice
device
)
{
return
Column
(
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
children:
[
Row
(
SizedBox
(
height:
80
.
h
,
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
Expanded
(
Expanded
(
child:
Material
(
child:
GestureDetector
(
color:
Colors
.
transparent
,
behavior:
HitTestBehavior
.
opaque
,
child:
InkWell
(
onTap:
onDeviceTap
!=
null
?
()
=>
onDeviceTap
!(
index
,
device
)
:
null
,
onTap:
onDeviceTap
!=
null
?
()
=>
onDeviceTap
!(
index
,
device
)
:
null
,
child:
Row
(
child:
Row
(
spacing:
8
.
w
,
children:
[
children:
[
Icon
(
Icon
(
device
.
icon
,
device
.
icon
,
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
size:
36
.
sp
,
size:
36
.
sp
,
),
),
SizedBox
(
width:
8
.
w
),
Text
(
Text
(
device
.
name
,
device
.
name
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -164,7 +152,6 @@ class DeviceControlCard extends StatelessWidget {
...
@@ -164,7 +152,6 @@ class DeviceControlCard extends StatelessWidget {
),
),
),
),
),
),
),
FlutterSwitch
(
FlutterSwitch
(
width:
80
.
w
,
width:
80
.
w
,
height:
35
.
h
,
height:
35
.
h
,
...
@@ -179,8 +166,8 @@ class DeviceControlCard extends StatelessWidget {
...
@@ -179,8 +166,8 @@ class DeviceControlCard extends StatelessWidget {
),
),
],
],
),
),
),
if
(
index
<
controlDevices
.
length
-
1
)
...[
if
(
index
<
controlDevices
.
length
-
1
)
...[
SizedBox
(
height:
30
.
h
),
Divider
(
Divider
(
height:
0.5
.
h
,
height:
0.5
.
h
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
0.2
),
...
...
lib/views/service/room/widget/room_device_status_card.dart
View file @
9474420e
...
@@ -61,13 +61,17 @@ class RoomDeviceStatusCard extends StatelessWidget {
...
@@ -61,13 +61,17 @@ class RoomDeviceStatusCard extends StatelessWidget {
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
size:
36
.
sp
,
size:
36
.
sp
,
),
),
Text
(
Expanded
(
child:
Text
(
device
.
name
,
device
.
name
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
28
.
sp
,
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
color:
const
Color
.
fromRGBO
(
66
,
165
,
245
,
1.0
),
fontWeight:
FontWeight
.
bold
,
fontWeight:
FontWeight
.
bold
,
),
),
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
),
),
),
],
],
),
),
...
...
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