Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
laki_icu_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
张宏
laki_icu_app
Commits
dd39c5b7
Commit
dd39c5b7
authored
Jun 23, 2026
by
张宏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重构设备控制页面。
parent
6106b9fe
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1180 additions
and
936 deletions
+1180
-936
box_no_device.png
lib/assets/monitoring/box_no_device.png
+0
-0
app_router.dart
lib/routes/app_router.dart
+8
-1
app_router.gr.dart
lib/routes/app_router.gr.dart
+86
-64
default_layout_cubit.dart
lib/views/layout/cubit/default_layout_cubit.dart
+2
-0
default_view.dart
lib/views/layout/default_view.dart
+1
-0
controller_index_cubit.dart
...s/monitoring/controller/cubit/controller_index_cubit.dart
+0
-13
controller_index_state.dart
...s/monitoring/controller/cubit/controller_index_state.dart
+0
-20
monitoring_controller_view.dart
...ews/monitoring/controller/monitoring_controller_view.dart
+0
-58
monitoring_environment_detail_view.dart
...ontroller/widgets/monitoring_environment_detail_view.dart
+0
-756
device_control_index_cubit.dart
...ring/device_control/cubit/device_control_index_cubit.dart
+68
-0
device_control_index_state.dart
...ring/device_control/cubit/device_control_index_state.dart
+45
-0
device_control_index_view.dart
.../monitoring/device_control/device_control_index_view.dart
+195
-0
device_control_care_panel.dart
...ing/device_control/widgets/device_control_care_panel.dart
+51
-0
device_control_common.dart
...itoring/device_control/widgets/device_control_common.dart
+266
-0
device_control_info_panel.dart
...ing/device_control/widgets/device_control_info_panel.dart
+68
-0
device_control_metric_card.dart
...ng/device_control/widgets/device_control_metric_card.dart
+122
-0
device_control_mode_panel.dart
...ing/device_control/widgets/device_control_mode_panel.dart
+94
-0
device_control_oxygen_timer_panel.dart
...ce_control/widgets/device_control_oxygen_timer_panel.dart
+50
-0
device_control_time_panel.dart
...ing/device_control/widgets/device_control_time_panel.dart
+37
-0
device_control_wind_panel.dart
...ing/device_control/widgets/device_control_wind_panel.dart
+78
-0
monitoring_index_view.dart
lib/views/monitoring/index/monitoring_index_view.dart
+9
-24
No files found.
lib/assets/monitoring/box_no_device.png
0 → 100644
View file @
dd39c5b7
1.15 MB
lib/routes/app_router.dart
View file @
dd39c5b7
...
@@ -4,6 +4,7 @@ import 'package:auto_route/auto_route.dart';
...
@@ -4,6 +4,7 @@ import 'package:auto_route/auto_route.dart';
import
'package:laki_icu_app/views/login/login_view.dart'
;
import
'package:laki_icu_app/views/login/login_view.dart'
;
import
'package:laki_icu_app/views/layout/default_view.dart'
;
import
'package:laki_icu_app/views/layout/default_view.dart'
;
import
'package:laki_icu_app/views/monitoring/index/monitoring_index_view.dart'
;
import
'package:laki_icu_app/views/monitoring/index/monitoring_index_view.dart'
;
import
'package:laki_icu_app/views/monitoring/device_control/device_control_index_view.dart'
;
import
'package:laki_icu_app/views/blood_pressure/blood_pressure_index_view.dart'
;
import
'package:laki_icu_app/views/blood_pressure/blood_pressure_index_view.dart'
;
import
'package:laki_icu_app/views/vital_signs/vital_signs_index_view.dart'
;
import
'package:laki_icu_app/views/vital_signs/vital_signs_index_view.dart'
;
import
'package:laki_icu_app/views/ecg_system/ecg_system_index_view.dart'
;
import
'package:laki_icu_app/views/ecg_system/ecg_system_index_view.dart'
;
...
@@ -28,7 +29,10 @@ class AppRouter extends $AppRouter {
...
@@ -28,7 +29,10 @@ class AppRouter extends $AppRouter {
initial:
true
,
initial:
true
,
children:
[
children:
[
// MonitoringIndexRoute / MonitoringIndexView(ICU中控 - Tab 0)
// MonitoringIndexRoute / MonitoringIndexView(ICU中控 - Tab 0)
AutoRoute
(
page:
MonitoringIndexRoute
.
page
,
initial:
true
),
AutoRoute
(
page:
MonitoringIndexRoute
.
page
,
initial:
true
,
),
// BloodPressureIndexRoute / BloodPressureIndexView(血压监测 - Tab 1)
// BloodPressureIndexRoute / BloodPressureIndexView(血压监测 - Tab 1)
AutoRoute
(
page:
BloodPressureIndexRoute
.
page
),
AutoRoute
(
page:
BloodPressureIndexRoute
.
page
),
// VitalSignsIndexRoute / VitalSignsIndexView(体征仪 - Tab 2)
// VitalSignsIndexRoute / VitalSignsIndexView(体征仪 - Tab 2)
...
@@ -41,7 +45,10 @@ class AppRouter extends $AppRouter {
...
@@ -41,7 +45,10 @@ class AppRouter extends $AppRouter {
AutoRoute
(
page:
RecordIndexRoute
.
page
),
AutoRoute
(
page:
RecordIndexRoute
.
page
),
// SettingsIndexRoute / SettingsIndexView(设置 - Tab 6)
// SettingsIndexRoute / SettingsIndexView(设置 - Tab 6)
AutoRoute
(
page:
SettingsIndexRoute
.
page
),
AutoRoute
(
page:
SettingsIndexRoute
.
page
),
AutoRoute
(
page:
DeviceControlIndexRoute
.
page
),
],
],
),
),
];
];
}
}
lib/routes/app_router.gr.dart
View file @
dd39c5b7
...
@@ -8,81 +8,89 @@
...
@@ -8,81 +8,89 @@
// coverage:ignore-file
// coverage:ignore-file
// ignore_for_file: no_leading_underscores_for_library_prefixes
// ignore_for_file: no_leading_underscores_for_library_prefixes
import
'package:auto_route/auto_route.dart'
as
_i1
0
;
import
'package:auto_route/auto_route.dart'
as
_i1
1
;
import
'package:flutter/material.dart'
as
_i1
1
;
import
'package:flutter/material.dart'
as
_i1
2
;
import
'package:laki_icu_app/views/blood_pressure/blood_pressure_index_view.dart'
import
'package:laki_icu_app/views/blood_pressure/blood_pressure_index_view.dart'
as
_i1
;
as
_i1
;
import
'package:laki_icu_app/views/ecg_system/ecg_system_index_view.dart'
import
'package:laki_icu_app/views/ecg_system/ecg_system_index_view.dart'
as
_i
3
;
as
_i
4
;
import
'package:laki_icu_app/views/layout/default_view.dart'
as
_i2
;
import
'package:laki_icu_app/views/layout/default_view.dart'
as
_i2
;
import
'package:laki_icu_app/views/login/login_view.dart'
as
_i4
;
import
'package:laki_icu_app/views/login/login_view.dart'
as
_i5
;
import
'package:laki_icu_app/views/monitoring/device_control/device_control_index_view.dart'
as
_i3
;
import
'package:laki_icu_app/views/monitoring/index/monitoring_index_view.dart'
import
'package:laki_icu_app/views/monitoring/index/monitoring_index_view.dart'
as
_i
5
;
as
_i
6
;
import
'package:laki_icu_app/views/record/record_index_view.dart'
as
_i
6
;
import
'package:laki_icu_app/views/record/record_index_view.dart'
as
_i
7
;
import
'package:laki_icu_app/views/settings/settings_index_view.dart'
as
_i
7
;
import
'package:laki_icu_app/views/settings/settings_index_view.dart'
as
_i
8
;
import
'package:laki_icu_app/views/tsaas/tsaas_index_view.dart'
as
_i
8
;
import
'package:laki_icu_app/views/tsaas/tsaas_index_view.dart'
as
_i
9
;
import
'package:laki_icu_app/views/vital_signs/vital_signs_index_view.dart'
import
'package:laki_icu_app/views/vital_signs/vital_signs_index_view.dart'
as
_i
9
;
as
_i
10
;
abstract
class
$
AppRouter
extends
_i1
0
.
RootStackRouter
{
abstract
class
$
AppRouter
extends
_i1
1
.
RootStackRouter
{
$AppRouter
({
super
.
navigatorKey
});
$AppRouter
({
super
.
navigatorKey
});
@override
@override
final
Map
<
String
,
_i1
0
.
PageFactory
>
pagesMap
=
{
final
Map
<
String
,
_i1
1
.
PageFactory
>
pagesMap
=
{
BloodPressureIndexRoute
.
name
:
(
routeData
)
{
BloodPressureIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i1
.
BloodPressureIndexView
(),
child:
const
_i1
.
BloodPressureIndexView
(),
);
);
},
},
DefaultLayoutRoute
.
name
:
(
routeData
)
{
DefaultLayoutRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i2
.
DefaultLayoutView
(),
child:
const
_i2
.
DefaultLayoutView
(),
);
);
},
},
DeviceControlIndexRoute
.
name
:
(
routeData
)
{
return
_i11
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
child:
const
_i3
.
DeviceControlIndexView
(),
);
},
EcgSystemIndexRoute
.
name
:
(
routeData
)
{
EcgSystemIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i
3
.
EcgSystemIndexView
(),
child:
const
_i
4
.
EcgSystemIndexView
(),
);
);
},
},
LoginRoute
.
name
:
(
routeData
)
{
LoginRoute
.
name
:
(
routeData
)
{
final
args
=
routeData
.
argsAs
<
LoginRouteArgs
>(
final
args
=
routeData
.
argsAs
<
LoginRouteArgs
>(
orElse:
()
=>
const
LoginRouteArgs
());
orElse:
()
=>
const
LoginRouteArgs
());
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
_i
4
.
LoginView
(
key:
args
.
key
),
child:
_i
5
.
LoginView
(
key:
args
.
key
),
);
);
},
},
MonitoringIndexRoute
.
name
:
(
routeData
)
{
MonitoringIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i
5
.
MonitoringIndexView
(),
child:
const
_i
6
.
MonitoringIndexView
(),
);
);
},
},
RecordIndexRoute
.
name
:
(
routeData
)
{
RecordIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i
6
.
RecordIndexView
(),
child:
const
_i
7
.
RecordIndexView
(),
);
);
},
},
SettingsIndexRoute
.
name
:
(
routeData
)
{
SettingsIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i
7
.
SettingsIndexView
(),
child:
const
_i
8
.
SettingsIndexView
(),
);
);
},
},
TsaasIndexRoute
.
name
:
(
routeData
)
{
TsaasIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i
8
.
TsaasIndexView
(),
child:
const
_i
9
.
TsaasIndexView
(),
);
);
},
},
VitalSignsIndexRoute
.
name
:
(
routeData
)
{
VitalSignsIndexRoute
.
name
:
(
routeData
)
{
return
_i1
0
.
AutoRoutePage
<
dynamic
>(
return
_i1
1
.
AutoRoutePage
<
dynamic
>(
routeData:
routeData
,
routeData:
routeData
,
child:
const
_i
9
.
VitalSignsIndexView
(),
child:
const
_i
10
.
VitalSignsIndexView
(),
);
);
},
},
};
};
...
@@ -90,8 +98,8 @@ abstract class $AppRouter extends _i10.RootStackRouter {
...
@@ -90,8 +98,8 @@ abstract class $AppRouter extends _i10.RootStackRouter {
/// generated route for
/// generated route for
/// [_i1.BloodPressureIndexView]
/// [_i1.BloodPressureIndexView]
class
BloodPressureIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
BloodPressureIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
BloodPressureIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
BloodPressureIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
BloodPressureIndexRoute
.
name
,
BloodPressureIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -99,13 +107,13 @@ class BloodPressureIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -99,13 +107,13 @@ class BloodPressureIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'BloodPressureIndexRoute'
;
static
const
String
name
=
'BloodPressureIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i2.DefaultLayoutView]
/// [_i2.DefaultLayoutView]
class
DefaultLayoutRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
DefaultLayoutRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
DefaultLayoutRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
DefaultLayoutRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
DefaultLayoutRoute
.
name
,
DefaultLayoutRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -113,13 +121,27 @@ class DefaultLayoutRoute extends _i10.PageRouteInfo<void> {
...
@@ -113,13 +121,27 @@ class DefaultLayoutRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'DefaultLayoutRoute'
;
static
const
String
name
=
'DefaultLayoutRoute'
;
static
const
_i10
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i11
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
/// generated route for
/// [_i3.DeviceControlIndexView]
class
DeviceControlIndexRoute
extends
_i11
.
PageRouteInfo
<
void
>
{
const
DeviceControlIndexRoute
({
List
<
_i11
.
PageRouteInfo
>?
children
})
:
super
(
DeviceControlIndexRoute
.
name
,
initialChildren:
children
,
);
static
const
String
name
=
'DeviceControlIndexRoute'
;
static
const
_i11
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i
3
.EcgSystemIndexView]
/// [_i
4
.EcgSystemIndexView]
class
EcgSystemIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
EcgSystemIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
EcgSystemIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
EcgSystemIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
EcgSystemIndexRoute
.
name
,
EcgSystemIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -127,15 +149,15 @@ class EcgSystemIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -127,15 +149,15 @@ class EcgSystemIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'EcgSystemIndexRoute'
;
static
const
String
name
=
'EcgSystemIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i
4
.LoginView]
/// [_i
5
.LoginView]
class
LoginRoute
extends
_i1
0
.
PageRouteInfo
<
LoginRouteArgs
>
{
class
LoginRoute
extends
_i1
1
.
PageRouteInfo
<
LoginRouteArgs
>
{
LoginRoute
({
LoginRoute
({
_i1
1
.
Key
?
key
,
_i1
2
.
Key
?
key
,
List
<
_i1
0
.
PageRouteInfo
>?
children
,
List
<
_i1
1
.
PageRouteInfo
>?
children
,
})
:
super
(
})
:
super
(
LoginRoute
.
name
,
LoginRoute
.
name
,
args:
LoginRouteArgs
(
key:
key
),
args:
LoginRouteArgs
(
key:
key
),
...
@@ -144,14 +166,14 @@ class LoginRoute extends _i10.PageRouteInfo<LoginRouteArgs> {
...
@@ -144,14 +166,14 @@ class LoginRoute extends _i10.PageRouteInfo<LoginRouteArgs> {
static
const
String
name
=
'LoginRoute'
;
static
const
String
name
=
'LoginRoute'
;
static
const
_i1
0
.
PageInfo
<
LoginRouteArgs
>
page
=
static
const
_i1
1
.
PageInfo
<
LoginRouteArgs
>
page
=
_i1
0
.
PageInfo
<
LoginRouteArgs
>(
name
);
_i1
1
.
PageInfo
<
LoginRouteArgs
>(
name
);
}
}
class
LoginRouteArgs
{
class
LoginRouteArgs
{
const
LoginRouteArgs
({
this
.
key
});
const
LoginRouteArgs
({
this
.
key
});
final
_i1
1
.
Key
?
key
;
final
_i1
2
.
Key
?
key
;
@override
@override
String
toString
()
{
String
toString
()
{
...
@@ -160,9 +182,9 @@ class LoginRouteArgs {
...
@@ -160,9 +182,9 @@ class LoginRouteArgs {
}
}
/// generated route for
/// generated route for
/// [_i
5
.MonitoringIndexView]
/// [_i
6
.MonitoringIndexView]
class
MonitoringIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
MonitoringIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
MonitoringIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
MonitoringIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
MonitoringIndexRoute
.
name
,
MonitoringIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -170,13 +192,13 @@ class MonitoringIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -170,13 +192,13 @@ class MonitoringIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'MonitoringIndexRoute'
;
static
const
String
name
=
'MonitoringIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i
6
.RecordIndexView]
/// [_i
7
.RecordIndexView]
class
RecordIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
RecordIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
RecordIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
RecordIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
RecordIndexRoute
.
name
,
RecordIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -184,13 +206,13 @@ class RecordIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -184,13 +206,13 @@ class RecordIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'RecordIndexRoute'
;
static
const
String
name
=
'RecordIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i
7
.SettingsIndexView]
/// [_i
8
.SettingsIndexView]
class
SettingsIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
SettingsIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
SettingsIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
SettingsIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
SettingsIndexRoute
.
name
,
SettingsIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -198,13 +220,13 @@ class SettingsIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -198,13 +220,13 @@ class SettingsIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'SettingsIndexRoute'
;
static
const
String
name
=
'SettingsIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i
8
.TsaasIndexView]
/// [_i
9
.TsaasIndexView]
class
TsaasIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
TsaasIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
TsaasIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
TsaasIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
TsaasIndexRoute
.
name
,
TsaasIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -212,13 +234,13 @@ class TsaasIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -212,13 +234,13 @@ class TsaasIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'TsaasIndexRoute'
;
static
const
String
name
=
'TsaasIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
/// generated route for
/// generated route for
/// [_i
9
.VitalSignsIndexView]
/// [_i
10
.VitalSignsIndexView]
class
VitalSignsIndexRoute
extends
_i1
0
.
PageRouteInfo
<
void
>
{
class
VitalSignsIndexRoute
extends
_i1
1
.
PageRouteInfo
<
void
>
{
const
VitalSignsIndexRoute
({
List
<
_i1
0
.
PageRouteInfo
>?
children
})
const
VitalSignsIndexRoute
({
List
<
_i1
1
.
PageRouteInfo
>?
children
})
:
super
(
:
super
(
VitalSignsIndexRoute
.
name
,
VitalSignsIndexRoute
.
name
,
initialChildren:
children
,
initialChildren:
children
,
...
@@ -226,5 +248,5 @@ class VitalSignsIndexRoute extends _i10.PageRouteInfo<void> {
...
@@ -226,5 +248,5 @@ class VitalSignsIndexRoute extends _i10.PageRouteInfo<void> {
static
const
String
name
=
'VitalSignsIndexRoute'
;
static
const
String
name
=
'VitalSignsIndexRoute'
;
static
const
_i1
0
.
PageInfo
<
void
>
page
=
_i10
.
PageInfo
<
void
>(
name
);
static
const
_i1
1
.
PageInfo
<
void
>
page
=
_i11
.
PageInfo
<
void
>(
name
);
}
}
lib/views/layout/cubit/default_layout_cubit.dart
View file @
dd39c5b7
...
@@ -17,6 +17,7 @@ const _menuIdToIndex = <String, int>{
...
@@ -17,6 +17,7 @@ const _menuIdToIndex = <String, int>{
'tsaas'
:
4
,
'tsaas'
:
4
,
'record'
:
5
,
'record'
:
5
,
'settings'
:
6
,
'settings'
:
6
,
'device_control'
:
7
};
};
const
_indexToMenuId
=
<
int
,
String
>{
const
_indexToMenuId
=
<
int
,
String
>{
...
@@ -27,6 +28,7 @@ const _indexToMenuId = <int, String>{
...
@@ -27,6 +28,7 @@ const _indexToMenuId = <int, String>{
4
:
'tsaas'
,
4
:
'tsaas'
,
5
:
'record'
,
5
:
'record'
,
6
:
'settings'
,
6
:
'settings'
,
7
:
'device_control'
,
};
};
/// 将 Tab 索引转换为菜单 ID
/// 将 Tab 索引转换为菜单 ID
...
...
lib/views/layout/default_view.dart
View file @
dd39c5b7
...
@@ -74,6 +74,7 @@ class _DefaultLayoutContent extends StatelessWidget {
...
@@ -74,6 +74,7 @@ class _DefaultLayoutContent extends StatelessWidget {
TsaasIndexRoute
(),
TsaasIndexRoute
(),
RecordIndexRoute
(),
RecordIndexRoute
(),
SettingsIndexRoute
(),
SettingsIndexRoute
(),
DeviceControlIndexRoute
(),
// index=7,该路由实际不在菜单栏。
],
],
appBarBuilder:
(
context
,
tabsRouter
)
{
appBarBuilder:
(
context
,
tabsRouter
)
{
return
PreferredSize
(
return
PreferredSize
(
...
...
lib/views/monitoring/controller/cubit/controller_index_cubit.dart
deleted
100644 → 0
View file @
6106b9fe
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'controller_index_state.dart'
;
class
ControllerIndexCubit
extends
Cubit
<
ControllerIndexState
>
{
ControllerIndexCubit
({
required
String
selectedMetricLabel
,
})
:
super
(
ControllerIndexState
(
selectedMetricLabel:
selectedMetricLabel
));
void
selectMetric
(
String
label
)
{
emit
(
state
.
copyWith
(
selectedMetricLabel:
label
));
}
}
lib/views/monitoring/controller/cubit/controller_index_state.dart
deleted
100644 → 0
View file @
6106b9fe
import
'package:equatable/equatable.dart'
;
class
ControllerIndexState
extends
Equatable
{
final
String
selectedMetricLabel
;
const
ControllerIndexState
({
required
this
.
selectedMetricLabel
,
});
ControllerIndexState
copyWith
({
String
?
selectedMetricLabel
,
})
{
return
ControllerIndexState
(
selectedMetricLabel:
selectedMetricLabel
??
this
.
selectedMetricLabel
,
);
}
@override
List
<
Object
?>
get
props
=>
[
selectedMetricLabel
];
}
lib/views/monitoring/controller/monitoring_controller_view.dart
deleted
100644 → 0
View file @
6106b9fe
import
'package:flutter/material.dart'
;
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
import
'cubit/controller_index_cubit.dart'
;
import
'cubit/controller_index_state.dart'
;
import
'widgets/monitoring_environment_detail_view.dart'
;
class
MonitoringControllerView
extends
StatelessWidget
{
const
MonitoringControllerView
({
super
.
key
,
required
this
.
metrics
,
required
this
.
selectedMetricLabel
,
required
this
.
onBack
,
});
final
List
<
MonitoringMetricBO
>
metrics
;
final
String
selectedMetricLabel
;
final
VoidCallback
onBack
;
@override
Widget
build
(
BuildContext
context
)
{
return
BlocProvider
(
create:
(
_
)
=>
ControllerIndexCubit
(
selectedMetricLabel:
selectedMetricLabel
,
),
child:
ControllerIndexContent
(
metrics:
metrics
,
onBack:
onBack
,
),
);
}
}
class
ControllerIndexContent
extends
StatelessWidget
{
const
ControllerIndexContent
({
super
.
key
,
required
this
.
metrics
,
required
this
.
onBack
,
});
final
List
<
MonitoringMetricBO
>
metrics
;
final
VoidCallback
onBack
;
@override
Widget
build
(
BuildContext
context
)
{
return
BlocBuilder
<
ControllerIndexCubit
,
ControllerIndexState
>(
builder:
(
context
,
state
)
{
return
MonitoringEnvironmentDetailView
(
metrics:
metrics
,
selectedLabel:
state
.
selectedMetricLabel
,
onBack:
onBack
,
onMetricSelected:
context
.
read
<
ControllerIndexCubit
>().
selectMetric
,
);
},
);
}
}
lib/views/monitoring/controller/widgets/monitoring_environment_detail_view.dart
deleted
100644 → 0
View file @
6106b9fe
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
const
_assetMetricBlue
=
'lib/assets/monitoring/box_bg_325x372.png'
;
const
_assetMetricGreen
=
'lib/assets/monitoring/frame_card_green_325x372.png'
;
const
_assetPanelWide
=
'lib/assets/monitoring/frame_button_324x164.png'
;
const
_assetPanelLarge
=
'lib/assets/monitoring/frame_panel_674x509.png'
;
const
_assetPanelTall
=
'lib/assets/monitoring/box_bg_460x905.png'
;
const
_assetButton
=
'lib/assets/monitoring/frame_button_324x164.png'
;
const
_assetArrowButton
=
'lib/assets/monitoring/frame_button_arrows_561x637.png'
;
class
MonitoringEnvironmentDetailView
extends
StatelessWidget
{
const
MonitoringEnvironmentDetailView
({
super
.
key
,
required
this
.
metrics
,
required
this
.
selectedLabel
,
required
this
.
onBack
,
required
this
.
onMetricSelected
,
});
final
List
<
MonitoringMetricBO
>
metrics
;
final
String
selectedLabel
;
final
VoidCallback
onBack
;
final
ValueChanged
<
String
>
onMetricSelected
;
@override
Widget
build
(
BuildContext
context
)
{
return
Row
(
children:
[
Expanded
(
flex:
74
,
child:
Column
(
children:
[
Expanded
(
flex:
42
,
child:
Row
(
children:
[
for
(
int
index
=
0
;
index
<
metrics
.
length
;
index
++)
...[
Expanded
(
child:
_MetricControlCard
(
metric:
metrics
[
index
])),
if
(
index
<
metrics
.
length
-
1
)
SizedBox
(
width:
24
.
w
),
],
],
),
),
SizedBox
(
height:
24
.
h
),
Expanded
(
flex:
58
,
child:
Row
(
children:
[
Expanded
(
flex:
48
,
child:
_buildModePanel
()),
SizedBox
(
width:
24
.
w
),
Expanded
(
flex:
23
,
child:
_buildWindPanel
()),
SizedBox
(
width:
24
.
w
),
Expanded
(
flex:
29
,
child:
_buildTimePanel
()),
],
),
),
],
),
),
SizedBox
(
width:
24
.
w
),
Expanded
(
flex:
26
,
child:
Column
(
children:
[
Expanded
(
flex:
21
,
child:
_buildCarePanel
()),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
flex:
20
,
child:
_InfoPanel
(
title:
'新风进化'
,
actionText:
'Auto'
,
icon:
Icons
.
cyclone
,
body:
'CO₂超过设定值时自动启动外循环
\n
净化,当降至2000ppm后,本
\n
功能自动关闭'
,
),
),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
flex:
20
,
child:
_InfoPanel
(
title:
'开放供氧'
,
actionText:
'Off'
,
icon:
Icons
.
air
,
body:
'开启后风扇打开、制冷、加热和
\n
循环等设备暂停。'
,
warning:
'*保持设备周围空气相对禁止,严禁烟火'
,
),
),
SizedBox
(
height:
24
.
h
),
Expanded
(
flex:
26
,
child:
_buildOxygenTimerPanel
()),
],
),
),
],
);
}
Widget
_buildModePanel
()
{
const
items
=
[
_ModeItem
(
label:
'外循环'
,
icon:
Icons
.
sync
,
active:
true
),
_ModeItem
(
label:
'检查灯'
,
icon:
Icons
.
light
),
_ModeItem
(
label:
'照明灯'
,
icon:
Icons
.
lightbulb
),
_ModeItem
(
label:
'内循环'
,
icon:
Icons
.
autorenew
),
_ModeItem
(
label:
'蓝光'
,
icon:
Icons
.
wb_sunny_outlined
),
_ModeItem
(
label:
'红光'
,
icon:
Icons
.
wb_sunny
),
];
return
_PanelFrame
(
backgroundAsset:
_assetPanelLarge
,
padding:
EdgeInsets
.
all
(
28
.
w
),
child:
GridView
.
count
(
crossAxisCount:
3
,
crossAxisSpacing:
24
.
w
,
mainAxisSpacing:
24
.
h
,
physics:
const
NeverScrollableScrollPhysics
(),
childAspectRatio:
1.1
,
children:
[
for
(
final
item
in
items
)
_ModeButton
(
label:
item
.
label
,
icon:
item
.
icon
,
active:
item
.
active
,
),
],
),
);
}
Widget
_buildWindPanel
()
{
return
_PanelFrame
(
backgroundAsset:
_assetPanelTall
,
padding:
EdgeInsets
.
fromLTRB
(
34
.
w
,
28
.
h
,
34
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
_PanelTitle
(
'风速调节'
),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
child:
_WideModeButton
(
label:
'睡眠模式'
,
icon:
Icons
.
nightlight_round
),
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
_WideModeButton
(
label:
'舒适模式'
,
icon:
Icons
.
favorite_border
),
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
_WideModeButton
(
label:
'强劲模式'
,
icon:
Icons
.
air
)),
],
),
);
}
Widget
_buildTimePanel
()
{
return
_PanelFrame
(
backgroundAsset:
_assetPanelTall
,
padding:
EdgeInsets
.
fromLTRB
(
34
.
w
,
28
.
h
,
34
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
_PanelTitle
(
'设置雾化时间'
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
_DigitalValueBox
(
value:
'00'
,
unit:
'分钟'
)),
Divider
(
color:
Colors
.
white
.
withValues
(
alpha:
0.16
),
height:
36
.
h
),
const
_PanelTitle
(
'设置消毒时间'
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
_DigitalValueBox
(
value:
'14'
,
unit:
'分钟'
,
active:
true
,
),
),
],
),
);
}
Widget
_buildCarePanel
()
{
return
_PanelFrame
(
backgroundAsset:
_assetPanelWide
,
padding:
EdgeInsets
.
fromLTRB
(
30
.
w
,
26
.
h
,
30
.
w
,
24
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
_PanelTitle
(
'护理等级'
),
const
Spacer
(),
Container
(
height:
20
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
10
.
r
),
gradient:
const
LinearGradient
(
colors:
[
Color
(
0xFFDCEFFC
),
Color
(
0xFF71FFCF
),
Color
(
0xFFE4CF1D
),
Color
(
0xFFFFA11B
),
Color
(
0xFFFF5945
),
Color
(
0xFFFFFFFF
),
],
),
),
),
SizedBox
(
height:
24
.
h
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
for
(
final
item
in
const
[
'关闭'
,
'三级'
,
'二级'
,
'一级'
,
'特级'
])
Text
(
item
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
24
.
sp
),
),
],
),
],
),
);
}
Widget
_buildOxygenTimerPanel
()
{
return
_PanelFrame
(
backgroundAsset:
_assetPanelWide
,
padding:
EdgeInsets
.
fromLTRB
(
30
.
w
,
26
.
h
,
30
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
_PanelTitle
(
'供氧计时'
),
const
Spacer
(),
Row
(
children:
[
Text
(
'00:00:00'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
42
.
sp
,
letterSpacing:
2
,
fontWeight:
FontWeight
.
w500
,
),
),
const
Spacer
(),
const
_Pill
(
text:
'清零'
),
],
),
Divider
(
color:
Colors
.
white
.
withValues
(
alpha:
0.16
),
height:
38
.
h
),
Text
(
'ICU舱设置重置'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
const
Spacer
(),
const
_BigActionButton
(
text:
'初始化设置'
),
],
),
);
}
}
class
_MetricControlCard
extends
StatelessWidget
{
const
_MetricControlCard
({
required
this
.
metric
});
final
MonitoringMetricBO
metric
;
@override
Widget
build
(
BuildContext
context
)
{
final
isOxygen
=
metric
.
label
.
contains
(
'氧气'
);
final
isCo2
=
metric
.
label
.
contains
(
'二氧化碳'
)
||
metric
.
label
.
toUpperCase
().
contains
(
'CO'
);
return
_PanelFrame
(
active:
isOxygen
,
backgroundAsset:
isOxygen
?
_assetMetricGreen
:
_assetMetricBlue
,
padding:
EdgeInsets
.
fromLTRB
(
32
.
w
,
26
.
h
,
32
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Expanded
(
child:
_PanelTitle
(
_title
(
metric
.
label
))),
_Pill
(
text:
isOxygen
?
'ON'
:
isCo2
?
'PPM'
:
'Off'
,
active:
isOxygen
),
],
),
const
Spacer
(),
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
end
,
children:
[
Text
(
metric
.
value
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
isCo2
?
60
.
sp
:
82
.
sp
,
height:
0.9
,
fontWeight:
FontWeight
.
bold
,
),
),
SizedBox
(
width:
12
.
w
),
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
8
.
h
),
child:
Text
(
isCo2
?
''
:
metric
.
unit
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
),
const
Spacer
(),
Image
.
asset
(
_iconAsset
(
metric
.
label
),
width:
72
.
w
,
height:
72
.
w
,
fit:
BoxFit
.
contain
,
),
],
),
Divider
(
color:
Colors
.
white
.
withValues
(
alpha:
0.18
),
height:
28
.
h
),
Text
(
isCo2
?
'告警阈值设定'
:
metric
.
label
.
contains
(
'温度'
)
?
'温度设定'
:
'湿度设定'
,
style:
TextStyle
(
color:
Colors
.
white
.
withValues
(
alpha:
0.78
),
fontSize:
26
.
sp
),
),
const
Spacer
(),
Row
(
children:
[
_AdjustText
(
'-'
,
active:
isOxygen
||
!
isCo2
),
const
Spacer
(),
Text
(
isCo2
?
'4000'
:
isOxygen
?
'90'
:
metric
.
label
.
contains
(
'湿度'
)
?
'10'
:
'24'
,
style:
TextStyle
(
color:
isCo2
?
const
Color
(
0xFFFFC400
)
:
const
Color
(
0xFF00B7F4
),
fontSize:
64
.
sp
,
height:
1
,
fontWeight:
FontWeight
.
bold
,
),
),
const
Spacer
(),
const
_AdjustText
(
'+'
,
active:
true
),
],
),
],
),
);
}
static
String
_title
(
String
label
)
{
if
(
label
.
contains
(
'二氧化碳'
))
return
'二氧化碳浓度'
;
return
label
;
}
}
class
_InfoPanel
extends
StatelessWidget
{
const
_InfoPanel
({
required
this
.
title
,
required
this
.
actionText
,
required
this
.
icon
,
required
this
.
body
,
this
.
warning
,
});
final
String
title
;
final
String
actionText
;
final
IconData
icon
;
final
String
body
;
final
String
?
warning
;
@override
Widget
build
(
BuildContext
context
)
{
return
_PanelFrame
(
backgroundAsset:
_assetPanelWide
,
padding:
EdgeInsets
.
fromLTRB
(
30
.
w
,
22
.
h
,
30
.
w
,
24
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Expanded
(
child:
_PanelTitle
(
title
)),
_Pill
(
text:
actionText
),
],
),
const
Spacer
(),
Row
(
children:
[
Icon
(
icon
,
color:
const
Color
(
0xFF6AC6F2
),
size:
54
.
w
),
SizedBox
(
width:
28
.
w
),
Expanded
(
child:
Text
(
body
,
style:
TextStyle
(
color:
const
Color
(
0xFFC9F8FF
),
fontSize:
20
.
sp
,
height:
1.35
,
),
),
),
],
),
if
(
warning
!=
null
)
...[
SizedBox
(
height:
8
.
h
),
Text
(
warning
!,
style:
TextStyle
(
color:
const
Color
(
0xFFFFC400
),
fontSize:
16
.
sp
),
),
],
],
),
);
}
}
class
_ModeButton
extends
StatelessWidget
{
const
_ModeButton
({
required
this
.
label
,
required
this
.
icon
,
this
.
active
=
false
,
});
final
String
label
;
final
IconData
icon
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
final
color
=
active
?
const
Color
(
0xFF45F36F
)
:
const
Color
(
0xFF7DC4EA
);
return
Container
(
decoration:
_buttonDecoration
(
active:
active
,
backgroundAsset:
_assetArrowButton
,
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
18
.
h
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Icon
(
icon
,
color:
color
,
size:
56
.
w
),
SizedBox
(
height:
20
.
h
),
Text
(
label
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
color
,
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
),
],
),
);
}
}
class
_WideModeButton
extends
StatelessWidget
{
const
_WideModeButton
({
required
this
.
label
,
required
this
.
icon
,
});
final
String
label
;
final
IconData
icon
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
decoration:
_buttonDecoration
(
backgroundAsset:
_assetButton
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Row
(
children:
[
Icon
(
icon
,
color:
const
Color
(
0xFF7DC4EA
),
size:
52
.
w
),
SizedBox
(
width:
34
.
w
),
Expanded
(
child:
Text
(
label
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
),
],
),
);
}
}
class
_DigitalValueBox
extends
StatelessWidget
{
const
_DigitalValueBox
({
required
this
.
value
,
required
this
.
unit
,
this
.
active
=
false
,
});
final
String
value
;
final
String
unit
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
decoration:
_buttonDecoration
(
active:
active
,
backgroundAsset:
_assetButton
,
),
alignment:
Alignment
.
center
,
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
value
,
style:
TextStyle
(
color:
active
?
const
Color
(
0xFFC8FFFF
)
:
Colors
.
white
,
fontSize:
46
.
sp
,
letterSpacing:
2
,
fontWeight:
FontWeight
.
w500
,
),
),
SizedBox
(
width:
28
.
w
),
Text
(
unit
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
30
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
],
),
);
}
}
class
_BigActionButton
extends
StatelessWidget
{
const
_BigActionButton
({
required
this
.
text
});
final
String
text
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
height:
64
.
h
,
decoration:
_buttonDecoration
(
backgroundAsset:
_assetButton
),
alignment:
Alignment
.
center
,
child:
Text
(
'《《
$text
》》'
,
style:
TextStyle
(
color:
const
Color
(
0xFFC9F8FF
),
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
),
);
}
}
class
_PanelFrame
extends
StatelessWidget
{
const
_PanelFrame
({
required
this
.
child
,
required
this
.
padding
,
this
.
active
=
false
,
this
.
backgroundAsset
,
});
final
Widget
child
;
final
EdgeInsetsGeometry
padding
;
final
bool
active
;
final
String
?
backgroundAsset
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
height:
double
.
infinity
,
padding:
padding
,
decoration:
BoxDecoration
(
color:
backgroundAsset
==
null
?
active
?
const
Color
(
0xFF003F14
).
withValues
(
alpha:
0.92
)
:
const
Color
(
0xFF061C34
).
withValues
(
alpha:
0.92
)
:
null
,
image:
backgroundAsset
==
null
?
null
:
DecorationImage
(
image:
AssetImage
(
backgroundAsset
!),
fit:
BoxFit
.
fill
,
),
border:
backgroundAsset
==
null
?
Border
.
all
(
color:
active
?
const
Color
(
0xFF3EFF5F
)
:
const
Color
(
0xFF89DFFF
),
width:
3
.
w
,
)
:
null
,
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
boxShadow:
[
BoxShadow
(
color:
(
active
?
const
Color
(
0xFF3EFF5F
)
:
const
Color
(
0xFF4FC8FF
))
.
withValues
(
alpha:
0.32
),
blurRadius:
18
.
r
,
spreadRadius:
2
.
r
,
),
],
),
child:
child
,
);
}
}
class
_PanelTitle
extends
StatelessWidget
{
const
_PanelTitle
(
this
.
text
);
final
String
text
;
@override
Widget
build
(
BuildContext
context
)
{
return
Text
(
text
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
);
}
}
class
_Pill
extends
StatelessWidget
{
const
_Pill
({
required
this
.
text
,
this
.
active
=
false
,
});
final
String
text
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
height:
40
.
h
,
constraints:
BoxConstraints
(
minWidth:
90
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
18
.
w
),
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
Colors
.
white
.
withValues
(
alpha:
active
?
0.14
:
0.06
),
border:
Border
.
all
(
color:
active
?
const
Color
(
0xFF52FFBB
)
:
const
Color
(
0xFF75C1DD
),
width:
1
.
w
,
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
),
child:
Text
(
text
,
style:
TextStyle
(
color:
active
?
const
Color
(
0xFF52FFBB
)
:
const
Color
(
0xFF75C1DD
),
fontSize:
22
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
),
);
}
}
class
_AdjustText
extends
StatelessWidget
{
const
_AdjustText
(
this
.
text
,
{
this
.
active
=
false
});
final
String
text
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
return
Text
(
text
,
style:
TextStyle
(
color:
active
?
const
Color
(
0xFF20E5FF
)
:
const
Color
(
0xFF4B7191
),
fontSize:
58
.
sp
,
height:
1
,
fontWeight:
FontWeight
.
w700
,
),
);
}
}
class
_ModeItem
{
final
String
label
;
final
IconData
icon
;
final
bool
active
;
const
_ModeItem
({
required
this
.
label
,
required
this
.
icon
,
this
.
active
=
false
,
});
}
BoxDecoration
_buttonDecoration
(
{
bool
active
=
false
,
String
?
backgroundAsset
})
{
return
BoxDecoration
(
color:
backgroundAsset
==
null
?
active
?
const
Color
(
0xFF063F1A
).
withValues
(
alpha:
0.96
)
:
const
Color
(
0xFF0A243F
).
withValues
(
alpha:
0.96
)
:
null
,
image:
backgroundAsset
==
null
?
null
:
DecorationImage
(
image:
AssetImage
(
backgroundAsset
),
fit:
BoxFit
.
fill
,
),
border:
backgroundAsset
==
null
?
Border
.
all
(
color:
active
?
const
Color
(
0xFF2DF765
)
:
const
Color
(
0xFF66BDE8
),
width:
2
,
)
:
null
,
borderRadius:
BorderRadius
.
circular
(
6
),
);
}
String
_iconAsset
(
String
label
)
{
if
(
label
.
contains
(
'温度'
))
{
return
'lib/assets/monitoring/cabin_temperature.png'
;
}
if
(
label
.
contains
(
'湿度'
))
{
return
'lib/assets/monitoring/cabin_humidity.png'
;
}
if
(
label
.
contains
(
'氧气'
))
{
return
'lib/assets/monitoring/oxygen_concentration.png'
;
}
return
'lib/assets/monitoring/carbon_dioxide_concentration.png'
;
}
lib/views/monitoring/device_control/cubit/device_control_index_cubit.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter_bloc/flutter_bloc.dart'
;
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
import
'package:laki_icu_app/services/monitoring_service.dart'
;
import
'device_control_index_state.dart'
;
class
DeviceControlIndexCubit
extends
Cubit
<
DeviceControlIndexState
>
{
final
MonitoringService
_monitoringService
;
DeviceControlIndexCubit
({
MonitoringService
?
monitoringService
,
})
:
_monitoringService
=
monitoringService
??
MonitoringService
(),
super
(
DeviceControlIndexState
())
{
loadMetrics
();
}
void
selectMetric
(
String
label
)
{
emit
(
state
.
copyWith
(
selectedMetricLabel:
label
));
}
Future
<
void
>
loadMetrics
()
async
{
emit
(
state
.
copyWith
(
status:
DeviceControlIndexStatus
.
loading
,
isLoading:
true
,
error:
null
,
));
try
{
final
allMetrics
=
await
_monitoringService
.
getMetrics
();
final
envMetrics
=
_environmentMetrics
(
allMetrics
);
emit
(
state
.
copyWith
(
status:
DeviceControlIndexStatus
.
success
,
isLoading:
false
,
metrics:
envMetrics
,
error:
null
,
));
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
status:
DeviceControlIndexStatus
.
failure
,
isLoading:
false
,
error:
e
.
toString
(),
));
}
}
/// 过滤出环境指标(温度/湿度/氧气/二氧化碳),最多取4个
List
<
MonitoringMetricBO
>
_environmentMetrics
(
List
<
MonitoringMetricBO
>
metrics
)
{
final
matched
=
metrics
.
where
((
item
)
=>
item
.
label
.
contains
(
'温度'
)
||
item
.
label
.
contains
(
'湿度'
)
||
item
.
label
.
contains
(
'氧气'
)
||
item
.
label
.
contains
(
'二氧化碳'
)
||
item
.
label
.
toUpperCase
().
contains
(
'CO'
))
.
take
(
4
)
.
toList
();
if
(
matched
.
length
==
4
)
return
matched
;
return
const
[
MonitoringMetricBO
(
value:
'--'
,
unit:
'℃'
,
label:
'舱内温度'
),
MonitoringMetricBO
(
value:
'--'
,
unit:
'RH'
,
label:
'舱内湿度'
),
MonitoringMetricBO
(
value:
'--'
,
unit:
'%'
,
label:
'氧气浓度'
),
MonitoringMetricBO
(
value:
'--'
,
unit:
'%'
,
label:
'二氧化碳'
),
];
}
}
lib/views/monitoring/device_control/cubit/device_control_index_state.dart
0 → 100644
View file @
dd39c5b7
import
'package:equatable/equatable.dart'
;
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
enum
DeviceControlIndexStatus
{
initial
,
loading
,
success
,
failure
}
class
DeviceControlIndexState
extends
Equatable
{
final
DeviceControlIndexStatus
status
;
final
bool
isLoading
;
final
String
?
error
;
final
List
<
MonitoringMetricBO
>
metrics
;
final
String
selectedMetricLabel
;
const
DeviceControlIndexState
({
this
.
status
=
DeviceControlIndexStatus
.
initial
,
this
.
isLoading
=
false
,
this
.
error
,
this
.
metrics
=
const
[],
this
.
selectedMetricLabel
=
''
,
});
DeviceControlIndexState
copyWith
({
DeviceControlIndexStatus
?
status
,
bool
?
isLoading
,
String
?
error
,
List
<
MonitoringMetricBO
>?
metrics
,
String
?
selectedMetricLabel
,
})
{
return
DeviceControlIndexState
(
status:
status
??
this
.
status
,
isLoading:
isLoading
??
this
.
isLoading
,
error:
error
??
this
.
error
,
metrics:
metrics
??
this
.
metrics
,
selectedMetricLabel:
selectedMetricLabel
??
this
.
selectedMetricLabel
,
);
}
@override
List
<
Object
?>
get
props
=>
[
status
,
isLoading
,
error
,
metrics
,
selectedMetricLabel
,
];
}
lib/views/monitoring/device_control/device_control_index_view.dart
0 → 100644
View file @
dd39c5b7
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:laki_icu_app/models/bo/monitoring_bo.dart'
;
import
'cubit/device_control_index_cubit.dart'
;
import
'cubit/device_control_index_state.dart'
;
import
'widgets/device_control_care_panel.dart'
;
import
'widgets/device_control_info_panel.dart'
;
import
'widgets/device_control_metric_card.dart'
;
import
'widgets/device_control_mode_panel.dart'
;
import
'widgets/device_control_oxygen_timer_panel.dart'
;
import
'widgets/device_control_time_panel.dart'
;
import
'widgets/device_control_wind_panel.dart'
;
@RoutePage
()
class
DeviceControlIndexView
extends
StatelessWidget
{
const
DeviceControlIndexView
({
super
.
key
,
// this.selectedMetricLabel = '',
});
// final String selectedMetricLabel;
@override
Widget
build
(
BuildContext
context
)
{
return
BlocProvider
(
create:
(
_
)
=>
DeviceControlIndexCubit
(),
child:
const
DeviceControlIndexContent
(),
);
}
}
class
DeviceControlIndexContent
extends
StatelessWidget
{
const
DeviceControlIndexContent
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
BlocBuilder
<
DeviceControlIndexCubit
,
DeviceControlIndexState
>(
builder:
(
context
,
state
)
{
if
(
state
.
isLoading
&&
state
.
metrics
.
isEmpty
)
{
return
const
Scaffold
(
backgroundColor:
Color
(
0xFF010B1D
),
body:
Center
(
child:
CircularProgressIndicator
(
color:
Colors
.
white
),
),
);
}
if
(
state
.
status
==
DeviceControlIndexStatus
.
failure
&&
state
.
metrics
.
isEmpty
)
{
return
Scaffold
(
backgroundColor:
const
Color
(
0xFF010B1D
),
body:
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
'加载失败:
${state.error ?? "未知错误"}
'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
22
.
sp
),
),
SizedBox
(
height:
22
.
h
),
ElevatedButton
(
onPressed:
()
=>
context
.
read
<
DeviceControlIndexCubit
>().
loadMetrics
(),
child:
const
Text
(
'重试'
),
),
],
),
),
);
}
return
_DeviceControlLayout
(
metrics:
state
.
metrics
,
selectedLabel:
state
.
selectedMetricLabel
,
onBack:
()
=>
context
.
router
.
popForced
(),
onMetricSelected:
context
.
read
<
DeviceControlIndexCubit
>().
selectMetric
,
);
},
);
}
}
/// 设备控制主布局
class
_DeviceControlLayout
extends
StatelessWidget
{
const
_DeviceControlLayout
({
required
this
.
metrics
,
required
this
.
selectedLabel
,
required
this
.
onBack
,
required
this
.
onMetricSelected
,
});
final
List
<
MonitoringMetricBO
>
metrics
;
final
String
selectedLabel
;
final
VoidCallback
onBack
;
final
ValueChanged
<
String
>
onMetricSelected
;
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
backgroundColor:
const
Color
(
0xFF010B1D
),
body:
SafeArea
(
maintainBottomViewPadding:
true
,
child:
Row
(
children:
[
Expanded
(
flex:
74
,
child:
Column
(
children:
[
Expanded
(
flex:
42
,
child:
Row
(
children:
[
for
(
int
index
=
0
;
index
<
metrics
.
length
;
index
++)
...[
Expanded
(
child:
DeviceControlMetricCard
(
metric:
metrics
[
index
],
),
),
if
(
index
<
metrics
.
length
-
1
)
SizedBox
(
width:
24
.
w
),
],
],
),
),
SizedBox
(
height:
24
.
h
),
Expanded
(
flex:
58
,
child:
Row
(
children:
[
const
Expanded
(
flex:
48
,
child:
DeviceControlModePanel
(),
),
SizedBox
(
width:
24
.
w
),
const
Expanded
(
flex:
23
,
child:
DeviceControlWindPanel
(),
),
SizedBox
(
width:
24
.
w
),
const
Expanded
(
flex:
29
,
child:
DeviceControlTimePanel
(),
),
],
),
),
],
),
),
SizedBox
(
width:
24
.
w
),
Expanded
(
flex:
26
,
child:
Column
(
children:
[
const
Expanded
(
flex:
21
,
child:
DeviceControlCarePanel
()),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
flex:
20
,
child:
DeviceControlInfoPanel
(
title:
'新风进化'
,
actionText:
'Auto'
,
icon:
Icons
.
cyclone
,
body:
'CO₂超过设定值时自动启动外循环
\n
净化,当降至2000ppm后,本
\n
功能自动关闭'
,
),
),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
flex:
20
,
child:
DeviceControlInfoPanel
(
title:
'开放供氧'
,
actionText:
'Off'
,
icon:
Icons
.
air
,
body:
'开启后风扇打开、制冷、加热和
\n
循环等设备暂停。'
,
warning:
'*保持设备周围空气相对禁止,严禁烟火'
,
),
),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
flex:
26
,
child:
DeviceControlOxygenTimerPanel
(),
),
],
),
),
],
),
),
);
}
}
lib/views/monitoring/device_control/widgets/device_control_care_panel.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'device_control_common.dart'
;
/// 护理等级面板
class
DeviceControlCarePanel
extends
StatelessWidget
{
const
DeviceControlCarePanel
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
DeviceControlPanelFrame
(
backgroundAsset:
assetPanelWide
,
padding:
EdgeInsets
.
fromLTRB
(
30
.
w
,
26
.
h
,
30
.
w
,
24
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
DeviceControlPanelTitle
(
'护理等级'
),
const
Spacer
(),
Container
(
height:
20
.
h
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
10
.
r
),
gradient:
const
LinearGradient
(
colors:
[
Color
(
0xFFDCEFFC
),
Color
(
0xFF71FFCF
),
Color
(
0xFFE4CF1D
),
Color
(
0xFFFFA11B
),
Color
(
0xFFFF5945
),
Color
(
0xFFFFFFFF
),
],
),
),
),
SizedBox
(
height:
24
.
h
),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
for
(
final
item
in
const
[
'关闭'
,
'三级'
,
'二级'
,
'一级'
,
'特级'
])
Text
(
item
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
24
.
sp
),
),
],
),
],
),
);
}
}
lib/views/monitoring/device_control/widgets/device_control_common.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
// -- 资源常量 --
const
String
assetMetricBlue
=
'lib/assets/monitoring/box_bg_325x372.png'
;
const
String
assetMetricGreen
=
'lib/assets/monitoring/frame_card_green_325x372.png'
;
const
String
assetPanelWide
=
'lib/assets/monitoring/frame_button_324x164.png'
;
const
String
assetPanelLarge
=
'lib/assets/monitoring/frame_panel_674x509.png'
;
const
String
assetPanelTall
=
'lib/assets/monitoring/box_bg_460x905.png'
;
const
String
assetButton
=
'lib/assets/monitoring/frame_button_324x164.png'
;
const
String
assetArrowButton
=
'lib/assets/monitoring/frame_button_arrows_561x637.png'
;
/// 面板外框容器
class
DeviceControlPanelFrame
extends
StatelessWidget
{
const
DeviceControlPanelFrame
({
super
.
key
,
required
this
.
child
,
required
this
.
padding
,
this
.
active
=
false
,
this
.
backgroundAsset
,
});
final
Widget
child
;
final
EdgeInsetsGeometry
padding
;
final
bool
active
;
final
String
?
backgroundAsset
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
height:
double
.
infinity
,
padding:
padding
,
decoration:
BoxDecoration
(
color:
backgroundAsset
==
null
?
active
?
const
Color
(
0xFF003F14
).
withValues
(
alpha:
0.92
)
:
const
Color
(
0xFF061C34
).
withValues
(
alpha:
0.92
)
:
null
,
image:
backgroundAsset
==
null
?
null
:
DecorationImage
(
image:
AssetImage
(
backgroundAsset
!),
fit:
BoxFit
.
fill
,
),
border:
backgroundAsset
==
null
?
Border
.
all
(
color:
active
?
const
Color
(
0xFF3EFF5F
)
:
const
Color
(
0xFF89DFFF
),
width:
3
.
w
,
)
:
null
,
borderRadius:
BorderRadius
.
circular
(
8
.
r
),
boxShadow:
[
BoxShadow
(
color:
(
active
?
const
Color
(
0xFF3EFF5F
)
:
const
Color
(
0xFF4FC8FF
))
.
withValues
(
alpha:
0.32
),
blurRadius:
18
.
r
,
spreadRadius:
2
.
r
,
),
],
),
child:
child
,
);
}
}
/// 面板标题
class
DeviceControlPanelTitle
extends
StatelessWidget
{
const
DeviceControlPanelTitle
(
this
.
text
,
{
super
.
key
});
final
String
text
;
@override
Widget
build
(
BuildContext
context
)
{
return
Text
(
text
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
);
}
}
/// 圆角标签
class
DeviceControlPill
extends
StatelessWidget
{
const
DeviceControlPill
({
super
.
key
,
required
this
.
text
,
this
.
active
=
false
,
});
final
String
text
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
height:
40
.
h
,
constraints:
BoxConstraints
(
minWidth:
90
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
18
.
w
),
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
Colors
.
white
.
withValues
(
alpha:
active
?
0.14
:
0.06
),
border:
Border
.
all
(
color:
active
?
const
Color
(
0xFF52FFBB
)
:
const
Color
(
0xFF75C1DD
),
width:
1
.
w
,
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
),
child:
Text
(
text
,
style:
TextStyle
(
color:
active
?
const
Color
(
0xFF52FFBB
)
:
const
Color
(
0xFF75C1DD
),
fontSize:
22
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
),
);
}
}
/// 加减调节文字
class
DeviceControlAdjustText
extends
StatelessWidget
{
const
DeviceControlAdjustText
(
this
.
text
,
{
super
.
key
,
this
.
active
=
false
});
final
String
text
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
return
Text
(
text
,
style:
TextStyle
(
color:
active
?
const
Color
(
0xFF20E5FF
)
:
const
Color
(
0xFF4B7191
),
fontSize:
58
.
sp
,
height:
1
,
fontWeight:
FontWeight
.
w700
,
),
);
}
}
/// 大号操作按钮
class
DeviceControlBigActionButton
extends
StatelessWidget
{
const
DeviceControlBigActionButton
({
super
.
key
,
required
this
.
text
});
final
String
text
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
height:
64
.
h
,
decoration:
deviceControlButtonDecoration
(
backgroundAsset:
assetButton
),
alignment:
Alignment
.
center
,
child:
Text
(
'《《
$text
》》'
,
style:
TextStyle
(
color:
const
Color
(
0xFFC9F8FF
),
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
),
);
}
}
/// 数字值展示框
class
DeviceControlDigitalValueBox
extends
StatelessWidget
{
const
DeviceControlDigitalValueBox
({
super
.
key
,
required
this
.
value
,
required
this
.
unit
,
this
.
active
=
false
,
});
final
String
value
;
final
String
unit
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
decoration:
deviceControlButtonDecoration
(
active:
active
,
backgroundAsset:
assetButton
,
),
alignment:
Alignment
.
center
,
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Text
(
value
,
style:
TextStyle
(
color:
active
?
const
Color
(
0xFFC8FFFF
)
:
Colors
.
white
,
fontSize:
46
.
sp
,
letterSpacing:
2
,
fontWeight:
FontWeight
.
w500
,
),
),
SizedBox
(
width:
28
.
w
),
Text
(
unit
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
30
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
],
),
);
}
}
/// 按钮装饰(公共样式)
BoxDecoration
deviceControlButtonDecoration
(
{
bool
active
=
false
,
String
?
backgroundAsset
,
})
{
return
BoxDecoration
(
color:
backgroundAsset
==
null
?
active
?
const
Color
(
0xFF063F1A
).
withValues
(
alpha:
0.96
)
:
const
Color
(
0xFF0A243F
).
withValues
(
alpha:
0.96
)
:
null
,
image:
backgroundAsset
==
null
?
null
:
DecorationImage
(
image:
AssetImage
(
backgroundAsset
),
fit:
BoxFit
.
fill
,
),
border:
backgroundAsset
==
null
?
Border
.
all
(
color:
active
?
const
Color
(
0xFF2DF765
)
:
const
Color
(
0xFF66BDE8
),
width:
2
,
)
:
null
,
borderRadius:
BorderRadius
.
circular
(
6
),
);
}
/// 指标图标资源映射
String
deviceControlIconAsset
(
String
label
)
{
if
(
label
.
contains
(
'温度'
))
{
return
'lib/assets/monitoring/cabin_temperature.png'
;
}
if
(
label
.
contains
(
'湿度'
))
{
return
'lib/assets/monitoring/cabin_humidity.png'
;
}
if
(
label
.
contains
(
'氧气'
))
{
return
'lib/assets/monitoring/oxygen_concentration.png'
;
}
return
'lib/assets/monitoring/carbon_dioxide_concentration.png'
;
}
lib/views/monitoring/device_control/widgets/device_control_info_panel.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'device_control_common.dart'
;
/// 信息展示面板(新风进化/开放供氧 等)
class
DeviceControlInfoPanel
extends
StatelessWidget
{
const
DeviceControlInfoPanel
({
super
.
key
,
required
this
.
title
,
required
this
.
actionText
,
required
this
.
icon
,
required
this
.
body
,
this
.
warning
,
});
final
String
title
;
final
String
actionText
;
final
IconData
icon
;
final
String
body
;
final
String
?
warning
;
@override
Widget
build
(
BuildContext
context
)
{
return
DeviceControlPanelFrame
(
backgroundAsset:
assetPanelWide
,
padding:
EdgeInsets
.
fromLTRB
(
30
.
w
,
22
.
h
,
30
.
w
,
24
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Expanded
(
child:
DeviceControlPanelTitle
(
title
)),
DeviceControlPill
(
text:
actionText
),
],
),
const
Spacer
(),
Row
(
children:
[
Icon
(
icon
,
color:
const
Color
(
0xFF6AC6F2
),
size:
54
.
w
),
SizedBox
(
width:
28
.
w
),
Expanded
(
child:
Text
(
body
,
style:
TextStyle
(
color:
const
Color
(
0xFFC9F8FF
),
fontSize:
20
.
sp
,
height:
1.35
,
),
),
),
],
),
if
(
warning
!=
null
)
...[
SizedBox
(
height:
8
.
h
),
Text
(
warning
!,
style:
TextStyle
(
color:
const
Color
(
0xFFFFC400
),
fontSize:
16
.
sp
,
),
),
],
],
),
);
}
}
lib/views/monitoring/device_control/widgets/device_control_metric_card.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
import
'device_control_common.dart'
;
/// 环境指标控制卡片(温度/湿度/氧气/二氧化碳)
class
DeviceControlMetricCard
extends
StatelessWidget
{
const
DeviceControlMetricCard
({
super
.
key
,
required
this
.
metric
});
final
MonitoringMetricBO
metric
;
@override
Widget
build
(
BuildContext
context
)
{
final
isOxygen
=
metric
.
label
.
contains
(
'氧气'
);
final
isCo2
=
metric
.
label
.
contains
(
'二氧化碳'
)
||
metric
.
label
.
toUpperCase
().
contains
(
'CO'
);
return
DeviceControlPanelFrame
(
active:
isOxygen
,
backgroundAsset:
isOxygen
?
assetMetricGreen
:
assetMetricBlue
,
padding:
EdgeInsets
.
fromLTRB
(
32
.
w
,
26
.
h
,
32
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Row
(
children:
[
Expanded
(
child:
DeviceControlPanelTitle
(
_title
(
metric
.
label
)),
),
DeviceControlPill
(
text:
isOxygen
?
'ON'
:
isCo2
?
'PPM'
:
'Off'
,
active:
isOxygen
,
),
],
),
const
Spacer
(),
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
end
,
children:
[
Text
(
metric
.
value
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
isCo2
?
60
.
sp
:
82
.
sp
,
height:
0.9
,
fontWeight:
FontWeight
.
bold
,
),
),
SizedBox
(
width:
12
.
w
),
Padding
(
padding:
EdgeInsets
.
only
(
bottom:
8
.
h
),
child:
Text
(
isCo2
?
''
:
metric
.
unit
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
),
const
Spacer
(),
Image
.
asset
(
deviceControlIconAsset
(
metric
.
label
),
width:
72
.
w
,
height:
72
.
w
,
fit:
BoxFit
.
contain
,
),
],
),
Divider
(
color:
Colors
.
white
.
withValues
(
alpha:
0.18
),
height:
28
.
h
),
Text
(
isCo2
?
'告警阈值设定'
:
metric
.
label
.
contains
(
'温度'
)
?
'温度设定'
:
'湿度设定'
,
style:
TextStyle
(
color:
Colors
.
white
.
withValues
(
alpha:
0.78
),
fontSize:
26
.
sp
,
),
),
const
Spacer
(),
Row
(
children:
[
DeviceControlAdjustText
(
'-'
,
active:
isOxygen
||
!
isCo2
),
const
Spacer
(),
Text
(
isCo2
?
'4000'
:
isOxygen
?
'90'
:
metric
.
label
.
contains
(
'湿度'
)
?
'10'
:
'24'
,
style:
TextStyle
(
color:
isCo2
?
const
Color
(
0xFFFFC400
)
:
const
Color
(
0xFF00B7F4
),
fontSize:
64
.
sp
,
height:
1
,
fontWeight:
FontWeight
.
bold
,
),
),
const
Spacer
(),
const
DeviceControlAdjustText
(
'+'
,
active:
true
),
],
),
],
),
);
}
static
String
_title
(
String
label
)
{
if
(
label
.
contains
(
'二氧化碳'
))
return
'二氧化碳浓度'
;
return
label
;
}
}
lib/views/monitoring/device_control/widgets/device_control_mode_panel.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'device_control_common.dart'
;
/// 模式切换面板(外循环/检查灯/照明灯/内循环/蓝光/红光)
class
DeviceControlModePanel
extends
StatelessWidget
{
const
DeviceControlModePanel
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
const
items
=
[
_ModeItem
(
label:
'外循环'
,
icon:
Icons
.
sync
,
active:
true
),
_ModeItem
(
label:
'检查灯'
,
icon:
Icons
.
light
),
_ModeItem
(
label:
'照明灯'
,
icon:
Icons
.
lightbulb
),
_ModeItem
(
label:
'内循环'
,
icon:
Icons
.
autorenew
),
_ModeItem
(
label:
'蓝光'
,
icon:
Icons
.
wb_sunny_outlined
),
_ModeItem
(
label:
'红光'
,
icon:
Icons
.
wb_sunny
),
];
return
DeviceControlPanelFrame
(
backgroundAsset:
assetPanelLarge
,
padding:
EdgeInsets
.
all
(
28
.
w
),
child:
GridView
.
count
(
crossAxisCount:
3
,
crossAxisSpacing:
24
.
w
,
mainAxisSpacing:
24
.
h
,
physics:
const
NeverScrollableScrollPhysics
(),
childAspectRatio:
1.1
,
children:
[
for
(
final
item
in
items
)
_ModeButton
(
label:
item
.
label
,
icon:
item
.
icon
,
active:
item
.
active
,
),
],
),
);
}
}
class
_ModeButton
extends
StatelessWidget
{
const
_ModeButton
({
required
this
.
label
,
required
this
.
icon
,
this
.
active
=
false
,
});
final
String
label
;
final
IconData
icon
;
final
bool
active
;
@override
Widget
build
(
BuildContext
context
)
{
final
color
=
active
?
const
Color
(
0xFF45F36F
)
:
const
Color
(
0xFF7DC4EA
);
return
Container
(
decoration:
deviceControlButtonDecoration
(
active:
active
,
backgroundAsset:
assetArrowButton
,
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
16
.
w
,
vertical:
18
.
h
),
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Icon
(
icon
,
color:
color
,
size:
56
.
w
),
SizedBox
(
height:
20
.
h
),
Text
(
label
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
color
,
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
w700
,
),
),
],
),
);
}
}
class
_ModeItem
{
final
String
label
;
final
IconData
icon
;
final
bool
active
;
const
_ModeItem
({
required
this
.
label
,
required
this
.
icon
,
this
.
active
=
false
,
});
}
lib/views/monitoring/device_control/widgets/device_control_oxygen_timer_panel.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'device_control_common.dart'
;
/// 供氧计时 + ICU重置面板
class
DeviceControlOxygenTimerPanel
extends
StatelessWidget
{
const
DeviceControlOxygenTimerPanel
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
DeviceControlPanelFrame
(
backgroundAsset:
assetPanelWide
,
padding:
EdgeInsets
.
fromLTRB
(
30
.
w
,
26
.
h
,
30
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
DeviceControlPanelTitle
(
'供氧计时'
),
const
Spacer
(),
Row
(
children:
[
Text
(
'00:00:00'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
42
.
sp
,
letterSpacing:
2
,
fontWeight:
FontWeight
.
w500
,
),
),
const
Spacer
(),
const
DeviceControlPill
(
text:
'清零'
),
],
),
Divider
(
color:
Colors
.
white
.
withValues
(
alpha:
0.16
),
height:
38
.
h
),
Text
(
'ICU舱设置重置'
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
28
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
const
Spacer
(),
const
DeviceControlBigActionButton
(
text:
'初始化设置'
),
],
),
);
}
}
lib/views/monitoring/device_control/widgets/device_control_time_panel.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'device_control_common.dart'
;
/// 设置雾化/消毒时间面板
class
DeviceControlTimePanel
extends
StatelessWidget
{
const
DeviceControlTimePanel
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
DeviceControlPanelFrame
(
backgroundAsset:
assetPanelTall
,
padding:
EdgeInsets
.
fromLTRB
(
34
.
w
,
28
.
h
,
34
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
DeviceControlPanelTitle
(
'设置雾化时间'
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
DeviceControlDigitalValueBox
(
value:
'00'
,
unit:
'分钟'
),
),
Divider
(
color:
Colors
.
white
.
withValues
(
alpha:
0.16
),
height:
36
.
h
),
const
DeviceControlPanelTitle
(
'设置消毒时间'
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
DeviceControlDigitalValueBox
(
value:
'14'
,
unit:
'分钟'
,
active:
true
,
),
),
],
),
);
}
}
lib/views/monitoring/device_control/widgets/device_control_wind_panel.dart
0 → 100644
View file @
dd39c5b7
import
'package:flutter/material.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'device_control_common.dart'
;
/// 风速调节面板
class
DeviceControlWindPanel
extends
StatelessWidget
{
const
DeviceControlWindPanel
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
DeviceControlPanelFrame
(
backgroundAsset:
assetPanelTall
,
padding:
EdgeInsets
.
fromLTRB
(
34
.
w
,
28
.
h
,
34
.
w
,
28
.
h
),
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
const
DeviceControlPanelTitle
(
'风速调节'
),
SizedBox
(
height:
24
.
h
),
const
Expanded
(
child:
_WideModeButton
(
label:
'睡眠模式'
,
icon:
Icons
.
nightlight_round
,
),
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
_WideModeButton
(
label:
'舒适模式'
,
icon:
Icons
.
favorite_border
,
),
),
SizedBox
(
height:
18
.
h
),
const
Expanded
(
child:
_WideModeButton
(
label:
'强劲模式'
,
icon:
Icons
.
air
),
),
],
),
);
}
}
class
_WideModeButton
extends
StatelessWidget
{
const
_WideModeButton
({
required
this
.
label
,
required
this
.
icon
,
});
final
String
label
;
final
IconData
icon
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
width:
double
.
infinity
,
decoration:
deviceControlButtonDecoration
(
backgroundAsset:
assetButton
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
28
.
w
),
child:
Row
(
children:
[
Icon
(
icon
,
color:
const
Color
(
0xFF7DC4EA
),
size:
52
.
w
),
SizedBox
(
width:
34
.
w
),
Expanded
(
child:
Text
(
label
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
26
.
sp
,
fontWeight:
FontWeight
.
w600
,
),
),
),
],
),
);
}
}
lib/views/monitoring/index/monitoring_index_view.dart
View file @
dd39c5b7
...
@@ -8,7 +8,7 @@ import 'package:laki_icu_app/enums/video_stream_mode_enum.dart';
...
@@ -8,7 +8,7 @@ import 'package:laki_icu_app/enums/video_stream_mode_enum.dart';
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
import
'package:laki_icu_app/models/bo/monitoring_bo.dart'
;
import
'package:laki_icu_app/utils/event_bus.dart'
;
import
'package:laki_icu_app/utils/event_bus.dart'
;
import
'../controller/monitoring_controller_view.dart'
;
import
'cubit/monitoring_index_cubit.dart'
;
import
'cubit/monitoring_index_cubit.dart'
;
import
'cubit/monitoring_index_state.dart'
;
import
'cubit/monitoring_index_state.dart'
;
import
'widgets/bluetooth_bind_dialog.dart'
;
import
'widgets/bluetooth_bind_dialog.dart'
;
...
@@ -40,7 +40,6 @@ class MonitoringIndexContent extends StatefulWidget {
...
@@ -40,7 +40,6 @@ class MonitoringIndexContent extends StatefulWidget {
class
_MonitoringIndexContentState
extends
State
<
MonitoringIndexContent
>
{
class
_MonitoringIndexContentState
extends
State
<
MonitoringIndexContent
>
{
late
final
MonitoringIndexCubit
_monitoringIndexCubit
;
late
final
MonitoringIndexCubit
_monitoringIndexCubit
;
StreamSubscription
<
OpenBluetoothScanEvent
>?
_bluetoothScanEventSub
;
StreamSubscription
<
OpenBluetoothScanEvent
>?
_bluetoothScanEventSub
;
String
?
_selectedEnvironmentMetricLabel
;
@override
@override
void
initState
()
{
void
initState
()
{
...
@@ -71,9 +70,6 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -71,9 +70,6 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
state
.
metrics
.
isEmpty
)
{
state
.
metrics
.
isEmpty
)
{
return
_buildError
(
state
.
error
);
return
_buildError
(
state
.
error
);
}
}
if
(
_selectedEnvironmentMetricLabel
!=
null
)
{
return
_buildEnvironmentDetail
(
state
);
}
return
_buildMainArea
(
state
);
return
_buildMainArea
(
state
);
},
},
);
);
...
@@ -116,7 +112,7 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -116,7 +112,7 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
children:
[
children:
[
Expanded
(
Expanded
(
flex:
32
,
flex:
32
,
child:
_buildMetrics
(
state
.
metrics
),
child:
state
.
metrics
.
isEmpty
?
_buildMetricsEmpty
()
:
_buildMetrics
(
state
.
metrics
),
),
),
SizedBox
(
height:
24
.
h
),
SizedBox
(
height:
24
.
h
),
Expanded
(
Expanded
(
...
@@ -153,6 +149,10 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -153,6 +149,10 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
);
);
}
}
Widget
_buildMetricsEmpty
()
{
return
Text
(
"data"
);
}
Widget
_buildMetrics
(
List
<
MonitoringMetricBO
>
metrics
)
{
Widget
_buildMetrics
(
List
<
MonitoringMetricBO
>
metrics
)
{
final
displayMetrics
=
_environmentMetrics
(
metrics
);
final
displayMetrics
=
_environmentMetrics
(
metrics
);
final
children
=
<
Widget
>[];
final
children
=
<
Widget
>[];
...
@@ -161,7 +161,7 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -161,7 +161,7 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
Expanded
(
Expanded
(
child:
MonitoringMetricCard
(
child:
MonitoringMetricCard
(
metric:
displayMetrics
[
i
],
metric:
displayMetrics
[
i
],
onTap:
()
=>
_open
EnvironmentDetai
l
(
displayMetrics
[
i
]),
onTap:
()
=>
_open
DeviceContro
l
(
displayMetrics
[
i
]),
),
),
),
),
);
);
...
@@ -174,23 +174,8 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -174,23 +174,8 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
);
);
}
}
Widget
_buildEnvironmentDetail
(
MonitoringIndexState
state
)
{
void
_openDeviceControl
(
MonitoringMetricBO
metric
)
{
final
metrics
=
_environmentMetrics
(
state
.
metrics
);
context
.
tabsRouter
.
setActiveIndex
(
7
);
return
MonitoringControllerView
(
metrics:
metrics
,
selectedMetricLabel:
_selectedEnvironmentMetricLabel
!,
onBack:
()
{
setState
(()
{
_selectedEnvironmentMetricLabel
=
null
;
});
},
);
}
void
_openEnvironmentDetail
(
MonitoringMetricBO
metric
)
{
setState
(()
{
_selectedEnvironmentMetricLabel
=
metric
.
label
;
});
}
}
/// 模式切换回调
/// 模式切换回调
...
...
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