view.dart 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import 'package:flutter/material.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/architecture/utils/advance_debounce.dart';
  4. import 'package:vitalapp/components/alert_dialog.dart';
  5. import 'package:vitalapp/pages/medical/widgets/heart_rate.dart';
  6. import 'package:vitalapp/pages/medical/widgets/twelve_ecg.dart';
  7. import 'package:vitalapp/pages/medical/widgets/urinalysis.dart';
  8. import 'package:vnote_device_plugin/consts/types.dart';
  9. import 'package:vitalapp/components/button.dart';
  10. import 'package:vitalapp/pages/medical/controller.dart';
  11. import 'package:vitalapp/pages/medical/widgets/blood_pressure.dart';
  12. import 'package:vitalapp/pages/medical/widgets/blood_sugar.dart';
  13. import 'package:vitalapp/pages/medical/widgets/body_temperature.dart';
  14. import 'package:vitalapp/pages/medical/widgets/body_bmi.dart';
  15. import 'package:vitalapp/pages/medical/widgets/bool_oxygen.dart';
  16. import 'package:vitalapp/store/store.dart';
  17. class MedicalPage extends GetView<MedicalController> {
  18. const MedicalPage({super.key});
  19. @override
  20. Widget build(BuildContext context) {
  21. return Scaffold(
  22. resizeToAvoidBottomInset: false,
  23. body: Column(
  24. children: [
  25. Expanded(
  26. child: Stack(
  27. children: [
  28. _buildMedical(),
  29. // _buildGenerateReport(),
  30. ],
  31. )),
  32. ],
  33. ),
  34. floatingActionButton: _buildSaveButton(context),
  35. );
  36. }
  37. Widget _buildMedical() {
  38. return Row(
  39. children: [
  40. _buildMedicalMenus(),
  41. Obx(
  42. () => _buildDeviceImage(controller.state.currentTab),
  43. ),
  44. _buildMedicalInput(),
  45. ],
  46. );
  47. }
  48. Widget _buildMedicalMenus() {
  49. return Expanded(
  50. flex: 2,
  51. child: Container(
  52. margin: const EdgeInsets.only(top: 100),
  53. child: Obx(
  54. () => ListView(
  55. // mainAxisAlignment: MainAxisAlignment.center,
  56. children: controller.state.medicalMenuList
  57. .map(
  58. (e) => Material(
  59. borderRadius: const BorderRadius.only(
  60. topRight: Radius.circular(30),
  61. bottomRight: Radius.circular(30),
  62. ),
  63. child: Ink(
  64. decoration: const BoxDecoration(
  65. borderRadius: BorderRadius.only(
  66. topRight: Radius.circular(30),
  67. bottomRight: Radius.circular(30),
  68. ),
  69. ),
  70. child: InkWell(
  71. borderRadius: const BorderRadius.only(
  72. topRight: Radius.circular(30),
  73. bottomRight: Radius.circular(30),
  74. ),
  75. onTap: () {
  76. controller.state.currentTab = e.key;
  77. },
  78. child: Obx(
  79. () => _SideBar(
  80. title: e.diagnosticItem,
  81. isActive: controller.state.currentTab == e.key,
  82. ),
  83. )),
  84. ),
  85. ),
  86. )
  87. .toList(),
  88. ),
  89. ),
  90. ),
  91. );
  92. }
  93. Widget _buildMedicalInput() {
  94. return Expanded(
  95. flex: 10,
  96. child: Stack(
  97. children: [
  98. Container(
  99. padding: const EdgeInsets.all(16),
  100. child: Column(
  101. children: [
  102. _buildContent(),
  103. ],
  104. ),
  105. ),
  106. ],
  107. ),
  108. );
  109. }
  110. String _deviceImageUrl(String? currentTab) {
  111. switch (currentTab) {
  112. case DeviceTypes.TEMP:
  113. return 'assets/images/healthCheck/temp.png';
  114. case DeviceTypes.SUGAR:
  115. return 'assets/images/healthCheck/sugar.png';
  116. case DeviceTypes.NIBP:
  117. return 'assets/images/healthCheck/nibp.png';
  118. case DeviceTypes.SPO2:
  119. return 'assets/images/healthCheck/spo2.png';
  120. case DeviceTypes.WEIGHT:
  121. return 'assets/images/healthCheck/bmi.png';
  122. case DeviceTypes.URINE:
  123. return 'assets/images/healthCheck/urine.png';
  124. default:
  125. return 'assets/images/exam/normalMeasurementChart.png';
  126. }
  127. }
  128. Widget _buildDeviceImage(String? currentTab) {
  129. if (currentTab == DeviceTypes.TWELVEHEART) return const SizedBox();
  130. return Expanded(
  131. flex: 6,
  132. child: Container(
  133. alignment: Alignment.topCenter,
  134. margin: const EdgeInsets.all(16).copyWith(top: 10),
  135. child: Obx(
  136. () => ClipRect(
  137. child: Align(
  138. alignment: Alignment.bottomCenter,
  139. heightFactor: 0.8,
  140. child: controller.state.currentTab != null
  141. ? Image.asset(
  142. _deviceImageUrl(controller.state.currentTab),
  143. height: double.infinity,
  144. fit: BoxFit.contain, // 设置图像的适应方式
  145. )
  146. : Container(),
  147. ),
  148. ),
  149. ),
  150. ),
  151. );
  152. }
  153. Widget _buildGenerateReport() {
  154. return Positioned(
  155. bottom: 100,
  156. left: 16,
  157. child: VButton(
  158. onTap: () {
  159. Get.dialog(
  160. VAlertDialog(
  161. title: '提示',
  162. content: Container(
  163. margin: const EdgeInsets.only(bottom: 20),
  164. child: const Text(
  165. '当前检测是否已完成,请确定是否结束本次检测',
  166. style: TextStyle(fontSize: 20),
  167. textAlign: TextAlign.center,
  168. ),
  169. ),
  170. showCancel: true,
  171. onConfirm: () {
  172. controller.saveCachedAppDataId();
  173. },
  174. ),
  175. );
  176. },
  177. child: const Text(
  178. '生成检测',
  179. style: TextStyle(fontSize: 26),
  180. ),
  181. ),
  182. );
  183. }
  184. Widget _buildSaveButton(BuildContext context) {
  185. return Obx(() {
  186. if (Store.user.currentSelectPatientInfo == null) {
  187. return const SizedBox();
  188. }
  189. return FloatingActionButton.extended(
  190. backgroundColor: Theme.of(context).primaryColor,
  191. onPressed: () {
  192. advanceDebounce(controller.createDiagnosis, "createDiagnosis", 1500);
  193. },
  194. label: const SizedBox(
  195. width: 240,
  196. height: 60,
  197. child: Center(
  198. child: Text(
  199. '提交',
  200. style: TextStyle(
  201. fontSize: 26,
  202. color: Colors.white,
  203. ),
  204. ),
  205. ),
  206. ),
  207. );
  208. });
  209. }
  210. Widget _buildContent() {
  211. return Obx(() {
  212. print(controller.state.currentTab);
  213. switch (controller.state.currentTab) {
  214. case DeviceTypes.TEMP:
  215. return const BodyTemperature();
  216. case DeviceTypes.SUGAR:
  217. return const BloodSugar();
  218. case DeviceTypes.NIBP:
  219. return const BloodPressure();
  220. case DeviceTypes.SPO2:
  221. return const BloodOxygen();
  222. case DeviceTypes.WEIGHT:
  223. return const BodyWeight();
  224. case DeviceTypes.URINE:
  225. return const Urinalysis();
  226. case DeviceTypes.HEART:
  227. return const HeartRate();
  228. case DeviceTypes.TWELVEHEART:
  229. return const TwelveHeartRate();
  230. default:
  231. return const SizedBox();
  232. }
  233. });
  234. }
  235. }
  236. class _SideBar extends StatelessWidget {
  237. const _SideBar({
  238. required this.title,
  239. this.isActive,
  240. });
  241. final String title;
  242. final bool? isActive;
  243. @override
  244. Widget build(BuildContext context) {
  245. return Container(
  246. alignment: Alignment.centerLeft,
  247. width: 140,
  248. child: Container(
  249. margin: const EdgeInsets.only(bottom: 2),
  250. decoration: BoxDecoration(
  251. color: isActive!
  252. ? Theme.of(context).primaryColor
  253. : Theme.of(context).primaryColor.withOpacity(.2),
  254. borderRadius: const BorderRadius.only(
  255. topRight: Radius.circular(30),
  256. bottomRight: Radius.circular(30),
  257. ),
  258. ),
  259. alignment: Alignment.center,
  260. width: isActive! ? 140 : 120,
  261. height: 60,
  262. child: Text(
  263. title,
  264. style: TextStyle(
  265. fontSize: 26,
  266. color: isActive! ? Colors.white : Colors.black,
  267. ),
  268. ),
  269. ),
  270. );
  271. }
  272. }