bool_oxygen.dart 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/architecture/app_parameters.dart';
  4. import 'package:vitalapp/components/dialog_number.dart';
  5. import 'package:vitalapp/managers/device_controller_manager.dart';
  6. import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
  7. import 'package:vnote_device_plugin/consts/types.dart';
  8. import 'package:vnote_device_plugin/devices/sp_o2.dart';
  9. import 'package:vnote_device_plugin/models/exams/sp_o2.dart';
  10. import 'package:vitalapp/pages/medical/widgets/exam_card.dart';
  11. import 'package:vitalapp/pages/medical/controller.dart';
  12. import 'package:vitalapp/pages/medical/models/worker.dart';
  13. import 'package:vitalapp/pages/medical/widgets/device_status.dart';
  14. import 'package:vitalapp/pages/medical/widgets/side_bar.dart';
  15. import 'package:fis_common/logger/logger.dart';
  16. class BloodOxygen extends StatefulWidget {
  17. const BloodOxygen({Key? key}) : super(key: key);
  18. @override
  19. State<BloodOxygen> createState() => _ExamBloodOxygenState();
  20. }
  21. class _ExamBloodOxygenState extends State<BloodOxygen> {
  22. final controller = Get.find<MedicalController>();
  23. bool get isPureSoftwareMode => AppParameters.data.isPureSoftwareMode;
  24. DeviceControllerManager? spo2;
  25. SpO2DeviceWorker? worker;
  26. String pulse = '';
  27. String spO2 = '';
  28. bool isConnectFail = false;
  29. int errorCount = 0;
  30. WorkerStatus _connectStatus = WorkerStatus.connecting;
  31. @override
  32. void initState() {
  33. super.initState();
  34. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  35. initOxygen();
  36. });
  37. }
  38. @override
  39. void dispose() {
  40. spo2?.dispose();
  41. spo2 = null;
  42. releaseListeners();
  43. disconnect();
  44. worker?.dispose();
  45. super.dispose();
  46. }
  47. Future<void> initOxygen() async {
  48. await currentDevice();
  49. await initData();
  50. }
  51. Future<void> currentDevice() async {
  52. try {
  53. final device = await controller.getDevice(DeviceTypes.SPO2);
  54. if (device == null) {
  55. _connectStatus = WorkerStatus.unboundDevice;
  56. setState(() {});
  57. worker = null;
  58. return;
  59. }
  60. spo2 =
  61. DeviceControllerManager(DeviceTypes.SPO2, device.model, device.mac);
  62. worker = spo2!.worker as SpO2DeviceWorker;
  63. _connectStatus = spo2!.connectStatus;
  64. loadListeners();
  65. connect();
  66. } catch (e) {}
  67. }
  68. Future<void> initData() async {
  69. setState(() {
  70. pulse = controller.diagnosisDataValue['SpO2']?['Pulse_Frequency'] ?? '';
  71. spO2 = controller.diagnosisDataValue['SpO2']?['Spo2'] ?? '';
  72. logger.i('_ExamBloodSugarState initData pulse:$pulse spO2:$spo2');
  73. });
  74. /// 体检系统 基础检查的特殊处理
  75. if (controller.diagnosisDataValue['Pulse_Frequency'] != null ||
  76. controller.diagnosisDataValue['Spo2'] != null) {
  77. pulse = controller.diagnosisDataValue['Pulse_Frequency'] ?? '';
  78. spO2 = controller.diagnosisDataValue['Spo2'] ?? '';
  79. logger.i('_ExamBloodSugarState initData pulse:$pulse spO2:$spo2');
  80. setState(() {});
  81. return;
  82. }
  83. }
  84. void loadListeners() {
  85. worker!.valueUpdateEvent.addListener(_onSuccess);
  86. worker!.connectErrorEvent.addListener(_onConnectFail);
  87. worker!.connectedEvent.addListener(_onConnectSuccess);
  88. worker!.disconnectedEvent.addListener(_onDisconnected);
  89. }
  90. void releaseListeners() {
  91. worker!.connectErrorEvent.removeListener(_onConnectFail);
  92. worker!.connectedEvent.removeListener(_onConnectSuccess);
  93. worker!.valueUpdateEvent.removeListener(_onSuccess);
  94. worker!.disconnectedEvent.removeListener(_onDisconnected);
  95. }
  96. Future<void> disconnect() async {
  97. if (worker != null) {
  98. await worker!.disconnect();
  99. }
  100. }
  101. Future<void> connect() async {
  102. if (worker != null) {
  103. await worker!.connect();
  104. }
  105. }
  106. /// 尝试重连
  107. Future<void> tryReconnect() async {
  108. if (worker != null) {
  109. await disconnect();
  110. await connect();
  111. }
  112. }
  113. void _onSuccess(_, SpO2ExamValue e) {
  114. setState(() {
  115. pulse = e.pulse.toString();
  116. spO2 = e.spO2.toString();
  117. controller.diagnosisDataValue['SpO2'] = {
  118. 'Pulse_Frequency': pulse,
  119. 'Spo2': spO2
  120. };
  121. controller.saveCachedRecord();
  122. _connectStatus = WorkerStatus.connected;
  123. });
  124. }
  125. void _onConnectFail(sender, e) {
  126. logger.i("连接设备失败:${worker!.mac}");
  127. if (errorCount < 3) {
  128. errorCount++;
  129. tryReconnect();
  130. } else {
  131. isConnectFail = true;
  132. }
  133. _connectStatus = WorkerStatus.connectionFailed;
  134. setState(() {});
  135. }
  136. void _onConnectSuccess(sender, e) {
  137. logger.i("设备连接成功:${worker!.mac}");
  138. _connectStatus = WorkerStatus.connected;
  139. errorCount = 0;
  140. isConnectFail = false;
  141. setState(() {});
  142. }
  143. void _onDisconnected(sender, e) {
  144. print('设备连接中断');
  145. logger.i("设备连接中断:${worker!.mac}");
  146. tryReconnect();
  147. errorCount = 0;
  148. _connectStatus = WorkerStatus.disconnected;
  149. setState(() {});
  150. }
  151. Future<void> _inputOxygen(String title) async {
  152. final result = await VDialogNumber(
  153. title: title,
  154. initialValue: spO2,
  155. ).show();
  156. if (result?.isNotEmpty ?? false) {
  157. spO2 = result ?? '';
  158. controller.diagnosisDataValue['SpO2'] = {
  159. 'Pulse_Frequency': pulse,
  160. 'Spo2': spO2
  161. };
  162. controller.saveCachedRecord();
  163. }
  164. setState(() {});
  165. }
  166. Future<void> _inputOxygen1(String title) async {
  167. final result = await VDialogNumber(
  168. title: title,
  169. initialValue: pulse,
  170. ).show();
  171. if (result?.isNotEmpty ?? false) {
  172. pulse = result ?? '';
  173. }
  174. controller.diagnosisDataValue['SpO2'] = {
  175. 'Pulse_Frequency': pulse,
  176. 'Spo2': spO2
  177. };
  178. controller.saveCachedRecord();
  179. setState(() {});
  180. }
  181. /// 需要封装一下
  182. Widget _buildErrorButton() {
  183. return DeviceStatusPosition(
  184. deviceStatus: Row(
  185. children: [
  186. const Text(
  187. '请确认设备是否启动',
  188. style: TextStyle(fontSize: 24, color: Colors.red),
  189. ),
  190. IconButton(
  191. onPressed: () {
  192. tryReconnect();
  193. setState(() {
  194. _connectStatus = WorkerStatus.connecting;
  195. isConnectFail = false;
  196. });
  197. },
  198. icon: const Icon(Icons.refresh),
  199. iconSize: 32,
  200. ),
  201. ],
  202. ),
  203. );
  204. }
  205. @override
  206. Widget build(BuildContext context) {
  207. return Stack(
  208. children: [
  209. ExamCard(
  210. content: Column(
  211. mainAxisAlignment: MainAxisAlignment.start,
  212. children: [
  213. SideBar(
  214. title: '血氧饱和度',
  215. value: spO2 == '0' ? '--' : spO2,
  216. unit: '%',
  217. onTap: () async {
  218. await _inputOxygen('血氧饱和度');
  219. },
  220. ),
  221. const Divider(indent: 30),
  222. SideBar(
  223. title: '脉率',
  224. value: pulse == '0' ? '--' : pulse,
  225. unit: 'bpm',
  226. onTap: () async {
  227. await _inputOxygen1('脉率');
  228. },
  229. ),
  230. ],
  231. ),
  232. ),
  233. if (!isPureSoftwareMode) ...[
  234. if (!isConnectFail)
  235. DeviceStatusPosition(
  236. deviceStatus: DeviceStatus(connectStatus: _connectStatus),
  237. )
  238. else
  239. _buildErrorButton(),
  240. ],
  241. ],
  242. );
  243. }
  244. }