body_temperature.dart 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/architecture/app_parameters.dart';
  4. import 'package:vitalapp/managers/device_controller_manager.dart';
  5. import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
  6. import 'package:vnote_device_plugin/consts/types.dart';
  7. import 'package:vnote_device_plugin/devices/temp.dart';
  8. import 'package:vitalapp/components/dialog_number.dart';
  9. import 'package:vitalapp/managers/interfaces/models/device.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:fis_common/logger/logger.dart';
  15. class BodyTemperature extends StatefulWidget {
  16. const BodyTemperature({
  17. super.key,
  18. });
  19. @override
  20. State<BodyTemperature> createState() => _ExamBodyTemperatureState();
  21. }
  22. class _ExamBodyTemperatureState extends State<BodyTemperature> {
  23. bool get isPureSoftwareMode => AppParameters.data.isPureSoftwareMode;
  24. var controller = Get.find<MedicalController>();
  25. DeviceControllerManager? temp;
  26. TempDeviceWorker? worker;
  27. WorkerStatus connectStatus = WorkerStatus.connecting;
  28. bool isConnectFail = false;
  29. int errorCount = 0;
  30. ///重试机制
  31. late String _value =
  32. controller.diagnosisDataValue['Temp']?['Temperature']?.toString() ?? '';
  33. @override
  34. void initState() {
  35. WidgetsBinding.instance.addPostFrameCallback(
  36. (timeStamp) {
  37. initTemperature();
  38. currentDevice();
  39. },
  40. );
  41. super.initState();
  42. }
  43. @override
  44. void didUpdateWidget(BodyTemperature oldWidget) {
  45. setState(() {});
  46. super.didUpdateWidget(oldWidget);
  47. }
  48. Future<void> currentDevice() async {
  49. DeviceModel? device = await controller.getDevice(DeviceTypes.TEMP);
  50. if (device == null) {
  51. connectStatus = WorkerStatus.unboundDevice;
  52. worker = null;
  53. return;
  54. }
  55. temp = DeviceControllerManager(DeviceTypes.TEMP, device.model, device.mac);
  56. worker = temp!.worker as TempDeviceWorker;
  57. connectStatus = temp!.connectStatus;
  58. loadListeners();
  59. connect();
  60. }
  61. Future<void> initTemperature() async {
  62. _value =
  63. controller.diagnosisDataValue['Temp']?['Temperature'].toString() ?? '';
  64. /// 体检系统 基础检查的特殊处理
  65. if (controller.diagnosisDataValue['Temperature'] != null) {
  66. _value = controller.diagnosisDataValue['Temperature']?.toString() ?? '';
  67. logger.i('_ExamBloodSugarState initData Temperature:$_value');
  68. setState(() {});
  69. return;
  70. }
  71. logger.i('_ExamBloodSugarState initData Temperature:$_value');
  72. setState(() {});
  73. }
  74. void loadListeners() {
  75. worker!.successEvent.addListener(_onSuccess);
  76. worker!.connectErrorEvent.addListener(_onConnectFail);
  77. worker!.connectedEvent.addListener(_onConnectSuccess);
  78. worker!.disconnectedEvent.addListener(_onDisconnected);
  79. worker!.tempTooLowEvent.addListener(_onTempTooLowOrTooHeigh);
  80. worker!.tempTooHighEvent.addListener(_onTempTooLowOrTooHeigh);
  81. }
  82. Future<void> disconnect() async {
  83. if (worker != null) {
  84. await worker!.disconnect();
  85. }
  86. }
  87. Future<void> connect() async {
  88. if (worker != null) {
  89. await worker!.connect();
  90. }
  91. }
  92. void releaseListeners() {
  93. if (worker != null) {
  94. worker!.connectErrorEvent.removeListener(_onConnectFail);
  95. worker!.connectedEvent.removeListener(_onConnectSuccess);
  96. worker!.successEvent.removeListener(_onSuccess);
  97. worker!.disconnectedEvent.removeListener(_onDisconnected);
  98. worker!.tempTooLowEvent.removeListener(_onTempTooLowOrTooHeigh);
  99. worker!.tempTooHighEvent.removeListener(_onTempTooLowOrTooHeigh);
  100. }
  101. // controller.deviceCloseSuccessEvent.removeListener(_onDeviceCloseSuccess);
  102. }
  103. /// 尝试重连
  104. Future<void> tryReconnect() async {
  105. if (worker != null) {
  106. await disconnect();
  107. await connect();
  108. }
  109. }
  110. @override
  111. void dispose() {
  112. if (worker != null) {
  113. temp?.dispose();
  114. temp = null;
  115. }
  116. releaseListeners();
  117. disconnect();
  118. worker?.dispose();
  119. super.dispose();
  120. }
  121. void _onSuccess(_, double e) {
  122. setState(() {
  123. _value = e.toString();
  124. controller.diagnosisDataValue['Temp'] = {'Temperature': _value};
  125. controller.saveCachedRecord();
  126. connectStatus = WorkerStatus.connected;
  127. });
  128. }
  129. void _onTempTooLowOrTooHeigh(sender, e) {
  130. _value = e.toString();
  131. controller.diagnosisDataValue['Temp'] = {'Temperature': _value};
  132. controller.saveCachedRecord();
  133. connectStatus = WorkerStatus.connected;
  134. setState(() {});
  135. }
  136. void _onConnectFail(sender, e) {
  137. print('连接设备失败');
  138. logger.i("连接设备失败:${worker!.mac}");
  139. if (errorCount < 3) {
  140. errorCount++;
  141. tryReconnect();
  142. } else {
  143. isConnectFail = true;
  144. }
  145. connectStatus = WorkerStatus.connectionFailed;
  146. setState(() {});
  147. }
  148. void _onConnectSuccess(sender, e) {
  149. logger.i("设备连接成功:${worker!.mac}");
  150. connectStatus = WorkerStatus.connected;
  151. errorCount = 0;
  152. isConnectFail = false;
  153. setState(() {});
  154. }
  155. void _onDisconnected(sender, e) {
  156. print('设备连接中断');
  157. logger.i("设备连接中断:${worker!.mac}");
  158. errorCount = 0;
  159. tryReconnect();
  160. connectStatus = WorkerStatus.disconnected;
  161. setState(() {});
  162. }
  163. @override
  164. Widget build(BuildContext context) {
  165. return Stack(
  166. children: [
  167. _buildTemperature(),
  168. if (!isPureSoftwareMode) ...[
  169. if (!isConnectFail)
  170. DeviceStatusPosition(
  171. deviceStatus: DeviceStatus(connectStatus: connectStatus),
  172. )
  173. else
  174. _buildErrorButton(),
  175. ],
  176. ],
  177. );
  178. }
  179. Widget _buildErrorButton() {
  180. return DeviceStatusPosition(
  181. deviceStatus: Row(
  182. children: [
  183. const Text(
  184. '请确认设备是否启动',
  185. style: TextStyle(fontSize: 24, color: Colors.red),
  186. ),
  187. IconButton(
  188. onPressed: () {
  189. tryReconnect();
  190. setState(() {
  191. connectStatus = WorkerStatus.connecting;
  192. isConnectFail = false;
  193. });
  194. },
  195. icon: const Icon(Icons.refresh),
  196. iconSize: 32,
  197. ),
  198. ],
  199. ),
  200. );
  201. }
  202. Widget _buildTemperature() {
  203. return ExamCard(
  204. title: '',
  205. clickCard: () {
  206. _inputTemperature();
  207. },
  208. content: Row(
  209. children: [
  210. const SizedBox(
  211. width: 25,
  212. ),
  213. const Text(
  214. '体温',
  215. style: TextStyle(fontSize: 25),
  216. ),
  217. const Expanded(child: SizedBox()),
  218. Container(
  219. alignment: Alignment.bottomRight,
  220. height: 100,
  221. child: FittedBox(
  222. child: Row(
  223. mainAxisAlignment: MainAxisAlignment.end,
  224. crossAxisAlignment: CrossAxisAlignment.center,
  225. children: [
  226. Text(
  227. _value.isEmpty ? '--' : _value,
  228. style: const TextStyle(
  229. fontSize: 60,
  230. color: Colors.black,
  231. ),
  232. ),
  233. const Text(
  234. ' °C',
  235. style: TextStyle(fontSize: 25),
  236. ),
  237. const SizedBox(
  238. width: 30,
  239. )
  240. ],
  241. ),
  242. ),
  243. ),
  244. ],
  245. ),
  246. );
  247. }
  248. Future<void> _inputTemperature() async {
  249. String? result = await VDialogNumber(
  250. title: '体温',
  251. initialValue: _value,
  252. ).show();
  253. if (result?.isNotEmpty ?? false) {
  254. _value = result ?? '';
  255. controller.diagnosisDataValue['Temp'] = {'Temperature': _value};
  256. controller.saveCachedRecord();
  257. }
  258. setState(() {});
  259. }
  260. }