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
a49802fa
Commit
a49802fa
authored
Jun 08, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
告警看板 添加告警分类处理
parent
186e3157
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
692 additions
and
214 deletions
+692
-214
alert_dashboard_bo.dart
lib/models/bo/alert_dashboard_bo.dart
+4
-0
device_control_bo.dart
lib/models/bo/device_control_bo.dart
+128
-0
alert_detail_repository.dart
lib/repositories/alert_detail_repository.dart
+9
-0
device_control_repository.dart
lib/repositories/device_control_repository.dart
+32
-0
app_router.gr.dart
lib/routes/app_router.gr.dart
+33
-5
alert_detail_service.dart
lib/services/alert_detail_service.dart
+8
-0
device_control_service.dart
lib/services/device_control_service.dart
+32
-0
abnormal_detail_view.dart
lib/views/home/abnormal/abnormal_detail_view.dart
+54
-17
abnormal_cubit.dart
lib/views/home/abnormal/cubit/abnormal_cubit.dart
+11
-2
abnormal_state.dart
lib/views/home/abnormal/cubit/abnormal_state.dart
+21
-0
device_cubit.dart
lib/views/home/device/cubit/device_cubit.dart
+71
-22
device_state.dart
lib/views/home/device/cubit/device_state.dart
+29
-2
device_detail_view.dart
lib/views/home/device/device_detail_view.dart
+123
-33
home_index_cubit.dart
lib/views/home/index/cubit/home_index_cubit.dart
+1
-38
home_index_state.dart
lib/views/home/index/cubit/home_index_state.dart
+7
-70
index_view.dart
lib/views/home/index/index_view.dart
+41
-20
对接方案.md
对接方案.md
+88
-5
No files found.
lib/models/bo/alert_dashboard_bo.dart
View file @
a49802fa
...
...
@@ -84,6 +84,7 @@ class AlertItemBO extends Equatable {
final
int
waitingDuration
;
final
String
waitingDurationDesc
;
final
String
alertTime
;
final
String
alertCategory
;
const
AlertItemBO
({
required
this
.
alertId
,
...
...
@@ -103,6 +104,7 @@ class AlertItemBO extends Equatable {
required
this
.
waitingDuration
,
required
this
.
waitingDurationDesc
,
required
this
.
alertTime
,
required
this
.
alertCategory
,
});
factory
AlertItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
...
...
@@ -124,6 +126,7 @@ class AlertItemBO extends Equatable {
waitingDuration:
json
[
'waitingDuration'
]
as
int
?
??
0
,
waitingDurationDesc:
json
[
'waitingDurationDesc'
]
as
String
?
??
''
,
alertTime:
json
[
'alertTime'
]
as
String
?
??
''
,
alertCategory:
json
[
'alertCategory'
]
as
String
?
??
''
,
);
}
...
...
@@ -146,6 +149,7 @@ class AlertItemBO extends Equatable {
waitingDuration
,
waitingDurationDesc
,
alertTime
,
alertCategory
,
];
}
...
...
lib/models/bo/device_control_bo.dart
0 → 100644
View file @
a49802fa
class
DeviceControlBO
{
final
DeviceBasicInfoBO
deviceBasicInfo
;
final
RealtimeParamsBO
realtimeParams
;
final
DeviceTrendChartBO
trendChart
;
const
DeviceControlBO
({
required
this
.
deviceBasicInfo
,
required
this
.
realtimeParams
,
required
this
.
trendChart
,
});
factory
DeviceControlBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DeviceControlBO
(
deviceBasicInfo:
DeviceBasicInfoBO
.
fromJson
(
json
[
'deviceBasicInfo'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
realtimeParams:
RealtimeParamsBO
.
fromJson
(
json
[
'realtimeParams'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
trendChart:
DeviceTrendChartBO
.
fromJson
(
json
[
'trendChart'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
);
}
}
class
DeviceBasicInfoBO
{
final
int
deviceId
;
final
String
deviceName
;
final
String
deviceCode
;
final
String
roomName
;
final
String
deviceTypeIcon
;
final
String
onlineStatus
;
const
DeviceBasicInfoBO
({
required
this
.
deviceId
,
required
this
.
deviceName
,
required
this
.
deviceCode
,
required
this
.
roomName
,
required
this
.
deviceTypeIcon
,
required
this
.
onlineStatus
,
});
factory
DeviceBasicInfoBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DeviceBasicInfoBO
(
deviceId:
json
[
'deviceId'
]
as
int
?
??
0
,
deviceName:
json
[
'deviceName'
]
as
String
?
??
''
,
deviceCode:
json
[
'deviceCode'
]
as
String
?
??
''
,
roomName:
json
[
'roomName'
]
as
String
?
??
''
,
deviceTypeIcon:
json
[
'deviceTypeIcon'
]
as
String
?
??
''
,
onlineStatus:
json
[
'onlineStatus'
]
as
String
?
??
''
,
);
}
}
class
RealtimeParamsBO
{
final
String
voltage
;
final
String
current
;
final
String
activePower
;
final
String
deviceTemperature
;
const
RealtimeParamsBO
({
required
this
.
voltage
,
required
this
.
current
,
required
this
.
activePower
,
required
this
.
deviceTemperature
,
});
factory
RealtimeParamsBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
RealtimeParamsBO
(
voltage:
json
[
'voltage'
]
as
String
?
??
''
,
current:
json
[
'current'
]
as
String
?
??
''
,
activePower:
json
[
'activePower'
]
as
String
?
??
''
,
deviceTemperature:
json
[
'deviceTemperature'
]
as
String
?
??
''
,
);
}
}
class
DeviceTrendChartBO
{
final
String
chartTitle
;
final
String
unit
;
final
List
<
DeviceDataPointBO
>
dataPoints
;
final
int
yaxisMax
;
final
int
yaxisMin
;
const
DeviceTrendChartBO
({
required
this
.
chartTitle
,
required
this
.
unit
,
required
this
.
dataPoints
,
required
this
.
yaxisMax
,
required
this
.
yaxisMin
,
});
factory
DeviceTrendChartBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DeviceTrendChartBO
(
chartTitle:
json
[
'chartTitle'
]
as
String
?
??
''
,
unit:
json
[
'unit'
]
as
String
?
??
''
,
dataPoints:
(
json
[
'dataPoints'
]
as
List
<
dynamic
>?)
?.
map
(
(
e
)
=>
DeviceDataPointBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
()
??
[],
yaxisMax:
json
[
'yaxisMax'
]
as
int
?
??
100
,
yaxisMin:
json
[
'yaxisMin'
]
as
int
?
??
0
,
);
}
}
class
DeviceDataPointBO
{
final
String
time
;
final
double
power
;
final
double
temperature
;
const
DeviceDataPointBO
({
required
this
.
time
,
required
this
.
power
,
required
this
.
temperature
,
});
factory
DeviceDataPointBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DeviceDataPointBO
(
time:
json
[
'time'
]
as
String
?
??
''
,
power:
(
json
[
'power'
]
as
num
?)?.
toDouble
()
??
0
,
temperature:
(
json
[
'temperature'
]
as
num
?)?.
toDouble
()
??
0
,
);
}
}
\ No newline at end of file
lib/repositories/alert_detail_repository.dart
View file @
a49802fa
...
...
@@ -12,4 +12,12 @@ class AlertDetailRepository {
AlertDetailBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
}
/// 确认处理告警
Future
<
ResponseModel
<
Map
<
String
,
dynamic
>>>
handleAlert
({
required
int
alertId
})
{
return
DioRequest
.
instance
.
post
<
Map
<
String
,
dynamic
>>(
'/app/alert/handle'
,
data:
{
'alertId'
:
alertId
},
);
}
}
\ No newline at end of file
lib/repositories/device_control_repository.dart
0 → 100644
View file @
a49802fa
import
'../utils/http/response_model.dart'
;
import
'../utils/http/dio_request.dart'
;
import
'../models/bo/device_control_bo.dart'
;
class
DeviceControlRepository
{
/// 获取设备控制详情
Future
<
ResponseModel
<
DeviceControlBO
>>
getDetail
({
required
int
deviceId
})
{
return
DioRequest
.
instance
.
get
<
DeviceControlBO
>(
'/app/device/control/detail'
,
queryParameters:
{
'deviceId'
:
deviceId
},
fromJsonT:
(
data
)
=>
DeviceControlBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
}
/// 远程送电
Future
<
ResponseModel
<
Map
<
String
,
dynamic
>>>
powerOn
({
required
int
deviceId
})
{
return
DioRequest
.
instance
.
post
<
Map
<
String
,
dynamic
>>(
'/app/device/control/powerOn'
,
data:
{
'deviceId'
:
deviceId
},
);
}
/// 远程断电
Future
<
ResponseModel
<
Map
<
String
,
dynamic
>>>
powerOff
({
required
int
deviceId
})
{
return
DioRequest
.
instance
.
post
<
Map
<
String
,
dynamic
>>(
'/app/device/control/powerOff'
,
data:
{
'deviceId'
:
deviceId
},
);
}
}
\ No newline at end of file
lib/routes/app_router.gr.dart
View file @
a49802fa
...
...
@@ -72,9 +72,13 @@ abstract class $AppRouter extends _i21.RootStackRouter {
);
},
DeviceDetailRoute
.
name
:
(
routeData
)
{
final
args
=
routeData
.
argsAs
<
DeviceDetailRouteArgs
>();
return
_i21
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
child:
const
_i4
.
DeviceDetailView
(),
child:
_i4
.
DeviceDetailView
(
key:
args
.
key
,
deviceId:
args
.
deviceId
,
),
);
},
HomeRoute
.
name
:
(
routeData
)
{
...
...
@@ -270,16 +274,40 @@ class DefaultLayoutRoute extends _i21.PageRouteInfo<void> {
/// generated route for
/// [_i4.DeviceDetailView]
class
DeviceDetailRoute
extends
_i21
.
PageRouteInfo
<
void
>
{
const
DeviceDetailRoute
({
List
<
_i21
.
PageRouteInfo
>?
children
})
:
super
(
class
DeviceDetailRoute
extends
_i21
.
PageRouteInfo
<
DeviceDetailRouteArgs
>
{
DeviceDetailRoute
({
_i22
.
Key
?
key
,
required
int
deviceId
,
List
<
_i21
.
PageRouteInfo
>?
children
,
})
:
super
(
DeviceDetailRoute
.
name
,
args:
DeviceDetailRouteArgs
(
key:
key
,
deviceId:
deviceId
,
),
initialChildren:
children
,
);
static
const
String
name
=
'DeviceDetailRoute'
;
static
const
_i21
.
PageInfo
<
void
>
page
=
_i21
.
PageInfo
<
void
>(
name
);
static
const
_i21
.
PageInfo
<
DeviceDetailRouteArgs
>
page
=
_i21
.
PageInfo
<
DeviceDetailRouteArgs
>(
name
);
}
class
DeviceDetailRouteArgs
{
const
DeviceDetailRouteArgs
({
this
.
key
,
required
this
.
deviceId
,
});
final
_i22
.
Key
?
key
;
final
int
deviceId
;
@override
String
toString
()
{
return
'DeviceDetailRouteArgs{key:
$key
, deviceId:
$deviceId
}'
;
}
}
/// generated route for
...
...
lib/services/alert_detail_service.dart
View file @
a49802fa
...
...
@@ -14,4 +14,11 @@ class AlertDetailService {
}
throw
Exception
(
result
.
msg
);
}
Future
<
void
>
handleAlert
({
required
int
alertId
})
async
{
final
result
=
await
_repository
.
handleAlert
(
alertId:
alertId
);
if
(!
result
.
success
)
{
throw
Exception
(
result
.
msg
);
}
}
}
\ No newline at end of file
lib/services/device_control_service.dart
0 → 100644
View file @
a49802fa
import
'../models/bo/device_control_bo.dart'
;
import
'../repositories/device_control_repository.dart'
;
class
DeviceControlService
{
final
DeviceControlRepository
_repository
;
DeviceControlService
({
required
DeviceControlRepository
repository
})
:
_repository
=
repository
;
Future
<
DeviceControlBO
>
getDetail
({
required
int
deviceId
})
async
{
final
result
=
await
_repository
.
getDetail
(
deviceId:
deviceId
);
if
(
result
.
success
&&
result
.
data
!=
null
)
{
return
result
.
data
!;
}
throw
Exception
(
result
.
msg
);
}
Future
<
void
>
powerOn
({
required
int
deviceId
})
async
{
final
result
=
await
_repository
.
powerOn
(
deviceId:
deviceId
);
if
(!
result
.
success
)
{
throw
Exception
(
result
.
msg
);
}
}
Future
<
void
>
powerOff
({
required
int
deviceId
})
async
{
final
result
=
await
_repository
.
powerOff
(
deviceId:
deviceId
);
if
(!
result
.
success
)
{
throw
Exception
(
result
.
msg
);
}
}
}
\ No newline at end of file
lib/views/home/abnormal/abnormal_detail_view.dart
View file @
a49802fa
...
...
@@ -96,23 +96,41 @@ class AbnormalDetailView extends StatelessWidget {
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Container
(
width:
double
.
infinity
,
height:
88
.
h
,
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
),
child:
TextButton
(
onPressed:
()
=>
cubit
.
handleConfirm
(),
child:
Text
(
'确认处理'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
),
BlocBuilder
<
AbnormalCubit
,
AbnormalState
>(
builder:
(
context
,
state
)
{
final
isDisabled
=
state
.
isHandling
||
state
.
isHandled
;
return
Container
(
width:
double
.
infinity
,
height:
88
.
h
,
decoration:
BoxDecoration
(
color:
isDisabled
?
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.4
)
:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
),
),
),
child:
TextButton
(
onPressed:
isDisabled
?
null
:
()
=>
_handleConfirm
(
context
,
cubit
),
child:
state
.
isHandling
?
SizedBox
(
width:
32
.
sp
,
height:
32
.
sp
,
child:
CircularProgressIndicator
(
strokeWidth:
3
,
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
),
),
)
:
Text
(
state
.
isHandled
?
'已处理'
:
'确认处理'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
),
),
),
),
);
},
),
SizedBox
(
height:
20
.
h
),
Container
(
...
...
@@ -124,7 +142,8 @@ class AbnormalDetailView extends StatelessWidget {
),
child:
TextButton
(
onPressed:
()
{
context
.
pushRoute
(
const
DeviceDetailRoute
());
// TODO: 替换为真实的 deviceId
context
.
pushRoute
(
DeviceDetailRoute
(
deviceId:
0
));
},
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
...
...
@@ -150,4 +169,21 @@ class AbnormalDetailView extends StatelessWidget {
),
);
}
Future
<
void
>
_handleConfirm
(
BuildContext
context
,
AbnormalCubit
cubit
)
async
{
try
{
await
cubit
.
handleConfirm
();
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'操作成功'
)),
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'操作失败:
$e
'
)),
);
}
}
}
}
\ No newline at end of file
lib/views/home/abnormal/cubit/abnormal_cubit.dart
View file @
a49802fa
...
...
@@ -63,7 +63,15 @@ class AbnormalCubit extends Cubit<AbnormalState> {
}
}
void
handleConfirm
()
{
print
(
'确认处理'
);
Future
<
void
>
handleConfirm
()
async
{
if
(
state
.
isHandling
||
state
.
isHandled
)
return
;
emit
(
state
.
copyWith
(
isHandling:
true
));
try
{
await
_service
.
handleAlert
(
alertId:
_alertId
);
emit
(
state
.
copyWith
(
isHandling:
false
,
isHandled:
true
));
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isHandling:
false
));
rethrow
;
}
}
}
\ No newline at end of file
lib/views/home/abnormal/cubit/abnormal_state.dart
View file @
a49802fa
...
...
@@ -38,10 +38,30 @@ class AbnormalState {
final
bool
isLoading
;
final
String
?
error
;
final
AlarmInfo
?
alarmInfo
;
final
bool
isHandling
;
final
bool
isHandled
;
const
AbnormalState
({
this
.
isLoading
=
false
,
this
.
error
,
this
.
alarmInfo
,
this
.
isHandling
=
false
,
this
.
isHandled
=
false
,
});
AbnormalState
copyWith
({
bool
?
isLoading
,
String
?
error
,
AlarmInfo
?
alarmInfo
,
bool
?
isHandling
,
bool
?
isHandled
,
})
{
return
AbnormalState
(
isLoading:
isLoading
??
this
.
isLoading
,
error:
error
??
this
.
error
,
alarmInfo:
alarmInfo
??
this
.
alarmInfo
,
isHandling:
isHandling
??
this
.
isHandling
,
isHandled:
isHandled
??
this
.
isHandled
,
);
}
}
\ No newline at end of file
lib/views/home/device/cubit/device_cubit.dart
View file @
a49802fa
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:smart_hotel_app/models/bo/device_control_bo.dart'
;
import
'package:smart_hotel_app/services/device_control_service.dart'
;
import
'package:smart_hotel_app/views/home/device/cubit/device_state.dart'
;
class
DeviceCubit
extends
Cubit
<
DeviceState
>
{
DeviceCubit
()
:
super
(
DeviceState
(
deviceInfo:
_getDeviceInfo
()));
static
DeviceInfo
_getDeviceInfo
()
{
return
const
DeviceInfo
(
deviceName:
'客房305 智能空开'
,
deviceId:
'A-305'
,
location:
'3楼客房区'
,
status:
'在线'
,
voltage:
'220V'
,
current:
'2.36A'
,
power:
'520W'
,
temperature:
'38°C'
,
powerData:
[
40
,
60
,
85
,
98
,
85
,
72
,
60
,
48
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
tempData:
[
28
,
30
,
32
,
35
,
33
,
31
,
30
,
29
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
final
DeviceControlService
_service
;
final
int
_deviceId
;
DeviceCubit
({
required
DeviceControlService
service
,
required
int
deviceId
,
})
:
_service
=
service
,
_deviceId
=
deviceId
,
super
(
const
DeviceState
())
{
loadDetail
();
}
Future
<
void
>
loadDetail
()
async
{
emit
(
const
DeviceState
(
isLoading:
true
));
try
{
final
detail
=
await
_service
.
getDetail
(
deviceId:
_deviceId
);
emit
(
DeviceState
(
deviceInfo:
_mapToDeviceInfo
(
detail
)));
}
catch
(
e
)
{
emit
(
DeviceState
(
error:
e
.
toString
()));
}
}
DeviceInfo
_mapToDeviceInfo
(
DeviceControlBO
detail
)
{
final
basic
=
detail
.
deviceBasicInfo
;
final
params
=
detail
.
realtimeParams
;
final
status
=
basic
.
onlineStatus
==
'1'
?
'在线'
:
'离线'
;
final
powerData
=
detail
.
trendChart
.
dataPoints
.
map
((
p
)
=>
p
.
power
.
toInt
())
.
toList
();
final
tempData
=
detail
.
trendChart
.
dataPoints
.
map
((
p
)
=>
p
.
temperature
.
toInt
())
.
toList
();
return
DeviceInfo
(
deviceName:
basic
.
deviceName
,
deviceId:
basic
.
deviceCode
,
location:
basic
.
roomName
,
status:
status
,
voltage:
params
.
voltage
,
current:
params
.
current
,
power:
params
.
activePower
,
temperature:
params
.
deviceTemperature
,
powerData:
powerData
,
tempData:
tempData
,
);
}
void
remotePowerOn
()
{}
Future
<
void
>
remotePowerOn
()
async
{
if
(
state
.
isPoweringOn
)
return
;
emit
(
state
.
copyWith
(
isPoweringOn:
true
));
try
{
await
_service
.
powerOn
(
deviceId:
_deviceId
);
emit
(
state
.
copyWith
(
isPoweringOn:
false
));
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isPoweringOn:
false
));
rethrow
;
}
}
void
remotePowerOff
()
{}
Future
<
void
>
remotePowerOff
()
async
{
if
(
state
.
isPoweringOff
)
return
;
emit
(
state
.
copyWith
(
isPoweringOff:
true
));
try
{
await
_service
.
powerOff
(
deviceId:
_deviceId
);
emit
(
state
.
copyWith
(
isPoweringOff:
false
));
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isPoweringOff:
false
));
rethrow
;
}
}
}
\ No newline at end of file
lib/views/home/device/cubit/device_state.dart
View file @
a49802fa
...
...
@@ -25,7 +25,33 @@ class DeviceInfo {
}
class
DeviceState
{
final
DeviceInfo
deviceInfo
;
final
bool
isLoading
;
final
String
?
error
;
final
DeviceInfo
?
deviceInfo
;
final
bool
isPoweringOn
;
final
bool
isPoweringOff
;
const
DeviceState
({
required
this
.
deviceInfo
});
const
DeviceState
({
this
.
isLoading
=
false
,
this
.
error
,
this
.
deviceInfo
,
this
.
isPoweringOn
=
false
,
this
.
isPoweringOff
=
false
,
});
DeviceState
copyWith
({
bool
?
isLoading
,
String
?
error
,
DeviceInfo
?
deviceInfo
,
bool
?
isPoweringOn
,
bool
?
isPoweringOff
,
})
{
return
DeviceState
(
isLoading:
isLoading
??
this
.
isLoading
,
error:
error
??
this
.
error
,
deviceInfo:
deviceInfo
??
this
.
deviceInfo
,
isPoweringOn:
isPoweringOn
??
this
.
isPoweringOn
,
isPoweringOff:
isPoweringOff
??
this
.
isPoweringOff
,
);
}
}
\ No newline at end of file
lib/views/home/device/device_detail_view.dart
View file @
a49802fa
...
...
@@ -2,6 +2,8 @@ import 'package:auto_route/auto_route.dart';
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/repositories/device_control_repository.dart'
;
import
'package:smart_hotel_app/services/device_control_service.dart'
;
import
'package:smart_hotel_app/views/home/device/cubit/device_cubit.dart'
;
import
'package:smart_hotel_app/views/home/device/cubit/device_state.dart'
;
import
'package:smart_hotel_app/views/home/device/widget/device_parms_block.dart'
;
...
...
@@ -10,12 +12,18 @@ import 'package:smart_hotel_app/views/home/device/widget/state_info_block.dart';
@RoutePage
()
class
DeviceDetailView
extends
StatelessWidget
{
const
DeviceDetailView
({
super
.
key
});
final
int
deviceId
;
const
DeviceDetailView
({
super
.
key
,
required
this
.
deviceId
});
@override
Widget
build
(
BuildContext
context
)
{
return
BlocProvider
(
create:
(
_
)
=>
DeviceCubit
(),
create:
(
_
)
{
final
repository
=
DeviceControlRepository
();
final
service
=
DeviceControlService
(
repository:
repository
);
return
DeviceCubit
(
service:
service
,
deviceId:
deviceId
);
},
child:
Scaffold
(
backgroundColor:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
appBar:
AppBar
(
...
...
@@ -38,31 +46,50 @@ class DeviceDetailView extends StatelessWidget {
),
centerTitle:
true
,
),
body:
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
BlocBuilder
<
DeviceCubit
,
DeviceState
>(
builder:
(
context
,
state
)
{
final
cubit
=
context
.
read
<
DeviceCubit
>();
return
Column
(
body:
BlocBuilder
<
DeviceCubit
,
DeviceState
>(
builder:
(
context
,
state
)
{
if
(
state
.
isLoading
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
}
if
(
state
.
error
!=
null
)
{
return
Center
(
child:
Text
(
'加载失败:
${state.error}
'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
);
}
final
deviceInfo
=
state
.
deviceInfo
;
if
(
deviceInfo
==
null
)
{
return
const
SizedBox
.
shrink
();
}
final
cubit
=
context
.
read
<
DeviceCubit
>();
return
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
children:
[
StateInfoBlock
(
deviceInfo:
state
.
deviceInfo
),
StateInfoBlock
(
deviceInfo:
deviceInfo
),
SizedBox
(
height:
10
.
h
),
DeviceParmsBlock
(
deviceInfo:
state
.
deviceInfo
),
DeviceParmsBlock
(
deviceInfo:
deviceInfo
),
SizedBox
(
height:
10
.
h
),
PowerCharBlock
(
deviceInfo:
state
.
deviceInfo
),
PowerCharBlock
(
deviceInfo:
deviceInfo
),
SizedBox
(
height:
10
.
h
),
_buildBottomButtons
(
c
ubit
),
_buildBottomButtons
(
c
ontext
,
cubit
,
state
),
SizedBox
(
height:
30
.
h
),
],
)
;
},
)
,
)
,
);
}
,
),
),
);
}
Widget
_buildBottomButtons
(
DeviceCubit
cubit
)
{
Widget
_buildBottomButtons
(
BuildContext
context
,
DeviceCubit
cubit
,
DeviceState
state
)
{
return
Container
(
width:
double
.
infinity
,
padding:
EdgeInsets
.
symmetric
(
vertical:
15
.
h
),
...
...
@@ -74,17 +101,30 @@ class DeviceDetailView extends StatelessWidget {
width:
300
.
w
,
height:
88
.
h
,
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
color:
state
.
isPoweringOn
?
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.4
)
:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
),
child:
TextButton
(
onPressed:
()
=>
cubit
.
remotePowerOn
(),
child:
Text
(
"远程送电"
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
)),
),
onPressed:
state
.
isPoweringOn
?
null
:
()
=>
_handlePowerOn
(
context
,
cubit
),
child:
state
.
isPoweringOn
?
SizedBox
(
width:
32
.
sp
,
height:
32
.
sp
,
child:
const
CircularProgressIndicator
(
strokeWidth:
3
,
color:
Color
.
fromRGBO
(
237
,
245
,
255
,
1
),
),
)
:
Text
(
"远程送电"
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
237
,
245
,
255
,
1
)),
),
),
),
SizedBox
(
width:
30
.
w
),
...
...
@@ -92,25 +132,74 @@ class DeviceDetailView extends StatelessWidget {
width:
300
.
w
,
height:
88
.
h
,
decoration:
BoxDecoration
(
color:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1.0
),
color:
state
.
isPoweringOff
?
const
Color
.
fromRGBO
(
229
,
241
,
255
,
0.6
)
:
const
Color
.
fromRGBO
(
229
,
241
,
255
,
1.0
),
border:
Border
.
all
(
color:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
color:
state
.
isPoweringOff
?
const
Color
.
fromRGBO
(
73
,
149
,
234
,
0.4
)
:
const
Color
.
fromRGBO
(
73
,
149
,
234
,
1
),
width:
1
.
w
,
),
borderRadius:
BorderRadius
.
circular
(
16
.
r
),
),
child:
TextButton
(
onPressed:
()
=>
cubit
.
remotePowerOff
(),
child:
Text
(
"远程断电"
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)),
),
onPressed:
state
.
isPoweringOff
?
null
:
()
=>
_handlePowerOff
(
context
,
cubit
),
child:
state
.
isPoweringOff
?
SizedBox
(
width:
32
.
sp
,
height:
32
.
sp
,
child:
const
CircularProgressIndicator
(
strokeWidth:
3
,
color:
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
),
)
:
Text
(
"远程断电"
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
100
,
116
,
139
,
1
)),
),
),
),
],
),
);
}
Future
<
void
>
_handlePowerOn
(
BuildContext
context
,
DeviceCubit
cubit
)
async
{
try
{
await
cubit
.
remotePowerOn
();
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'远程送电成功'
)),
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'远程送电失败:
$e
'
)),
);
}
}
}
Future
<
void
>
_handlePowerOff
(
BuildContext
context
,
DeviceCubit
cubit
)
async
{
try
{
await
cubit
.
remotePowerOff
();
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
const
SnackBar
(
content:
Text
(
'远程断电成功'
)),
);
}
}
catch
(
e
)
{
if
(
context
.
mounted
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
'远程断电失败:
$e
'
)),
);
}
}
}
}
\ No newline at end of file
lib/views/home/index/cubit/home_index_cubit.dart
View file @
a49802fa
...
...
@@ -30,44 +30,7 @@ class HomeIndexCubit extends Cubit<HomeIndexState> {
highAlarmCount:
dashboard
.
statistics
.
highAlertCount
,
mediumAlarmCount:
dashboard
.
statistics
.
mediumAlertCount
,
onlineDeviceCount:
dashboard
.
statistics
.
onlineDeviceCount
,
temperatureAlarmTitle:
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
alertTitle
:
''
,
temperatureAlarmLocation:
dashboard
.
alerts
.
isNotEmpty
?
'
${dashboard.alerts[0].roomName}
·
${dashboard.alerts[0].deviceName}
'
:
''
,
currentTemperature:
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
temperature
:
''
,
currentVoltage:
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
voltage
:
''
,
currentCurrent:
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
current
:
''
,
waitTime:
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
waitingDurationDesc
:
''
,
alarmLevel:
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
alertLevelText
:
''
,
voltageAlarmTitle:
dashboard
.
alerts
.
length
>
1
?
dashboard
.
alerts
[
1
].
alertTitle
:
''
,
voltageAlarmLocation:
dashboard
.
alerts
.
length
>
1
?
'
${dashboard.alerts[1].roomName}
·
${dashboard.alerts[1].deviceName}
'
:
''
,
voltageValue:
dashboard
.
alerts
.
length
>
1
?
dashboard
.
alerts
[
1
].
voltage
:
''
,
normalVoltage:
''
,
voltageWaitTime:
dashboard
.
alerts
.
length
>
1
?
dashboard
.
alerts
[
1
].
waitingDurationDesc
:
''
,
voltageAlarmLevel:
dashboard
.
alerts
.
length
>
1
?
dashboard
.
alerts
[
1
].
alertLevelText
:
''
,
voltageAlertId:
dashboard
.
alerts
.
length
>
1
?
dashboard
.
alerts
[
1
].
alertId
:
0
,
alerts:
dashboard
.
alerts
,
equipmentList:
dashboard
.
devices
.
map
((
d
)
=>
_mapDeviceToEquipment
(
d
))
.
toList
(),
...
...
lib/views/home/index/cubit/home_index_state.dart
View file @
a49802fa
import
'package:equatable/equatable.dart'
;
import
'package:flutter/material.dart'
;
import
'package:smart_hotel_app/models/bo/alert_dashboard_bo.dart'
;
class
EquipmentItem
{
final
IconData
icon
;
...
...
@@ -23,20 +24,7 @@ class HomeIndexState extends Equatable {
final
int
highAlarmCount
;
final
int
mediumAlarmCount
;
final
int
onlineDeviceCount
;
final
String
temperatureAlarmTitle
;
final
String
temperatureAlarmLocation
;
final
String
currentTemperature
;
final
String
currentVoltage
;
final
String
currentCurrent
;
final
String
waitTime
;
final
String
alarmLevel
;
final
int
voltageAlertId
;
final
String
voltageAlarmTitle
;
final
String
voltageAlarmLocation
;
final
String
voltageValue
;
final
String
normalVoltage
;
final
String
voltageWaitTime
;
final
String
voltageAlarmLevel
;
final
List
<
AlertItemBO
>
alerts
;
final
List
<
EquipmentItem
>
equipmentList
;
const
HomeIndexState
({
...
...
@@ -45,20 +33,7 @@ class HomeIndexState extends Equatable {
this
.
highAlarmCount
=
0
,
this
.
mediumAlarmCount
=
0
,
this
.
onlineDeviceCount
=
0
,
this
.
temperatureAlarmTitle
=
''
,
this
.
temperatureAlarmLocation
=
''
,
this
.
currentTemperature
=
''
,
this
.
currentVoltage
=
''
,
this
.
currentCurrent
=
''
,
this
.
waitTime
=
''
,
this
.
alarmLevel
=
''
,
this
.
voltageAlarmTitle
=
''
,
this
.
voltageAlarmLocation
=
''
,
this
.
voltageValue
=
''
,
this
.
normalVoltage
=
''
,
this
.
voltageWaitTime
=
''
,
this
.
voltageAlarmLevel
=
''
,
this
.
voltageAlertId
=
0
,
this
.
alerts
=
const
[],
this
.
equipmentList
=
const
[],
});
...
...
@@ -68,20 +43,7 @@ class HomeIndexState extends Equatable {
int
?
highAlarmCount
,
int
?
mediumAlarmCount
,
int
?
onlineDeviceCount
,
String
?
temperatureAlarmTitle
,
String
?
temperatureAlarmLocation
,
String
?
currentTemperature
,
String
?
currentVoltage
,
String
?
currentCurrent
,
String
?
waitTime
,
String
?
alarmLevel
,
int
?
voltageAlertId
,
String
?
voltageAlarmTitle
,
String
?
voltageAlarmLocation
,
String
?
voltageValue
,
String
?
normalVoltage
,
String
?
voltageWaitTime
,
String
?
voltageAlarmLevel
,
List
<
AlertItemBO
>?
alerts
,
List
<
EquipmentItem
>?
equipmentList
,
})
{
return
HomeIndexState
(
...
...
@@ -90,20 +52,7 @@ class HomeIndexState extends Equatable {
highAlarmCount:
highAlarmCount
??
this
.
highAlarmCount
,
mediumAlarmCount:
mediumAlarmCount
??
this
.
mediumAlarmCount
,
onlineDeviceCount:
onlineDeviceCount
??
this
.
onlineDeviceCount
,
temperatureAlarmTitle:
temperatureAlarmTitle
??
this
.
temperatureAlarmTitle
,
temperatureAlarmLocation:
temperatureAlarmLocation
??
this
.
temperatureAlarmLocation
,
currentTemperature:
currentTemperature
??
this
.
currentTemperature
,
currentVoltage:
currentVoltage
??
this
.
currentVoltage
,
currentCurrent:
currentCurrent
??
this
.
currentCurrent
,
waitTime:
waitTime
??
this
.
waitTime
,
alarmLevel:
alarmLevel
??
this
.
alarmLevel
,
voltageAlarmTitle:
voltageAlarmTitle
??
this
.
voltageAlarmTitle
,
voltageAlarmLocation:
voltageAlarmLocation
??
this
.
voltageAlarmLocation
,
voltageValue:
voltageValue
??
this
.
voltageValue
,
normalVoltage:
normalVoltage
??
this
.
normalVoltage
,
voltageWaitTime:
voltageWaitTime
??
this
.
voltageWaitTime
,
voltageAlarmLevel:
voltageAlarmLevel
??
this
.
voltageAlarmLevel
,
voltageAlertId:
voltageAlertId
??
this
.
voltageAlertId
,
alerts:
alerts
??
this
.
alerts
,
equipmentList:
equipmentList
??
this
.
equipmentList
,
);
}
...
...
@@ -115,20 +64,7 @@ class HomeIndexState extends Equatable {
highAlarmCount
,
mediumAlarmCount
,
onlineDeviceCount
,
temperatureAlarmTitle
,
temperatureAlarmLocation
,
currentTemperature
,
currentVoltage
,
currentCurrent
,
waitTime
,
alarmLevel
,
voltageAlarmTitle
,
voltageAlarmLocation
,
voltageValue
,
normalVoltage
,
voltageWaitTime
,
voltageAlarmLevel
,
voltageAlertId
,
alerts
,
equipmentList
,
];
}
\ No newline at end of file
lib/views/home/index/index_view.dart
View file @
a49802fa
...
...
@@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:smart_hotel_app/models/bo/alert_dashboard_bo.dart'
;
import
'package:smart_hotel_app/repositories/alert_dashboard_repository.dart'
;
import
'package:smart_hotel_app/services/alert_dashboard_service.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart'
;
...
...
@@ -46,26 +47,7 @@ class HomeView extends StatelessWidget {
mediumAlarmCount:
state
.
mediumAlarmCount
,
onlineDeviceCount:
state
.
onlineDeviceCount
,
),
SizedBox
(
height:
20
.
h
),
TemperatureBlock
(
temperatureAlarmTitle:
state
.
temperatureAlarmTitle
,
temperatureAlarmLocation:
state
.
temperatureAlarmLocation
,
currentTemperature:
state
.
currentTemperature
,
currentVoltage:
state
.
currentVoltage
,
currentCurrent:
state
.
currentCurrent
,
waitTime:
state
.
waitTime
,
alarmLevel:
state
.
alarmLevel
,
),
SizedBox
(
height:
20
.
h
),
VoltageOperateBlock
(
alertId:
state
.
voltageAlertId
,
voltageAlarmTitle:
state
.
voltageAlarmTitle
,
voltageAlarmLocation:
state
.
voltageAlarmLocation
,
voltageValue:
state
.
voltageValue
,
normalVoltage:
state
.
normalVoltage
,
voltageWaitTime:
state
.
voltageWaitTime
,
voltageAlarmLevel:
state
.
voltageAlarmLevel
,
),
...
_buildAlertBlocks
(
state
.
alerts
),
SizedBox
(
height:
20
.
h
),
EquipmentListBlock
(
equipmentList:
state
.
equipmentList
,
...
...
@@ -82,4 +64,42 @@ class HomeView extends StatelessWidget {
),
);
}
List
<
Widget
>
_buildAlertBlocks
(
List
<
AlertItemBO
>
alerts
)
{
final
blocks
=
<
Widget
>[];
for
(
final
alert
in
alerts
)
{
final
location
=
'
${alert.roomName}
·
${alert.deviceName}
'
;
switch
(
alert
.
alertCategory
)
{
case
'temperature'
:
blocks
.
addAll
([
SizedBox
(
height:
20
.
h
),
TemperatureBlock
(
temperatureAlarmTitle:
alert
.
alertTitle
,
temperatureAlarmLocation:
location
,
currentTemperature:
alert
.
temperature
,
currentVoltage:
alert
.
voltage
,
currentCurrent:
alert
.
current
,
waitTime:
alert
.
waitingDurationDesc
,
alarmLevel:
alert
.
alertLevelText
,
),
]);
case
'voltage'
:
case
'current'
:
case
'power'
:
blocks
.
addAll
([
SizedBox
(
height:
20
.
h
),
VoltageOperateBlock
(
alertId:
alert
.
alertId
,
voltageAlarmTitle:
alert
.
alertTitle
,
voltageAlarmLocation:
location
,
voltageValue:
alert
.
voltage
,
normalVoltage:
''
,
voltageWaitTime:
alert
.
waitingDurationDesc
,
voltageAlarmLevel:
alert
.
alertLevelText
,
),
]);
}
}
return
blocks
;
}
}
\ No newline at end of file
对接方案.md
View file @
a49802fa
# 智慧酒
店 App 接口对接方案
# 智慧酒
店 App 接口对接方案
...
...
@@ -183,10 +183,15 @@ class xxxBO extends Equatable {
|
登录页 |POST | /app/auth/login/password | 已对接 | 用户模块 |
|
告警 |GET | /app/alert/dashboard | 已对接 | 设备告警看板 |
|
告警详情 |GET | /app/alert/detail | 已对接 | 告警详情 |
|
告警详情-确认处理 |POST | /app/alert/handle | 未对接 | 告警详情 | 在告警详情页面点击 确认处理 按钮,调用该接口。需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示。成功之后按钮不可再点击 |
|
设备控制 |GET | /app/device/control/detail | 未对接 | 设备控制 | |
|
设备控制 |POST | /app/device/control/powerOn | 未对接 | 设备控制-远程送电 | 需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示 |
|
设备控制 |POST | /app/device/control/powerOff | 未对接 | 设备控制-远程断电 | 需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示|
|
告警详情-确认处理 |POST | /app/alert/handle | 已对接 | 告警详情 | 在告警详情页面点击 确认处理 按钮,调用该接口。需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示。成功之后按钮不可再点击 |
|
设备控制 |GET | /app/device/control/detail | 已对接 | 设备控制 | |
|
设备控制 |POST | /app/device/control/powerOn | 已对接 | 设备控制-远程送电 | 需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示 |
|
设备控制 |POST | /app/device/control/powerOff | 已对接 | 设备控制-远程断电 | 需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示|
|
设备拓扑 |GET | /app/device/topology | 未对接 | 设备拓扑 | 相关页面:InspectionTopologyView |
#
## 3.2 接口详细定义
...
...
@@ -250,6 +255,7 @@ class xxxBO extends Equatable {
"alertLevel": "string", // 告警级别编码
"alertLevelText": "string", // 告警级别中文描述
"alertStatus": "string",// 告警状态编码(0=待处理,1=处理中,2=已处理,3=忽略,4=误报)
"alertCategory": "string", // 预警分类(temperature=温度 current=电流 voltage=电压 power=用电 device=设备)
"roomName": "string", // 所属房间名称
"deviceName": "string",// 告警设备名称
"alertValue": "string",
...
...
@@ -405,6 +411,83 @@ class xxxBO extends Equatable {
}
`
``
#
### 设备控制-远程送电
*
*POST /app/device/control/powerOn**
`
``
请
求体:
{
"deviceId": 0 // 设备ID
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"success": true,
"affectedDeviceCount": 0
}
}
`
``
#
### 设备控制-远程断电
*
*POST /app/device/control/powerOff**
`
``
请
求体:
{
"deviceId": 0 // 设备ID
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"success": true,
"affectedDeviceCount": 0
}
}
`
``
#
### 设备拓扑
*
*POST /app/device/topology**
`
``
请
求体:
{
"deviceId": 0 // 设备ID
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"deviceInfo": {
"deviceId": 0,
"deviceName": "string",
"deviceCode": "string",
"locationText": "string"
},
"treeNodes": [
{
"deviceId": 0,
"deviceName": "string",
"deviceType": "string",
"icon": "string",
"status": "string",
"statusText": "string",
"deviceCode": "string"
}
]
}
}
`
``
...
...
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