view.dart 7.9 KB

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