configurable_card.dart 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827
  1. import 'dart:convert';
  2. import 'package:fis_common/index.dart';
  3. import 'package:fis_common/logger/logger.dart';
  4. import 'package:fis_jsonrpc/rpc.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/services.dart';
  7. import 'package:get/get.dart';
  8. import 'package:intl/intl.dart';
  9. import 'package:vitalapp/architecture/utils/compute_children_level.dart';
  10. import 'package:vitalapp/architecture/utils/prompt_box.dart';
  11. import 'package:vitalapp/components/button.dart';
  12. import 'package:vitalapp/components/dialog_date.dart';
  13. import 'package:vitalapp/components/dialog_gxy_medication.dart';
  14. import 'package:vitalapp/components/dialog_input.dart';
  15. import 'package:vitalapp/components/dialog_medication.dart';
  16. import 'package:vitalapp/components/dialog_number.dart';
  17. import 'package:vitalapp/components/dynamic_drawer.dart';
  18. import 'package:vitalapp/managers/interfaces/cachedRecord.dart';
  19. import 'package:vitalapp/managers/interfaces/follow_up.dart';
  20. import 'package:vitalapp/managers/interfaces/template.dart';
  21. import 'package:vitalapp/pages/check/models/form.dart';
  22. import 'package:vitalapp/pages/check/prescription/prescription.dart';
  23. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_child_anterior_fontanelle.dart';
  24. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_blood_sugar.dart';
  25. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_body_temperature.dart';
  26. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_body_weight.dart';
  27. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_boold_oxygen.dart';
  28. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_check_box.dart';
  29. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_checkbox_frequency.dart';
  30. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_input.dart';
  31. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_medication.dart';
  32. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_number_input.dart';
  33. import 'dart:math' as math;
  34. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio.dart';
  35. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio_score.dart';
  36. import 'package:vitalapp/pages/check/widgets/device_controller.dart';
  37. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_table.dart';
  38. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_toxic_substance.dart';
  39. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_urinalys.dart';
  40. import 'package:vitalapp/pages/check/widgets/exam_configurable/follow_blood_pressure.dart';
  41. import 'package:vitalapp/pages/check/widgets/exam_table/homecare_bed_history_from.dart';
  42. import 'package:vitalapp/pages/check/widgets/exam_table/hospitalization_history_from.dart';
  43. import 'package:vitalapp/pages/check/widgets/exam_table/inoculate_history_from.dart';
  44. import 'package:vitalapp/pages/check/widgets/exam_table/main_medication_status_from.dart';
  45. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_child_anterior_fontanelle_other.dart';
  46. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_child_height_and_weight.dart';
  47. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_child_radio_input.dart';
  48. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_child_referral.dart';
  49. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_medication.dart';
  50. import 'package:vitalapp/pages/check/widgets/follow_up_configurable/follow_up_resident_detail.dart';
  51. import 'package:vitalapp/pages/check/widgets/title_clip_path.dart';
  52. import 'package:flutter/services.dart' show rootBundle;
  53. import 'package:vitalapp/pages/form/form_info.dart';
  54. import 'package:vitalapp/store/store.dart';
  55. class ConfigurableCard extends StatefulWidget {
  56. final String cardKey;
  57. final Future<bool> Function(String, String, dynamic, String?) callBack;
  58. final Widget? followUpWidget;
  59. final String? patientCode;
  60. final String? examData;
  61. final bool canPrescribe;
  62. final void Function(String, String, dynamic)? onClickPrescribe;
  63. const ConfigurableCard({
  64. super.key,
  65. required this.cardKey,
  66. required this.callBack,
  67. this.followUpWidget,
  68. this.patientCode,
  69. this.examData,
  70. this.canPrescribe = false,
  71. this.onClickPrescribe,
  72. });
  73. @override
  74. State<ConfigurableCard> createState() => _ConfigurableFormState();
  75. }
  76. class _ConfigurableFormState extends State<ConfigurableCard> {
  77. /// 当前最新的模板的键值对
  78. Map<String, dynamic> templateRelation = {};
  79. /// 当前模板数据
  80. List<FormObject> currentTemplate = [];
  81. /// 当前title的下标
  82. int currentTitleIndex = 0;
  83. /// 处方key
  84. String prescriptionKey = '';
  85. Map<String, dynamic> formValue = {};
  86. var scaffoldKey = GlobalKey<ScaffoldState>();
  87. final _templateManager = Get.find<ITemplateManager>();
  88. final _cachedRecordManager = Get.find<ICachedRecordManager>();
  89. final _followUpManager = Get.find<IFollowUpManager>();
  90. // _followUpManager.onFollowMedicalData
  91. final arrowHeight = math.tan(120 / 180) * 19;
  92. List<String> deviceList = ['Temp', 'GLU', 'NIBP', 'SpO2', 'BMI'];
  93. Map<String, dynamic> deviceCached = {};
  94. Map currentTable = {};
  95. @override
  96. void initState() {
  97. Get.put(DeviceController());
  98. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  99. if (mounted) {
  100. initTemplate();
  101. }
  102. });
  103. _followUpManager.onFollowMedicalData.addListener(_setFollowUpData);
  104. super.initState();
  105. switch (widget.cardKey) {
  106. case "TNB":
  107. prescriptionKey = "DiabetesPrescription";
  108. break;
  109. case "GXY":
  110. prescriptionKey = "HypertensionPrescription";
  111. break;
  112. case "FollowUpTuberculosisRecord":
  113. prescriptionKey = "TuberculosisPrescription";
  114. break;
  115. case "YZJSZASFFW":
  116. prescriptionKey = "PsychiatricPrescription";
  117. break;
  118. }
  119. }
  120. @override
  121. void dispose() {
  122. _followUpManager.onFollowMedicalData.removeListener(_setFollowUpData);
  123. super.dispose();
  124. }
  125. Future<void> initTemplate() async {
  126. Get.find<DeviceController>().busy = true;
  127. await fetchTemplateIndex();
  128. await fetchTemplate(widget.cardKey);
  129. await fetchTemplateData();
  130. Get.find<DeviceController>().busy = false;
  131. }
  132. /// 读取健康检测的缓存
  133. Future<String?> readCachedRecord(String currentDevice) async {
  134. if (widget.patientCode == null) {
  135. return null;
  136. }
  137. String? value = await _cachedRecordManager.readCachedRecord(
  138. currentDevice,
  139. widget.patientCode!,
  140. 'ZLZS',
  141. );
  142. return value;
  143. }
  144. /// 读取体检的缓存
  145. Future<String?> readCachedCheck() async {
  146. if (widget.patientCode == null) {
  147. return null;
  148. }
  149. String? value = await _cachedRecordManager.readCachedRecord(
  150. widget.cardKey,
  151. widget.patientCode!,
  152. 'exam',
  153. );
  154. return value;
  155. }
  156. Future<void> readCached() async {
  157. for (var element in deviceList) {
  158. String? value = await readCachedRecord(element);
  159. if (value?.isNotEmpty ?? false) {
  160. deviceCached.addAll(jsonDecode(value!));
  161. }
  162. }
  163. }
  164. Future<void> fetchTemplateIndex() async {
  165. try {
  166. /// 获取模板的键值对
  167. String? templates;
  168. templates =
  169. await _templateManager.readTemplateRelation('templateRelation');
  170. templateRelation = jsonDecode(templates!);
  171. setState(() {});
  172. } catch (error) {
  173. print('发生错误: $error');
  174. }
  175. }
  176. Future<String> loadJsonData() async {
  177. return await rootBundle.loadString('assets/data/3-6.json');
  178. }
  179. Future<void> fetchTemplateData() async {
  180. // / 这逻辑需要优化
  181. if (widget.examData?.isNotEmpty ?? false) {
  182. formValue = jsonDecode(widget.examData!);
  183. return;
  184. }
  185. String? value = await readCachedCheck();
  186. await readCached();
  187. if (deviceCached.isNotEmpty) {
  188. formValue = deviceCached;
  189. setState(() {});
  190. return;
  191. }
  192. if (value?.isNotEmpty ?? false) {
  193. formValue = jsonDecode(value!);
  194. }
  195. formValue.forEach(
  196. (key, value) {
  197. if (value is List<String>) {
  198. formValue[key] = List<String>.from(formValue[key]);
  199. } else if (value is List<Map>) {
  200. formValue[key] = List<Map>.from(formValue[key]);
  201. }
  202. },
  203. );
  204. setState(() {});
  205. }
  206. Future<String> loadJsonFromAssets(String filePath) async {
  207. String jsonString = await rootBundle.loadString(filePath);
  208. return jsonString;
  209. }
  210. Future<void> fetchTemplateDebug() async {
  211. try {
  212. // if (templateRelation[key] == null) {
  213. // currentTemplate = [];
  214. // setState(() {});
  215. // return;
  216. // }
  217. // var template =
  218. // await _templateManager.readTemplate(templateRelation[key]!);
  219. var template = await loadJsonData();
  220. List<Map<String, dynamic>> list =
  221. jsonDecode(template)["Content"].cast<Map<String, dynamic>>();
  222. for (var i in list) {
  223. if (i['children'] != null) {
  224. List<FormObject> currentChildren = [];
  225. for (var j in i['children']) {
  226. currentChildren.add(FormObject.fromJson(j));
  227. }
  228. i['children'] = currentChildren;
  229. }
  230. var item = FormObject.fromJson(i);
  231. currentTemplate.add(item);
  232. }
  233. setState(() {});
  234. } catch (error) {
  235. print('发生错误: $error');
  236. }
  237. }
  238. Future<void> fetchTemplate(String key) async {
  239. try {
  240. // String? templateContent = "";
  241. // String? template = "";
  242. // if (key == "FollowUpTuberculosisFirstRecord") {
  243. // templateContent = await loadJsonFromAssets('assets/${key}.json');
  244. // }
  245. // if (templateRelation[key] == null && templateContent.isNullOrEmpty) {
  246. if (templateRelation[key] == null) {
  247. logger.i(
  248. "ConfigurableCard - fetchTemplate Template not exist key: $key.");
  249. currentTemplate = [];
  250. setState(() {});
  251. return;
  252. }
  253. // if (templateContent.isNullOrEmpty)
  254. // template = await _templateManager.readTemplate(templateRelation[key]!);
  255. // if (templateContent.isNullOrEmpty)
  256. // templateContent =
  257. var template =
  258. await _templateManager.readTemplate(templateRelation[key]!);
  259. String templateContent =
  260. TemplateDTO.fromJson(jsonDecode(template!)).templateContent!;
  261. List<Map<String, dynamic>> list =
  262. jsonDecode(templateContent).cast<Map<String, dynamic>>();
  263. for (var i in list) {
  264. if (i['children'] != null) {
  265. List<FormObject> currentChildren = [];
  266. for (var j in i['children']) {
  267. currentChildren.add(FormObject.fromJson(j));
  268. }
  269. i['children'] = currentChildren;
  270. }
  271. var item = FormObject.fromJson(i);
  272. currentTemplate.add(item);
  273. }
  274. // if (widget.cardKey == 'LNRZYYJKGLFWJL') {
  275. // for (var element in storeTypeList) {
  276. // formValue[element] = calculatePhysicalFitnessScore(
  277. // element,
  278. // element == 'Ping_Score',
  279. // );
  280. // }
  281. // }
  282. setState(() {});
  283. } catch (error) {
  284. print('发生错误: $error');
  285. }
  286. }
  287. @override
  288. Widget build(BuildContext context) {
  289. return Scaffold(
  290. key: scaffoldKey,
  291. endDrawer: VDynamicDrawerWrapper(scaffoldKey: scaffoldKey),
  292. resizeToAvoidBottomInset: false,
  293. body: Column(
  294. children: [
  295. Row(
  296. crossAxisAlignment: CrossAxisAlignment.start,
  297. children: [
  298. const SizedBox(
  299. width: 16,
  300. ),
  301. Container(
  302. margin: const EdgeInsets.only(top: 8),
  303. width: 130,
  304. height: 54,
  305. child: VButton(
  306. onTap: () {
  307. FormInfo.instance.formValue.clear();
  308. Get.back();
  309. },
  310. child: Row(
  311. mainAxisAlignment: MainAxisAlignment.center,
  312. children: const [
  313. Icon(Icons.arrow_back_ios_new, size: 24),
  314. SizedBox(
  315. width: 8,
  316. ),
  317. Text("返回", style: TextStyle(fontSize: 20)),
  318. ],
  319. ),
  320. ),
  321. ),
  322. Expanded(
  323. child: Container(
  324. padding:
  325. const EdgeInsets.symmetric(vertical: 16, horizontal: 10),
  326. child: _buildTitleList(),
  327. ),
  328. ),
  329. if (widget.canPrescribe)
  330. Container(
  331. margin: const EdgeInsets.only(top: 8, right: 16),
  332. width: 130,
  333. height: 54,
  334. child: VButton(
  335. onTap: () {
  336. widget.onClickPrescribe?.call(
  337. widget.cardKey,
  338. templateRelation[widget.cardKey]!,
  339. jsonEncode(formValue),
  340. );
  341. },
  342. child: Row(
  343. mainAxisAlignment: MainAxisAlignment.center,
  344. children: const [
  345. Icon(Icons.assignment_outlined, size: 24),
  346. SizedBox(
  347. width: 8,
  348. ),
  349. Text("处方", style: TextStyle(fontSize: 20)),
  350. ],
  351. ),
  352. ),
  353. ),
  354. Container(
  355. margin: const EdgeInsets.only(top: 8, right: 16),
  356. width: 130,
  357. height: 54,
  358. child: VButton(
  359. onTap: () async {
  360. final result = await widget.callBack(
  361. widget.cardKey,
  362. templateRelation[widget.cardKey]!,
  363. jsonEncode(formValue),
  364. prescriptionKey,
  365. );
  366. if (result) {
  367. Get.back();
  368. }
  369. },
  370. child: Row(
  371. mainAxisAlignment: MainAxisAlignment.center,
  372. children: const [
  373. Icon(Icons.save, size: 24),
  374. SizedBox(
  375. width: 8,
  376. ),
  377. Text("保存", style: TextStyle(fontSize: 20)),
  378. ],
  379. ),
  380. ),
  381. ),
  382. ],
  383. ),
  384. Expanded(
  385. child: Stack(
  386. children: [
  387. Row(
  388. mainAxisAlignment: MainAxisAlignment.start,
  389. crossAxisAlignment: CrossAxisAlignment.start,
  390. children: [
  391. _buildDiagram(),
  392. _buildContent(),
  393. ],
  394. ),
  395. if (currentTitleIndex != currentTemplate.length - 1)
  396. _buildPositionedButton(
  397. () async {
  398. currentTitleIndex++;
  399. setState(() {});
  400. },
  401. right: -30,
  402. ),
  403. ],
  404. ),
  405. )
  406. ],
  407. ),
  408. );
  409. }
  410. Widget buildSingleItem(Widget item, int span) {
  411. return FractionallySizedBox(
  412. widthFactor: span == 24 ? 1 : 0.5,
  413. child: item,
  414. );
  415. }
  416. Widget buildWidget(FormObject? currentFormObject) {
  417. Map<String, Widget Function(FormObject)> widgetMap = {
  418. 'checkbox': _buildCheckBox,
  419. 'numberInput': _buildNumberInput,
  420. 'input': _buildInput,
  421. 'radio': _buildRadio,
  422. 'radioScore': _buildRadioScore,
  423. 'radioInput': _buildRadioInput,
  424. 'bloodPressure': _buildBloodPressure,
  425. 'bodyTemperature': _buildBodyTemperature,
  426. 'weight': _buildBodyWeight,
  427. 'sugar': _buildBodySugar,
  428. 'bloodOxygen': _buildBloodOxygen,
  429. 'medicalHistory': _buildMedicalHistory,
  430. 'homecareBedHistor': _buildHomecareBedHistory,
  431. 'table': _buildMainMedicationHistory,
  432. 'inoculateHistory': _buildInoculateHistory,
  433. 'safetyPrecautions': _buildToxicSubstance,
  434. 'urinalys': _buildUrinalysis,
  435. 'date': _buildDate,
  436. 'checkBoxFrequency': _buildCheckBoxFrequency,
  437. 'radioHospitalization': _buildRadioHospitalization,
  438. 'radioReferral': _buildRadioReferral,
  439. 'medication': _buildMedication,
  440. 'gxyAndTnbMedication': _buildGxyAndTnbMedication,
  441. 'radioExtraDescription': _buildRadioExtraDescription,
  442. 'checkBoxIncludeOther': _buildCheckBoxIncludeOther,
  443. 'inputAndRadio': _buildChildHeightAndWeight,
  444. 'anteriorFontanelle': _buildAnteriorFontanelle,
  445. 'anteriorFontanelleOther': _buildAnteriorFontanelleOther,
  446. 'referral': _buildFollowUpChildReferral,
  447. 'prescriptionType': _buildPrescription,
  448. 'residentdetail': _buildResidentDetail,
  449. };
  450. Widget Function(FormObject) builder =
  451. widgetMap[currentFormObject?.type] ?? _buildInput;
  452. return builder(currentFormObject!);
  453. }
  454. Widget flowCardList() {
  455. int itemCount = 0;
  456. bool currentTemplateOptionsIsNotEmpty = false;
  457. if (currentTemplate.isNotEmpty) {
  458. itemCount = currentTemplate[currentTitleIndex].children?.length ?? 0;
  459. currentTemplateOptionsIsNotEmpty =
  460. currentTemplate[currentTitleIndex].options?.isNotEmpty ?? false;
  461. }
  462. List<Widget> items = List.generate(itemCount, (index) {
  463. FormObject? currentFormObject =
  464. currentTemplate[currentTitleIndex].children?[index];
  465. int span = currentFormObject?.span ?? 12;
  466. //父结构的options不等于空或null
  467. if (true) {
  468. //子结构的options若是无值则取父类的options值
  469. if (currentTemplateOptionsIsNotEmpty) {
  470. currentFormObject!.options =
  471. currentTemplate[currentTitleIndex].options;
  472. }
  473. }
  474. return buildSingleItem(buildWidget(currentFormObject), span);
  475. });
  476. return Scrollbar(
  477. thumbVisibility: true,
  478. child: SingleChildScrollView(
  479. child: Container(
  480. alignment: Alignment.topCenter,
  481. padding: const EdgeInsets.all(15),
  482. child: Wrap(
  483. runSpacing: 20, // 纵向元素间距
  484. alignment: WrapAlignment.start,
  485. children: items,
  486. ),
  487. ),
  488. ),
  489. );
  490. }
  491. void _setFollowUpData(sender, e) {
  492. if (mounted) {
  493. print(e);
  494. Map<String, dynamic> followUpData = jsonDecode(e);
  495. followUpData.forEach((key, value) {
  496. if (key == "BMI") {
  497. formValue.addAll(value);
  498. }
  499. if (key == "NIBP") {
  500. /// 之前区分左右,后面重新设计
  501. List bloodValue = [];
  502. if (value["Sbp"] != null &&
  503. value["Dbp"] != null &&
  504. value["Pulse_Beat"] != null) {
  505. bloodValue.addAll([value["Sbp"], value["Dbp"]]);
  506. Map<String, dynamic> nibpData = {
  507. "Blood": {"Blood": jsonEncode(bloodValue)},
  508. "Heart_Rate": value["Pulse_Beat"],
  509. };
  510. formValue.addAll(nibpData);
  511. }
  512. }
  513. if (key == "GLU") {
  514. Map<String, dynamic> sugar = {
  515. "Blood_Sugar": value["sugar"],
  516. };
  517. formValue.addAll(sugar);
  518. }
  519. });
  520. logger.i("当前表单数据:${formValue}");
  521. setState(() {});
  522. print(e);
  523. }
  524. }
  525. /// title标签
  526. Widget _buildTitleList() {
  527. return Wrap(
  528. runSpacing: 10, // 设置子小部件之间的间距
  529. spacing: -12,
  530. alignment: WrapAlignment.start,
  531. children: currentTemplate.asMap().entries.map(
  532. (e) {
  533. /// 处方的处理
  534. if (FormInfo.instance.formValue.isNotEmpty) {
  535. formValue["Prescription"] = [];
  536. }
  537. /// TODO 这边需要改下
  538. MaterialColor currentColors = Colors.grey;
  539. e.value.children?.forEach((element) {
  540. if (formValue.containsKey(element.key))
  541. currentColors = Colors.green;
  542. });
  543. return TitleClipRect(
  544. title: e.value.label ?? '',
  545. color: currentTitleIndex == e.key ? null : currentColors,
  546. arrowHeight: arrowHeight,
  547. clickTitle: () {
  548. currentTitleIndex = e.key;
  549. setState(() {});
  550. },
  551. );
  552. },
  553. ).toList(),
  554. );
  555. }
  556. /// 示意图
  557. Widget _buildDiagram() {
  558. if (widget.cardKey == 'ZYYYFMYGHYFJZS') {
  559. return const SizedBox();
  560. }
  561. return Expanded(
  562. flex: 1,
  563. child: Stack(
  564. children: [
  565. /// TODO BAKA-优化
  566. _buildImageCard(),
  567. if (currentTitleIndex != 0)
  568. _buildPositionedButton(
  569. () async {
  570. if (currentTitleIndex == 0) {
  571. Get.back();
  572. } else {
  573. currentTitleIndex--;
  574. setState(() {});
  575. }
  576. },
  577. left: -30,
  578. ),
  579. ],
  580. ),
  581. );
  582. }
  583. Widget _buildImageCard() {
  584. // if (currentTemplate[currentTitleIndex].key == 'Temperature') {
  585. // return Container(
  586. // alignment: Alignment.topCenter,
  587. // margin: const EdgeInsets.all(16).copyWith(top: 0),
  588. // child: Image.asset(
  589. // 'assets/images/healthCheck/temp.png',
  590. // height: double.infinity,
  591. // fit: BoxFit.fitWidth, // 设置图像的适应方式
  592. // ),
  593. // );
  594. // }
  595. if ([
  596. 'GXY',
  597. 'TNB',
  598. 'LNRZYYJKGLFWJL',
  599. 'YZJSZASFFW',
  600. ].contains(widget.cardKey) ||
  601. widget.cardKey.contains("ET_") ||
  602. widget.cardKey.contains("FollowUpTuberculosis")) {
  603. return widget.followUpWidget!;
  604. } else {
  605. return Container(
  606. alignment: Alignment.topCenter,
  607. margin: const EdgeInsets.all(16).copyWith(top: 0),
  608. child: Image.asset(
  609. 'assets/images/exam/normalMeasurementChart.png',
  610. height: double.infinity,
  611. fit: BoxFit.fitWidth, // 设置图像的适应方式
  612. ),
  613. );
  614. }
  615. }
  616. /// 前囟
  617. Widget _buildAnteriorFontanelle(FormObject currentFormObject) {
  618. List<Option> options = currentFormObject.options ?? [];
  619. String currentSelected = formValue[currentFormObject.key!] ?? "";
  620. String currentLength = formValue["Fontanel_Length"] ?? "";
  621. String currentWidth = formValue["Fontanel_Width"] ?? "";
  622. void selectRaidoChange(Option e) {
  623. currentSelected = e.value ?? '';
  624. formValue[currentFormObject.key!] = currentSelected;
  625. if (e.value == '1' && options.length == 2) {
  626. formValue["Fontanel_Length"] = "";
  627. formValue["Fontanel_Width"] = "";
  628. }
  629. setState(() {});
  630. }
  631. void selectInputChange(String inputKey, String? inputValue) {
  632. if (inputValue == null) return;
  633. if (inputKey == "length") {
  634. currentLength = inputValue;
  635. formValue["Fontanel_Length"] = currentLength;
  636. } else if (inputKey == "width") {
  637. currentWidth = inputValue;
  638. formValue["Fontanel_Width"] = currentWidth;
  639. }
  640. setState(() {});
  641. }
  642. return FollowUpChildAnteriorFontanelle(
  643. options: options,
  644. currentFormObject: currentFormObject,
  645. selectRaidoChange: selectRaidoChange,
  646. currentSelected: currentSelected,
  647. selectInputChange: selectInputChange,
  648. formValue: formValue,
  649. );
  650. }
  651. /// 前囟其他
  652. Widget _buildAnteriorFontanelleOther(FormObject currentFormObject) {
  653. List<Option> options = currentFormObject.options ?? [];
  654. String currentSelected = formValue[currentFormObject.key!] ?? "";
  655. String currentLength = formValue["Fontanel_Length"] ?? "";
  656. String currentWidth = formValue["Fontanel_Width"] ?? "";
  657. void selectRaidoChange(Option e) {
  658. currentSelected = e.value ?? '';
  659. formValue[currentFormObject.key!] = currentSelected;
  660. if (e.value == '1' && options.length == 2) {
  661. formValue["Fontanel_Length"] = "";
  662. formValue["Fontanel_Width"] = "";
  663. }
  664. setState(() {});
  665. }
  666. void selectOtherValue(String value) {
  667. formValue["Fontanel_Other"] = value;
  668. setState(() {});
  669. }
  670. if (currentSelected != '4') {
  671. formValue["Fontanel_Other"] = "";
  672. }
  673. void selectInputChange(String inputKey, String? inputValue) {
  674. if (inputValue == null) return;
  675. if (inputKey == "length") {
  676. currentLength = inputValue;
  677. formValue["Fontanel_Length"] = currentLength;
  678. } else if (inputKey == "width") {
  679. currentWidth = inputValue;
  680. formValue["Fontanel_Width"] = currentWidth;
  681. }
  682. setState(() {});
  683. }
  684. return FollowUpChildAnteriorFontanelleOther(
  685. options: options,
  686. currentFormObject: currentFormObject,
  687. selectRaidoChange: selectRaidoChange,
  688. currentSelected: currentSelected,
  689. selectInputChange: selectInputChange,
  690. selectOtherValue: selectOtherValue,
  691. formValue: formValue,
  692. );
  693. }
  694. /// 转诊建议
  695. Widget _buildFollowUpChildReferral(FormObject currentFormObject) {
  696. List<Option> options = currentFormObject.options ?? [];
  697. String currentSelected = formValue[currentFormObject.key!] ?? "";
  698. String referralReason = formValue["referralReason"] ?? "";
  699. String referralOrg = formValue["referralOrg"] ?? "";
  700. void selectRaidoChange(Option e) {
  701. currentSelected = e.value ?? '';
  702. formValue[currentFormObject.key!] = currentSelected;
  703. if (e.value == '1') {
  704. formValue["referralReason"] = "";
  705. formValue["referralOrg"] = "";
  706. }
  707. setState(() {});
  708. }
  709. void selectInputChange(String inputKey, String? inputValue) {
  710. if (inputValue == null) return;
  711. if (inputKey == "reason") {
  712. referralReason = inputValue;
  713. formValue["referralReason"] = referralReason;
  714. } else if (inputKey == "org") {
  715. referralOrg = inputValue;
  716. formValue["referralOrg"] = referralOrg;
  717. }
  718. setState(() {});
  719. }
  720. return FollowUpChildReferral(
  721. options: options,
  722. currentFormObject: currentFormObject,
  723. selectRaidoChange: selectRaidoChange,
  724. currentSelected: currentSelected,
  725. selectInputChange: selectInputChange,
  726. formValue: formValue,
  727. );
  728. }
  729. /// 按钮
  730. Widget _buildPositionedButton(Function onTap, {double? right, double? left}) {
  731. return Positioned(
  732. right: right,
  733. left: left,
  734. bottom: 0,
  735. top: 0,
  736. child: Container(
  737. width: 100,
  738. height: 100,
  739. alignment: Alignment.centerLeft,
  740. child: InkWell(
  741. onTap: () => onTap.call(),
  742. child: Container(
  743. width: 100,
  744. height: 100,
  745. padding: const EdgeInsets.all(20),
  746. alignment:
  747. right == null ? Alignment.centerRight : Alignment.centerLeft,
  748. decoration: BoxDecoration(
  749. borderRadius: BorderRadius.circular(50),
  750. color: Theme.of(context).primaryColor.withOpacity(
  751. .8,
  752. ),
  753. ),
  754. child: Image.asset(
  755. right == null
  756. ? "assets/images/exam/left-arrow.png"
  757. : "assets/images/exam/right-arrow.png",
  758. width: 40,
  759. height: 40,
  760. color: Colors.white,
  761. fit: BoxFit.contain,
  762. ),
  763. ),
  764. ),
  765. ),
  766. );
  767. }
  768. /// 主页面
  769. Widget _buildContent() {
  770. return Expanded(
  771. flex: 2,
  772. child: flowCardList(),
  773. );
  774. }
  775. /// 多选框组件
  776. Widget _buildCheckBox(FormObject currentFormObject) {
  777. List<Option> options = currentFormObject.options ?? [];
  778. if (currentFormObject.key == "Diseases_Type") {
  779. String deathCauseValue = formValue["Death_Cause"] ?? "";
  780. if (deathCauseValue.isEmpty || deathCauseValue != '1') {
  781. formValue.remove('Diseases_Type');
  782. return Container();
  783. }
  784. }
  785. List<dynamic> currentSelectedCheckBox = [];
  786. if (formValue[currentFormObject.key!] is List<dynamic>) {
  787. currentSelectedCheckBox = formValue[currentFormObject.key!] ?? [];
  788. } else {
  789. currentSelectedCheckBox = [];
  790. }
  791. dynamic disabledValue = currentFormObject.disabledValue;
  792. void selectCheckBoxChange(Option e) {
  793. if (currentSelectedCheckBox.contains(e.value)) {
  794. currentSelectedCheckBox.remove(e.value);
  795. } else {
  796. if (disabledValue == e.value) {
  797. currentSelectedCheckBox = [disabledValue];
  798. } else {
  799. if (currentSelectedCheckBox.contains(disabledValue)) {
  800. // PromptBox.toast('选项冲突');
  801. } else {
  802. // 最大可选处理
  803. if (currentFormObject.maxItems != null &&
  804. currentSelectedCheckBox.length >= currentFormObject.maxItems!) {
  805. PromptBox.toast('最多选择${currentFormObject.maxItems}项');
  806. return;
  807. }
  808. currentSelectedCheckBox.add(e.value ?? '');
  809. }
  810. }
  811. }
  812. formValue[currentFormObject.key!] = currentSelectedCheckBox;
  813. setState(() {});
  814. }
  815. return ExamCheckBox(
  816. options: options,
  817. currentSelectedCheckBox: currentSelectedCheckBox,
  818. currentFormObject: currentFormObject,
  819. selectCheckBoxChange: selectCheckBoxChange,
  820. disbaleOthers: currentSelectedCheckBox.contains(disabledValue),
  821. );
  822. }
  823. Widget _buildCheckBoxIncludeOther(FormObject currentFormObject) {
  824. List<Option> options = currentFormObject.options ?? [];
  825. List<dynamic> currentSelected = formValue[currentFormObject.key!] ?? [];
  826. dynamic disabledValue = currentFormObject.disabledValue;
  827. dynamic otherItem = currentFormObject.groupKeys!.first;
  828. String otherDecrition =
  829. formValue[currentFormObject.childrenKey!.first] ?? "";
  830. void selectCheckBoxChange(Option e) {
  831. if (currentSelected.contains(e.value)) {
  832. currentSelected.remove(e.value);
  833. if (e.value == otherItem) {
  834. otherDecrition = '';
  835. }
  836. } else {
  837. if (disabledValue == e.value) {
  838. currentSelected = [disabledValue];
  839. } else {
  840. if (currentSelected.contains(disabledValue)) {
  841. // PromptBox.toast('选项冲突');
  842. } else {
  843. // 最大可选处理
  844. if (currentFormObject.maxItems != null &&
  845. currentSelected.length >= currentFormObject.maxItems!) {
  846. PromptBox.toast('最多选择${currentFormObject.maxItems}项');
  847. return;
  848. }
  849. currentSelected.add(e.value ?? '');
  850. }
  851. }
  852. }
  853. formValue[currentFormObject.key!] = currentSelected;
  854. setState(() {});
  855. }
  856. void changeExtraDescription(String? extraDescription) {
  857. otherDecrition = extraDescription ?? '';
  858. formValue[currentFormObject.childrenKey!.first] = otherDecrition;
  859. setState(() {});
  860. }
  861. return ExamCheckBoxIncludeOther(
  862. options: options,
  863. currentSelectedCheckBox: currentSelected,
  864. currentFormObject: currentFormObject,
  865. selectCheckBoxChange: selectCheckBoxChange,
  866. disbaleOthers: currentSelected.contains(disabledValue),
  867. changeExtraDescription: changeExtraDescription,
  868. currentExtraDescription: otherDecrition,
  869. extraDescriptiveItem: otherItem,
  870. );
  871. }
  872. /// 危险行为
  873. Widget _buildCheckBoxFrequency(FormObject currentFormObject) {
  874. List<Option> options = currentFormObject.options ?? [];
  875. List<dynamic> currentFormObjectFrom =
  876. formValue[currentFormObject.key!] ?? [];
  877. String? otherItem = currentFormObject.groupKeys != null &&
  878. currentFormObject.groupKeys!.length > 0
  879. ? currentFormObject.groupKeys?.first
  880. : '';
  881. String otherDecrition =
  882. formValue[currentFormObject.childrenKey?.first] ?? "";
  883. List<DangerFrequency> currentSelectedCheckBox =
  884. currentFormObjectFrom.map((e) {
  885. if (e is Map<String, dynamic>) {
  886. return DangerFrequency.fromJson(e);
  887. } else {
  888. return DangerFrequency.fromJson(e.toJson());
  889. }
  890. }).toList();
  891. dynamic disabledValue = currentFormObject.disabledValue;
  892. Future<void> selectCheckBoxChange(Option e) async {
  893. var ddd =
  894. currentSelectedCheckBox.firstWhereOrNull((f) => f.value == e.value);
  895. if (ddd != null) {
  896. currentSelectedCheckBox.remove(ddd);
  897. if (otherItem == e.value) {
  898. formValue[currentFormObject.childrenKey?.first] = "";
  899. }
  900. } else {
  901. if (disabledValue == e.value) {
  902. currentSelectedCheckBox = [
  903. DangerFrequency(frequency: "0", value: disabledValue)
  904. ];
  905. } else {
  906. if (otherItem == e.value) {
  907. currentSelectedCheckBox
  908. .add(DangerFrequency(frequency: "0", value: otherItem));
  909. } else {
  910. var ccc = currentSelectedCheckBox
  911. .firstWhereOrNull((f) => f.value == disabledValue);
  912. if (ccc != null) {
  913. // PromptBox.toast('选项冲突');
  914. } else {
  915. String? result = await VDialogNumber(
  916. title: "${e.label}次数",
  917. // initialValue: formValue[currentFormObject.key],
  918. ).show();
  919. if (result?.isNotEmpty ?? false) {
  920. currentSelectedCheckBox.add(
  921. DangerFrequency(frequency: result, value: e.value ?? ''));
  922. }
  923. }
  924. }
  925. }
  926. }
  927. formValue[currentFormObject.key!] = currentSelectedCheckBox;
  928. setState(() {});
  929. }
  930. void changeExtraDescription(String? extraDescription) {
  931. otherDecrition = extraDescription ?? '';
  932. formValue[currentFormObject.childrenKey?.first] = otherDecrition;
  933. setState(() {});
  934. }
  935. return ExamCheckBoxFrequency(
  936. options: options,
  937. currentSelectedCheckBox: currentSelectedCheckBox,
  938. currentFormObject: currentFormObject,
  939. func: selectCheckBoxChange,
  940. disbaleOthers: currentSelectedCheckBox
  941. .firstWhereOrNull((f) => f.value == disabledValue) !=
  942. null,
  943. changeExtraDescription: changeExtraDescription,
  944. currentExtraDescription: otherDecrition,
  945. extraDescriptiveItem: otherItem,
  946. );
  947. }
  948. /// 数字输入框组件
  949. Widget _buildNumberInput(FormObject currentFormObject) {
  950. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  951. if ((formValue['Height']?.isNotEmpty ?? false) &&
  952. (formValue['Weight']?.isNotEmpty ?? false)) {
  953. formValue['Bmi'] = (double.parse(formValue['Weight']) /
  954. ((double.parse(formValue['Height']) / 100) *
  955. (double.parse(formValue['Height']) / 100)))
  956. .toStringAsFixed(2);
  957. }
  958. Future<void> commonInput() async {
  959. String? result = await VDialogNumber(
  960. title: currentFormObject.label,
  961. initialValue: formValue[currentFormObject.key],
  962. ).show();
  963. if (result?.isNotEmpty ?? false) {
  964. formValue[currentFormObject.key!] = result;
  965. currentInputValue = formValue[currentFormObject.key!];
  966. setState(() {});
  967. }
  968. }
  969. void specialInput(String value) {
  970. formValue[currentFormObject.key!] = value;
  971. currentInputValue = formValue[currentFormObject.key!];
  972. setState(() {});
  973. }
  974. return ExamNumberInput(
  975. currentInputValue: currentInputValue,
  976. commonInput: commonInput,
  977. specialInput: specialInput,
  978. currentFormObject: currentFormObject,
  979. );
  980. }
  981. Widget _buildInput(FormObject currentFormObject) {
  982. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  983. Future<void> commonInput() async {
  984. String? result = await VDialogInput(
  985. title: currentFormObject.label,
  986. initialValue: formValue[currentFormObject.key],
  987. ).show();
  988. if (result?.isNotEmpty ?? false) {
  989. formValue[currentFormObject.key!] = result;
  990. currentInputValue = formValue[currentFormObject.key!];
  991. setState(() {});
  992. }
  993. }
  994. return ExamInput(
  995. currentInputValue: currentInputValue,
  996. commonInput: commonInput,
  997. currentFormObject: currentFormObject,
  998. );
  999. }
  1000. /// 血压组件
  1001. Widget _buildBloodPressure(FormObject currentFormObject) {
  1002. Map currentValue = formValue[currentFormObject.key!] ?? {};
  1003. print(currentFormObject.key!);
  1004. void bloodPressure(Map value) {
  1005. currentValue = value;
  1006. formValue[currentFormObject.key!] = currentValue;
  1007. // setState(() {});
  1008. }
  1009. return FollowBloodPressure(
  1010. currentValue: currentValue,
  1011. bloodPressure: bloodPressure,
  1012. );
  1013. }
  1014. Widget _buildUrinalysis(FormObject currentFormObject) {
  1015. Map currentValue = formValue[currentFormObject.key!] ?? {};
  1016. void urinalysis(Map value) {
  1017. currentValue = value;
  1018. formValue[currentFormObject.key!] = currentValue;
  1019. setState(() {});
  1020. }
  1021. return ExamUrinalysis(
  1022. currentValue: currentValue,
  1023. urinalysis: urinalysis,
  1024. );
  1025. }
  1026. ///时间组件
  1027. Widget _buildDate(FormObject currentFormObject) {
  1028. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  1029. DateTime currentDateValue = DateTime.now();
  1030. if (currentInputValue.isNotNullOrEmpty) {
  1031. DateFormat format = DateFormat('yyyy-MM-dd');
  1032. currentDateValue = format.parse(currentInputValue);
  1033. }
  1034. Future<void> commonInput() async {
  1035. DateTime? result = await VDialogDate(
  1036. title: currentFormObject.label,
  1037. initialValue: currentDateValue,
  1038. maxValue: DateTime.now(),
  1039. ).show();
  1040. if (result != null) {
  1041. formValue[currentFormObject.key!] =
  1042. DateFormat("yyyy-MM-dd").format(result);
  1043. currentInputValue = formValue[currentFormObject.key!];
  1044. setState(() {});
  1045. }
  1046. }
  1047. return ExamInput(
  1048. currentInputValue: currentInputValue,
  1049. commonInput: commonInput,
  1050. currentFormObject: currentFormObject,
  1051. );
  1052. }
  1053. ///两次随访期间住院情况
  1054. Widget _buildRadioHospitalization(FormObject currentFormObject) {
  1055. List<Option> options = currentFormObject.options ?? [];
  1056. String currentSelected = formValue[currentFormObject.key!] ?? '';
  1057. String dateOfDischarge =
  1058. formValue[currentFormObject.childrenKey!.first] ?? '';
  1059. void selectRaidoChange(Option e) {
  1060. currentSelected = currentSelected = e.value ?? "";
  1061. formValue[currentFormObject.key!] = currentSelected;
  1062. setState(() {});
  1063. }
  1064. Future<void> commonInputDate() async {
  1065. DateTime? result = await VDialogDate(
  1066. title: currentFormObject.label,
  1067. // initialValue: currentDateValue,
  1068. maxValue: DateTime.now(),
  1069. ).show();
  1070. if (result != null) {
  1071. dateOfDischarge = DateFormat("yyyy-MM-dd").format(result);
  1072. formValue[currentFormObject.childrenKey!.first] = dateOfDischarge;
  1073. setState(() {});
  1074. }
  1075. }
  1076. return ExamRadioHospitalization(
  1077. options: options,
  1078. currentFormObject: currentFormObject,
  1079. selectRaidoChange: selectRaidoChange,
  1080. currentSelected: currentSelected,
  1081. commonInput: commonInputDate,
  1082. dateOfDischarge: dateOfDischarge,
  1083. );
  1084. }
  1085. ///用药情况与指导
  1086. Widget _buildMedication(FormObject currentFormObject) {
  1087. List<dynamic> currentValue = [];
  1088. var value = formValue[currentFormObject.key!];
  1089. if (value is String) {
  1090. return Container();
  1091. } else {
  1092. if (value != null) currentValue = value;
  1093. }
  1094. Future<void> addVeterinaryDrug() async {
  1095. MedicationModel? result = await VDialogMedication(
  1096. title: currentFormObject.label,
  1097. ).show();
  1098. if (result != null) {
  1099. currentValue.add(result.toJson());
  1100. formValue[currentFormObject.key!] = null;
  1101. formValue[currentFormObject.key!] = currentValue;
  1102. setState(() {});
  1103. }
  1104. }
  1105. Future<void> deleteVeterinaryDrug(int index) async {
  1106. currentValue.removeAt(index);
  1107. formValue[currentFormObject.key!] = null;
  1108. formValue[currentFormObject.key!] = currentValue;
  1109. setState(() {});
  1110. }
  1111. Future<void> editVeterinaryDrug(int index) async {
  1112. MedicationModel medicationModel =
  1113. MedicationModel.fromJson(currentValue[index]);
  1114. MedicationModel? result = await VDialogMedication(
  1115. title: currentFormObject.label,
  1116. medicationModel: medicationModel,
  1117. ).show();
  1118. if (result != null) {
  1119. currentValue[index] = result.toJson();
  1120. formValue[currentFormObject.key!] = null;
  1121. formValue[currentFormObject.key!] = currentValue;
  1122. setState(() {});
  1123. }
  1124. }
  1125. return ExamMedication(
  1126. currentFormObject: currentFormObject,
  1127. currentValues: currentValue,
  1128. addVeterinaryDrug: addVeterinaryDrug,
  1129. deleteVeterinaryDrug: deleteVeterinaryDrug,
  1130. editVeterinaryDrug: editVeterinaryDrug,
  1131. );
  1132. }
  1133. /// 高血压和糖尿病用药情况与指导
  1134. Widget _buildGxyAndTnbMedication(FormObject currentFormObject) {
  1135. List<dynamic> currentValue = [];
  1136. var value = formValue[currentFormObject.key!];
  1137. if (value is String) {
  1138. return Container();
  1139. } else {
  1140. if (value != null) currentValue = value;
  1141. }
  1142. Future<void> addVeterinaryDrug() async {
  1143. MedicationModel? result = await VDialogGxyMedication(
  1144. title: currentFormObject.label,
  1145. ).show();
  1146. if (result != null) {
  1147. currentValue.add(result.toJson());
  1148. formValue[currentFormObject.key!] = null;
  1149. formValue[currentFormObject.key!] = currentValue;
  1150. setState(() {});
  1151. }
  1152. }
  1153. Future<void> deleteVeterinaryDrug(int index) async {
  1154. currentValue.removeAt(index);
  1155. formValue[currentFormObject.key!] = null;
  1156. formValue[currentFormObject.key!] = currentValue;
  1157. setState(() {});
  1158. }
  1159. Future<void> editVeterinaryDrug(int index) async {
  1160. MedicationModel medicationModel =
  1161. MedicationModel.fromJson(currentValue[index]);
  1162. MedicationModel? result = await VDialogGxyMedication(
  1163. title: currentFormObject.label,
  1164. medicationModel: medicationModel,
  1165. ).show();
  1166. if (result != null) {
  1167. currentValue[index] = result.toJson();
  1168. formValue[currentFormObject.key!] = null;
  1169. formValue[currentFormObject.key!] = currentValue;
  1170. setState(() {});
  1171. }
  1172. }
  1173. return FollowUpGxyAndTnbMedication(
  1174. currentFormObject: currentFormObject,
  1175. currentValues: currentValue,
  1176. addVeterinaryDrug: addVeterinaryDrug,
  1177. deleteVeterinaryDrug: deleteVeterinaryDrug,
  1178. editVeterinaryDrug: editVeterinaryDrug,
  1179. );
  1180. }
  1181. ///转诊
  1182. Widget _buildRadioReferral(FormObject currentFormObject) {
  1183. List<Option> options = currentFormObject.options ?? [];
  1184. String currentSelected = formValue[currentFormObject.key!] ?? '';
  1185. String reasonReferral =
  1186. formValue[currentFormObject.childrenKey!.first] ?? '';
  1187. String organizationSection =
  1188. formValue[currentFormObject.childrenKey!.last] ?? '';
  1189. void selectRaidoChange(Option e) {
  1190. currentSelected = e.value ?? '';
  1191. formValue[currentFormObject.key!] = currentSelected;
  1192. setState(() {});
  1193. }
  1194. Future<void> commonInputDate(bool isReasonReferral) async {
  1195. String? result = await VDialogInput(
  1196. title: isReasonReferral ? "转诊原因" : "转诊至机构及科室",
  1197. initialValue: isReasonReferral ? reasonReferral : organizationSection,
  1198. ).show();
  1199. if (result?.isNotEmpty ?? false) {
  1200. if (isReasonReferral) {
  1201. reasonReferral = result ?? '';
  1202. } else {
  1203. organizationSection = result ?? '';
  1204. }
  1205. var currentKey = isReasonReferral
  1206. ? currentFormObject.childrenKey!.first
  1207. : currentFormObject.childrenKey!.last;
  1208. formValue[currentKey] = result ?? '';
  1209. setState(() {});
  1210. }
  1211. }
  1212. return ExamRadioReferral(
  1213. options: options,
  1214. currentFormObject: currentFormObject,
  1215. selectRaidoChange: selectRaidoChange,
  1216. currentSelected: currentSelected,
  1217. commonInput: commonInputDate,
  1218. organizationSection: organizationSection,
  1219. reasonReferral: reasonReferral,
  1220. );
  1221. }
  1222. /// 单选框组件
  1223. Widget _buildRadio(FormObject currentFormObject) {
  1224. List<Option> options = currentFormObject.options ?? [];
  1225. String currentSelected = formValue[currentFormObject.key!] ?? "";
  1226. void selectRaidoChange(Option e) {
  1227. currentSelected = e.value ?? '';
  1228. formValue[currentFormObject.key!] = currentSelected;
  1229. setState(() {});
  1230. }
  1231. return ExamRadio(
  1232. options: options,
  1233. currentFormObject: currentFormObject,
  1234. selectRaidoChange: selectRaidoChange,
  1235. currentSelected: currentSelected,
  1236. );
  1237. }
  1238. /// 居民详情组件
  1239. Widget _buildResidentDetail(FormObject currentFormObject) {
  1240. return FollowUpResidentDetail();
  1241. }
  1242. Widget _buildRadioScore(FormObject currentFormObject) {
  1243. print(currentFormObject.toJson());
  1244. List<Option> options = currentFormObject.options ?? [];
  1245. String currentSelected =
  1246. formValue[currentFormObject.childrenKey!.first] ?? "";
  1247. String currentScore = formValue[currentFormObject.childrenKey!.last] ?? "";
  1248. void selectRaidoChange(Option e) {
  1249. currentSelected = e.value ?? '';
  1250. formValue[currentFormObject.childrenKey!.first] = currentSelected;
  1251. setState(() {});
  1252. }
  1253. void changeScore(String? score) {
  1254. currentScore = score ?? '';
  1255. formValue[currentFormObject.childrenKey!.last] = currentScore;
  1256. setState(() {});
  1257. }
  1258. return ExamRadioScore(
  1259. options: options,
  1260. currentFormObject: currentFormObject,
  1261. selectRaidoChange: selectRaidoChange,
  1262. currentSelected: currentSelected,
  1263. changeScore: changeScore,
  1264. currentScore: currentScore,
  1265. );
  1266. }
  1267. Widget _buildRadioInput(FormObject currentFormObject) {
  1268. List<Option> options = currentFormObject.options ?? [];
  1269. String currentSelected =
  1270. formValue[currentFormObject.childrenKey!.first] ?? "";
  1271. String currentValue = formValue[currentFormObject.childrenKey!.last] ?? "";
  1272. void selectRaidoChange(Option e) {
  1273. currentSelected = e.value ?? '';
  1274. formValue[currentFormObject.childrenKey!.first] = currentSelected;
  1275. setState(() {});
  1276. }
  1277. void changeValue(String? value) {
  1278. currentValue = value ?? '';
  1279. formValue[currentFormObject.childrenKey!.last] = currentValue;
  1280. setState(() {});
  1281. }
  1282. return FollowUpChildRadioInput(
  1283. options: options,
  1284. currentFormObject: currentFormObject,
  1285. selectRaidoChange: selectRaidoChange,
  1286. currentSelected: currentSelected,
  1287. changeValue: changeValue,
  1288. currentValue: currentValue,
  1289. );
  1290. }
  1291. Widget _buildRadioExtraDescription(FormObject currentFormObject) {
  1292. print(currentFormObject.toJson());
  1293. List<Option> options = currentFormObject.options ?? [];
  1294. String currentValue = formValue[currentFormObject.key!] ?? "";
  1295. String otherDecrition =
  1296. formValue[currentFormObject.childrenKey!.first] ?? "";
  1297. dynamic otherItem = currentFormObject.groupKeys!.first;
  1298. void selectRaidoChange(Option e) {
  1299. currentValue = e.value ?? '';
  1300. formValue[currentFormObject.key!] = currentValue;
  1301. setState(() {});
  1302. }
  1303. void changeExtraDescription(String? extraDescription) {
  1304. otherDecrition = extraDescription ?? '';
  1305. formValue[currentFormObject.childrenKey!.first] = otherDecrition;
  1306. setState(() {});
  1307. }
  1308. return ExamRadioExtraDescription(
  1309. options: options,
  1310. currentFormObject: currentFormObject,
  1311. selectRaidoChange: selectRaidoChange,
  1312. currentSelected: currentValue,
  1313. changeExtraDescription: changeExtraDescription,
  1314. currentExtraDescription: otherDecrition,
  1315. extraDescriptiveItem: otherItem,
  1316. );
  1317. }
  1318. /// 体温组件
  1319. Widget _buildBodyTemperature(FormObject currentFormObject) {
  1320. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  1321. void bodyTemperatureInput(String value) {
  1322. formValue[currentFormObject.key!] = value;
  1323. currentInputValue = formValue[currentFormObject.key!];
  1324. setState(() {});
  1325. }
  1326. return ExamBodyTemperature(
  1327. currentInputValue: currentInputValue,
  1328. bodyTemperatureInput: bodyTemperatureInput,
  1329. currentFormObject: currentFormObject,
  1330. );
  1331. }
  1332. Widget _buildToxicSubstance(FormObject currentFormObject) {
  1333. List<Option> options = currentFormObject.options ?? [];
  1334. String currentValue = formValue[currentFormObject.childrenKey!.first] ?? "";
  1335. Map? currentSelectedToxicSubstance =
  1336. formValue[currentFormObject.childrenKey!.last];
  1337. void selectRaidoChange(Map e) {
  1338. currentSelectedToxicSubstance = e;
  1339. formValue[currentFormObject.childrenKey!.last] =
  1340. currentSelectedToxicSubstance;
  1341. setState(() {});
  1342. }
  1343. void selectValueChange(String e) {
  1344. currentValue = e;
  1345. formValue[currentFormObject.childrenKey!.first] = currentValue;
  1346. setState(() {});
  1347. }
  1348. return ExamToxicSubstance(
  1349. currentFormObject: currentFormObject,
  1350. currentSelectedToxicSubstance: currentSelectedToxicSubstance,
  1351. currentValue: currentValue,
  1352. options: options,
  1353. selectRadioChange: selectRaidoChange,
  1354. selectValueChange: selectValueChange,
  1355. );
  1356. }
  1357. /// 血氧
  1358. Widget _buildBloodOxygen(FormObject currentFormObject) {
  1359. Map<String, dynamic> currentValue = formValue;
  1360. void bloodOxygenInput(Map<String, dynamic> bloodOxygen) {
  1361. formValue['Pulse_Frequency'] = bloodOxygen['Pulse_Frequency'];
  1362. formValue['Spo2'] = bloodOxygen['Spo2'];
  1363. currentValue = bloodOxygen;
  1364. setState(() {});
  1365. }
  1366. return ExamBloodOxygen(
  1367. currentValue: currentValue,
  1368. bloodOxygenInput: bloodOxygenInput,
  1369. );
  1370. }
  1371. /// 住院史
  1372. Widget _buildMedicalHistory(FormObject currentFormObject) {
  1373. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  1374. int currentId = currentValue.length + 1;
  1375. void resultChange(Map result) {
  1376. currentValue.add(result);
  1377. formValue[currentFormObject.key!] = currentValue;
  1378. setState(() {});
  1379. }
  1380. void editResult(EditTableValue result) {
  1381. currentValue[result.id! - 1] = result.value;
  1382. formValue[currentFormObject.key!] = currentValue;
  1383. setState(() {});
  1384. }
  1385. Future<void> addTableData() async {
  1386. Get.dialog(
  1387. HospitalizationHistoryForm(
  1388. fromResult: (result) => resultChange(result),
  1389. currentId: currentId,
  1390. ),
  1391. );
  1392. }
  1393. Future<void> editTableData(EditTableValue editTableValue) async {
  1394. Get.dialog(
  1395. HospitalizationHistoryForm(
  1396. fromResult: (result) => editResult(result),
  1397. currentId: editTableValue.id!,
  1398. admissionJson: editTableValue.value,
  1399. ),
  1400. );
  1401. }
  1402. return ExamTable(
  1403. tableThList: const ['序号', '入院日期', '出院日期', '原因', '医疗机构名称', '病案号', '操作'],
  1404. currentFormObject: currentFormObject,
  1405. currentValue: currentValue,
  1406. addTableData: addTableData,
  1407. editTableData: (value) => editTableData(value),
  1408. );
  1409. }
  1410. /// 家庭病床史
  1411. Widget _buildHomecareBedHistory(FormObject currentFormObject) {
  1412. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  1413. int currentId = currentValue.length + 1;
  1414. void resultChange(Map result) {
  1415. for (var i in result.keys) {
  1416. if (result[i] == "") {
  1417. return;
  1418. }
  1419. }
  1420. currentValue.add(result);
  1421. formValue[currentFormObject.key!] = currentValue;
  1422. setState(() {});
  1423. }
  1424. void editResult(EditTableValue result) {
  1425. currentValue[result.id! - 1] = result.value;
  1426. formValue[currentFormObject.key!] = currentValue;
  1427. setState(() {});
  1428. }
  1429. Future<void> addTableData() async {
  1430. Get.dialog(
  1431. HomecareBedHistoryFrom(
  1432. fromResult: (result) => resultChange(result),
  1433. currentId: currentId,
  1434. ),
  1435. );
  1436. }
  1437. Future<void> editTableData(EditTableValue editTableValue) async {
  1438. Get.dialog(
  1439. HomecareBedHistoryFrom(
  1440. fromResult: (result) => editResult(result),
  1441. currentId: editTableValue.id!,
  1442. admissionJson: editTableValue.value,
  1443. ),
  1444. );
  1445. }
  1446. return ExamTable(
  1447. tableThList: const ['序号', '建床日期', '撤床日期', '原因', '医疗机构名称', '病案号', '操作'],
  1448. currentFormObject: currentFormObject,
  1449. currentValue: currentValue,
  1450. addTableData: addTableData,
  1451. editTableData: (value) => editTableData(value),
  1452. );
  1453. }
  1454. Widget _buildMainMedicationHistory(FormObject currentFormObject) {
  1455. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  1456. int currentId = currentValue.length + 1;
  1457. void resultChange(Map result) {
  1458. currentValue.add(result);
  1459. formValue[currentFormObject.key!] = currentValue;
  1460. setState(() {});
  1461. }
  1462. void editResult(EditTableValue result) {
  1463. currentValue[result.id! - 1] = result.value;
  1464. formValue[currentFormObject.key!] = currentValue;
  1465. setState(() {});
  1466. }
  1467. Future<void> addTableData() async {
  1468. Get.dialog(
  1469. MainMedicationStatusFrom(
  1470. fromResult: (result) => resultChange(result),
  1471. currentId: currentId,
  1472. ),
  1473. );
  1474. }
  1475. Future<void> editTableData(EditTableValue editTableValue) async {
  1476. Get.dialog(
  1477. MainMedicationStatusFrom(
  1478. fromResult: (result) => editResult(result),
  1479. currentId: editTableValue.id!,
  1480. admissionJson: editTableValue.value,
  1481. ),
  1482. );
  1483. }
  1484. return ExamTable(
  1485. tableThList: const ['序号', '药物名称', '用法', '用量', '用药时间', '服药依从性', '操作'],
  1486. currentFormObject: currentFormObject,
  1487. currentValue: currentValue,
  1488. addTableData: addTableData,
  1489. editTableData: (value) => editTableData(value),
  1490. );
  1491. }
  1492. Widget _buildInoculateHistory(FormObject currentFormObject) {
  1493. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  1494. int currentId = currentValue.length + 1;
  1495. void resultChange(Map result) {
  1496. currentValue.add(result);
  1497. formValue[currentFormObject.key!] = currentValue;
  1498. setState(() {});
  1499. }
  1500. void editResult(EditTableValue result) {
  1501. currentValue[result.id! - 1] = result.value;
  1502. formValue[currentFormObject.key!] = currentValue;
  1503. setState(() {});
  1504. }
  1505. Future<void> addTableData() async {
  1506. Get.dialog(
  1507. InoculateHistoryFrom(
  1508. fromResult: (result) => resultChange(result),
  1509. currentId: currentId,
  1510. ),
  1511. );
  1512. }
  1513. Future<void> editTableData(EditTableValue editTableValue) async {
  1514. Get.dialog(
  1515. InoculateHistoryFrom(
  1516. fromResult: (result) => editResult(result),
  1517. currentId: editTableValue.id!,
  1518. admissionJson: editTableValue.value,
  1519. ),
  1520. );
  1521. }
  1522. return ExamTable(
  1523. tableThList: const ['序号', '疫苗名称', '接种日期', '接种机构', '操作'],
  1524. currentFormObject: currentFormObject,
  1525. currentValue: currentValue,
  1526. addTableData: addTableData,
  1527. editTableData: (value) => editTableData(value),
  1528. );
  1529. }
  1530. /// 体重
  1531. Widget _buildBodyWeight(FormObject currentFormObject) {
  1532. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  1533. void bodyWeightInput(String value) {
  1534. formValue[currentFormObject.key!] = value;
  1535. currentInputValue = formValue[currentFormObject.key!];
  1536. setState(() {});
  1537. }
  1538. return ExamBodyWeight(
  1539. currentInputValue: currentInputValue,
  1540. bodyWeightInput: bodyWeightInput,
  1541. currentFormObject: currentFormObject,
  1542. );
  1543. }
  1544. /// 血糖
  1545. Widget _buildBodySugar(FormObject currentFormObject) {
  1546. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  1547. void bloodSugarInput(String value) {
  1548. formValue[currentFormObject.key!] = value;
  1549. currentInputValue = formValue[currentFormObject.key!];
  1550. setState(() {});
  1551. }
  1552. return ExamBloodSugar(
  1553. currentInputValue: currentInputValue,
  1554. bloodSugarInput: bloodSugarInput,
  1555. currentFormObject: currentFormObject,
  1556. );
  1557. }
  1558. /// 处方组件
  1559. Widget _buildPrescription(FormObject currentFormObject) {
  1560. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  1561. prescriptionKey = currentFormObject.buttonName ?? '';
  1562. return Prescription(
  1563. prescription: prescriptionKey,
  1564. );
  1565. }
  1566. /// 计算儿童状态的方法
  1567. String _setChildHeightAndWeightStatus(
  1568. String currentKey,
  1569. String currentValue,
  1570. ) {
  1571. PatientDTO? currentSelectPatientInfo = Store.user.currentSelectPatientInfo;
  1572. String statusValue = "";
  1573. if (currentSelectPatientInfo != null) {
  1574. int birthdayMonths = int.parse(
  1575. ComputeChildrenLevel.calculateMonthsFromBirthday(
  1576. Store.user.currentSelectPatientInfo?.birthday,
  1577. ),
  1578. );
  1579. switch (currentKey) {
  1580. case "Stature":
  1581. statusValue = ComputeChildrenLevel.calculateHeightStatus(
  1582. Store.user.currentSelectPatientInfo?.patientGender ??
  1583. GenderEnum.Male,
  1584. birthdayMonths,
  1585. double.parse(currentValue),
  1586. );
  1587. break;
  1588. case "Weight":
  1589. statusValue = ComputeChildrenLevel.calculateWidthStatus(
  1590. Store.user.currentSelectPatientInfo?.patientGender ??
  1591. GenderEnum.Male,
  1592. birthdayMonths,
  1593. double.parse(currentValue),
  1594. );
  1595. break;
  1596. case "Wh":
  1597. statusValue = ComputeChildrenLevel.calculateBmiStatus(
  1598. Store.user.currentSelectPatientInfo?.patientGender ??
  1599. GenderEnum.Male,
  1600. birthdayMonths,
  1601. double.parse(formValue["Weight"]),
  1602. double.parse(formValue["Stature"]),
  1603. );
  1604. break;
  1605. default:
  1606. break;
  1607. }
  1608. }
  1609. return statusValue;
  1610. }
  1611. /// 儿童身高、体重、BMI
  1612. Widget _buildChildHeightAndWeight(FormObject currentFormObject) {
  1613. List<Option> options = currentFormObject.options ?? [];
  1614. List<dynamic>? childrenKey = currentFormObject.childrenKey;
  1615. String inputKey = "";
  1616. String radioKey = "";
  1617. if (childrenKey != null && childrenKey.isNotEmpty) {
  1618. inputKey = childrenKey.first;
  1619. radioKey = childrenKey.last;
  1620. }
  1621. void childHeightAndWeightInput(String value) async {
  1622. formValue[inputKey] = value;
  1623. var currentSelectValue =
  1624. await _setChildHeightAndWeightStatus(inputKey, value);
  1625. formValue[radioKey] = options
  1626. .firstWhereOrNull((element) => element.label == currentSelectValue)
  1627. ?.value;
  1628. if (formValue["Stature"] != null && formValue["Weight"] != null) {
  1629. formValue["Wh"] = ((double.parse(formValue["Weight"])) /
  1630. ((double.parse(formValue["Stature"]) / 100) *
  1631. (double.parse(formValue["Stature"]) / 100)))
  1632. .toStringAsFixed(2);
  1633. var currentWhEvaluateSelectValue =
  1634. await _setChildHeightAndWeightStatus("Wh", formValue["Wh"]);
  1635. formValue["Wh_Evaluate"] = options
  1636. .firstWhereOrNull(
  1637. (element) => element.label == currentWhEvaluateSelectValue)
  1638. ?.value;
  1639. print(formValue["Wh_Evaluate"]);
  1640. }
  1641. setState(() {});
  1642. }
  1643. void selectRaidoChange(Option e) {
  1644. formValue[radioKey] = e.value ?? '';
  1645. setState(() {});
  1646. }
  1647. return FollowUpChildHeightAndWeight(
  1648. options: options,
  1649. currentFormObject: currentFormObject,
  1650. childHeightAndWeightInput: childHeightAndWeightInput,
  1651. formValue: formValue,
  1652. selectRaidoChange: selectRaidoChange,
  1653. keys: [inputKey, radioKey],
  1654. );
  1655. }
  1656. }