configurable_card.dart 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  1. import 'dart:convert';
  2. import 'package:fis_jsonrpc/rpc.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:get/get.dart';
  5. import 'package:vitalapp/components/button.dart';
  6. import 'package:vitalapp/components/dialog_input.dart';
  7. import 'package:vitalapp/components/dialog_number.dart';
  8. import 'package:vitalapp/components/dynamic_drawer.dart';
  9. import 'package:vitalapp/managers/interfaces/cachedRecord.dart';
  10. import 'package:vitalapp/managers/interfaces/template.dart';
  11. import 'package:vitalapp/pages/check/models/form.dart';
  12. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_blood_pressure.dart';
  13. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_blood_sugar.dart';
  14. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_body_temperature.dart';
  15. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_body_weight.dart';
  16. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_boold_oxygen.dart';
  17. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_check_box.dart';
  18. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_health_guidance_check_box.dart';
  19. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_input.dart';
  20. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_number_input.dart';
  21. import 'dart:math' as math;
  22. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio.dart';
  23. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio_score.dart';
  24. import 'package:vitalapp/pages/check/widgets/device_controller.dart';
  25. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_table.dart';
  26. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_toxic_substance.dart';
  27. import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_urinalys.dart';
  28. import 'package:vitalapp/pages/check/widgets/exam_table/homecare_bed_history_from.dart';
  29. import 'package:vitalapp/pages/check/widgets/exam_table/hospitalization_history_from.dart';
  30. import 'package:vitalapp/pages/check/widgets/exam_table/inoculate_history_from.dart';
  31. import 'package:vitalapp/pages/check/widgets/exam_table/main_medication_status_from.dart';
  32. import 'package:vitalapp/pages/check/widgets/title_clip_path.dart';
  33. class ConfigurableCard extends StatefulWidget {
  34. final String cardKey;
  35. final Future<bool> Function(String, String, dynamic) callBack;
  36. final Widget? followUpWidget;
  37. final String? patientCode;
  38. final String? examData;
  39. const ConfigurableCard({
  40. super.key,
  41. required this.cardKey,
  42. required this.callBack,
  43. this.followUpWidget,
  44. this.patientCode,
  45. this.examData,
  46. });
  47. @override
  48. State<ConfigurableCard> createState() => _ConfigurableFormState();
  49. }
  50. class _ConfigurableFormState extends State<ConfigurableCard> {
  51. /// 当前最新的模板的键值对
  52. Map<String, dynamic> templateRelation = {};
  53. /// 当前模板数据
  54. List<FormObject> currentTemplate = [];
  55. /// 当前title的下标
  56. int currentTitleIndex = 0;
  57. Map<String, dynamic> formValue = {};
  58. var scaffoldKey = GlobalKey<ScaffoldState>();
  59. final _templateManager = Get.find<ITemplateManager>();
  60. final _cachedRecordManager = Get.find<ICachedRecordManager>();
  61. final arrowHeight = math.tan(120 / 180) * 19;
  62. List<String> deviceList = ['Temp', 'GLU', 'NIBP', 'SpO2', 'BMI'];
  63. Map<String, dynamic> deviceCached = {};
  64. Map currentTable = {};
  65. List<String> storeTypeList = [
  66. 'Qi_Score',
  67. 'Yang_Score',
  68. 'Yin_Score',
  69. 'Tan_Score',
  70. 'Shi_Score',
  71. 'Xue_Score',
  72. 'Qiyu_Score',
  73. 'Te_Score',
  74. 'Ping_Score'
  75. ];
  76. @override
  77. void initState() {
  78. Get.put(DeviceController());
  79. super.initState();
  80. WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
  81. if (mounted) {
  82. initTemplate();
  83. }
  84. });
  85. }
  86. @override
  87. void dispose() {
  88. super.dispose();
  89. }
  90. Future<void> initTemplate() async {
  91. Get.find<DeviceController>().busy = true;
  92. await fetchTemplateIndex();
  93. await fetchTemplate(widget.cardKey);
  94. await fetchTemplateData();
  95. // GlobalCacheHelper.setItem(GlobalCacheHelper.keys.followUpEditTemp, "");//TODO
  96. Get.find<DeviceController>().busy = false;
  97. // if (!['GXY', 'TNB'].contains(widget.cardKey)) {
  98. // fetchTemplateData();
  99. // }
  100. }
  101. /// 读取健康检测的缓存
  102. Future<String?> readCachedRecord(String currentDevice) async {
  103. if (widget.patientCode == null) {
  104. return null;
  105. }
  106. String? value = await _cachedRecordManager.readCachedRecord(
  107. currentDevice,
  108. widget.patientCode!,
  109. 'ZLZS',
  110. );
  111. return value;
  112. }
  113. /// 读取体检的缓存
  114. Future<String?> readCachedCheck() async {
  115. if (widget.patientCode == null) {
  116. return null;
  117. }
  118. String? value = await _cachedRecordManager.readCachedRecord(
  119. widget.cardKey,
  120. widget.patientCode!,
  121. 'exam',
  122. );
  123. return value;
  124. }
  125. Future<void> readCached() async {
  126. for (var element in deviceList) {
  127. String? value = await readCachedRecord(element);
  128. if (value?.isNotEmpty ?? false) {
  129. deviceCached.addAll(jsonDecode(value!));
  130. }
  131. }
  132. }
  133. Future<void> fetchTemplateIndex() async {
  134. try {
  135. /// 获取模板的键值对
  136. String? templates;
  137. templates =
  138. await _templateManager.readTemplateRelation('templateRelation');
  139. templateRelation = jsonDecode(templates!);
  140. setState(() {});
  141. } catch (error) {
  142. print('发生错误: $error');
  143. }
  144. }
  145. Future<void> fetchTemplateData() async {
  146. // / 这逻辑需要优化
  147. if (widget.examData?.isNotEmpty ?? false) {
  148. formValue = jsonDecode(widget.examData!);
  149. return;
  150. }
  151. String? value = await readCachedCheck();
  152. await readCached();
  153. if (deviceCached.isNotEmpty) {
  154. formValue = deviceCached;
  155. setState(() {});
  156. return;
  157. }
  158. if (value?.isNotEmpty ?? false) {
  159. formValue = jsonDecode(value!);
  160. }
  161. formValue.forEach(
  162. (key, value) {
  163. if (value is List<String>) {
  164. formValue[key] = List<String>.from(formValue[key]);
  165. } else if (value is List<Map>) {
  166. formValue[key] = List<Map>.from(formValue[key]);
  167. }
  168. },
  169. );
  170. setState(() {});
  171. }
  172. Future<void> fetchTemplate(String key) async {
  173. try {
  174. if (templateRelation[key] == null) {
  175. currentTemplate = [];
  176. setState(() {});
  177. return;
  178. }
  179. var template =
  180. await _templateManager.readTemplate(templateRelation[key]!);
  181. String templateContent =
  182. TemplateDTO.fromJson(jsonDecode(template!)).templateContent!;
  183. List<Map<String, dynamic>> list =
  184. jsonDecode(templateContent).cast<Map<String, dynamic>>();
  185. for (var i in list) {
  186. if (i['children'] != null) {
  187. List<FormObject> currentChildren = [];
  188. for (var j in i['children']) {
  189. currentChildren.add(FormObject.fromJson(j));
  190. }
  191. i['children'] = currentChildren;
  192. }
  193. var item = FormObject.fromJson(i);
  194. currentTemplate.add(item);
  195. }
  196. if (widget.cardKey == 'LNRZYYJKGLFWJL') {
  197. for (var element in storeTypeList) {
  198. formValue[element] =
  199. calculatePhysicalFitnessScore(element, element == 'Ping_Score');
  200. }
  201. }
  202. setState(() {});
  203. } catch (error) {
  204. print('发生错误: $error');
  205. }
  206. }
  207. @override
  208. Widget build(BuildContext context) {
  209. return Scaffold(
  210. key: scaffoldKey,
  211. endDrawer: VDynamicDrawerWrapper(scaffoldKey: scaffoldKey),
  212. resizeToAvoidBottomInset: false,
  213. body: Column(
  214. children: [
  215. Row(
  216. crossAxisAlignment: CrossAxisAlignment.start,
  217. children: [
  218. const SizedBox(
  219. width: 16,
  220. ),
  221. Container(
  222. margin: const EdgeInsets.only(top: 8),
  223. width: 130,
  224. height: 54,
  225. child: VButton(
  226. onTap: () => {Get.back()},
  227. child: Row(
  228. mainAxisAlignment: MainAxisAlignment.center,
  229. children: const [
  230. Icon(Icons.arrow_back_ios_new, size: 24),
  231. SizedBox(
  232. width: 8,
  233. ),
  234. Text("返回", style: TextStyle(fontSize: 20)),
  235. ],
  236. ),
  237. ),
  238. ),
  239. Expanded(
  240. child: Container(
  241. padding:
  242. const EdgeInsets.symmetric(vertical: 16, horizontal: 10),
  243. child: _buildTitleList(),
  244. ),
  245. ),
  246. Container(
  247. margin: const EdgeInsets.only(top: 8, right: 16),
  248. width: 130,
  249. height: 54,
  250. child: VButton(
  251. onTap: () async {
  252. final result = await widget.callBack(
  253. widget.cardKey,
  254. templateRelation[widget.cardKey]!,
  255. jsonEncode(formValue),
  256. );
  257. if (result) {
  258. Get.back();
  259. }
  260. },
  261. child: Row(
  262. mainAxisAlignment: MainAxisAlignment.center,
  263. children: const [
  264. Icon(Icons.save, size: 24),
  265. SizedBox(
  266. width: 8,
  267. ),
  268. Text("保存", style: TextStyle(fontSize: 20)),
  269. ],
  270. ),
  271. ),
  272. ),
  273. ],
  274. ),
  275. Expanded(
  276. child: Stack(
  277. children: [
  278. Row(
  279. mainAxisAlignment: MainAxisAlignment.start,
  280. crossAxisAlignment: CrossAxisAlignment.start,
  281. children: [
  282. _buildDiagram(),
  283. _buildContent(),
  284. ],
  285. ),
  286. if (currentTitleIndex != currentTemplate.length - 1)
  287. _buildPositionedButton(
  288. () async {
  289. currentTitleIndex++;
  290. setState(() {});
  291. },
  292. right: -30,
  293. ),
  294. ],
  295. ),
  296. )
  297. ],
  298. ),
  299. );
  300. }
  301. Widget buildSingleItem(Widget item, int span) {
  302. return FractionallySizedBox(
  303. widthFactor: span == 24 ? 1 : 0.5,
  304. child: item,
  305. );
  306. }
  307. Widget buildWidget(FormObject? currentFormObject) {
  308. Map<String, Widget Function(FormObject)> widgetMap = {
  309. 'checkbox': _buildCheckBox,
  310. 'numberInput': _buildNumberInput,
  311. 'input': _buildInput,
  312. 'radio': _buildRadio,
  313. 'radioScore': _buildRadioScore,
  314. 'bloodPressure': _buildBloodPressure,
  315. 'bodyTemperature': _buildBodyTemperature,
  316. 'weight': _buildBodyWeight,
  317. 'sugar': _buildBodySugar,
  318. 'bloodOxygen': _buildBloodOxygen,
  319. 'healthGuidanceCheckBox': _buildHealthGuidanceCheckBox,
  320. 'medicalHistory': _buildMedicalHistory,
  321. 'homecareBedHistor': _buildHomecareBedHistory,
  322. 'table': _buildMainMedicationHistory,
  323. 'inoculateHistory': _buildInoculateHistory,
  324. 'safetyPrecautions': _buildToxicSubstance,
  325. 'urinalys': _buildUrinalysis,
  326. };
  327. Widget Function(FormObject) builder =
  328. widgetMap[currentFormObject?.type] ?? _buildInput;
  329. return builder(currentFormObject!);
  330. }
  331. Widget flowCardList() {
  332. int itemCount = 0;
  333. bool currentTemplateOptionsIsNotEmpty = false;
  334. if (currentTemplate.isNotEmpty) {
  335. itemCount = currentTemplate[currentTitleIndex].children?.length ?? 0;
  336. currentTemplateOptionsIsNotEmpty =
  337. currentTemplate[currentTitleIndex].options?.isNotEmpty ?? false;
  338. }
  339. List<Widget> items = List.generate(itemCount, (index) {
  340. FormObject? currentFormObject =
  341. currentTemplate[currentTitleIndex].children?[index];
  342. int span = currentFormObject?.span ?? 12;
  343. //父结构的options不等于空或null
  344. if (true) {
  345. //子结构的options若是无值则取父类的options值
  346. if (currentTemplateOptionsIsNotEmpty) {
  347. currentFormObject!.options =
  348. currentTemplate[currentTitleIndex].options;
  349. }
  350. }
  351. return buildSingleItem(buildWidget(currentFormObject), span);
  352. });
  353. return Scrollbar(
  354. thumbVisibility: true,
  355. child: SingleChildScrollView(
  356. child: Container(
  357. alignment: Alignment.topCenter,
  358. padding: const EdgeInsets.all(15),
  359. child: Wrap(
  360. runSpacing: 20, // 纵向元素间距
  361. alignment: WrapAlignment.start,
  362. children: items,
  363. ),
  364. ),
  365. ),
  366. );
  367. }
  368. /// title标签
  369. Widget _buildTitleList() {
  370. return Wrap(
  371. runSpacing: 10, // 设置子小部件之间的间距
  372. spacing: -12,
  373. alignment: WrapAlignment.start,
  374. children: currentTemplate.asMap().entries.map(
  375. (e) {
  376. /// TODO 这边需要改下
  377. MaterialColor currentColors = Colors.grey;
  378. e.value.children?.forEach((element) {
  379. if (formValue.containsKey(element.key)) {
  380. if (!(widget.cardKey == 'LNRZYYJKGLFWJL' &&
  381. element.parentKey == 'Ping_Score')) {
  382. currentColors = Colors.green;
  383. } else if (element.key == 'qusition1') {
  384. {
  385. currentColors = Colors.green;
  386. }
  387. }
  388. }
  389. });
  390. return TitleClipRect(
  391. title: e.value.label ?? '',
  392. color: currentTitleIndex == e.key ? null : currentColors,
  393. arrowHeight: arrowHeight,
  394. clickTitle: () {
  395. // if (widget.cardKey == 'LNRZYYJKGLFWJL' &&
  396. // currentTitleIndex == 0 &&
  397. // formValue.length != 33) {
  398. // PromptBox.toast('题目未答全,不可进行指导');
  399. // } else
  400. {
  401. currentTitleIndex = e.key;
  402. setState(() {});
  403. }
  404. },
  405. );
  406. },
  407. ).toList(),
  408. );
  409. }
  410. /// 示意图
  411. Widget _buildDiagram() {
  412. if (widget.cardKey == 'ZYYYFMYGHYFJZS') {
  413. return const SizedBox();
  414. }
  415. return Expanded(
  416. flex: 1,
  417. child: Stack(
  418. children: [
  419. /// TODO BAKA-优化
  420. _buildImageCard(),
  421. if (currentTitleIndex != 0)
  422. _buildPositionedButton(
  423. () async {
  424. if (currentTitleIndex == 0) {
  425. Get.back();
  426. } else {
  427. currentTitleIndex--;
  428. setState(() {});
  429. }
  430. },
  431. left: -30,
  432. ),
  433. ],
  434. ),
  435. );
  436. }
  437. Widget _buildImageCard() {
  438. // if (currentTemplate[currentTitleIndex].key == 'Temperature') {
  439. // return Container(
  440. // alignment: Alignment.topCenter,
  441. // margin: const EdgeInsets.all(16).copyWith(top: 0),
  442. // child: Image.asset(
  443. // 'assets/images/healthCheck/temp.png',
  444. // height: double.infinity,
  445. // fit: BoxFit.fitWidth, // 设置图像的适应方式
  446. // ),
  447. // );
  448. // }
  449. if (['GXY', 'TNB', 'LNRZYYJKGLFWJL'].contains(widget.cardKey)) {
  450. return widget.followUpWidget!;
  451. } else {
  452. return Container(
  453. alignment: Alignment.topCenter,
  454. margin: const EdgeInsets.all(16).copyWith(top: 0),
  455. child: Image.asset(
  456. 'assets/images/exam/normalMeasurementChart.png',
  457. height: double.infinity,
  458. fit: BoxFit.fitWidth, // 设置图像的适应方式
  459. ),
  460. );
  461. }
  462. }
  463. /// 按钮
  464. Widget _buildPositionedButton(Function onTap, {double? right, double? left}) {
  465. return Positioned(
  466. right: right,
  467. left: left,
  468. bottom: 0,
  469. top: 0,
  470. child: Container(
  471. width: 100,
  472. height: 100,
  473. alignment: Alignment.centerLeft,
  474. child: InkWell(
  475. onTap: () => onTap.call(),
  476. child: Container(
  477. width: 100,
  478. height: 100,
  479. padding: const EdgeInsets.all(20),
  480. alignment:
  481. right == null ? Alignment.centerRight : Alignment.centerLeft,
  482. decoration: BoxDecoration(
  483. borderRadius: BorderRadius.circular(50),
  484. color: Theme.of(context).primaryColor.withOpacity(
  485. .8,
  486. ),
  487. ),
  488. child: Image.asset(
  489. right == null
  490. ? "assets/images/exam/left-arrow.png"
  491. : "assets/images/exam/right-arrow.png",
  492. width: 40,
  493. height: 40,
  494. color: Colors.white,
  495. fit: BoxFit.contain,
  496. ),
  497. ),
  498. ),
  499. ),
  500. );
  501. }
  502. /// 主页面
  503. Widget _buildContent() {
  504. return Expanded(
  505. flex: 2,
  506. child: flowCardList(),
  507. );
  508. }
  509. /// 多选框组件
  510. Widget _buildCheckBox(FormObject currentFormObject) {
  511. List<Option> options = currentFormObject.options ?? [];
  512. List<dynamic> currentSelectedCheckBox =
  513. formValue[currentFormObject.key!] ?? [];
  514. dynamic disabledValue = currentFormObject.disabledValue;
  515. void selectCheckBoxChange(Option e) {
  516. if (currentSelectedCheckBox.contains(e.value)) {
  517. currentSelectedCheckBox.remove(e.value);
  518. } else {
  519. if (disabledValue == e.value) {
  520. currentSelectedCheckBox = [disabledValue];
  521. } else {
  522. if (currentSelectedCheckBox.contains(disabledValue)) {
  523. // PromptBox.toast('选项冲突');
  524. } else {
  525. currentSelectedCheckBox.add(e.value ?? '');
  526. }
  527. }
  528. }
  529. formValue[currentFormObject.key!] = currentSelectedCheckBox;
  530. setState(() {});
  531. }
  532. return ExamCheckBox(
  533. options: options,
  534. currentSelectedCheckBox: currentSelectedCheckBox,
  535. currentFormObject: currentFormObject,
  536. selectCheckBoxChange: selectCheckBoxChange,
  537. disbaleOthers: currentSelectedCheckBox.contains(disabledValue),
  538. );
  539. }
  540. ///中医药健康指导多选框组件
  541. Widget _buildHealthGuidanceCheckBox(FormObject currentFormObject) {
  542. List<Option> options = currentFormObject.options ?? [];
  543. List<dynamic> currentSelectedCheckBox =
  544. formValue[currentFormObject.key!] ?? [];
  545. // var templateFromObj = currentTemplate.firstWhere(
  546. // (element) => element.label!.contains());
  547. var currentScoreKey = currentFormObject.groupKeys != null
  548. ? currentFormObject.groupKeys![0]
  549. : '';
  550. int score = formValue[currentScoreKey] ?? 0;
  551. String judgmentResult = getJudgmentResult(currentScoreKey);
  552. void selectCheckBoxChange(Option e) {
  553. if (currentSelectedCheckBox.contains(e.value)) {
  554. currentSelectedCheckBox.remove(e.value);
  555. } else {
  556. currentSelectedCheckBox.add(e.value ?? '');
  557. }
  558. formValue[currentFormObject.key!] = currentSelectedCheckBox;
  559. setState(() {});
  560. }
  561. return ExamHealthGuidanceCheckBox(
  562. options: options,
  563. currentSelectedCheckBox: currentSelectedCheckBox,
  564. currentFormObject: currentFormObject,
  565. selectCheckBoxChange: selectCheckBoxChange,
  566. score: score,
  567. judgmentResult: judgmentResult,
  568. );
  569. }
  570. String getJudgmentResult(String storeKey) {
  571. var score = formValue[storeKey] ?? 0;
  572. if (storeKey == 'Ping_Score') {
  573. if (score >= 17) {
  574. bool is8 = true;
  575. bool is10 = true;
  576. for (var e in storeTypeList) {
  577. if (formValue[e] != null && e != 'Ping_Score') {
  578. var otherScore = formValue[e];
  579. if (otherScore > 8) {
  580. if (is8) {
  581. is8 = false;
  582. }
  583. if (otherScore > 10) {
  584. is10 = false;
  585. }
  586. }
  587. if (!is10) {
  588. break;
  589. }
  590. }
  591. }
  592. if (is8) {
  593. return '是';
  594. } else if (is10) {
  595. return '基本是';
  596. }
  597. }
  598. return '否';
  599. } else {
  600. if (score >= 11) {
  601. return '是';
  602. } else if (9 == score && score == 10) {
  603. return '倾向是';
  604. } else {
  605. return '否';
  606. }
  607. }
  608. }
  609. /// 数字输入框组件
  610. Widget _buildNumberInput(FormObject currentFormObject) {
  611. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  612. if ((formValue['Height']?.isNotEmpty ?? false) &&
  613. (formValue['Weight']?.isNotEmpty ?? false)) {
  614. formValue['Bmi'] = (double.parse(formValue['Weight']) /
  615. ((double.parse(formValue['Height']) / 100) *
  616. (double.parse(formValue['Height']) / 100)))
  617. .toStringAsFixed(2);
  618. }
  619. Future<void> commonInput() async {
  620. String? result = await VDialogNumber(
  621. title: currentFormObject.label,
  622. initialValue: formValue[currentFormObject.key],
  623. ).show();
  624. if (result?.isNotEmpty ?? false) {
  625. formValue[currentFormObject.key!] = result;
  626. currentInputValue = formValue[currentFormObject.key!];
  627. setState(() {});
  628. }
  629. }
  630. void specialInput(String value) {
  631. formValue[currentFormObject.key!] = value;
  632. currentInputValue = formValue[currentFormObject.key!];
  633. setState(() {});
  634. }
  635. return ExamNumberInput(
  636. currentInputValue: currentInputValue,
  637. commonInput: commonInput,
  638. specialInput: specialInput,
  639. currentFormObject: currentFormObject,
  640. );
  641. }
  642. Widget _buildInput(FormObject currentFormObject) {
  643. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  644. Future<void> commonInput() async {
  645. String? result = await VDialogInput(
  646. title: currentFormObject.label,
  647. initialValue: formValue[currentFormObject.key],
  648. ).show();
  649. if (result?.isNotEmpty ?? false) {
  650. formValue[currentFormObject.key!] = result;
  651. currentInputValue = formValue[currentFormObject.key!];
  652. setState(() {});
  653. }
  654. }
  655. return ExamInput(
  656. currentInputValue: currentInputValue,
  657. commonInput: commonInput,
  658. currentFormObject: currentFormObject,
  659. );
  660. }
  661. /// 血压组件
  662. Widget _buildBloodPressure(FormObject currentFormObject) {
  663. Map currentValue = formValue[currentFormObject.key!] ?? {};
  664. print(currentFormObject.key!);
  665. void bloodPressure(Map value) {
  666. currentValue = value;
  667. formValue[currentFormObject.key!] = currentValue;
  668. // setState(() {});
  669. }
  670. return ExamBloodPressure(
  671. currentValue: currentValue,
  672. bloodPressure: bloodPressure,
  673. );
  674. }
  675. Widget _buildUrinalysis(FormObject currentFormObject) {
  676. Map currentValue = formValue[currentFormObject.key!] ?? {};
  677. void urinalysis(Map value) {
  678. currentValue = value;
  679. formValue[currentFormObject.key!] = currentValue;
  680. setState(() {});
  681. }
  682. return ExamUrinalysis(
  683. currentValue: currentValue,
  684. urinalysis: urinalysis,
  685. );
  686. }
  687. /// 单选框组件
  688. Widget _buildRadio(FormObject currentFormObject) {
  689. List<Option> options = currentFormObject.options ?? [];
  690. String currentSelected = formValue[currentFormObject.key!] ?? "";
  691. void selectRaidoChange(Option e) {
  692. currentSelected = e.value ?? '';
  693. formValue[currentFormObject.key!] = currentSelected;
  694. if (widget.cardKey == 'LNRZYYJKGLFWJL') {
  695. var pingScore = [
  696. 'qusition1',
  697. 'qusition2',
  698. 'qusition4',
  699. 'qusition5',
  700. 'qusition13'
  701. ];
  702. var isPingScore = pingScore.contains(currentFormObject.key);
  703. formValue[currentFormObject.groupKeys?[0]] =
  704. calculatePhysicalFitnessScore(
  705. currentFormObject.groupKeys?[0], false);
  706. if (isPingScore) {
  707. formValue['Ping_Score'] =
  708. calculatePhysicalFitnessScore('Ping_Score', isPingScore);
  709. }
  710. }
  711. setState(() {});
  712. }
  713. return ExamRadio(
  714. options: options,
  715. currentFormObject: currentFormObject,
  716. selectRaidoChange: selectRaidoChange,
  717. currentSelected: currentSelected,
  718. );
  719. }
  720. int calculatePhysicalFitnessScore(String currentScoreKey, bool isPingScore) {
  721. int score = 0;
  722. var currentTemplateStoreList = currentTemplate[0].children?.where(
  723. (element) =>
  724. element.groupKeys != null &&
  725. element.groupKeys!.contains(currentScoreKey));
  726. if (!isPingScore) {
  727. for (var element in currentTemplateStoreList!) {
  728. if (formValue[element.key!] != null) {
  729. score += int.parse(formValue[element.key!]!);
  730. }
  731. }
  732. } else {
  733. int index = 0;
  734. for (var element in currentTemplateStoreList!) {
  735. if (index == 0) {
  736. if (formValue[element.key!] != null) {
  737. score += int.parse(formValue[element.key!]!);
  738. }
  739. } else {
  740. score += formValue[element.key!] != null
  741. ? (6 - int.parse(formValue[element.key!]!))
  742. : 0;
  743. }
  744. index++;
  745. }
  746. }
  747. return score;
  748. }
  749. Widget _buildRadioScore(FormObject currentFormObject) {
  750. print(currentFormObject.toJson());
  751. List<Option> options = currentFormObject.options ?? [];
  752. String currentSelected =
  753. formValue[currentFormObject.childrenKey!.first] ?? "";
  754. String currentScore = formValue[currentFormObject.childrenKey!.last] ?? "";
  755. void selectRaidoChange(Option e) {
  756. currentSelected = e.value ?? '';
  757. formValue[currentFormObject.childrenKey!.first] = currentSelected;
  758. setState(() {});
  759. }
  760. void changeScore(String? score) {
  761. currentScore = score ?? '';
  762. formValue[currentFormObject.childrenKey!.last] = currentScore;
  763. setState(() {});
  764. }
  765. return ExamRadioScore(
  766. options: options,
  767. currentFormObject: currentFormObject,
  768. selectRaidoChange: selectRaidoChange,
  769. currentSelected: currentSelected,
  770. changeScore: changeScore,
  771. currentScore: currentScore,
  772. );
  773. }
  774. /// 体温组件
  775. Widget _buildBodyTemperature(FormObject currentFormObject) {
  776. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  777. void bodyTemperatureInput(String value) {
  778. formValue[currentFormObject.key!] = value;
  779. currentInputValue = formValue[currentFormObject.key!];
  780. setState(() {});
  781. }
  782. return ExamBodyTemperature(
  783. currentInputValue: currentInputValue,
  784. bodyTemperatureInput: bodyTemperatureInput,
  785. currentFormObject: currentFormObject,
  786. );
  787. }
  788. Widget _buildToxicSubstance(FormObject currentFormObject) {
  789. List<Option> options = currentFormObject.options ?? [];
  790. String currentValue = formValue[currentFormObject.childrenKey!.first] ?? "";
  791. Map? currentSelectedToxicSubstance =
  792. formValue[currentFormObject.childrenKey!.last];
  793. void selectRaidoChange(Map e) {
  794. currentSelectedToxicSubstance = e;
  795. formValue[currentFormObject.childrenKey!.last] =
  796. currentSelectedToxicSubstance;
  797. setState(() {});
  798. }
  799. void selectValueChange(String e) {
  800. currentValue = e;
  801. formValue[currentFormObject.childrenKey!.first] = currentValue;
  802. setState(() {});
  803. }
  804. return ExamToxicSubstance(
  805. currentFormObject: currentFormObject,
  806. currentSelectedToxicSubstance: currentSelectedToxicSubstance,
  807. currentValue: currentValue,
  808. options: options,
  809. selectRadioChange: selectRaidoChange,
  810. selectValueChange: selectValueChange,
  811. );
  812. }
  813. /// 血氧
  814. Widget _buildBloodOxygen(FormObject currentFormObject) {
  815. Map<String, dynamic> currentValue = formValue;
  816. void bloodOxygenInput(Map<String, dynamic> bloodOxygen) {
  817. formValue['Pulse_Frequency'] = bloodOxygen['Pulse_Frequency'];
  818. formValue['Spo2'] = bloodOxygen['Spo2'];
  819. currentValue = bloodOxygen;
  820. setState(() {});
  821. }
  822. return ExamBloodOxygen(
  823. currentValue: currentValue,
  824. bloodOxygenInput: bloodOxygenInput,
  825. );
  826. }
  827. /// 住院史
  828. Widget _buildMedicalHistory(FormObject currentFormObject) {
  829. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  830. int currentId = currentValue.length + 1;
  831. void resultChange(Map result) {
  832. currentValue.add(result);
  833. formValue[currentFormObject.key!] = currentValue;
  834. setState(() {});
  835. }
  836. void editResult(EditTableValue result) {
  837. currentValue[result.id! - 1] = result.value;
  838. formValue[currentFormObject.key!] = currentValue;
  839. setState(() {});
  840. }
  841. Future<void> addTableData() async {
  842. Get.dialog(
  843. HospitalizationHistoryForm(
  844. fromResult: (result) => resultChange(result),
  845. currentId: currentId,
  846. ),
  847. );
  848. }
  849. Future<void> editTableData(EditTableValue editTableValue) async {
  850. Get.dialog(
  851. HospitalizationHistoryForm(
  852. fromResult: (result) => editResult(result),
  853. currentId: editTableValue.id!,
  854. admissionJson: editTableValue.value,
  855. ),
  856. );
  857. }
  858. return ExamTable(
  859. tableThList: const ['序号', '入院日期', '出院日期', '原因', '医疗机构名称', '病案号', '操作'],
  860. currentFormObject: currentFormObject,
  861. currentValue: currentValue,
  862. addTableData: addTableData,
  863. editTableData: (value) => editTableData(value),
  864. );
  865. }
  866. /// 家庭病床史
  867. Widget _buildHomecareBedHistory(FormObject currentFormObject) {
  868. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  869. int currentId = currentValue.length + 1;
  870. void resultChange(Map result) {
  871. for (var i in result.keys) {
  872. if (result[i] == "") {
  873. return;
  874. }
  875. }
  876. currentValue.add(result);
  877. formValue[currentFormObject.key!] = currentValue;
  878. setState(() {});
  879. }
  880. void editResult(EditTableValue result) {
  881. currentValue[result.id! - 1] = result.value;
  882. formValue[currentFormObject.key!] = currentValue;
  883. setState(() {});
  884. }
  885. Future<void> addTableData() async {
  886. Get.dialog(
  887. HomecareBedHistoryFrom(
  888. fromResult: (result) => resultChange(result),
  889. currentId: currentId,
  890. ),
  891. );
  892. }
  893. Future<void> editTableData(EditTableValue editTableValue) async {
  894. Get.dialog(
  895. HomecareBedHistoryFrom(
  896. fromResult: (result) => editResult(result),
  897. currentId: editTableValue.id!,
  898. admissionJson: editTableValue.value,
  899. ),
  900. );
  901. }
  902. return ExamTable(
  903. tableThList: const ['序号', '建床日期', '撤床日期', '原因', '医疗机构名称', '病案号', '操作'],
  904. currentFormObject: currentFormObject,
  905. currentValue: currentValue,
  906. addTableData: addTableData,
  907. editTableData: (value) => editTableData(value),
  908. );
  909. }
  910. Widget _buildMainMedicationHistory(FormObject currentFormObject) {
  911. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  912. int currentId = currentValue.length + 1;
  913. void resultChange(Map result) {
  914. currentValue.add(result);
  915. formValue[currentFormObject.key!] = currentValue;
  916. setState(() {});
  917. }
  918. void editResult(EditTableValue result) {
  919. currentValue[result.id! - 1] = result.value;
  920. formValue[currentFormObject.key!] = currentValue;
  921. setState(() {});
  922. }
  923. Future<void> addTableData() async {
  924. Get.dialog(
  925. MainMedicationStatusFrom(
  926. fromResult: (result) => resultChange(result),
  927. currentId: currentId,
  928. ),
  929. );
  930. }
  931. Future<void> editTableData(EditTableValue editTableValue) async {
  932. Get.dialog(
  933. MainMedicationStatusFrom(
  934. fromResult: (result) => editResult(result),
  935. currentId: editTableValue.id!,
  936. admissionJson: editTableValue.value,
  937. ),
  938. );
  939. }
  940. return ExamTable(
  941. tableThList: const ['序号', '药物名称', '用法', '用量', '用药时间', '服药依从性', '操作'],
  942. currentFormObject: currentFormObject,
  943. currentValue: currentValue,
  944. addTableData: addTableData,
  945. editTableData: (value) => editTableData(value),
  946. );
  947. }
  948. Widget _buildInoculateHistory(FormObject currentFormObject) {
  949. List<dynamic> currentValue = formValue[currentFormObject.key!] ?? [];
  950. int currentId = currentValue.length + 1;
  951. void resultChange(Map result) {
  952. currentValue.add(result);
  953. formValue[currentFormObject.key!] = currentValue;
  954. setState(() {});
  955. }
  956. void editResult(EditTableValue result) {
  957. currentValue[result.id! - 1] = result.value;
  958. formValue[currentFormObject.key!] = currentValue;
  959. setState(() {});
  960. }
  961. Future<void> addTableData() async {
  962. Get.dialog(
  963. InoculateHistoryFrom(
  964. fromResult: (result) => resultChange(result),
  965. currentId: currentId,
  966. ),
  967. );
  968. }
  969. Future<void> editTableData(EditTableValue editTableValue) async {
  970. Get.dialog(
  971. InoculateHistoryFrom(
  972. fromResult: (result) => editResult(result),
  973. currentId: editTableValue.id!,
  974. admissionJson: editTableValue.value,
  975. ),
  976. );
  977. }
  978. return ExamTable(
  979. tableThList: const ['序号', '疫苗名称', '接种日期', '接种机构', '操作'],
  980. currentFormObject: currentFormObject,
  981. currentValue: currentValue,
  982. addTableData: addTableData,
  983. editTableData: (value) => editTableData(value),
  984. );
  985. }
  986. /// 体重
  987. Widget _buildBodyWeight(FormObject currentFormObject) {
  988. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  989. void bodyWeightInput(String value) {
  990. formValue[currentFormObject.key!] = value;
  991. currentInputValue = formValue[currentFormObject.key!];
  992. setState(() {});
  993. }
  994. return ExamBodyWeight(
  995. currentInputValue: currentInputValue,
  996. bodyWeightInput: bodyWeightInput,
  997. currentFormObject: currentFormObject,
  998. );
  999. }
  1000. /// 血糖
  1001. Widget _buildBodySugar(FormObject currentFormObject) {
  1002. String currentInputValue = formValue[currentFormObject.key!] ?? '';
  1003. void bloodSugarInput(String value) {
  1004. formValue[currentFormObject.key!] = value;
  1005. currentInputValue = formValue[currentFormObject.key!];
  1006. setState(() {});
  1007. }
  1008. return ExamBloodSugar(
  1009. currentInputValue: currentInputValue,
  1010. bloodSugarInput: bloodSugarInput,
  1011. currentFormObject: currentFormObject,
  1012. );
  1013. }
  1014. }