configurable_card.dart 34 KB

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