exam_blood_sugar.dart 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vnote_device_plugin/devices/sugar.dart';
  4. import 'package:vnote_device_plugin/models/exams/sugar.dart';
  5. import 'package:vnoteapp/components/alert_dialog.dart';
  6. import 'package:vnoteapp/components/button.dart';
  7. import 'package:vnoteapp/managers/interfaces/permission.dart';
  8. import 'package:vnoteapp/pages/check/models/form.dart';
  9. import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_card.dart';
  10. class ExamBloodSugar extends StatefulWidget {
  11. const ExamBloodSugar({
  12. super.key,
  13. required this.currentFormObject,
  14. required this.currentInputValue,
  15. this.specialInput,
  16. });
  17. final FormObject currentFormObject;
  18. final String currentInputValue;
  19. final Function(String value)? specialInput;
  20. @override
  21. State<ExamBloodSugar> createState() => _ExamBloodSugarState();
  22. }
  23. class _ExamBloodSugarState extends State<ExamBloodSugar> {
  24. var permissionManager = Get.find<IPermissionManager>();
  25. @override
  26. void initState() {
  27. permissionManager.requestLocationPermission();
  28. super.initState();
  29. }
  30. @override
  31. Widget build(BuildContext context) {
  32. return ExamCard(
  33. title: widget.currentFormObject.label ?? '',
  34. clickCard: () {
  35. _buildTempertureInput(widget.currentFormObject);
  36. },
  37. content: Container(
  38. alignment: Alignment.bottomRight,
  39. padding: const EdgeInsets.only(
  40. bottom: 20,
  41. right: 30,
  42. left: 40,
  43. ),
  44. constraints: const BoxConstraints(minHeight: 150),
  45. child: FittedBox(
  46. child: Row(
  47. mainAxisAlignment: MainAxisAlignment.end,
  48. crossAxisAlignment: CrossAxisAlignment.end,
  49. children: [
  50. RichText(
  51. text: TextSpan(
  52. text: widget.currentInputValue,
  53. style: const TextStyle(
  54. fontSize: 80,
  55. color: Colors.black,
  56. ),
  57. children: [
  58. TextSpan(
  59. text: widget.currentFormObject.append ?? '',
  60. style: const TextStyle(fontSize: 25),
  61. )
  62. ],
  63. ),
  64. ),
  65. ],
  66. ),
  67. ),
  68. ),
  69. );
  70. }
  71. Future<void> _buildTempertureInput(FormObject currentFormObject) async {
  72. // Future.delayed(const Duration(milliseconds: 3000), () {
  73. // specialInputController.text = generateRandomNumber().toString();
  74. // widget.specialInput?.call(specialInputController.text);
  75. // setState(() {});
  76. // });
  77. final result = await Get.dialog(
  78. BloodSugar(
  79. currentFormObject: widget.currentFormObject,
  80. bloodSugar: widget.currentInputValue,
  81. ),
  82. barrierDismissible: false,
  83. );
  84. widget.specialInput?.call(result);
  85. print(result);
  86. }
  87. }
  88. class BloodSugar extends StatefulWidget {
  89. const BloodSugar({
  90. super.key,
  91. required this.currentFormObject,
  92. this.bloodSugar,
  93. });
  94. final FormObject currentFormObject;
  95. final String? bloodSugar;
  96. @override
  97. State<BloodSugar> createState() => _BloodSugarState();
  98. }
  99. class _BloodSugarState extends State<BloodSugar> {
  100. late final SugarDeviceWorker worker = SugarDeviceWorker(
  101. mac: '60:98:66:C4:0E:51',
  102. model: 'i-sens630',
  103. );
  104. late TextEditingController specialInputController =
  105. TextEditingController(text: widget.bloodSugar ?? '00.0');
  106. bool connectFailState = false;
  107. bool connectSuccessState = false;
  108. bool isConnect = false;
  109. @override
  110. void initState() {
  111. connect();
  112. worker.successEvent.addListener(_onSuccess);
  113. worker.connectErrorEvent.addListener(_onConnectFail);
  114. worker.connectedEvent.addListener(_onConnectSuccess);
  115. super.initState();
  116. }
  117. Future<void> connect() async {
  118. connectFailState = false;
  119. isConnect = true;
  120. connectSuccessState = false;
  121. setState(() {});
  122. await worker.connect();
  123. }
  124. Future<void> disconnect() async {
  125. worker.connectErrorEvent.removeListener(_onConnectFail);
  126. worker.connectedEvent.removeListener(_onConnectSuccess);
  127. await worker.disconnect();
  128. }
  129. @override
  130. void dispose() {
  131. super.dispose();
  132. }
  133. void _onSuccess(_, SugarExamData e) {
  134. setState(() {
  135. specialInputController.text = e.sugar.toString();
  136. // connectFailState = false;
  137. // connectSuccessState = false;
  138. isConnect = false;
  139. // disconnect();
  140. });
  141. }
  142. void _onConnectFail(sender, e) {
  143. print('连接设备失败');
  144. connectFailState = true;
  145. connectSuccessState = false;
  146. isConnect = false;
  147. disconnect();
  148. setState(() {});
  149. }
  150. void _onConnectSuccess(sender, e) {
  151. connectSuccessState = true;
  152. connectFailState = false;
  153. isConnect = false;
  154. setState(() {});
  155. }
  156. @override
  157. Widget build(BuildContext context) {
  158. return VAlertDialog(
  159. title: widget.currentFormObject.label ?? '',
  160. width: 600,
  161. contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
  162. content: buildMainWidget(),
  163. showCancel: true,
  164. onConfirm: () {
  165. disconnect();
  166. Get.back(result: specialInputController.text);
  167. },
  168. onCanceled: () {
  169. disconnect();
  170. },
  171. );
  172. }
  173. Widget buildInputField() {
  174. return Container(
  175. width: 350,
  176. padding: const EdgeInsets.only(left: 15),
  177. child: TextFormField(
  178. keyboardType: TextInputType.number,
  179. style: const TextStyle(
  180. fontSize: 100,
  181. ),
  182. showCursor: false,
  183. controller: specialInputController,
  184. decoration: const InputDecoration(
  185. labelStyle: TextStyle(
  186. fontSize: 100,
  187. ),
  188. ),
  189. ),
  190. );
  191. }
  192. Widget buildConnectFailText() {
  193. return const Text(
  194. '设备连接失败',
  195. style: TextStyle(
  196. color: Colors.red,
  197. fontSize: 25,
  198. ),
  199. textAlign: TextAlign.left,
  200. );
  201. }
  202. Widget buildConnectSuccessText() {
  203. return const Text(
  204. '设备连接成功',
  205. style: TextStyle(
  206. color: Colors.green,
  207. fontSize: 25,
  208. ),
  209. textAlign: TextAlign.left,
  210. );
  211. }
  212. Widget buildConnectingText() {
  213. return const Row(
  214. children: [
  215. Expanded(
  216. child: Text(
  217. '设备连接中',
  218. style: TextStyle(
  219. fontSize: 40,
  220. color: Colors.blue,
  221. ),
  222. ),
  223. ),
  224. CircularProgressIndicator(
  225. valueColor: AlwaysStoppedAnimation(
  226. Colors.blue,
  227. ),
  228. ),
  229. SizedBox(
  230. width: 20,
  231. ),
  232. ],
  233. );
  234. }
  235. Widget buildReconnectButton() {
  236. return Container(
  237. margin: const EdgeInsets.only(top: 4),
  238. width: 134,
  239. child: VButton(
  240. onTap: () async {
  241. /// TODO
  242. await connect();
  243. worker.connectErrorEvent.addListener(_onConnectFail);
  244. worker.connectedEvent.addListener(_onConnectSuccess);
  245. /// TODO 后面需要改,这边暂时演示用
  246. Future.delayed(const Duration(milliseconds: 8000), () {
  247. if (!connectSuccessState) {
  248. connectFailState = true;
  249. }
  250. });
  251. },
  252. child: const Row(
  253. mainAxisAlignment: MainAxisAlignment.center,
  254. children: [
  255. Icon(Icons.connected_tv_rounded, size: 24),
  256. SizedBox(
  257. width: 8,
  258. ),
  259. Text("重连", style: TextStyle(fontSize: 20)),
  260. ],
  261. ),
  262. ),
  263. );
  264. }
  265. Widget buildConnectStateWidgets() {
  266. return Column(
  267. children: [
  268. if (connectFailState) buildConnectFailText(),
  269. if (connectSuccessState) buildConnectSuccessText(),
  270. if (isConnect)
  271. buildConnectingText()
  272. else if (connectFailState)
  273. buildReconnectButton(),
  274. ],
  275. );
  276. }
  277. Widget buildMainWidget() {
  278. return SizedBox(
  279. height: 100,
  280. child: Row(
  281. children: [
  282. buildInputField(),
  283. Expanded(
  284. child: buildConnectStateWidgets(),
  285. ),
  286. ],
  287. ),
  288. );
  289. }
  290. }