exam_boold_oxygen.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vnote_device_plugin/consts/types.dart';
  4. import 'package:vnote_device_plugin/devices/sp_o2.dart';
  5. import 'package:vnote_device_plugin/models/exams/sp_o2.dart';
  6. import 'package:vitalapp/managers/interfaces/models/device.dart';
  7. import 'package:vitalapp/managers/interfaces/permission.dart';
  8. import 'package:vitalapp/pages/check/widgets/device_controller.dart';
  9. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_card.dart';
  10. import 'package:vitalapp/pages/medical/models/worker.dart';
  11. import 'package:vitalapp/pages/medical/widgets/device_status.dart';
  12. // ignore: must_be_immutable
  13. class ExamBloodOxygen extends StatefulWidget {
  14. ExamBloodOxygen({
  15. super.key,
  16. required this.currentValue,
  17. required this.bloodOxygenInput,
  18. });
  19. Map<String, dynamic> currentValue;
  20. Function(Map<String, dynamic>) bloodOxygenInput;
  21. @override
  22. State<ExamBloodOxygen> createState() => _ExamBloodOxygenState();
  23. }
  24. class _ExamBloodOxygenState extends State<ExamBloodOxygen> {
  25. var permissionManager = Get.find<IPermissionManager>();
  26. final controller = Get.find<DeviceController>();
  27. late SpO2DeviceWorker worker;
  28. bool isAccessTypeAuth = false;
  29. late WorkerStatus connectStatus = WorkerStatus.connecting;
  30. late String pulse = widget.currentValue['Pulse_Frequency'] ?? '0';
  31. late String spO2 = widget.currentValue['Spo2'] ?? '0';
  32. @override
  33. void initState() {
  34. getPermission();
  35. currentDevice();
  36. super.initState();
  37. }
  38. Future<void> currentDevice() async {
  39. DeviceModel? device = await controller.getDevice(DeviceTypes.SPO2);
  40. isAccessTypeAuth = await controller.isAccessTypeAuth(DeviceTypes.SPO2);
  41. if (device == null) {
  42. connectStatus = WorkerStatus.unboundDevice;
  43. setState(() {});
  44. return;
  45. }
  46. worker = SpO2DeviceWorker(
  47. mac: device.mac,
  48. model: device.model,
  49. );
  50. loadListeners();
  51. }
  52. Future<void> connect() async {
  53. setState(() {});
  54. await worker.connect();
  55. }
  56. void loadListeners() {
  57. worker.valueUpdateEvent.addListener(_onSuccess);
  58. worker.connectErrorEvent.addListener(_onConnectFail);
  59. worker.connectedEvent.addListener(_onConnectSuccess);
  60. worker.connect();
  61. }
  62. Future<void> disconnect() async {
  63. worker.connectErrorEvent.removeListener(_onConnectFail);
  64. worker.connectedEvent.removeListener(_onConnectSuccess);
  65. worker.valueUpdateEvent.removeListener(_onSuccess);
  66. worker.disconnectedEvent.removeListener(_onDisconnected);
  67. await worker.disconnect();
  68. }
  69. @override
  70. void dispose() {
  71. disconnect();
  72. super.dispose();
  73. }
  74. void _onSuccess(_, SpO2ExamValue e) {
  75. setState(() {
  76. pulse = e.pulse.toString();
  77. spO2 = e.spO2.toString();
  78. // connectFailState = false;
  79. // connectSuccessState = false;
  80. widget.bloodOxygenInput.call({
  81. 'Spo2': spO2,
  82. 'Pulse_Frequency': pulse,
  83. });
  84. widget.currentValue = {
  85. 'Spo2': spO2,
  86. 'Pulse_Frequency': pulse,
  87. };
  88. connectStatus = WorkerStatus.connected;
  89. // disconnect();
  90. });
  91. }
  92. void _onConnectFail(sender, e) {
  93. print('连接设备失败');
  94. connectStatus = WorkerStatus.connectionFailed;
  95. setState(() {});
  96. }
  97. void _onConnectSuccess(sender, e) {
  98. connectStatus = WorkerStatus.connected;
  99. setState(() {});
  100. }
  101. void _onDisconnected(sender, e) {
  102. print('设备连接中断');
  103. connectStatus = WorkerStatus.disconnected;
  104. setState(() {});
  105. }
  106. Future<void> getPermission() async {
  107. await permissionManager.requestLocationPermission();
  108. await permissionManager.requestBluetoothConnectPermission();
  109. await permissionManager.requestBluetoothAdvertisePermission();
  110. await permissionManager.requestBluetoothScanPermission();
  111. }
  112. @override
  113. Widget build(BuildContext context) {
  114. return Stack(
  115. children: [
  116. ExamCard(
  117. // clickCard: () {},
  118. content: Column(
  119. mainAxisAlignment: MainAxisAlignment.start,
  120. children: [
  121. const SizedBox(
  122. height: 40,
  123. ),
  124. _SideBar(
  125. title: '血氧饱和度',
  126. value: spO2,
  127. unit: '%',
  128. ),
  129. const Divider(indent: 30),
  130. const SizedBox(
  131. height: 32,
  132. ),
  133. _SideBar(
  134. title: '脉率',
  135. value: pulse,
  136. unit: 'bpm',
  137. ),
  138. ],
  139. )),
  140. if (isAccessTypeAuth) DeviceStatus(connectStatus: connectStatus),
  141. ],
  142. );
  143. }
  144. }
  145. class _SideBar extends StatelessWidget {
  146. final String title;
  147. final String value;
  148. final String unit;
  149. const _SideBar({
  150. required this.title,
  151. required this.value,
  152. required this.unit,
  153. });
  154. @override
  155. Widget build(BuildContext context) {
  156. return Row(
  157. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  158. crossAxisAlignment: CrossAxisAlignment.start,
  159. children: [
  160. Container(
  161. padding: const EdgeInsets.symmetric(horizontal: 30),
  162. child: Text(
  163. title,
  164. style: const TextStyle(
  165. fontSize: 25,
  166. ),
  167. ),
  168. ),
  169. Container(
  170. alignment: Alignment.bottomRight,
  171. padding: const EdgeInsets.only(
  172. bottom: 20,
  173. right: 30,
  174. left: 40,
  175. ),
  176. child: FittedBox(
  177. child: Row(
  178. mainAxisAlignment: MainAxisAlignment.end,
  179. crossAxisAlignment: CrossAxisAlignment.end,
  180. children: [
  181. RichText(
  182. text: TextSpan(
  183. text: value,
  184. style: const TextStyle(
  185. fontSize: 80,
  186. color: Colors.black,
  187. ),
  188. children: [
  189. TextSpan(
  190. text: unit,
  191. style: const TextStyle(fontSize: 25),
  192. )
  193. ],
  194. ),
  195. ),
  196. ],
  197. ),
  198. ),
  199. ),
  200. ],
  201. );
  202. }
  203. }