follow_up_from.dart 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import 'dart:convert';
  2. import 'package:fis_common/logger/logger.dart';
  3. import 'package:fis_jsonrpc/rpc.dart';
  4. import 'package:flutter/foundation.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:get/get.dart';
  7. import 'package:image_picker/image_picker.dart';
  8. import 'package:intl/intl.dart';
  9. import 'package:vitalapp/architecture/app_parameters.dart';
  10. import 'package:vitalapp/architecture/storage/storage.dart';
  11. import 'package:vitalapp/components/appbar.dart';
  12. import 'package:vitalapp/components/button.dart';
  13. import 'package:vitalapp/components/cell.dart';
  14. import 'package:vitalapp/components/dialog_date.dart';
  15. import 'package:vitalapp/components/dialog_select.dart';
  16. import 'package:vitalapp/consts/rpc_enum_labels.dart';
  17. import 'package:vitalapp/consts/styles.dart';
  18. import 'package:vitalapp/managers/interfaces/follow_up.dart';
  19. import 'package:vitalapp/pages/check/follow_up/controller.dart';
  20. import 'package:vitalapp/pages/medical/views/follow_medical.dart';
  21. import 'package:vitalapp/rpc.dart';
  22. import 'package:vitalapp/store/store.dart';
  23. import '../models/select_model.dart';
  24. class FollowUpFrom extends GetView<FollowUpController> {
  25. FollowUpFrom({
  26. super.key,
  27. required this.cardKey,
  28. this.dataDTO,
  29. });
  30. final String cardKey;
  31. final FollowUpRecordDataDTO? dataDTO;
  32. final _followUpManager = Get.find<IFollowUpManager>();
  33. @override
  34. Widget build(BuildContext context) {
  35. return _buildFollowUp();
  36. }
  37. Widget _buildFollowUp() {
  38. return Card(
  39. elevation: 6,
  40. shape: RoundedRectangleBorder(
  41. borderRadius: GlobalStyles.borderRadius,
  42. ),
  43. margin: const EdgeInsets.all(16),
  44. child: Material(
  45. color: Colors.white,
  46. borderRadius: const BorderRadius.all(
  47. GlobalStyles.borderRadiusValue,
  48. ),
  49. child: Container(
  50. padding: const EdgeInsets.symmetric(horizontal: 16),
  51. child: Column(
  52. children: [
  53. _buildFrom(),
  54. if (["GXY", "TNB"].contains(cardKey))
  55. VButton(
  56. onTap: () async {
  57. Map<String, dynamic>? result =
  58. await Get.dialog<Map<String, dynamic>>(
  59. Scaffold(
  60. body: FollowMedicalPage(cardKey: cardKey),
  61. appBar: VAppBar(
  62. titleText: "检测",
  63. ),
  64. ),
  65. );
  66. logger
  67. .i("当前表单数据:${jsonEncode(result!)},当前模模板为${cardKey}");
  68. _followUpManager.onFollowMedicalData
  69. .emit(this, jsonEncode(result));
  70. // /// TODO BAKA 需要优化
  71. // controller.followUpMedicalData = result;
  72. },
  73. child: Text(
  74. '检测',
  75. style: TextStyle(fontSize: 26),
  76. ),
  77. ),
  78. ],
  79. )),
  80. ),
  81. );
  82. }
  83. Widget _buildFrom() {
  84. return Obx(
  85. () => VListFormCellGroup(
  86. // mainAxisAlignment: MainAxisAlignment.center,
  87. children: [
  88. VListFormCell(
  89. label: '居民姓名',
  90. labelWidth: 130,
  91. content: controller.patientName,
  92. ),
  93. VListFormCell(
  94. label: '随访医生',
  95. labelWidth: 130,
  96. content: dataDTO != null
  97. ? dataDTO!.followUpDoctor
  98. : Store.user.displayName,
  99. ),
  100. VListFormCell(
  101. isRequired: ["GXY", "TNB"].contains(cardKey) ? true : false,
  102. label: '本次随访日期',
  103. labelWidth: 130,
  104. endIcon: Icon(
  105. Icons.keyboard_arrow_right,
  106. size: 32,
  107. color: Colors.grey.shade400,
  108. ),
  109. content: getFollowUpTime(controller.state.followUpTime),
  110. onTap: () async {
  111. DateTime? result;
  112. bool _isLocalStation = AppParameters.data.isLocalStation;
  113. if (kIsWeb || _isLocalStation) {
  114. result = await showDatePicker(
  115. context: Get.context!,
  116. initialDate: controller.state.followUpTime ?? DateTime.now(),
  117. firstDate: DateTime(1900),
  118. lastDate: DateTime(2100),
  119. );
  120. } else {
  121. result = await VDialogDate(
  122. title: '本次随访日期',
  123. initialValue: controller.state.followUpTime,
  124. ).show();
  125. }
  126. if (result != null)
  127. controller.state.followUpTime =
  128. DateTime(result.year, result.month, result.day, 23, 59, 59);
  129. },
  130. ),
  131. VListFormCell(
  132. isRequired: ["GXY", "TNB"].contains(cardKey) ? true : false,
  133. label: '下次随访日期',
  134. labelWidth: 130,
  135. endIcon: Icon(
  136. Icons.keyboard_arrow_right,
  137. size: 32,
  138. color: Colors.grey.shade400,
  139. ),
  140. content: getFollowUpTime(controller.state.nextFollowUpTime),
  141. onTap: () async {
  142. DateTime? result;
  143. bool _isLocalStation = AppParameters.data.isLocalStation;
  144. if (kIsWeb || _isLocalStation) {
  145. result = await showDatePicker(
  146. context: Get.context!,
  147. initialDate:
  148. controller.state.nextFollowUpTime ?? DateTime.now(),
  149. firstDate: controller.state.followUpTime ?? DateTime(1900),
  150. lastDate: DateTime(2100),
  151. );
  152. } else {
  153. result = await VDialogDate(
  154. title: '下次随访日期',
  155. initialValue: controller.state.nextFollowUpTime,
  156. minimumDate: controller.state.followUpTime,
  157. ).show();
  158. }
  159. if (result != null)
  160. controller.state.nextFollowUpTime =
  161. DateTime(result.year, result.month, result.day, 23, 59, 59);
  162. },
  163. ),
  164. // if (cardKey == "ET_3SETJKJCLB")
  165. // VListFormCell(
  166. // label: '月(年)龄',
  167. // labelWidth: 130,
  168. // endIcon: Icon(
  169. // Icons.keyboard_arrow_right,
  170. // size: 32,
  171. // color: Colors.grey.shade400,
  172. // ),
  173. // content: RpcEnumLabels
  174. // .followUpChild3_6_Year[controller.state.followUp3_6_Year],
  175. // onTap: () async {
  176. // final result =
  177. // await VDialogSelect<SelectModel, FollowUpChild3_6YearEnum>(
  178. // source: controller.state.followUpChild3_6YearSelectList,
  179. // valueGetter: (data) => data.code,
  180. // labelGetter: (data) => data.name,
  181. // initialValue: controller.state.followUp3_6_Year,
  182. // ).show();
  183. // if (result != null) {
  184. // controller.state.followUp3_6_Year = result;
  185. // }
  186. // },
  187. // ),
  188. // if (cardKey != "ET_3SETJKJCLB")
  189. VListFormCell(
  190. isRequired: ["GXY", "TNB"].contains(cardKey) ? true : false,
  191. label: '随访方式',
  192. labelWidth: 130,
  193. endIcon: Icon(
  194. Icons.keyboard_arrow_right,
  195. size: 32,
  196. color: Colors.grey.shade400,
  197. ),
  198. content: RpcEnumLabels.followUpMode[controller.state.followUpMode],
  199. onTap: () async {
  200. List<SelectModel<FollowUpModeEnum>> followUpModeEnumSelectList =
  201. controller.state.followUpModeEnumSelectList;
  202. if (cardKey.contains("FollowUpTuberculosisFirstRecord")) {
  203. followUpModeEnumSelectList = controller
  204. .state.followUpModeEnumSelectList
  205. .take(2)
  206. .toList();
  207. }
  208. final result = await VDialogSelect<SelectModel, FollowUpModeEnum>(
  209. source: followUpModeEnumSelectList,
  210. valueGetter: (data) => data.code,
  211. labelGetter: (data) => data.name,
  212. initialValue: controller.state.followUpMode,
  213. ).show();
  214. if (result != null) {
  215. controller.state.followUpMode = result;
  216. }
  217. },
  218. ),
  219. VListFormCell(
  220. label: '拍照',
  221. labelWidth: 130,
  222. endIcon: Icon(
  223. Icons.keyboard_arrow_right,
  224. size: 32,
  225. color: Colors.grey.shade400,
  226. ),
  227. contentWidget: _buildFollowImage(controller.state.followUpPhoto),
  228. onTap: () async {
  229. XFile? image =
  230. await ImagePicker().pickImage(source: ImageSource.camera);
  231. final url = await rpc.storage.upload(image!);
  232. controller.state.followUpPhoto = url;
  233. },
  234. ),
  235. ],
  236. ),
  237. );
  238. }
  239. Widget _buildFollowImage(String? followUpPhoto) {
  240. if (followUpPhoto?.isNotEmpty ?? false) {
  241. return Image.network(followUpPhoto!);
  242. } else {
  243. return const SizedBox();
  244. }
  245. }
  246. String getFollowUpTime(DateTime? time) {
  247. // print(time);
  248. if (time != null) {
  249. return DateFormat('yyyy-MM-dd').format(time);
  250. }
  251. return '';
  252. }
  253. }