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
42fc065d
Commit
42fc065d
authored
Jun 08, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
告警、告警详情 接口对接
parent
695103c3
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
988 additions
and
90 deletions
+988
-90
alert_dashboard_bo.dart
lib/models/bo/alert_dashboard_bo.dart
+220
-0
alert_detail_bo.dart
lib/models/bo/alert_detail_bo.dart
+193
-0
alert_dashboard_repository.dart
lib/repositories/alert_dashboard_repository.dart
+14
-0
alert_detail_repository.dart
lib/repositories/alert_detail_repository.dart
+16
-0
app_router.gr.dart
lib/routes/app_router.gr.dart
+33
-5
alert_dashboard_service.dart
lib/services/alert_dashboard_service.dart
+18
-0
alert_detail_service.dart
lib/services/alert_detail_service.dart
+18
-0
abnormal_detail_view.dart
lib/views/home/abnormal/abnormal_detail_view.dart
+40
-14
abnormal_cubit.dart
lib/views/home/abnormal/cubit/abnormal_cubit.dart
+56
-27
abnormal_state.dart
lib/views/home/abnormal/cubit/abnormal_state.dart
+7
-2
alarm_info_block.dart
lib/views/home/abnormal/widget/alarm_info_block.dart
+7
-1
home_index_cubit.dart
lib/views/home/index/cubit/home_index_cubit.dart
+118
-34
home_index_state.dart
lib/views/home/index/cubit/home_index_state.dart
+16
-0
index_view.dart
lib/views/home/index/index_view.dart
+8
-1
temperature_block.dart
lib/views/home/index/widget/temperature_block.dart
+1
-1
voltage_operate_block.dart
lib/views/home/index/widget/voltage_operate_block.dart
+3
-1
对接方案.md
对接方案.md
+220
-4
No files found.
lib/models/bo/alert_dashboard_bo.dart
0 → 100644
View file @
42fc065d
import
'package:equatable/equatable.dart'
;
// ==================== 设备告警看板 Dashboard ====================
class
AlertDashboardBO
extends
Equatable
{
final
int
total
;
final
AlertDashboardStatisticsBO
statistics
;
final
List
<
AlertItemBO
>
alerts
;
final
List
<
DeviceItemBO
>
devices
;
const
AlertDashboardBO
({
required
this
.
total
,
required
this
.
statistics
,
required
this
.
alerts
,
required
this
.
devices
,
});
factory
AlertDashboardBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AlertDashboardBO
(
total:
json
[
'total'
]
as
int
?
??
0
,
statistics:
AlertDashboardStatisticsBO
.
fromJson
(
json
[
'statistics'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
alerts:
(
json
[
'alerts'
]
as
List
<
dynamic
>?)
?.
map
((
e
)
=>
AlertItemBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
()
??
[],
devices:
(
json
[
'devices'
]
as
List
<
dynamic
>?)
?.
map
((
e
)
=>
DeviceItemBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
()
??
[],
);
}
@override
List
<
Object
?>
get
props
=>
[
total
,
statistics
,
alerts
,
devices
];
}
// ==================== 统计数据 ====================
class
AlertDashboardStatisticsBO
extends
Equatable
{
final
int
highAlertCount
;
final
int
mediumAlertCount
;
final
int
onlineDeviceCount
;
const
AlertDashboardStatisticsBO
({
required
this
.
highAlertCount
,
required
this
.
mediumAlertCount
,
required
this
.
onlineDeviceCount
,
});
factory
AlertDashboardStatisticsBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AlertDashboardStatisticsBO
(
highAlertCount:
json
[
'highAlertCount'
]
as
int
?
??
0
,
mediumAlertCount:
json
[
'mediumAlertCount'
]
as
int
?
??
0
,
onlineDeviceCount:
json
[
'onlineDeviceCount'
]
as
int
?
??
0
,
);
}
@override
List
<
Object
?>
get
props
=>
[
highAlertCount
,
mediumAlertCount
,
onlineDeviceCount
];
}
// ==================== 告警信息 ====================
class
AlertItemBO
extends
Equatable
{
final
int
alertId
;
final
String
alertNo
;
final
String
alertTitle
;
final
String
alertLevel
;
final
String
alertLevelText
;
final
String
alertStatus
;
final
String
roomName
;
final
String
deviceName
;
final
String
alertValue
;
final
String
thresholdValue
;
final
String
alertContent
;
final
String
voltage
;
final
String
current
;
final
String
temperature
;
final
int
waitingDuration
;
final
String
waitingDurationDesc
;
final
String
alertTime
;
const
AlertItemBO
({
required
this
.
alertId
,
required
this
.
alertNo
,
required
this
.
alertTitle
,
required
this
.
alertLevel
,
required
this
.
alertLevelText
,
required
this
.
alertStatus
,
required
this
.
roomName
,
required
this
.
deviceName
,
required
this
.
alertValue
,
required
this
.
thresholdValue
,
required
this
.
alertContent
,
required
this
.
voltage
,
required
this
.
current
,
required
this
.
temperature
,
required
this
.
waitingDuration
,
required
this
.
waitingDurationDesc
,
required
this
.
alertTime
,
});
factory
AlertItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AlertItemBO
(
alertId:
json
[
'alertId'
]
as
int
?
??
0
,
alertNo:
json
[
'alertNo'
]
as
String
?
??
''
,
alertTitle:
json
[
'alertTitle'
]
as
String
?
??
''
,
alertLevel:
json
[
'alertLevel'
]
as
String
?
??
''
,
alertLevelText:
json
[
'alertLevelText'
]
as
String
?
??
''
,
alertStatus:
json
[
'alertStatus'
]
as
String
?
??
'0'
,
roomName:
json
[
'roomName'
]
as
String
?
??
''
,
deviceName:
json
[
'deviceName'
]
as
String
?
??
''
,
alertValue:
json
[
'alertValue'
]
as
String
?
??
''
,
thresholdValue:
json
[
'thresholdValue'
]
as
String
?
??
''
,
alertContent:
json
[
'alertContent'
]
as
String
?
??
''
,
voltage:
json
[
'voltage'
]
as
String
?
??
''
,
current:
json
[
'current'
]
as
String
?
??
''
,
temperature:
json
[
'temperature'
]
as
String
?
??
''
,
waitingDuration:
json
[
'waitingDuration'
]
as
int
?
??
0
,
waitingDurationDesc:
json
[
'waitingDurationDesc'
]
as
String
?
??
''
,
alertTime:
json
[
'alertTime'
]
as
String
?
??
''
,
);
}
@override
List
<
Object
?>
get
props
=>
[
alertId
,
alertNo
,
alertTitle
,
alertLevel
,
alertLevelText
,
alertStatus
,
roomName
,
deviceName
,
alertValue
,
thresholdValue
,
alertContent
,
voltage
,
current
,
temperature
,
waitingDuration
,
waitingDurationDesc
,
alertTime
,
];
}
// ==================== 设备巡检列表 ====================
class
DeviceItemBO
extends
Equatable
{
final
int
deviceId
;
final
String
deviceName
;
final
String
deviceTypeIcon
;
final
String
deviceTypeName
;
final
String
runStatus
;
final
String
runStatusText
;
final
String
roomName
;
final
String
temperature
;
final
String
voltage
;
final
String
power
;
final
String
current
;
final
String
onlineStatus
;
final
String
lastHeartbeat
;
const
DeviceItemBO
({
required
this
.
deviceId
,
required
this
.
deviceName
,
required
this
.
deviceTypeIcon
,
required
this
.
deviceTypeName
,
required
this
.
runStatus
,
required
this
.
runStatusText
,
required
this
.
roomName
,
required
this
.
temperature
,
required
this
.
voltage
,
required
this
.
power
,
required
this
.
current
,
required
this
.
onlineStatus
,
required
this
.
lastHeartbeat
,
});
factory
DeviceItemBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DeviceItemBO
(
deviceId:
json
[
'deviceId'
]
as
int
?
??
0
,
deviceName:
json
[
'deviceName'
]
as
String
?
??
''
,
deviceTypeIcon:
json
[
'deviceTypeIcon'
]
as
String
?
??
''
,
deviceTypeName:
json
[
'deviceTypeName'
]
as
String
?
??
''
,
runStatus:
json
[
'runStatus'
]
as
String
?
??
''
,
runStatusText:
json
[
'runStatusText'
]
as
String
?
??
''
,
roomName:
json
[
'roomName'
]
as
String
?
??
''
,
temperature:
json
[
'temperature'
]
as
String
?
??
''
,
voltage:
json
[
'voltage'
]
as
String
?
??
''
,
power:
json
[
'power'
]
as
String
?
??
''
,
current:
json
[
'current'
]
as
String
?
??
''
,
onlineStatus:
json
[
'onlineStatus'
]
as
String
?
??
'0'
,
lastHeartbeat:
json
[
'lastHeartbeat'
]
as
String
?
??
''
,
);
}
@override
List
<
Object
?>
get
props
=>
[
deviceId
,
deviceName
,
deviceTypeIcon
,
deviceTypeName
,
runStatus
,
runStatusText
,
roomName
,
temperature
,
voltage
,
power
,
current
,
onlineStatus
,
lastHeartbeat
,
];
}
\ No newline at end of file
lib/models/bo/alert_detail_bo.dart
0 → 100644
View file @
42fc065d
import
'package:equatable/equatable.dart'
;
// ==================== 告警详情 ====================
class
AlertDetailBO
extends
Equatable
{
final
AlertBasicInfoBO
alertBasicInfo
;
final
TrendChartBO
trendChart
;
final
AlertDetailInfoBO
alertDetailInfo
;
const
AlertDetailBO
({
required
this
.
alertBasicInfo
,
required
this
.
trendChart
,
required
this
.
alertDetailInfo
,
});
factory
AlertDetailBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AlertDetailBO
(
alertBasicInfo:
AlertBasicInfoBO
.
fromJson
(
json
[
'alertBasicInfo'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
trendChart:
TrendChartBO
.
fromJson
(
json
[
'trendChart'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
alertDetailInfo:
AlertDetailInfoBO
.
fromJson
(
json
[
'alertDetailInfo'
]
as
Map
<
String
,
dynamic
>?
??
{},
),
);
}
@override
List
<
Object
?>
get
props
=>
[
alertBasicInfo
,
trendChart
,
alertDetailInfo
];
}
// ==================== 告警基本信息 ====================
class
AlertBasicInfoBO
extends
Equatable
{
final
int
alertId
;
final
String
alertTitle
;
final
String
alertLevel
;
final
String
alertLevelText
;
final
String
alertStatus
;
final
String
alertDeviceLocation
;
final
int
alertCount
;
final
String
alertTime
;
final
String
alertIcon
;
const
AlertBasicInfoBO
({
required
this
.
alertId
,
required
this
.
alertTitle
,
required
this
.
alertLevel
,
required
this
.
alertLevelText
,
required
this
.
alertStatus
,
required
this
.
alertDeviceLocation
,
required
this
.
alertCount
,
required
this
.
alertTime
,
required
this
.
alertIcon
,
});
factory
AlertBasicInfoBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AlertBasicInfoBO
(
alertId:
json
[
'alertId'
]
as
int
?
??
0
,
alertTitle:
json
[
'alertTitle'
]
as
String
?
??
''
,
alertLevel:
json
[
'alertLevel'
]
as
String
?
??
''
,
alertLevelText:
json
[
'alertLevelText'
]
as
String
?
??
''
,
alertStatus:
json
[
'alertStatus'
]
as
String
?
??
''
,
alertDeviceLocation:
json
[
'alertDeviceLocation'
]
as
String
?
??
''
,
alertCount:
json
[
'alertCount'
]
as
int
?
??
0
,
alertTime:
json
[
'alertTime'
]
as
String
?
??
''
,
alertIcon:
json
[
'alertIcon'
]
as
String
?
??
''
,
);
}
@override
List
<
Object
?>
get
props
=>
[
alertId
,
alertTitle
,
alertLevel
,
alertLevelText
,
alertStatus
,
alertDeviceLocation
,
alertCount
,
alertTime
,
alertIcon
,
];
}
// ==================== 趋势图 ====================
class
TrendChartBO
extends
Equatable
{
final
String
chartTitle
;
final
String
chartDate
;
final
String
unit
;
final
List
<
DataPointBO
>
dataPoints
;
final
int
yaxisMax
;
final
int
yaxisMin
;
const
TrendChartBO
({
required
this
.
chartTitle
,
required
this
.
chartDate
,
required
this
.
unit
,
required
this
.
dataPoints
,
required
this
.
yaxisMax
,
required
this
.
yaxisMin
,
});
factory
TrendChartBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
TrendChartBO
(
chartTitle:
json
[
'chartTitle'
]
as
String
?
??
''
,
chartDate:
json
[
'chartDate'
]
as
String
?
??
''
,
unit:
json
[
'unit'
]
as
String
?
??
''
,
dataPoints:
(
json
[
'dataPoints'
]
as
List
<
dynamic
>?)
?.
map
(
(
e
)
=>
DataPointBO
.
fromJson
(
e
as
Map
<
String
,
dynamic
>))
.
toList
()
??
[],
yaxisMax:
json
[
'yaxisMax'
]
as
int
?
??
100
,
yaxisMin:
json
[
'yaxisMin'
]
as
int
?
??
0
,
);
}
@override
List
<
Object
?>
get
props
=>
[
chartTitle
,
chartDate
,
unit
,
dataPoints
,
yaxisMax
,
yaxisMin
];
}
class
DataPointBO
extends
Equatable
{
final
String
time
;
final
double
value
;
final
int
recordId
;
const
DataPointBO
({
required
this
.
time
,
required
this
.
value
,
required
this
.
recordId
,
});
factory
DataPointBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DataPointBO
(
time:
json
[
'time'
]
as
String
?
??
''
,
value:
(
json
[
'value'
]
as
num
?)?.
toDouble
()
??
0
,
recordId:
json
[
'recordId'
]
as
int
?
??
0
,
);
}
@override
List
<
Object
?>
get
props
=>
[
time
,
value
,
recordId
];
}
// ==================== 告警详细信息 ====================
class
AlertDetailInfoBO
extends
Equatable
{
final
String
thresholdSetting
;
final
String
duration
;
final
int
durationMinutes
;
final
String
peakRecord
;
final
String
linkageAction
;
final
String
alertValue
;
final
String
alertContent
;
const
AlertDetailInfoBO
({
required
this
.
thresholdSetting
,
required
this
.
duration
,
required
this
.
durationMinutes
,
required
this
.
peakRecord
,
required
this
.
linkageAction
,
required
this
.
alertValue
,
required
this
.
alertContent
,
});
factory
AlertDetailInfoBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
AlertDetailInfoBO
(
thresholdSetting:
json
[
'thresholdSetting'
]
as
String
?
??
''
,
duration:
json
[
'duration'
]
as
String
?
??
''
,
durationMinutes:
json
[
'durationMinutes'
]
as
int
?
??
0
,
peakRecord:
json
[
'peakRecord'
]
as
String
?
??
''
,
linkageAction:
json
[
'linkageAction'
]
as
String
?
??
''
,
alertValue:
json
[
'alertValue'
]
as
String
?
??
''
,
alertContent:
json
[
'alertContent'
]
as
String
?
??
''
,
);
}
@override
List
<
Object
?>
get
props
=>
[
thresholdSetting
,
duration
,
durationMinutes
,
peakRecord
,
linkageAction
,
alertValue
,
alertContent
,
];
}
\ No newline at end of file
lib/repositories/alert_dashboard_repository.dart
0 → 100644
View file @
42fc065d
import
'../utils/http/response_model.dart'
;
import
'../utils/http/dio_request.dart'
;
import
'../models/bo/alert_dashboard_bo.dart'
;
class
AlertDashboardRepository
{
Future
<
ResponseModel
<
AlertDashboardBO
>>
getDashboard
()
{
return
DioRequest
.
instance
.
get
<
AlertDashboardBO
>(
'/app/alert/dashboard'
,
fromJsonT:
(
data
)
=>
AlertDashboardBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
}
}
\ No newline at end of file
lib/repositories/alert_detail_repository.dart
0 → 100644
View file @
42fc065d
import
'../utils/http/response_model.dart'
;
import
'../utils/http/dio_request.dart'
;
import
'../models/bo/alert_detail_bo.dart'
;
class
AlertDetailRepository
{
/// 获取告警详情
Future
<
ResponseModel
<
AlertDetailBO
>>
getDetail
({
required
int
alertId
})
{
return
DioRequest
.
instance
.
get
<
AlertDetailBO
>(
'/app/alert/detail'
,
queryParameters:
{
'alertId'
:
alertId
},
fromJsonT:
(
data
)
=>
AlertDetailBO
.
fromJson
(
data
as
Map
<
String
,
dynamic
>),
);
}
}
\ No newline at end of file
lib/routes/app_router.gr.dart
View file @
42fc065d
...
@@ -50,9 +50,13 @@ abstract class $AppRouter extends _i21.RootStackRouter {
...
@@ -50,9 +50,13 @@ abstract class $AppRouter extends _i21.RootStackRouter {
@override
@override
final
Map
<
String
,
_i21
.
PageFactory
>
pagesMap
=
{
final
Map
<
String
,
_i21
.
PageFactory
>
pagesMap
=
{
AbnormalDetailRoute
.
name
:
(
routeData
)
{
AbnormalDetailRoute
.
name
:
(
routeData
)
{
final
args
=
routeData
.
argsAs
<
AbnormalDetailRouteArgs
>();
return
_i21
.
AutoRoutePage
<
dynamic
>(
return
_i21
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i1
.
AbnormalDetailView
(),
child:
_i1
.
AbnormalDetailView
(
key:
args
.
key
,
alertId:
args
.
alertId
,
),
);
);
},
},
AbnormalListRoute
.
name
:
(
routeData
)
{
AbnormalListRoute
.
name
:
(
routeData
)
{
...
@@ -200,16 +204,40 @@ abstract class $AppRouter extends _i21.RootStackRouter {
...
@@ -200,16 +204,40 @@ abstract class $AppRouter extends _i21.RootStackRouter {
/// generated route for
/// generated route for
/// [_i1.AbnormalDetailView]
/// [_i1.AbnormalDetailView]
class
AbnormalDetailRoute
extends
_i21
.
PageRouteInfo
<
void
>
{
class
AbnormalDetailRoute
extends
_i21
.
PageRouteInfo
<
AbnormalDetailRouteArgs
>
{
const
AbnormalDetailRoute
({
List
<
_i21
.
PageRouteInfo
>?
children
})
AbnormalDetailRoute
({
:
super
(
_i22
.
Key
?
key
,
required
int
alertId
,
List
<
_i21
.
PageRouteInfo
>?
children
,
})
:
super
(
AbnormalDetailRoute
.
name
,
AbnormalDetailRoute
.
name
,
args:
AbnormalDetailRouteArgs
(
key:
key
,
alertId:
alertId
,
),
initialChildren:
children
,
initialChildren:
children
,
);
);
static
const
String
name
=
'AbnormalDetailRoute'
;
static
const
String
name
=
'AbnormalDetailRoute'
;
static
const
_i21
.
PageInfo
<
void
>
page
=
_i21
.
PageInfo
<
void
>(
name
);
static
const
_i21
.
PageInfo
<
AbnormalDetailRouteArgs
>
page
=
_i21
.
PageInfo
<
AbnormalDetailRouteArgs
>(
name
);
}
class
AbnormalDetailRouteArgs
{
const
AbnormalDetailRouteArgs
({
this
.
key
,
required
this
.
alertId
,
});
final
_i22
.
Key
?
key
;
final
int
alertId
;
@override
String
toString
()
{
return
'AbnormalDetailRouteArgs{key:
$key
, alertId:
$alertId
}'
;
}
}
}
/// generated route for
/// generated route for
...
...
lib/services/alert_dashboard_service.dart
0 → 100644
View file @
42fc065d
import
'../models/bo/alert_dashboard_bo.dart'
;
import
'../repositories/alert_dashboard_repository.dart'
;
class
AlertDashboardService
{
final
AlertDashboardRepository
_repository
;
AlertDashboardService
({
required
AlertDashboardRepository
repository
})
:
_repository
=
repository
;
Future
<
AlertDashboardBO
>
getDashboard
()
async
{
final
result
=
await
_repository
.
getDashboard
();
if
(
result
.
success
&&
result
.
data
!=
null
)
{
return
result
.
data
!;
}
throw
Exception
(
result
.
msg
);
}
}
\ No newline at end of file
lib/services/alert_detail_service.dart
0 → 100644
View file @
42fc065d
import
'../models/bo/alert_detail_bo.dart'
;
import
'../repositories/alert_detail_repository.dart'
;
class
AlertDetailService
{
final
AlertDetailRepository
_repository
;
AlertDetailService
({
required
AlertDetailRepository
repository
})
:
_repository
=
repository
;
Future
<
AlertDetailBO
>
getDetail
({
required
int
alertId
})
async
{
final
result
=
await
_repository
.
getDetail
(
alertId:
alertId
);
if
(
result
.
success
&&
result
.
data
!=
null
)
{
return
result
.
data
!;
}
throw
Exception
(
result
.
msg
);
}
}
\ No newline at end of file
lib/views/home/abnormal/abnormal_detail_view.dart
View file @
42fc065d
...
@@ -2,7 +2,9 @@ import 'package:auto_route/auto_route.dart';
...
@@ -2,7 +2,9 @@ import 'package:auto_route/auto_route.dart';
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/repositories/alert_detail_repository.dart'
;
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:smart_hotel_app/services/alert_detail_service.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_cubit.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_cubit.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_state.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_state.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/widget/alarm_info_block.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/widget/alarm_info_block.dart'
;
...
@@ -11,12 +13,18 @@ import 'package:smart_hotel_app/views/home/abnormal/widget/temperature_char_bloc
...
@@ -11,12 +13,18 @@ import 'package:smart_hotel_app/views/home/abnormal/widget/temperature_char_bloc
@RoutePage
()
@RoutePage
()
class
AbnormalDetailView
extends
StatelessWidget
{
class
AbnormalDetailView
extends
StatelessWidget
{
const
AbnormalDetailView
({
super
.
key
});
final
int
alertId
;
const
AbnormalDetailView
({
super
.
key
,
required
this
.
alertId
});
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
BlocProvider
(
return
BlocProvider
(
create:
(
_
)
=>
AbnormalCubit
(),
create:
(
_
)
{
final
repository
=
AlertDetailRepository
();
final
service
=
AlertDetailService
(
repository:
repository
);
return
AbnormalCubit
(
service:
service
,
alertId:
alertId
);
},
child:
Scaffold
(
child:
Scaffold
(
backgroundColor:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
backgroundColor:
const
Color
.
fromRGBO
(
242
,
243
,
245
,
1
),
appBar:
AppBar
(
appBar:
AppBar
(
...
@@ -39,25 +47,43 @@ class AbnormalDetailView extends StatelessWidget {
...
@@ -39,25 +47,43 @@ class AbnormalDetailView extends StatelessWidget {
),
),
centerTitle:
true
,
centerTitle:
true
,
),
),
body:
SingleChildScrollView
(
body:
BlocBuilder
<
AbnormalCubit
,
AbnormalState
>(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
builder:
(
context
,
state
)
{
child:
BlocBuilder
<
AbnormalCubit
,
AbnormalState
>(
if
(
state
.
isLoading
)
{
builder:
(
context
,
state
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
final
cubit
=
context
.
read
<
AbnormalCubit
>();
}
return
Column
(
if
(
state
.
error
!=
null
)
{
return
Center
(
child:
Text
(
'加载失败:
${state.error}
'
,
style:
TextStyle
(
fontSize:
28
.
sp
,
color:
const
Color
.
fromRGBO
(
255
,
100
,
101
,
1
),
),
),
);
}
final
alarmInfo
=
state
.
alarmInfo
;
if
(
alarmInfo
==
null
)
{
return
const
SizedBox
.
shrink
();
}
final
cubit
=
context
.
read
<
AbnormalCubit
>();
return
SingleChildScrollView
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Column
(
children:
[
children:
[
TemperatureBlock
(
alarmInfo:
state
.
alarmInfo
),
TemperatureBlock
(
alarmInfo:
alarmInfo
),
SizedBox
(
height:
10
.
h
),
SizedBox
(
height:
10
.
h
),
TemperatureCharBlock
(
alarmInfo:
state
.
alarmInfo
),
TemperatureCharBlock
(
alarmInfo:
alarmInfo
),
SizedBox
(
height:
10
.
h
),
SizedBox
(
height:
10
.
h
),
AlarmInfoBlock
(
alarmInfo:
state
.
alarmInfo
),
AlarmInfoBlock
(
alarmInfo:
alarmInfo
),
SizedBox
(
height:
10
.
h
),
SizedBox
(
height:
10
.
h
),
_buildBottomButtons
(
context
,
cubit
),
_buildBottomButtons
(
context
,
cubit
),
SizedBox
(
height:
30
.
h
),
SizedBox
(
height:
30
.
h
),
],
],
)
;
)
,
},
);
)
,
}
,
),
),
),
),
);
);
...
...
lib/views/home/abnormal/cubit/abnormal_cubit.dart
View file @
42fc065d
import
'package:fl_chart/fl_chart.dart'
;
import
'package:fl_chart/fl_chart.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:smart_hotel_app/models/bo/alert_detail_bo.dart'
;
import
'package:smart_hotel_app/services/alert_detail_service.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_state.dart'
;
import
'package:smart_hotel_app/views/home/abnormal/cubit/abnormal_state.dart'
;
class
AbnormalCubit
extends
Cubit
<
AbnormalState
>
{
class
AbnormalCubit
extends
Cubit
<
AbnormalState
>
{
AbnormalCubit
()
:
super
(
AbnormalState
(
alarmInfo:
_getAlarmInfo
()));
final
AlertDetailService
_service
;
final
int
_alertId
;
static
AlarmInfo
_getAlarmInfo
()
{
AbnormalCubit
({
return
const
AlarmInfo
(
required
AlertDetailService
service
,
alarmType:
'温度异常告警'
,
required
int
alertId
,
deviceInfo:
'A-301智能空开·客房301'
,
})
:
_service
=
service
,
alarmLevel:
'高警'
,
_alertId
=
alertId
,
urgency:
'紧急'
,
super
(
const
AbnormalState
())
{
currentTemp:
'85℃'
,
loadDetail
();
voltage:
'22V'
,
}
current:
'3.2A'
,
triggerTime:
'2026-05-09 14:23:18'
,
Future
<
void
>
loadDetail
()
async
{
threshold:
'温度>80℃触发'
,
emit
(
const
AbnormalState
(
isLoading:
true
));
duration:
'2小时37分钟'
,
try
{
peak:
'89.2℃ (15:02)'
,
final
detail
=
await
_service
.
getDetail
(
alertId:
_alertId
);
linkAction:
'自动断电保护'
,
emit
(
AbnormalState
(
alarmInfo:
_mapToAlarmInfo
(
detail
)));
date:
'5月9日'
,
}
catch
(
e
)
{
temperatureSpots:
[
emit
(
AbnormalState
(
error:
e
.
toString
()));
FlSpot
(
0
,
40
),
}
FlSpot
(
4
,
40
),
}
FlSpot
(
8
,
15
),
FlSpot
(
12
,
55
),
AlarmInfo
_mapToAlarmInfo
(
AlertDetailBO
detail
)
{
FlSpot
(
16
,
50
),
final
basic
=
detail
.
alertBasicInfo
;
FlSpot
(
18
,
55
),
final
trend
=
detail
.
trendChart
;
FlSpot
(
20
,
75
),
final
info
=
detail
.
alertDetailInfo
;
FlSpot
(
22
,
82
),
FlSpot
(
24
,
85
),
return
AlarmInfo
(
],
alarmType:
basic
.
alertTitle
,
deviceInfo:
basic
.
alertDeviceLocation
,
alarmLevel:
basic
.
alertLevelText
,
urgency:
_mapUrgency
(
basic
.
alertLevel
),
currentTemp:
info
.
alertValue
,
voltage:
''
,
current:
''
,
triggerTime:
basic
.
alertTime
,
threshold:
info
.
thresholdSetting
,
duration:
info
.
duration
,
peak:
info
.
peakRecord
,
linkAction:
info
.
linkageAction
,
date:
trend
.
chartDate
,
temperatureSpots:
trend
.
dataPoints
.
asMap
().
entries
.
map
((
entry
)
{
return
FlSpot
(
entry
.
key
.
toDouble
(),
entry
.
value
.
value
);
}).
toList
(),
);
);
}
}
String
_mapUrgency
(
String
level
)
{
switch
(
level
)
{
case
'high'
:
return
'紧急'
;
case
'medium'
:
return
'一般'
;
default
:
return
'一般'
;
}
}
void
handleConfirm
()
{
void
handleConfirm
()
{
print
(
'确认处理'
);
print
(
'确认处理'
);
}
}
...
...
lib/views/home/abnormal/cubit/abnormal_state.dart
View file @
42fc065d
...
@@ -35,9 +35,13 @@ class AlarmInfo {
...
@@ -35,9 +35,13 @@ class AlarmInfo {
}
}
class
AbnormalState
{
class
AbnormalState
{
final
AlarmInfo
alarmInfo
;
final
bool
isLoading
;
final
String
?
error
;
final
AlarmInfo
?
alarmInfo
;
const
AbnormalState
({
const
AbnormalState
({
required
this
.
alarmInfo
,
this
.
isLoading
=
false
,
this
.
error
,
this
.
alarmInfo
,
});
});
}
}
\ No newline at end of file
lib/views/home/abnormal/widget/alarm_info_block.dart
View file @
42fc065d
...
@@ -57,7 +57,13 @@ class AlarmInfoBlock extends StatelessWidget {
...
@@ -57,7 +57,13 @@ class AlarmInfoBlock extends StatelessWidget {
);
);
}
}
String
_truncateText
(
String
text
,
{
int
maxLength
=
20
})
{
if
(
text
.
length
<=
maxLength
)
return
text
;
return
'
${text.substring(0, maxLength)}
...'
;
}
Widget
_buildInfoRow
(
String
label
,
String
value
,
{
Color
?
valueColor
})
{
Widget
_buildInfoRow
(
String
label
,
String
value
,
{
Color
?
valueColor
})
{
final
displayValue
=
_truncateText
(
value
);
return
Row
(
return
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
...
@@ -69,7 +75,7 @@ class AlarmInfoBlock extends StatelessWidget {
...
@@ -69,7 +75,7 @@ class AlarmInfoBlock extends StatelessWidget {
),
),
),
),
Text
(
Text
(
v
alue
,
displayV
alue
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
24
.
sp
,
fontSize:
24
.
sp
,
color:
valueColor
??
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
color:
valueColor
??
Color
.
fromRGBO
(
100
,
116
,
139
,
1
),
...
...
lib/views/home/index/cubit/home_index_cubit.dart
View file @
42fc065d
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:smart_hotel_app/models/bo/alert_dashboard_bo.dart'
;
import
'package:smart_hotel_app/services/alert_dashboard_service.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_state.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_state.dart'
;
import
'package:flutter/material.dart'
;
class
HomeIndexCubit
extends
Cubit
<
HomeIndexState
>
{
class
HomeIndexCubit
extends
Cubit
<
HomeIndexState
>
{
HomeIndexCubit
()
:
super
(
const
HomeIndexState
())
{
final
AlertDashboardService
_service
;
initData
();
HomeIndexCubit
({
required
AlertDashboardService
service
})
:
_service
=
service
,
super
(
const
HomeIndexState
())
{
loadDashboard
();
}
}
void
initData
()
{
Future
<
void
>
loadDashboard
()
async
{
emit
(
state
.
copyWith
(
isLoading:
true
,
error:
null
));
try
{
final
dashboard
=
await
_service
.
getDashboard
();
_emitFromDashboard
(
dashboard
);
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
isLoading:
false
,
error:
e
.
toString
()));
}
}
void
_emitFromDashboard
(
AlertDashboardBO
dashboard
)
{
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
highAlarmCount:
1
,
isLoading:
false
,
mediumAlarmCount:
1
,
error:
null
,
onlineDeviceCount:
48
,
highAlarmCount:
dashboard
.
statistics
.
highAlertCount
,
temperatureAlarmTitle:
'温度异常告警'
,
mediumAlarmCount:
dashboard
.
statistics
.
mediumAlertCount
,
temperatureAlarmLocation:
'客房301·A-301智能空开'
,
onlineDeviceCount:
dashboard
.
statistics
.
onlineDeviceCount
,
currentTemperature:
'85'
,
temperatureAlarmTitle:
dashboard
.
alerts
.
isNotEmpty
currentVoltage:
'220'
,
?
dashboard
.
alerts
[
0
].
alertTitle
currentCurrent:
'3.2'
,
:
''
,
waitTime:
'2h37m'
,
temperatureAlarmLocation:
dashboard
.
alerts
.
isNotEmpty
alarmLevel:
'紧急'
,
?
'
${dashboard.alerts[0].roomName}
·
${dashboard.alerts[0].deviceName}
'
voltageAlarmTitle:
'电压波动告警'
,
:
''
,
voltageAlarmLocation:
'会议室2F-01'
,
currentTemperature:
dashboard
.
alerts
.
isNotEmpty
voltageValue:
'248'
,
?
dashboard
.
alerts
[
0
].
temperature
normalVoltage:
'235'
,
:
''
,
voltageWaitTime:
'1h19m'
,
currentVoltage:
voltageAlarmLevel:
'中警'
,
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
voltage
:
''
,
equipmentList:
const
[
currentCurrent:
EquipmentItem
(
icon:
Icons
.
power
,
title:
'客房305空开'
,
subtitle:
'38°C·220V·520W'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
dashboard
.
alerts
.
isNotEmpty
?
dashboard
.
alerts
[
0
].
current
:
''
,
EquipmentItem
(
icon:
Icons
.
power
,
title:
'大堂总空开L-01'
,
subtitle:
'380V·42A·28.6kW'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
waitTime:
dashboard
.
alerts
.
isNotEmpty
EquipmentItem
(
icon:
Icons
.
wifi
,
title:
'招牌AP-03'
,
subtitle:
'信号弱·RSSI-78dBm'
,
status:
'注意'
,
statusColor:
Color
.
fromRGBO
(
255
,
193
,
7
,
1.0
)),
?
dashboard
.
alerts
[
0
].
waitingDurationDesc
EquipmentItem
(
icon:
Icons
.
power
,
title:
'客房201空开'
,
subtitle:
'25°C·220V·380W'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
:
''
,
EquipmentItem
(
icon:
Icons
.
power
,
title:
'水泵控制箱'
,
subtitle:
'运行中·2.2kW'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
alarmLevel:
dashboard
.
alerts
.
isNotEmpty
EquipmentItem
(
icon:
Icons
.
thermostat
,
title:
'冷库温控器'
,
subtitle:
'-18°C·异常波动'
,
status:
'告警'
,
statusColor:
Color
.
fromRGBO
(
255
,
77
,
79
,
1.0
)),
?
dashboard
.
alerts
[
0
].
alertLevelText
EquipmentItem
(
icon:
Icons
.
light
,
title:
'走廊照明回路'
,
subtitle:
'12盏·功率240W'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
:
''
,
EquipmentItem
(
icon:
Icons
.
wifi
,
title:
'会议室AP-01'
,
subtitle:
'连接数12·信号强'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
voltageAlarmTitle:
dashboard
.
alerts
.
length
>
1
EquipmentItem
(
icon:
Icons
.
power
,
title:
'电梯控制柜'
,
subtitle:
'运行中·电压稳定'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
?
dashboard
.
alerts
[
1
].
alertTitle
EquipmentItem
(
icon:
Icons
.
thermostat
,
title:
'空调外机'
,
subtitle:
'压力偏高·需检查'
,
status:
'注意'
,
statusColor:
Color
.
fromRGBO
(
255
,
193
,
7
,
1.0
)),
:
''
,
EquipmentItem
(
icon:
Icons
.
wifi
,
title:
'楼道AP-05'
,
subtitle:
'离线·需重启'
,
status:
'离线'
,
statusColor:
Color
.
fromRGBO
(
102
,
102
,
102
,
1.0
)),
voltageAlarmLocation:
dashboard
.
alerts
.
length
>
1
EquipmentItem
(
icon:
Icons
.
power
,
title:
'厨房消毒柜'
,
subtitle:
'消毒中·温度120°C'
,
status:
'正常'
,
statusColor:
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
)),
?
'
${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
,
equipmentList:
dashboard
.
devices
.
map
((
d
)
=>
_mapDeviceToEquipment
(
d
))
.
toList
(),
));
));
}
}
EquipmentItem
_mapDeviceToEquipment
(
DeviceItemBO
d
)
{
return
EquipmentItem
(
icon:
_mapDeviceIcon
(
d
.
deviceTypeIcon
),
title:
d
.
deviceName
,
subtitle:
_buildDeviceSubtitle
(
d
),
status:
d
.
onlineStatus
==
'1'
?
d
.
runStatusText
:
'离线'
,
statusColor:
_mapStatusColor
(
d
.
onlineStatus
,
d
.
runStatus
),
);
}
IconData
_mapDeviceIcon
(
String
icon
)
{
switch
(
icon
)
{
case
'power'
:
return
Icons
.
power
;
case
'wifi'
:
return
Icons
.
wifi
;
case
'thermostat'
:
return
Icons
.
thermostat
;
case
'light'
:
return
Icons
.
light
;
default
:
return
Icons
.
devices_other
;
}
}
String
_buildDeviceSubtitle
(
DeviceItemBO
d
)
{
final
parts
=
<
String
>[];
if
(
d
.
roomName
.
isNotEmpty
)
parts
.
add
(
d
.
roomName
);
if
(
d
.
temperature
.
isNotEmpty
)
parts
.
add
(
'
${d.temperature}
°C'
);
if
(
d
.
voltage
.
isNotEmpty
)
parts
.
add
(
'
${d.voltage}
V'
);
if
(
d
.
power
.
isNotEmpty
)
parts
.
add
(
'
${d.power}
kW'
);
if
(
d
.
current
.
isNotEmpty
)
parts
.
add
(
'
${d.current}
A'
);
return
parts
.
isNotEmpty
?
parts
.
join
(
'·'
)
:
''
;
}
Color
_mapStatusColor
(
String
onlineStatus
,
String
runStatus
)
{
if
(
onlineStatus
==
'0'
)
{
return
const
Color
.
fromRGBO
(
102
,
102
,
102
,
1.0
);
}
switch
(
runStatus
)
{
case
'alert'
:
case
'alarm'
:
return
const
Color
.
fromRGBO
(
255
,
77
,
79
,
1.0
);
case
'warning'
:
case
'注意'
:
return
const
Color
.
fromRGBO
(
255
,
193
,
7
,
1.0
);
default
:
return
const
Color
.
fromRGBO
(
26
,
188
,
156
,
1.0
);
}
}
}
}
\ No newline at end of file
lib/views/home/index/cubit/home_index_state.dart
View file @
42fc065d
...
@@ -18,6 +18,8 @@ class EquipmentItem {
...
@@ -18,6 +18,8 @@ class EquipmentItem {
}
}
class
HomeIndexState
extends
Equatable
{
class
HomeIndexState
extends
Equatable
{
final
bool
isLoading
;
final
String
?
error
;
final
int
highAlarmCount
;
final
int
highAlarmCount
;
final
int
mediumAlarmCount
;
final
int
mediumAlarmCount
;
final
int
onlineDeviceCount
;
final
int
onlineDeviceCount
;
...
@@ -28,6 +30,7 @@ class HomeIndexState extends Equatable {
...
@@ -28,6 +30,7 @@ class HomeIndexState extends Equatable {
final
String
currentCurrent
;
final
String
currentCurrent
;
final
String
waitTime
;
final
String
waitTime
;
final
String
alarmLevel
;
final
String
alarmLevel
;
final
int
voltageAlertId
;
final
String
voltageAlarmTitle
;
final
String
voltageAlarmTitle
;
final
String
voltageAlarmLocation
;
final
String
voltageAlarmLocation
;
final
String
voltageValue
;
final
String
voltageValue
;
...
@@ -37,6 +40,8 @@ class HomeIndexState extends Equatable {
...
@@ -37,6 +40,8 @@ class HomeIndexState extends Equatable {
final
List
<
EquipmentItem
>
equipmentList
;
final
List
<
EquipmentItem
>
equipmentList
;
const
HomeIndexState
({
const
HomeIndexState
({
this
.
isLoading
=
false
,
this
.
error
,
this
.
highAlarmCount
=
0
,
this
.
highAlarmCount
=
0
,
this
.
mediumAlarmCount
=
0
,
this
.
mediumAlarmCount
=
0
,
this
.
onlineDeviceCount
=
0
,
this
.
onlineDeviceCount
=
0
,
...
@@ -53,10 +58,13 @@ class HomeIndexState extends Equatable {
...
@@ -53,10 +58,13 @@ class HomeIndexState extends Equatable {
this
.
normalVoltage
=
''
,
this
.
normalVoltage
=
''
,
this
.
voltageWaitTime
=
''
,
this
.
voltageWaitTime
=
''
,
this
.
voltageAlarmLevel
=
''
,
this
.
voltageAlarmLevel
=
''
,
this
.
voltageAlertId
=
0
,
this
.
equipmentList
=
const
[],
this
.
equipmentList
=
const
[],
});
});
HomeIndexState
copyWith
({
HomeIndexState
copyWith
({
bool
?
isLoading
,
String
?
error
,
int
?
highAlarmCount
,
int
?
highAlarmCount
,
int
?
mediumAlarmCount
,
int
?
mediumAlarmCount
,
int
?
onlineDeviceCount
,
int
?
onlineDeviceCount
,
...
@@ -67,6 +75,7 @@ class HomeIndexState extends Equatable {
...
@@ -67,6 +75,7 @@ class HomeIndexState extends Equatable {
String
?
currentCurrent
,
String
?
currentCurrent
,
String
?
waitTime
,
String
?
waitTime
,
String
?
alarmLevel
,
String
?
alarmLevel
,
int
?
voltageAlertId
,
String
?
voltageAlarmTitle
,
String
?
voltageAlarmTitle
,
String
?
voltageAlarmLocation
,
String
?
voltageAlarmLocation
,
String
?
voltageValue
,
String
?
voltageValue
,
...
@@ -76,6 +85,8 @@ class HomeIndexState extends Equatable {
...
@@ -76,6 +85,8 @@ class HomeIndexState extends Equatable {
List
<
EquipmentItem
>?
equipmentList
,
List
<
EquipmentItem
>?
equipmentList
,
})
{
})
{
return
HomeIndexState
(
return
HomeIndexState
(
isLoading:
isLoading
??
this
.
isLoading
,
error:
error
,
highAlarmCount:
highAlarmCount
??
this
.
highAlarmCount
,
highAlarmCount:
highAlarmCount
??
this
.
highAlarmCount
,
mediumAlarmCount:
mediumAlarmCount
??
this
.
mediumAlarmCount
,
mediumAlarmCount:
mediumAlarmCount
??
this
.
mediumAlarmCount
,
onlineDeviceCount:
onlineDeviceCount
??
this
.
onlineDeviceCount
,
onlineDeviceCount:
onlineDeviceCount
??
this
.
onlineDeviceCount
,
...
@@ -92,12 +103,15 @@ class HomeIndexState extends Equatable {
...
@@ -92,12 +103,15 @@ class HomeIndexState extends Equatable {
normalVoltage:
normalVoltage
??
this
.
normalVoltage
,
normalVoltage:
normalVoltage
??
this
.
normalVoltage
,
voltageWaitTime:
voltageWaitTime
??
this
.
voltageWaitTime
,
voltageWaitTime:
voltageWaitTime
??
this
.
voltageWaitTime
,
voltageAlarmLevel:
voltageAlarmLevel
??
this
.
voltageAlarmLevel
,
voltageAlarmLevel:
voltageAlarmLevel
??
this
.
voltageAlarmLevel
,
voltageAlertId:
voltageAlertId
??
this
.
voltageAlertId
,
equipmentList:
equipmentList
??
this
.
equipmentList
,
equipmentList:
equipmentList
??
this
.
equipmentList
,
);
);
}
}
@override
@override
List
<
Object
?>
get
props
=>
[
List
<
Object
?>
get
props
=>
[
isLoading
,
error
,
highAlarmCount
,
highAlarmCount
,
mediumAlarmCount
,
mediumAlarmCount
,
onlineDeviceCount
,
onlineDeviceCount
,
...
@@ -114,6 +128,7 @@ class HomeIndexState extends Equatable {
...
@@ -114,6 +128,7 @@ class HomeIndexState extends Equatable {
normalVoltage
,
normalVoltage
,
voltageWaitTime
,
voltageWaitTime
,
voltageAlarmLevel
,
voltageAlarmLevel
,
voltageAlertId
,
equipmentList
,
equipmentList
,
];
];
}
}
\ No newline at end of file
lib/views/home/index/index_view.dart
View file @
42fc065d
...
@@ -2,6 +2,8 @@ import 'package:auto_route/auto_route.dart';
...
@@ -2,6 +2,8 @@ import 'package:auto_route/auto_route.dart';
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/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'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_cubit.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_state.dart'
;
import
'package:smart_hotel_app/views/home/index/cubit/home_index_state.dart'
;
import
'package:smart_hotel_app/views/home/index/widget/equipment_list_block.dart'
;
import
'package:smart_hotel_app/views/home/index/widget/equipment_list_block.dart'
;
...
@@ -17,7 +19,11 @@ class HomeView extends StatelessWidget {
...
@@ -17,7 +19,11 @@ class HomeView extends StatelessWidget {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
BlocProvider
(
return
BlocProvider
(
create:
(
_
)
=>
HomeIndexCubit
(),
create:
(
_
)
{
final
repository
=
AlertDashboardRepository
();
final
service
=
AlertDashboardService
(
repository:
repository
);
return
HomeIndexCubit
(
service:
service
);
},
child:
LayoutBuilder
(
child:
LayoutBuilder
(
builder:
(
context
,
constraints
)
{
builder:
(
context
,
constraints
)
{
return
SingleChildScrollView
(
return
SingleChildScrollView
(
...
@@ -52,6 +58,7 @@ class HomeView extends StatelessWidget {
...
@@ -52,6 +58,7 @@ class HomeView extends StatelessWidget {
),
),
SizedBox
(
height:
20
.
h
),
SizedBox
(
height:
20
.
h
),
VoltageOperateBlock
(
VoltageOperateBlock
(
alertId:
state
.
voltageAlertId
,
voltageAlarmTitle:
state
.
voltageAlarmTitle
,
voltageAlarmTitle:
state
.
voltageAlarmTitle
,
voltageAlarmLocation:
state
.
voltageAlarmLocation
,
voltageAlarmLocation:
state
.
voltageAlarmLocation
,
voltageValue:
state
.
voltageValue
,
voltageValue:
state
.
voltageValue
,
...
...
lib/views/home/index/widget/temperature_block.dart
View file @
42fc065d
...
@@ -200,7 +200,7 @@ class TemperatureBlock extends StatelessWidget {
...
@@ -200,7 +200,7 @@ class TemperatureBlock extends StatelessWidget {
),
),
GestureDetector
(
GestureDetector
(
onTap:
()
{
onTap:
()
{
context
.
pushRoute
(
const
AbnormalDetailRoute
());
//
context.pushRoute(const AbnormalDetailRoute());
},
},
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
32
.
w
,
vertical:
20
.
h
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
32
.
w
,
vertical:
20
.
h
),
...
...
lib/views/home/index/widget/voltage_operate_block.dart
View file @
42fc065d
...
@@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
...
@@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
import
'package:smart_hotel_app/routes/app_router.gr.dart'
;
class
VoltageOperateBlock
extends
StatelessWidget
{
class
VoltageOperateBlock
extends
StatelessWidget
{
final
int
alertId
;
final
String
voltageAlarmTitle
;
final
String
voltageAlarmTitle
;
final
String
voltageAlarmLocation
;
final
String
voltageAlarmLocation
;
final
String
voltageValue
;
final
String
voltageValue
;
...
@@ -13,6 +14,7 @@ class VoltageOperateBlock extends StatelessWidget {
...
@@ -13,6 +14,7 @@ class VoltageOperateBlock extends StatelessWidget {
const
VoltageOperateBlock
({
const
VoltageOperateBlock
({
super
.
key
,
super
.
key
,
required
this
.
alertId
,
required
this
.
voltageAlarmTitle
,
required
this
.
voltageAlarmTitle
,
required
this
.
voltageAlarmLocation
,
required
this
.
voltageAlarmLocation
,
required
this
.
voltageValue
,
required
this
.
voltageValue
,
...
@@ -132,7 +134,7 @@ class VoltageOperateBlock extends StatelessWidget {
...
@@ -132,7 +134,7 @@ class VoltageOperateBlock extends StatelessWidget {
Expanded
(
Expanded
(
child:
GestureDetector
(
child:
GestureDetector
(
onTap:
()
{
onTap:
()
{
context
.
pushRoute
(
const
AbnormalDetailRoute
(
));
context
.
pushRoute
(
AbnormalDetailRoute
(
alertId:
alertId
));
},
},
child:
Container
(
child:
Container
(
height:
88
.
h
,
height:
88
.
h
,
...
...
对接方案.md
View file @
42fc065d
# 智慧酒
店 App 接口对接方案
# 智慧酒
店 App 接口对接方案
...
@@ -178,9 +178,16 @@ class xxxBO extends Equatable {
...
@@ -178,9 +178,16 @@ class xxxBO extends Equatable {
### 3.1 接口总览
### 3.1 接口总览
|
页面序号
|
方法
|
路径
|
状态
|
所属模块
|
|
页面序号
|
方法
|
路径
|
状态
|
所属模块
|
要求描述
|
|
------|------|------|------|---------|
|
------|------|------|------|---------|
|
登录页 |POST | /app/auth/login/sms | 已对接 | 用户模块 |
|
登录页 |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 | 未对接 | 设备控制-远程断电 | 需要做下防重复提交,处理过程中不可点。处理完成之后弹出操作成功/操作失败提示|
#
## 3.2 接口详细定义
#
## 3.2 接口详细定义
...
@@ -215,9 +222,218 @@ class xxxBO extends Equatable {
...
@@ -215,9 +222,218 @@ class xxxBO extends Equatable {
}
}
`
``
`
``
#
### 设备告警看板
-
--
*
*GET /app/alert/dashboard**
`
``
请
求体:
{
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"total": 0,
"statistics": {
"highAlertCount": 0, // 高警待处理数量
"mediumAlertCount": 0, // 中警待处理数量
"onlineDeviceCount": 0 // 在线设备数量
},
"alerts": [ //告警信息列表
{
"alertId": 0, // 告警ID
"alertNo": "string",
"alertTitle": "string", // 告警标题
"alertLevel": "string", // 告警级别编码
"alertLevelText": "string", // 告警级别中文描述
"alertStatus": "string",// 告警状态编码(0=待处理,1=处理中,2=已处理,3=忽略,4=误报)
"roomName": "string", // 所属房间名称
"deviceName": "string",// 告警设备名称
"alertValue": "string",
"thresholdValue": "string",
"alertContent": "string",
"voltage": "string", // 告警时电压(V)
"current": "string", // 告警时电流(A)
"temperature": "string", // 告警时温度(℃)
"waitingDuration": 0, // 告警持续时长(分钟)
"waitingDurationDesc": "string", // 告警持续时长的中文描述
"alertTime": "string"
}
],
"devices": [ // 设备巡检列表
{
"deviceId": 0, // 设备ID
"deviceName": "string", // 设备名称
"deviceTypeIcon": "string",
"deviceTypeName": "string",
"runStatus": "string",
"runStatusText": "string", // 运行状态中文描述
"roomName": "string", // 所属房间名称
"temperature": "string", // 告警时温度(℃)
"voltage": "string", // 设备当前电压(V)
"power": "string", // 设备当前功率(kW)
"current": "string", // 设备当前电流(A)
"onlineStatus": "string", // 在线状态(0=离线,1=在线)
"lastHeartbeat": "string",
"deviceTypeIcon": "string", // 设备类型图标标识
}
]
}
}
`
``
#
### 告警详情
*
*GET /app/alert/detail**
`
``
请
求体:
{
"alertId": 0 // 告警ID
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"alertBasicInfo": { // 告警基本信息
"alertId": 0,
"alertTitle": "string", // 告警标题(如"温度异常告警")
"alertLevel": "string",
"alertLevelText": "string",
"alertStatus": "string",
"alertDeviceLocation": "string",
"alertCount": 0,
"alertTime": "string",
"alertIcon": "string"
},
"trendChart": { // 趋势图
"chartTitle": "string",
"chartDate": "string",
"unit": "string",
"dataPoints": [
{
"time": "string",
"value": 0,
"recordId": 0
}
],
"yaxisMax": 0,
"yaxisMin": 0
},
"alertDetailInfo": { //
"thresholdSetting": "string", // 预设阈值描述(如"温度>80°C触发")
"duration": "string", // 持续时长文本(如"2小时37分钟")
"durationMinutes": 0, // 持续时长(分钟)
"peakRecord": "string", // 峰值记录(如"88.2℃(15:02)")
"linkageAction": "string", // 联动动作描述(如"自动断电保护")
"alertValue": "string", // 告警触发值
"alertContent": "string" // 告警内容详情
}
}
}
`
``
#
### 告警详情-确认处理
*
*POST /app/alert/handle**
`
``
请
求体:
{
"alertId": 0 // 告警ID
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"success": true
}
}
`
``
#
### 设备控制
*
*GET /app/device/control/detail**
`
``
请
求体:
{
"deviceId": 0 // 设备ID
}
响
应 data:
{
"code": 0,
"msg": "string",
"data": {
"deviceBasicInfo": { // 设备基本信息
"deviceId": 0,
"deviceName": "string",
"deviceCode": "string",
"roomName": "string",
"deviceTypeIcon": "string",
"onlineStatus": "string"
},
"realtimeParams": { // 实时电气参数
"voltage": "string",
"current": "string",
"activePower": "string",
"deviceTemperature": "string"
},
"trendChart": { // 趋势图表数据
"chartTitle": "string",
"unit": "string",
"dataPoints": [
{
"time": "string",
"power": 0,
"temperature": 0
}
],
"yaxisMax": 0,
"yaxisMin": 0
}
}
}
`
``
-
--
## 6. 注意事项
## 6. 注意事项
...
...
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