|
@@ -12,8 +12,9 @@ import 'package:vitalapp/pages/medical/controller.dart';
|
|
|
import 'package:vitalapp/pages/medical/models/worker.dart';
|
|
|
import 'package:vitalapp/pages/medical/widgets/device_status.dart';
|
|
|
import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
|
|
|
-import 'package:vitalapp/pages/medical/widgets/ecg_view/index.dart';
|
|
|
import 'package:vitalapp/pages/medical/widgets/side_bar.dart';
|
|
|
+import 'package:vitalapp/pages/medical/widgets/twelve_ecg_view/controller.dart';
|
|
|
+import 'package:vitalapp/pages/medical/widgets/twelve_ecg_view/view.dart';
|
|
|
import 'package:vnote_device_plugin/consts/types.dart';
|
|
|
import 'package:http/http.dart' as http;
|
|
|
import 'package:vnote_device_plugin/devices/twelve_heart.dart';
|
|
@@ -58,117 +59,146 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
children: [
|
|
|
ExamCard(
|
|
|
titleText: const SizedBox(),
|
|
|
- bottomPadding: 10,
|
|
|
- content: Column(
|
|
|
- mainAxisAlignment: MainAxisAlignment.start,
|
|
|
- children: [
|
|
|
- Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.end,
|
|
|
- children: [
|
|
|
- const SideBar(
|
|
|
- title: '心率',
|
|
|
- value: '',
|
|
|
- unit: '',
|
|
|
- ),
|
|
|
- const Expanded(child: SizedBox()),
|
|
|
- Text(
|
|
|
- _heart.isEmpty ? '--' : _heart,
|
|
|
- style: const TextStyle(
|
|
|
- fontSize: 60,
|
|
|
- color: Colors.black,
|
|
|
- ),
|
|
|
- ),
|
|
|
- const Text(
|
|
|
- " bpm",
|
|
|
- style: TextStyle(fontSize: 25),
|
|
|
- ),
|
|
|
- const SizedBox(
|
|
|
- width: 15,
|
|
|
- )
|
|
|
- ],
|
|
|
- ),
|
|
|
- if (_deviceError.isNotEmpty)
|
|
|
+ // bottomPadding: 10,
|
|
|
+ content: SizedBox(
|
|
|
+ height: 620,
|
|
|
+ // margin: const EdgeInsets.only(bottom: 10),
|
|
|
+ child: Column(
|
|
|
+ children: [
|
|
|
Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ mainAxisAlignment: MainAxisAlignment.end,
|
|
|
children: [
|
|
|
- Container(
|
|
|
- padding: const EdgeInsets.symmetric(
|
|
|
- horizontal: 30,
|
|
|
- ),
|
|
|
- child: const Text(
|
|
|
- '心率测量出错',
|
|
|
- style: TextStyle(
|
|
|
- fontSize: 25,
|
|
|
- ),
|
|
|
- ),
|
|
|
+ const SideBar(
|
|
|
+ title: '心率',
|
|
|
+ value: '',
|
|
|
+ unit: '',
|
|
|
),
|
|
|
- Container(
|
|
|
- padding: const EdgeInsets.symmetric(
|
|
|
- horizontal: 50,
|
|
|
- ),
|
|
|
- child: Text(
|
|
|
- _deviceError,
|
|
|
- style: const TextStyle(
|
|
|
- fontSize: 24,
|
|
|
- ),
|
|
|
+ const Expanded(child: SizedBox()),
|
|
|
+ Text(
|
|
|
+ _heart.isEmpty ? '--' : _heart,
|
|
|
+ style: const TextStyle(
|
|
|
+ fontSize: 60,
|
|
|
+ color: Colors.black,
|
|
|
),
|
|
|
),
|
|
|
+ const Text(
|
|
|
+ " bpm",
|
|
|
+ style: TextStyle(fontSize: 25),
|
|
|
+ ),
|
|
|
+ const SizedBox(
|
|
|
+ width: 15,
|
|
|
+ )
|
|
|
],
|
|
|
),
|
|
|
- if (_assess.isNotEmpty)
|
|
|
- Row(
|
|
|
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
- children: [
|
|
|
- Container(
|
|
|
- padding: const EdgeInsets.symmetric(
|
|
|
- horizontal: 30,
|
|
|
- ),
|
|
|
- child: const Text(
|
|
|
- '心率评估',
|
|
|
- style: TextStyle(
|
|
|
- fontSize: 25,
|
|
|
- ),
|
|
|
+ // if (_deviceError.isNotEmpty)
|
|
|
+ // Row(
|
|
|
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ // crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ // children: [
|
|
|
+ // Container(
|
|
|
+ // padding: const EdgeInsets.symmetric(
|
|
|
+ // horizontal: 30,
|
|
|
+ // ),
|
|
|
+ // child: const Text(
|
|
|
+ // '心率测量出错',
|
|
|
+ // style: TextStyle(
|
|
|
+ // fontSize: 25,
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // Container(
|
|
|
+ // padding: const EdgeInsets.symmetric(
|
|
|
+ // horizontal: 50,
|
|
|
+ // ),
|
|
|
+ // child: Text(
|
|
|
+ // _deviceError,
|
|
|
+ // style: const TextStyle(
|
|
|
+ // fontSize: 24,
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // ],
|
|
|
+ // ),
|
|
|
+ // if (_assess.isNotEmpty)
|
|
|
+ // Row(
|
|
|
+ // mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
+ // crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ // children: [
|
|
|
+ // Container(
|
|
|
+ // padding: const EdgeInsets.symmetric(
|
|
|
+ // horizontal: 30,
|
|
|
+ // ),
|
|
|
+ // child: const Text(
|
|
|
+ // '心率评估',
|
|
|
+ // style: TextStyle(
|
|
|
+ // fontSize: 25,
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // Container(
|
|
|
+ // padding: const EdgeInsets.only(
|
|
|
+ // right: 15,
|
|
|
+ // ),
|
|
|
+ // child: Text(
|
|
|
+ // dataConvertManager.heartRateConversion(
|
|
|
+ // int.parse(TwelveheartRate.toString())),
|
|
|
+ // style: const TextStyle(
|
|
|
+ // fontSize: 24,
|
|
|
+ // fontWeight: FontWeight.bold,
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ // ],
|
|
|
+ // ),
|
|
|
+ // const SizedBox(
|
|
|
+ // height: 10,
|
|
|
+ // ),
|
|
|
+ // Expanded(
|
|
|
+ // child: SizedBox(
|
|
|
+ // height: 900,
|
|
|
+ // child: LayoutBuilder(builder: (context, constraints) {
|
|
|
+ // if (initEcgData == null) {
|
|
|
+ // return Container();
|
|
|
+ // } else {
|
|
|
+ // return TwelveEcgView(
|
|
|
+ // width: constraints.maxWidth,
|
|
|
+ // height: constraints.maxHeight,
|
|
|
+ // initData: initEcgData!,
|
|
|
+ // currentIndex: 0,
|
|
|
+ // );
|
|
|
+ // }
|
|
|
+ // }),
|
|
|
+ // ),
|
|
|
+ // ),
|
|
|
+ Expanded(
|
|
|
+ child: ListView(
|
|
|
+ shrinkWrap: true,
|
|
|
+ children: [
|
|
|
+ SizedBox(
|
|
|
+ height: 450,
|
|
|
+ child: LayoutBuilder(builder: (context, constraints) {
|
|
|
+ if (initEcgData == null) {
|
|
|
+ return Container();
|
|
|
+ } else {
|
|
|
+ return TwelveEcgView(
|
|
|
+ width: constraints.maxWidth,
|
|
|
+ height: constraints.maxHeight,
|
|
|
+ initData: initEcgData!,
|
|
|
+ currentIndex: 0,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }),
|
|
|
),
|
|
|
- ),
|
|
|
- Container(
|
|
|
- padding: const EdgeInsets.only(
|
|
|
- right: 15,
|
|
|
- ),
|
|
|
- child: Text(
|
|
|
- dataConvertManager.heartRateConversion(
|
|
|
- int.parse(TwelveheartRate.toString())),
|
|
|
- style: const TextStyle(
|
|
|
- fontSize: 24,
|
|
|
- fontWeight: FontWeight.bold,
|
|
|
- ),
|
|
|
- ),
|
|
|
- ),
|
|
|
- ],
|
|
|
+ ],
|
|
|
+ ),
|
|
|
),
|
|
|
- const SizedBox(
|
|
|
- height: 10,
|
|
|
- ),
|
|
|
- SizedBox(
|
|
|
- height: 240,
|
|
|
- child: LayoutBuilder(builder: (context, constraints) {
|
|
|
- if (initEcgData == null) {
|
|
|
- return Container();
|
|
|
- } else {
|
|
|
- return EcgView(
|
|
|
- width: constraints.maxWidth,
|
|
|
- height: constraints.maxHeight,
|
|
|
- initData: initEcgData!,
|
|
|
- );
|
|
|
- }
|
|
|
- }),
|
|
|
- ),
|
|
|
- Container(
|
|
|
- // !! 这一层 Container 不能删 ,否则会引发 EcgView 的 controller 被异常删除
|
|
|
- child: _buildResetButton(),
|
|
|
- ),
|
|
|
- ],
|
|
|
+
|
|
|
+ // Container(
|
|
|
+ // // !! 这一层 Container 不能删 ,否则会引发 TwelveEcgView 的 controller 被异常删除
|
|
|
+ // child: _buildResetButton(),
|
|
|
+ // ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
),
|
|
|
),
|
|
|
if (!isConnectFail)
|
|
@@ -280,7 +310,8 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
/// 重置数据以及心电图
|
|
|
void resetEcgView() {
|
|
|
try {
|
|
|
- EcgViewController ecgViewController = Get.find<EcgViewController>();
|
|
|
+ TwelveEcgViewController ecgViewController =
|
|
|
+ Get.find<TwelveEcgViewController>();
|
|
|
ecgPoint = [];
|
|
|
ecgViewController.reset();
|
|
|
} catch (e) {
|
|
@@ -334,7 +365,7 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
worker.disconnectedEvent.addListener(_onDisconnected);
|
|
|
// worker.hrValueUpdateEvent.addListener(_onHrValueUpdate);
|
|
|
// worker.ecgValueUpdateEvent.addListener(_onEcgValueUpdate);
|
|
|
- worker.resultReceivedEvent.addListener(_onRCesultReceived);
|
|
|
+ worker.resultReceivedEvent.addListener(_onHrValueUpdate);
|
|
|
worker.errorEvent.addListener(_onError);
|
|
|
}
|
|
|
|
|
@@ -344,7 +375,7 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
worker.disconnectedEvent.removeListener(_onDisconnected);
|
|
|
// worker.hrValueUpdateEvent.removeListener(_onHrValueUpdate);
|
|
|
// worker.ecgValueUpdateEvent.removeListener(_onEcgValueUpdate);
|
|
|
- worker.resultReceivedEvent.removeListener(_onRCesultReceived);
|
|
|
+ worker.resultReceivedEvent.removeListener(_onHrValueUpdate);
|
|
|
worker.errorEvent.removeListener(_onError);
|
|
|
}
|
|
|
|
|
@@ -407,7 +438,8 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
// 心电图数据更新
|
|
|
void _onEcgValueUpdate(_, List<int> e) {
|
|
|
try {
|
|
|
- EcgViewController ecgViewController = Get.find<EcgViewController>();
|
|
|
+ TwelveEcgViewController ecgViewController =
|
|
|
+ Get.find<TwelveEcgViewController>();
|
|
|
ecgPoint.addAll(e);
|
|
|
if (ecgPoint.length > 125 * 3) {
|
|
|
// 3s 后开始塞数据
|
|
@@ -419,8 +451,8 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
}
|
|
|
|
|
|
/// 更新心率
|
|
|
- void _onHrValueUpdate(_, int e) {
|
|
|
- logger.i('心率更新:$e');
|
|
|
+ void _onHrValueUpdate(_, TwelveHeartExamData e) {
|
|
|
+ logger.i('心率更新:${e.heartRate}');
|
|
|
|
|
|
if (_deviceError.isNotEmpty || _assess.isNotEmpty) {
|
|
|
// 如果上次因错误而停止了,这里需要先重置
|
|
@@ -428,8 +460,22 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
_assess = '';
|
|
|
resetEcgView();
|
|
|
}
|
|
|
+
|
|
|
setState(() {
|
|
|
- _heart = e.toString();
|
|
|
+ _heart = e.heartRate.toString();
|
|
|
+ try {
|
|
|
+ TwelveEcgViewController ecgViewController =
|
|
|
+ Get.find<TwelveEcgViewController>();
|
|
|
+ ecgViewController.addData(e.ecgPoints);
|
|
|
+ print('🌽🌽🌽🌽🌽🌽');
|
|
|
+ print(e.ecgPoints.length);
|
|
|
+ print('🌽🌽🌽🌽🌽🌽');
|
|
|
+ } catch (e) {
|
|
|
+ print('🥥🥥🥥🥥');
|
|
|
+ print(e);
|
|
|
+ print('🥥🥥🥥🥥');
|
|
|
+ }
|
|
|
+
|
|
|
showResetButton = false;
|
|
|
});
|
|
|
}
|
|
@@ -496,7 +542,8 @@ class _HeartRateState extends State<TwelveHeartRate> {
|
|
|
|
|
|
/// 设置最终数据
|
|
|
Future<void> setEcgData() async {
|
|
|
- EcgViewController ecgViewController = Get.find<EcgViewController>();
|
|
|
+ TwelveEcgViewController ecgViewController =
|
|
|
+ Get.find<TwelveEcgViewController>();
|
|
|
medicalController.diagnosisDataValue['Heart']?['ECG'] =
|
|
|
await ecgViewController.getFullDataImageBase64();
|
|
|
medicalController.diagnosisDataValue['Heart']?['ECG_POINT'] =
|