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
192f8476
Commit
192f8476
authored
Jun 23, 2026
by
akari
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 修复蓝牙相关
parent
d697b832
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
343 additions
and
37 deletions
+343
-37
laki_mqtt_client.dart
lib/utils/mqtt/laki_mqtt_client.dart
+20
-13
monitoring_index_cubit.dart
lib/views/monitoring/index/cubit/monitoring_index_cubit.dart
+154
-3
monitoring_index_state.dart
lib/views/monitoring/index/cubit/monitoring_index_state.dart
+82
-2
monitoring_index_view.dart
lib/views/monitoring/index/monitoring_index_view.dart
+20
-10
bluetooth_bind_dialog.dart
...views/monitoring/index/widgets/bluetooth_bind_dialog.dart
+0
-0
monitoring_top_status_bar.dart
...s/monitoring/index/widgets/monitoring_top_status_bar.dart
+66
-9
pubspec.yaml
pubspec.yaml
+1
-0
No files found.
lib/utils/mqtt/laki_mqtt_client.dart
View file @
192f8476
...
@@ -28,19 +28,26 @@ class LakiMqttConfig {
...
@@ -28,19 +28,26 @@ class LakiMqttConfig {
this
.
logging
=
false
,
this
.
logging
=
false
,
});
});
/// TODO: 替换为腾讯云 IoT MQTT broker 地址、端口、clientId 和鉴权信息。
factory
LakiMqttConfig
.
tencentTdmq
({
const
LakiMqttConfig
.
placeholder
()
required
String
deviceSn
,
:
host
=
''
,
bool
logging
=
false
,
port
=
1883
,
})
{
clientId
=
''
,
return
LakiMqttConfig
(
username
=
null
,
host:
_tencentTdmqHost
,
password
=
null
,
port:
_tencentTdmqPort
,
useSsl
=
false
,
clientId:
'
$_tencentTdmqClientIdPrefix$deviceSn
'
,
useWebSocket
=
false
,
username:
_tencentTdmqUsername
,
webSocketProtocols
=
null
,
password:
_tencentTdmqPassword
,
keepAliveSeconds
=
30
,
logging:
logging
,
connectTimeoutMs
=
5000
,
);
logging
=
false
;
}
static
const
String
_tencentTdmqHost
=
'mqtt-7jqojva8-sh-public.mqtt.tencenttdmq.com'
;
static
const
int
_tencentTdmqPort
=
1883
;
static
const
String
_tencentTdmqClientIdPrefix
=
'GID_icu@@@'
;
static
const
String
_tencentTdmqUsername
=
'root'
;
static
const
String
_tencentTdmqPassword
=
'sk665f2b219cb3700b'
;
final
String
host
;
final
String
host
;
final
int
port
;
final
int
port
;
...
...
lib/views/monitoring/index/cubit/monitoring_index_cubit.dart
View file @
192f8476
...
@@ -6,6 +6,8 @@ import 'package:laki_icu_app/enums/video_stream_mode_enum.dart';
...
@@ -6,6 +6,8 @@ import 'package:laki_icu_app/enums/video_stream_mode_enum.dart';
import
'package:laki_icu_app/services/monitoring_service.dart'
;
import
'package:laki_icu_app/services/monitoring_service.dart'
;
import
'package:laki_icu_app/services/p2p_video_service.dart'
;
import
'package:laki_icu_app/services/p2p_video_service.dart'
;
import
'package:laki_icu_app/services/webrtc_service.dart'
;
import
'package:laki_icu_app/services/webrtc_service.dart'
;
import
'package:laki_icu_app/utils/bluetooth/index.dart'
;
import
'package:laki_icu_app/utils/storage/storage_service.dart'
;
import
'monitoring_index_state.dart'
;
import
'monitoring_index_state.dart'
;
...
@@ -16,9 +18,16 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
...
@@ -16,9 +18,16 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
final
MonitoringService
_monitoringService
;
final
MonitoringService
_monitoringService
;
final
WebrtcService
_webrtcService
;
final
WebrtcService
_webrtcService
;
final
P2pVideoService
_p2pVideoService
;
final
P2pVideoService
_p2pVideoService
;
final
StorageService
_storageService
;
final
BleBluetoothManager
_bluetoothManager
;
final
McuReportFrameDecoder
_mcuReportDecoder
;
StreamSubscription
<
WebrtcConnectionState
>?
_webrtcStateSub
;
StreamSubscription
<
WebrtcConnectionState
>?
_webrtcStateSub
;
StreamSubscription
<
P2pServiceState
>?
_p2pStateSub
;
StreamSubscription
<
P2pServiceState
>?
_p2pStateSub
;
StreamSubscription
<
List
<
BluetoothScanDevice
>>?
_bluetoothScanSub
;
StreamSubscription
<
BluetoothConnectionStatus
>?
_bluetoothStateSub
;
StreamSubscription
<
String
>?
_bluetoothMessageSub
;
StreamSubscription
<
BluetoothDataPacket
>?
_bluetoothDataSub
;
/// 连接代际计数器 —— 每次切换模式时 +1,
/// 连接代际计数器 —— 每次切换模式时 +1,
/// 防止旧连接的异步结果污染当前模式的状态。
/// 防止旧连接的异步结果污染当前模式的状态。
...
@@ -28,9 +37,14 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
...
@@ -28,9 +37,14 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
:
_monitoringService
=
MonitoringService
(),
:
_monitoringService
=
MonitoringService
(),
_webrtcService
=
WebrtcService
(),
_webrtcService
=
WebrtcService
(),
_p2pVideoService
=
P2pVideoService
(),
_p2pVideoService
=
P2pVideoService
(),
_storageService
=
StorageService
(),
_bluetoothManager
=
BleBluetoothManager
(),
_mcuReportDecoder
=
McuReportFrameDecoder
(),
super
(
const
MonitoringIndexState
())
{
super
(
const
MonitoringIndexState
())
{
_listenWebrtcState
();
_listenWebrtcState
();
_listenP2pState
();
_listenP2pState
();
_listenBluetoothState
();
_loadBoundBluetoothDevice
();
loadData
();
loadData
();
}
}
...
@@ -47,11 +61,69 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
...
@@ -47,11 +61,69 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
_p2pStateSub
=
_p2pVideoService
.
stateStream
.
listen
((
state
)
{
_p2pStateSub
=
_p2pVideoService
.
stateStream
.
listen
((
state
)
{
if
(
isClosed
)
return
;
if
(
isClosed
)
return
;
emit
(
this
.
state
.
copyWith
(
emit
(
this
.
state
.
copyWith
(
isP2pConnected:
state
==
P2pServiceState
.
connected
,
isP2pConnected:
state
==
P2pServiceState
.
connected
,
));
));
});
});
}
}
/// 监听蓝牙扫描、连接和数据状态
void
_listenBluetoothState
()
{
_bluetoothScanSub
=
_bluetoothManager
.
scanDevicesStream
.
listen
((
devices
)
{
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
bluetoothDevices:
devices
));
});
_bluetoothStateSub
=
_bluetoothManager
.
stateStream
.
listen
((
status
)
{
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
bluetoothConnectionStatus:
status
));
});
_bluetoothMessageSub
=
_bluetoothManager
.
messageStream
.
listen
((
message
)
{
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
bluetoothMessage:
message
));
});
_bluetoothDataSub
=
_bluetoothManager
.
dataStream
.
listen
((
packet
)
{
if
(
isClosed
)
return
;
try
{
final
reports
=
_mcuReportDecoder
.
addBytes
(
packet
.
bytes
);
final
latestReport
=
reports
.
isEmpty
?
null
:
reports
.
last
;
emit
(
state
.
copyWith
(
latestBluetoothRawHex:
packet
.
rawHex
,
latestMcuReport:
latestReport
,
bluetoothMessage:
latestReport
==
null
?
state
.
bluetoothMessage
:
'蓝牙数据解析成功:
${latestReport.sn.isEmpty ? latestReport.head : latestReport.sn}
'
,
));
}
catch
(
e
)
{
emit
(
state
.
copyWith
(
latestBluetoothRawHex:
packet
.
rawHex
,
bluetoothMessage:
'蓝牙数据解析失败:
$e
'
,
));
}
});
}
Future
<
void
>
_loadBoundBluetoothDevice
()
async
{
final
boundDevice
=
await
_storageService
.
getBoundBluetoothDevice
();
if
(
isClosed
)
return
;
final
deviceId
=
boundDevice
[
'deviceId'
];
if
(
deviceId
!=
null
&&
deviceId
.
isNotEmpty
)
{
final
userMac
=
await
_storageService
.
getUserMac
();
if
(
userMac
==
null
||
userMac
.
isEmpty
)
{
await
_storageService
.
saveUserMac
(
deviceId
);
}
}
else
{
await
_storageService
.
getUserMac
();
}
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
boundBluetoothDeviceId:
deviceId
==
null
||
deviceId
.
isEmpty
?
null
:
deviceId
,
boundBluetoothDeviceName:
boundDevice
[
'deviceName'
],
));
}
Future
<
void
>
loadData
()
async
{
Future
<
void
>
loadData
()
async
{
emit
(
state
.
copyWith
(
emit
(
state
.
copyWith
(
status:
MonitoringIndexStatus
.
loading
,
status:
MonitoringIndexStatus
.
loading
,
...
@@ -204,6 +276,81 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
...
@@ -204,6 +276,81 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
}
}
}
}
// ==================== 蓝牙扫描/绑定 ====================
Future
<
void
>
scanBluetoothDevices
()
async
{
if
(
state
.
isBluetoothScanning
)
return
;
emit
(
state
.
copyWith
(
isBluetoothScanning:
true
,
bluetoothDevices:
const
[],
bluetoothMessage:
'开始扫描蓝牙设备'
,
));
try
{
await
_bluetoothManager
.
scanForDevices
(
namePrefixes:
const
[],
timeout:
const
Duration
(
seconds:
10
),
);
}
catch
(
e
)
{
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
bluetoothMessage:
'蓝牙扫描失败:
$e
'
));
}
finally
{
if
(!
isClosed
)
{
emit
(
state
.
copyWith
(
isBluetoothScanning:
false
));
}
}
}
Future
<
void
>
bindBluetoothDevice
(
BluetoothScanDevice
device
)
async
{
if
(
state
.
isBluetoothBinding
)
return
;
_mcuReportDecoder
.
clear
();
emit
(
state
.
copyWith
(
isBluetoothBinding:
true
,
bindingBluetoothDeviceId:
device
.
remoteId
,
bluetoothMessage:
'正在绑定蓝牙设备:
${device.name}
'
,
));
try
{
await
_bluetoothManager
.
connectToDevice
(
device
);
await
_storageService
.
saveBoundBluetoothDevice
(
deviceId:
device
.
remoteId
,
deviceName:
device
.
name
,
);
await
_storageService
.
saveUserMac
(
device
.
remoteId
);
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
isBluetoothBinding:
false
,
bindingBluetoothDeviceId:
''
,
boundBluetoothDeviceId:
device
.
remoteId
,
boundBluetoothDeviceName:
device
.
name
,
bluetoothMessage:
'蓝牙设备已绑定:
${device.name}
'
,
));
}
catch
(
e
)
{
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
isBluetoothBinding:
false
,
bindingBluetoothDeviceId:
''
,
bluetoothMessage:
'蓝牙绑定失败:
$e
'
,
));
}
}
Future
<
void
>
unbindBluetoothDevice
()
async
{
await
_bluetoothManager
.
disconnect
();
await
_storageService
.
deleteBoundBluetoothDevice
();
await
_storageService
.
deleteUserMac
();
_mcuReportDecoder
.
clear
();
if
(
isClosed
)
return
;
emit
(
state
.
copyWith
(
clearBoundBluetoothDevice:
true
,
clearLatestMcuReport:
true
,
bluetoothMessage:
'蓝牙设备已解绑'
,
latestBluetoothRawHex:
''
,
));
}
/// 获取 WebRTC 渲染器供 UI 层使用
/// 获取 WebRTC 渲染器供 UI 层使用
WebrtcService
get
webrtcService
=>
_webrtcService
;
WebrtcService
get
webrtcService
=>
_webrtcService
;
...
@@ -214,8 +361,12 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
...
@@ -214,8 +361,12 @@ class MonitoringIndexCubit extends Cubit<MonitoringIndexState> {
Future
<
void
>
close
()
{
Future
<
void
>
close
()
{
_webrtcStateSub
?.
cancel
();
_webrtcStateSub
?.
cancel
();
_p2pStateSub
?.
cancel
();
_p2pStateSub
?.
cancel
();
_bluetoothScanSub
?.
cancel
();
_bluetoothStateSub
?.
cancel
();
_bluetoothMessageSub
?.
cancel
();
_bluetoothDataSub
?.
cancel
();
_webrtcService
.
dispose
();
_webrtcService
.
dispose
();
_p2pVideoService
.
dispose
();
_p2pVideoService
.
dispose
();
return
super
.
close
(
);
return
_bluetoothManager
.
release
().
then
((
_
)
=>
super
.
close
()
);
}
}
}
}
lib/views/monitoring/index/cubit/monitoring_index_state.dart
View file @
192f8476
...
@@ -2,6 +2,7 @@ import 'package:equatable/equatable.dart';
...
@@ -2,6 +2,7 @@ import 'package:equatable/equatable.dart';
import
'package:laki_icu_app/enums/video_stream_mode_enum.dart'
;
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/services/webrtc_service.dart'
;
import
'package:laki_icu_app/services/webrtc_service.dart'
;
import
'package:laki_icu_app/utils/bluetooth/index.dart'
;
enum
MonitoringIndexStatus
{
enum
MonitoringIndexStatus
{
initial
,
initial
,
...
@@ -31,6 +32,36 @@ class MonitoringIndexState extends Equatable {
...
@@ -31,6 +32,36 @@ class MonitoringIndexState extends Equatable {
/// P2P 模式是否已连接
/// P2P 模式是否已连接
final
bool
isP2pConnected
;
final
bool
isP2pConnected
;
/// 蓝牙扫描中
final
bool
isBluetoothScanning
;
/// 蓝牙绑定/连接处理中
final
bool
isBluetoothBinding
;
/// 正在绑定/连接的蓝牙设备 ID
final
String
bindingBluetoothDeviceId
;
/// 扫描到的蓝牙设备
final
List
<
BluetoothScanDevice
>
bluetoothDevices
;
/// 已绑定蓝牙设备 ID
final
String
?
boundBluetoothDeviceId
;
/// 已绑定蓝牙设备名称
final
String
?
boundBluetoothDeviceName
;
/// 蓝牙连接状态
final
BluetoothConnectionStatus
bluetoothConnectionStatus
;
/// 蓝牙状态提示
final
String
?
bluetoothMessage
;
/// 最近收到的蓝牙原始 Hex 数据
final
String
?
latestBluetoothRawHex
;
/// 最近解析出的 MCU 上报数据
final
McuReport
?
latestMcuReport
;
const
MonitoringIndexState
({
const
MonitoringIndexState
({
this
.
status
=
MonitoringIndexStatus
.
initial
,
this
.
status
=
MonitoringIndexStatus
.
initial
,
this
.
isLoading
=
false
,
this
.
isLoading
=
false
,
...
@@ -43,6 +74,16 @@ class MonitoringIndexState extends Equatable {
...
@@ -43,6 +74,16 @@ class MonitoringIndexState extends Equatable {
this
.
videoStreamMode
=
VideoStreamMode
.
p2p
,
this
.
videoStreamMode
=
VideoStreamMode
.
p2p
,
this
.
isSwitchingMode
=
false
,
this
.
isSwitchingMode
=
false
,
this
.
isP2pConnected
=
false
,
this
.
isP2pConnected
=
false
,
this
.
isBluetoothScanning
=
false
,
this
.
isBluetoothBinding
=
false
,
this
.
bindingBluetoothDeviceId
=
''
,
this
.
bluetoothDevices
=
const
[],
this
.
boundBluetoothDeviceId
,
this
.
boundBluetoothDeviceName
,
this
.
bluetoothConnectionStatus
=
BluetoothConnectionStatus
.
disconnected
,
this
.
bluetoothMessage
,
this
.
latestBluetoothRawHex
,
this
.
latestMcuReport
,
});
});
MonitoringIndexState
copyWith
({
MonitoringIndexState
copyWith
({
...
@@ -57,6 +98,18 @@ class MonitoringIndexState extends Equatable {
...
@@ -57,6 +98,18 @@ class MonitoringIndexState extends Equatable {
VideoStreamMode
?
videoStreamMode
,
VideoStreamMode
?
videoStreamMode
,
bool
?
isSwitchingMode
,
bool
?
isSwitchingMode
,
bool
?
isP2pConnected
,
bool
?
isP2pConnected
,
bool
?
isBluetoothScanning
,
bool
?
isBluetoothBinding
,
String
?
bindingBluetoothDeviceId
,
List
<
BluetoothScanDevice
>?
bluetoothDevices
,
String
?
boundBluetoothDeviceId
,
String
?
boundBluetoothDeviceName
,
BluetoothConnectionStatus
?
bluetoothConnectionStatus
,
String
?
bluetoothMessage
,
String
?
latestBluetoothRawHex
,
McuReport
?
latestMcuReport
,
bool
clearBoundBluetoothDevice
=
false
,
bool
clearLatestMcuReport
=
false
,
})
{
})
{
return
MonitoringIndexState
(
return
MonitoringIndexState
(
status:
status
??
this
.
status
,
status:
status
??
this
.
status
,
...
@@ -66,11 +119,28 @@ class MonitoringIndexState extends Equatable {
...
@@ -66,11 +119,28 @@ class MonitoringIndexState extends Equatable {
patientInfo:
patientInfo
??
this
.
patientInfo
,
patientInfo:
patientInfo
??
this
.
patientInfo
,
alerts:
alerts
??
this
.
alerts
,
alerts:
alerts
??
this
.
alerts
,
menuItems:
menuItems
??
this
.
menuItems
,
menuItems:
menuItems
??
this
.
menuItems
,
videoConnectionState:
videoConnectionState:
videoConnectionState
??
this
.
videoConnectionState
,
videoConnectionState
??
this
.
videoConnectionState
,
videoStreamMode:
videoStreamMode
??
this
.
videoStreamMode
,
videoStreamMode:
videoStreamMode
??
this
.
videoStreamMode
,
isSwitchingMode:
isSwitchingMode
??
this
.
isSwitchingMode
,
isSwitchingMode:
isSwitchingMode
??
this
.
isSwitchingMode
,
isP2pConnected:
isP2pConnected
??
this
.
isP2pConnected
,
isP2pConnected:
isP2pConnected
??
this
.
isP2pConnected
,
isBluetoothScanning:
isBluetoothScanning
??
this
.
isBluetoothScanning
,
isBluetoothBinding:
isBluetoothBinding
??
this
.
isBluetoothBinding
,
bindingBluetoothDeviceId:
bindingBluetoothDeviceId
??
this
.
bindingBluetoothDeviceId
,
bluetoothDevices:
bluetoothDevices
??
this
.
bluetoothDevices
,
boundBluetoothDeviceId:
clearBoundBluetoothDevice
?
null
:
boundBluetoothDeviceId
??
this
.
boundBluetoothDeviceId
,
boundBluetoothDeviceName:
clearBoundBluetoothDevice
?
null
:
boundBluetoothDeviceName
??
this
.
boundBluetoothDeviceName
,
bluetoothConnectionStatus:
bluetoothConnectionStatus
??
this
.
bluetoothConnectionStatus
,
bluetoothMessage:
bluetoothMessage
??
this
.
bluetoothMessage
,
latestBluetoothRawHex:
latestBluetoothRawHex
??
this
.
latestBluetoothRawHex
,
latestMcuReport:
clearLatestMcuReport
?
null
:
latestMcuReport
??
this
.
latestMcuReport
,
);
);
}
}
...
@@ -87,5 +157,15 @@ class MonitoringIndexState extends Equatable {
...
@@ -87,5 +157,15 @@ class MonitoringIndexState extends Equatable {
videoStreamMode
,
videoStreamMode
,
isSwitchingMode
,
isSwitchingMode
,
isP2pConnected
,
isP2pConnected
,
isBluetoothScanning
,
isBluetoothBinding
,
bindingBluetoothDeviceId
,
bluetoothDevices
,
boundBluetoothDeviceId
,
boundBluetoothDeviceName
,
bluetoothConnectionStatus
,
bluetoothMessage
,
latestBluetoothRawHex
,
latestMcuReport
,
];
];
}
}
lib/views/monitoring/index/monitoring_index_view.dart
View file @
192f8476
...
@@ -7,6 +7,7 @@ import 'package:laki_icu_app/models/bo/monitoring_bo.dart';
...
@@ -7,6 +7,7 @@ import 'package:laki_icu_app/models/bo/monitoring_bo.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/monitoring_alert_card.dart'
;
import
'widgets/monitoring_alert_card.dart'
;
import
'widgets/monitoring_bottom_menu.dart'
;
import
'widgets/monitoring_bottom_menu.dart'
;
import
'widgets/monitoring_metric_card.dart'
;
import
'widgets/monitoring_metric_card.dart'
;
...
@@ -95,24 +96,25 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -95,24 +96,25 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
Container
(
Container
(
height:
topHeight
.
clamp
(
80.0
,
104.0
),
height:
topHeight
.
clamp
(
80.0
,
104.0
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)),
),
child:
MonitoringTopStatusBar
(
child:
const
MonitoringTopStatusBar
(),
isBluetoothBound:
state
.
boundBluetoothDeviceId
?.
isNotEmpty
==
true
,
onBluetoothTap:
_showBluetoothDialog
,
),
),
),
Expanded
(
Expanded
(
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
zero
,
padding:
EdgeInsets
.
zero
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)),
),
child:
_buildMainArea
(
state
,
gap
),
child:
_buildMainArea
(
state
,
gap
),
),
),
),
),
Container
(
Container
(
height:
bottomHeight
.
clamp
(
92.0
,
134.0
),
height:
bottomHeight
.
clamp
(
92.0
,
134.0
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)),
),
child:
MonitoringBottomMenu
(
menuItems:
state
.
menuItems
),
child:
MonitoringBottomMenu
(
menuItems:
state
.
menuItems
),
),
),
],
],
...
@@ -142,7 +144,6 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -142,7 +144,6 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
child:
_buildMetrics
(
state
.
metrics
,
gap
),
child:
_buildMetrics
(
state
.
metrics
,
gap
),
),
),
// SizedBox(width: gap),
// SizedBox(width: gap),
],
],
),
),
),
),
...
@@ -190,8 +191,7 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -190,8 +191,7 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
zero
,
padding:
EdgeInsets
.
zero
,
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)
border:
BoxBorder
.
all
(
width:
1
.
w
,
color:
Colors
.
red
)),
),
// padding: EdgeInsets.only(
// padding: EdgeInsets.only(
// right: metric == displayMetrics.last ? 0 : gap,
// right: metric == displayMetrics.last ? 0 : gap,
// ),
// ),
...
@@ -213,6 +213,16 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
...
@@ -213,6 +213,16 @@ class _MonitoringIndexContentState extends State<MonitoringIndexContent> {
cubit
.
switchStreamMode
(
nextMode
);
cubit
.
switchStreamMode
(
nextMode
);
}
}
void
_showBluetoothDialog
()
{
showDialog
<
void
>(
context:
context
,
builder:
(
_
)
=>
BlocProvider
.
value
(
value:
_monitoringIndexCubit
,
child:
const
BluetoothBindDialog
(),
),
);
}
List
<
MonitoringMetricBO
>
_environmentMetrics
(
List
<
MonitoringMetricBO
>
_environmentMetrics
(
List
<
MonitoringMetricBO
>
metrics
)
{
List
<
MonitoringMetricBO
>
metrics
)
{
final
matched
=
metrics
final
matched
=
metrics
...
...
lib/views/monitoring/index/widgets/bluetooth_bind_dialog.dart
0 → 100644
View file @
192f8476
This diff is collapsed.
Click to expand it.
lib/views/monitoring/index/widgets/monitoring_top_status_bar.dart
View file @
192f8476
...
@@ -2,7 +2,14 @@ import 'package:flutter/material.dart';
...
@@ -2,7 +2,14 @@ import 'package:flutter/material.dart';
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
import
'package:flutter_screenutil/flutter_screenutil.dart'
;
class
MonitoringTopStatusBar
extends
StatelessWidget
{
class
MonitoringTopStatusBar
extends
StatelessWidget
{
const
MonitoringTopStatusBar
({
super
.
key
});
const
MonitoringTopStatusBar
({
super
.
key
,
this
.
isBluetoothBound
=
false
,
this
.
onBluetoothTap
,
});
final
bool
isBluetoothBound
;
final
VoidCallback
?
onBluetoothTap
;
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
...
@@ -13,15 +20,15 @@ class MonitoringTopStatusBar extends StatelessWidget {
...
@@ -13,15 +20,15 @@ class MonitoringTopStatusBar extends StatelessWidget {
fit:
BoxFit
.
fill
,
fit:
BoxFit
.
fill
,
),
),
),
),
padding:
EdgeInsets
.
only
(
left:
20
.
w
,
bottom:
22
.
h
),
padding:
EdgeInsets
.
only
(
left:
20
.
w
,
right:
20
.
w
,
bottom:
22
.
h
),
child:
Row
(
child:
Row
(
children:
[
children:
[
// SizedBox(width: 18.w),
// SizedBox(width: 18.w),
Text
(
Text
(
'总运行时长:9999h'
,
'总运行时长:9999h'
,
style:
TextStyle
(
style:
TextStyle
(
color:
Colors
.
white
,
color:
Colors
.
white
,
fontSize:
16
.
sp
,
fontSize:
16
.
sp
,
),
),
),
),
SizedBox
(
width:
8
.
w
),
SizedBox
(
width:
8
.
w
),
...
@@ -29,7 +36,7 @@ class MonitoringTopStatusBar extends StatelessWidget {
...
@@ -29,7 +36,7 @@ class MonitoringTopStatusBar extends StatelessWidget {
'环境温度:30.68'
,
'环境温度:30.68'
,
style:
TextStyle
(
style:
TextStyle
(
color:
Colors
.
white
,
color:
Colors
.
white
,
fontSize:
16
.
sp
,
fontSize:
16
.
sp
,
),
),
),
),
SizedBox
(
width:
8
.
w
),
SizedBox
(
width:
8
.
w
),
...
@@ -37,14 +44,64 @@ class MonitoringTopStatusBar extends StatelessWidget {
...
@@ -37,14 +44,64 @@ class MonitoringTopStatusBar extends StatelessWidget {
'总制氧时长:500h'
,
'总制氧时长:500h'
,
style:
TextStyle
(
style:
TextStyle
(
color:
Colors
.
white
,
color:
Colors
.
white
,
fontSize:
16
.
sp
,
fontSize:
16
.
sp
,
),
),
),
),
// const Spacer(),
const
Spacer
(),
_BluetoothStatusButton
(
isActive:
isBluetoothBound
,
onTap:
onBluetoothTap
,
),
],
],
),
),
);
);
}
}
}
class
_BluetoothStatusButton
extends
StatelessWidget
{
const
_BluetoothStatusButton
({
required
this
.
isActive
,
required
this
.
onTap
,
});
final
bool
isActive
;
final
VoidCallback
?
onTap
;
@override
Widget
build
(
BuildContext
context
)
{
final
foregroundColor
=
isActive
?
const
Color
(
0xFF003A8C
)
:
Colors
.
white
;
final
backgroundColor
=
isActive
?
const
Color
(
0xFF00F6FF
)
:
Colors
.
white
.
withValues
(
alpha:
0.08
);
final
borderColor
=
isActive
?
const
Color
(
0xFFB8FFFF
)
:
Colors
.
white24
;
return
InkWell
(
onTap:
onTap
,
borderRadius:
BorderRadius
.
circular
(
18
.
r
),
child:
Container
(
height:
34
.
h
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
12
.
w
),
decoration:
BoxDecoration
(
color:
backgroundColor
,
border:
Border
.
all
(
color:
borderColor
,
width:
1
),
borderRadius:
BorderRadius
.
circular
(
18
.
r
),
),
child:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Icon
(
Icons
.
bluetooth
,
color:
foregroundColor
,
size:
18
.
w
),
SizedBox
(
width:
6
.
w
),
Text
(
'TSAAS'
,
style:
TextStyle
(
color:
foregroundColor
,
fontSize:
14
.
sp
,
fontWeight:
isActive
?
FontWeight
.
w700
:
FontWeight
.
w400
,
),
),
],
),
),
);
}
}
}
pubspec.yaml
View file @
192f8476
...
@@ -59,6 +59,7 @@ dependencies:
...
@@ -59,6 +59,7 @@ dependencies:
path
:
./plugins/vsdk
path
:
./plugins/vsdk
flutter_reactive_ble
:
^5.5.0
flutter_reactive_ble
:
^5.5.0
mqtt_client
:
^10.5.1
mqtt_client
:
^10.5.1
marionette_flutter
:
^0.5.0
dev_dependencies
:
dev_dependencies
:
flutter_test
:
flutter_test
:
sdk
:
flutter
sdk
:
flutter
...
...
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