configurable_card.dart 60 KB

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