1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150 |
- import 'dart:convert';
- import 'dart:math';
- import 'package:fis_common/index.dart';
- import 'package:fis_jsonrpc/rpc.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:get/get.dart';
- import 'package:vitalapp/architecture/storage/text_storage.dart';
- import 'package:vitalapp/architecture/utils/prompt_box.dart';
- import 'package:vitalapp/components/alert_dialog.dart';
- import 'package:vitalapp/components/appbar.dart';
- import 'package:vitalapp/components/button.dart';
- import 'package:vitalapp/components/dialog_input.dart';
- import 'package:vitalapp/components/dialog_select.dart';
- import 'package:vitalapp/components/dynamic_drawer.dart';
- import 'package:vitalapp/consts/styles.dart';
- import 'package:vitalapp/global.dart';
- import 'package:vitalapp/managers/interfaces/cachedRecord.dart';
- import 'package:vitalapp/managers/interfaces/template.dart';
- import 'package:vitalapp/pages/check/models/form.dart';
- import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_health_guidance_check_box.dart';
- import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_input.dart';
- import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio.dart';
- import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_radio_score.dart';
- import 'package:vitalapp/store/store.dart';
- class TCMConstitutionModule extends StatefulWidget {
- final String cardKey;
- final Future<bool> Function(String, String, dynamic) callBack;
- final String? patientCode;
- final String? examData;
- final bool? isEdit;
- const TCMConstitutionModule({
- super.key,
- required this.cardKey,
- required this.callBack,
- this.patientCode,
- this.examData,
- this.isEdit = false,
- });
- @override
- State<TCMConstitutionModule> createState() => _ConfigurableFormState();
- }
- class _ConfigurableFormState extends State<TCMConstitutionModule> {
-
- Map<String, dynamic> templateRelation = {};
- bool isFirstEnter = true;
- String templateCode = '';
-
- List<FormObject> currentTemplate = [];
-
- int currentTitleIndex = 0;
- Map<String, dynamic> formValue = {};
- var scaffoldKey = GlobalKey<ScaffoldState>();
- List<TCMData> resourceInfo = [];
- final _templateManager = Get.find<ITemplateManager>();
- final _cachedRecordManager = Get.find<ICachedRecordManager>();
- Map currentTable = {};
- late MapEntry<String, dynamic> currentResult;
- late List<MapEntry<String, dynamic>> compatibleResult =
- <MapEntry<String, dynamic>>[];
- late List<String> unansweredQuestions = <String>[];
- List<String> storeTypeList = [
- 'Qi_Score',
- 'Yang_Score',
- 'Yin_Score',
- 'Tan_Score',
- 'Shi_Score',
- 'Xue_Score',
- 'Qiyu_Score',
- 'Te_Score',
- 'Ping_Score'
- ];
- Map<String, dynamic> storeTypeMap = {
- "Qi_Score": '气虚质',
- "Yang_Score": '阳虚质',
- "Yin_Score": '阴虚质',
- "Tan_Score": '痰湿质',
- "Shi_Score": '湿热质',
- "Xue_Score": '血瘀质',
- "Qiyu_Score": '气郁质',
- "Te_Score": '特禀质',
- "Ping_Score": '平和质',
- };
- Map<String, dynamic> storeTypeMapDefaultTitle = {
- "Qi_Score": [2, 3, 4, 14],
- "Yang_Score": [11, 12, 13, 29],
- "Yin_Score": [10, 21, 26, 31],
- "Tan_Score": [9, 16, 28, 32],
- "Shi_Score": [23, 25, 27, 30],
- "Xue_Score": [19, 22, 24, 33],
- "Qiyu_Score": [5, 6, 7, 8],
- "Te_Score": [15, 17, 18, 20],
- "Ping_Score": [1, 2, 4, 5, 13],
- };
- Map<String, String> typeMap = {
- 'Peaceful_Quality': "Ping_Score",
- "Yang_Deficiency_Substance": "Yang_Score",
- "Idiosyncratic_Quality": "Te_Score",
- "Qi_Stagnation_Constitution": "Qiyu_Score",
- "Blood_Stasis_Substance": "Xue_Score",
- "Damp-heat_constitution": "Shi_Score",
- "Phlegm-dampness_constitution": "Tan_Score",
- "Yin_Deficiency_Substance": "Yin_Score",
- "Qi_Deficiency_Constitution": "Qi_Score",
- };
- String resultConstitution = "";
- late int? selectedIndex = -1;
- @override
- void initState() {
- selectedIndex = -1;
- super.initState();
- initReadCached();
- getResourceInfo();
- unansweredQuestions.clear();
-
- WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
- if (mounted) {
- initTemplate();
- }
- });
- }
- Future<void> initReadCached() async {
- TextStorage cachedRecord = TextStorage(
- fileName: 'ZYTZ',
- directory: "patient/${widget.patientCode}",
- );
- String? value = await cachedRecord.read();
- if (value == null) {
- formValue = {};
- Store.resident.handleSaveMedicalData(jsonEncode(formValue));
- return;
- }
- Store.resident.handleSaveMedicalData(value);
- formValue = jsonDecode(value);
- }
- Future<bool?> saveCachedRecord() async {
-
- Store.resident.handleSaveMedicalData(jsonEncode(formValue));
- TextStorage cachedRecord = TextStorage(
- fileName: 'ZYTZ',
- directory: "patient/${widget.patientCode}",
- );
- return cachedRecord.save(jsonEncode(formValue));
- }
- Future<bool?> deleteDirectory() async {
- TextStorage cachedRecord = TextStorage(
- fileName: 'ZYTZ',
- directory: "patient/${widget.patientCode}",
- );
- return cachedRecord.deleteDirectory();
- }
- Future<void> getResourceInfo() async {
- if (FPlatform.isWindows) {
- return;
- }
- TextStorage resourceInfoCacheRecord = TextStorage(
- fileName: "healthGuidance",
- directory: "HealthGuidance/temlpate",
- );
- String? value = await resourceInfoCacheRecord.read();
- if (value != null) {
- var json = jsonDecode(value);
- resourceInfo =
- List<TCMData>.from(json['TCMDesc'].map((x) => TCMData.fromJson(x)));
- }
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- key: scaffoldKey,
- appBar: VAppBar(
- titleText: "中医体质",
- actions: (currentTitleIndex == 0 && !isFirstEnter)
- ? [
- TextButton(
- onPressed: () async {
- final result = await VDialogSelect<String, String>(
- title: "体质类型",
- source: storeTypeList,
- valueGetter: (data) => data,
- labelGetter: (data) => storeTypeMap[data],
- initialValue: formValue["PhysicalConclusion"],
- ).show();
- if (result != null) {
- Random random = Random();
- formValue.clear();
- formValue["PhysicalConclusion"] = result;
- if (result == "Ping_Score") {
- for (var i = 1; i < 34; i++) {
- if (i == 1) {
- int randomNumber = 3 + random.nextInt(3);
- formValue["qusition$i"] = randomNumber.toString();
- } else {
- int randomNumber = 1 + random.nextInt(2);
- formValue["qusition$i"] = randomNumber.toString();
- }
- }
- } else {
- for (var i = 1; i < 34; i++) {
- var questions =
- storeTypeMapDefaultTitle[result] as List<int>;
- if (questions.contains(i)) {
- int randomNumber = 3 + random.nextInt(3);
- formValue["qusition$i"] = randomNumber.toString();
- } else {
- int randomNumber = 1 + random.nextInt(2);
- formValue["qusition$i"] = randomNumber.toString();
- }
- }
- }
- for (var currentFormObject
- in currentTemplate[currentTitleIndex].children!) {
- optionUpdate(currentFormObject,
- formValue[currentFormObject.key]);
- }
- var currentFormObject =
- currentTemplate[currentTitleIndex].children!.first;
- optionUpdate(
- currentFormObject, formValue[currentFormObject.key]);
- }
- setState(() {});
- },
- child: Text(
- "选择体质",
- style: TextStyle(
- color: Colors.white,
- fontSize: 24,
- ),
- ),
- ),
- ]
- : null,
- ),
- resizeToAvoidBottomInset: false,
- body: (!widget.isEdit!) && isFirstEnter
- ? Container(
- decoration: const BoxDecoration(
- image: DecorationImage(
- image:
- AssetImage("assets/images/healthGuidanceBackground.png"),
- fit: BoxFit.cover,
- ),
- ),
- child: Column(
- children: [
- const SizedBox(
- height: 120,
- ),
- Center(
- child: Container(
- decoration: BoxDecoration(
- border: Border.all(color: Colors.black, width: 1)),
- padding: const EdgeInsets.all(10),
- child: Container(
- decoration: BoxDecoration(
- border: Border.all(color: Colors.black, width: 1)),
- padding: const EdgeInsets.all(10),
- child: const SizedBox(
- width: 900,
- child: Text(
- '《中医体质分类与判定标准》于2009年4月9日,由中华中医药学会正式发布,该标准旨在为体质辨识及中医体质相关疾病的防治、养生保健、健康管理提供依据,使体质分类科学化、规范化,是我国第一部指导和规范中医体质研究及应用的文件。适用于从事中医体质研究的中医临床医生、科研人员及相关管理人员,并可作为临床实践、判定规范及质量评定的重要参考依据。其中将中国人的体质分为九种,是体质分类的一种规范。具体有平和质、阳虚质、阴虚质、气虚质、痰湿质、湿热质、气郁质、血瘀质、特禀质。',
- style: TextStyle(fontSize: 24),
- ),
- ),
- ),
- ),
- ),
- const SizedBox(
- height: 120,
- ),
- VButton(
- label: "开始检测",
- onTap: () {
- setState(() {
- isFirstEnter = false;
- });
- },
- ),
- ],
- ),
- )
- : Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const SizedBox(
- height: 20,
- ),
- if (currentTitleIndex == 1)
- Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- const SizedBox(
- width: 80,
- ),
- Text(
- '当前体质判定为:${storeTypeMap[currentResult.key]} (${jsonDecode(currentResult.value)["Result"]} ${jsonDecode(currentResult.value)["Value"]}分)',
- style: const TextStyle(
- fontSize: 28,
- color: Colors.black,
- ),
- )
- ],
- ),
- if (compatibleResult.isNotEmpty)
- Row(
- children: const [
- SizedBox(
- width: 80,
- ),
- Text(
- '兼夹体质有:',
- style: TextStyle(
- fontSize: 25,
- color: Colors.black,
- ),
- ),
- ],
- ),
- if (compatibleResult.isNotEmpty)
- ListView.builder(
- shrinkWrap: true,
- itemCount: (compatibleResult.length / 3).ceil(),
- itemBuilder: (context, index) {
- return Row(
- children: [
- const SizedBox(width: 120),
- for (int i = index * 5;
- i < (index + 1) * 5;
- i++)
- if (i < compatibleResult.length)
- Column(
- crossAxisAlignment:
- CrossAxisAlignment.start,
- children: [
- Text(
- '${storeTypeMap[compatibleResult[i].key]} (${jsonDecode(compatibleResult[i].value)["Result"]} ${jsonDecode(compatibleResult[i].value)["Value"]}分) ',
- style: const TextStyle(
- fontSize: 20,
- color: Colors.black,
- ),
- softWrap: true,
- ),
- ],
- ),
- if ((index + 1) * 3 < compatibleResult.length)
- Container(height: 20),
- ],
- );
- },
- ),
- ],
- ),
- Expanded(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
-
- _buildContent(),
-
- ],
- ),
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- if (currentTitleIndex == 0)
- VButton(
- onTap: _buildCompute,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(
- "计算体质辨识结果",
- style: const TextStyle(
- fontSize: 20,
- ),
- ),
- ],
- ),
- ),
- const SizedBox(
- width: 10,
- ),
- if (currentTitleIndex == 1)
- VButton(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text(widget.isEdit! ? "修改" : "返回",
- style: TextStyle(fontSize: 20)),
- ],
- ),
- onTap: () {
- setState(() {
-
- currentTitleIndex = 0;
- });
- },
- ),
- const SizedBox(
- width: 10,
- ),
- if (currentTitleIndex == 1)
- VButton(
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Text("提交", style: const TextStyle(fontSize: 20)),
- ],
- ),
- onTap: () async {
- final result = await widget.callBack(
- widget.cardKey,
- templateCode,
- jsonEncode(formValue),
- );
- if (result) {
- setState(() {
- if (!widget.isEdit!) formValue.clear();
- currentTitleIndex = 0;
- if (!FPlatform.isWindows) {
- deleteDirectory();
- }
- });
- }
- Get.back();
- },
- ),
- ],
- ),
- const SizedBox(
- height: 10,
- ),
- ],
- ),
- );
- }
- String getHealthGuidance(String key) {
- String? value =
- resourceInfo.firstWhereOrNull((element) => element.key == key)?.value;
- return value ?? '';
- }
-
- Widget _buildContent() {
- return Expanded(
- child: flowCardList(),
- );
- }
- @override
- void dispose() {
- super.dispose();
- }
- Future<void> initTemplate() async {
- Store.app.busy = true;
- await fetchTemplateIndex();
- await fetchTemplate(widget.cardKey);
- await fetchTemplateData();
- Store.app.busy = false;
- }
-
- Future<String?> readCachedCheck() async {
- if (widget.patientCode == null) {
- return null;
- }
- String? value = await _cachedRecordManager.readCachedRecord(
- widget.cardKey,
- widget.patientCode!,
- 'FollowUp',
- );
- return value;
- }
- Future<void> fetchTemplateIndex() async {
- try {
-
- String? templates;
- templates =
- await _templateManager.readTemplateRelation('templateRelation');
- templateRelation = jsonDecode(templates!);
- setState(() {});
- } catch (error) {
- print('发生错误: $error');
- }
- }
- Future<void> fetchTemplateData() async {
- if (widget.examData?.isNotEmpty ?? false) {
- formValue = jsonDecode(widget.examData!);
- var jsonKey = formValue["PhysicalConclusion"];
- currentResult = MapEntry(jsonKey, formValue[jsonKey]);
- compatibleResult = calculateAllResylts();
- if (widget.isEdit!) {
- currentTitleIndex = 1;
- }
- setState(() {});
- return;
- }
- formValue.forEach(
- (key, value) {
- if (value is List<String>) {
- formValue[key] = List<String>.from(formValue[key]);
- } else if (value is List<Map>) {
- formValue[key] = List<Map>.from(formValue[key]);
- }
- },
- );
-
-
-
-
- setState(() {});
- }
- Future<void> fetchTemplate(String key) async {
- try {
- if (templateRelation[key] == null) {
- currentTemplate = [];
- setState(() {});
- if (!FPlatform.isWindows) {
- return;
- }
- }
- List<Map<String, dynamic>> list = [];
- String? template;
- if (templateRelation.containsKey(key)) {
- templateCode = templateRelation[key]!;
- template = await _templateManager.readTemplate(templateCode);
- }
- if (template == null) {
- var json = await loadJsonFromAssets('assets/templates/${key}.json');
- list = jsonDecode(json)["Content"].cast<Map<String, dynamic>>();
- } else {
- var templateContent =
- TemplateDTO.fromJson(jsonDecode(template)).templateContent!;
- list = jsonDecode(templateContent).cast<Map<String, dynamic>>();
- }
- for (var i in list) {
- if (i['children'] != null) {
- List<FormObject> currentChildren = [];
- for (var j in i['children']) {
- currentChildren.add(FormObject.fromJson(j));
- }
- i['children'] = currentChildren;
- }
- var item = FormObject.fromJson(i);
- currentTemplate.add(item);
- }
-
-
-
-
-
-
- setState(() {});
- } catch (error) {
- print('发生错误: $error');
- }
- }
- Future<String> loadJsonFromAssets(String filePath) async {
- String jsonString = await rootBundle.loadString(filePath);
- return jsonString;
- }
- Widget buildSingleItem(Widget item, int span) {
- return Column(
- children: [
- FractionallySizedBox(
- widthFactor: span == 24 ? 1 : 0.5,
- child: item,
- ),
- ],
- );
- }
- Widget buildWidget(FormObject? currentFormObject) {
- Map<String, Widget Function(FormObject)> widgetMap = {
- 'input': _buildInput,
- 'radio': _buildRadio,
- 'radioScore': _buildRadioScore,
- 'healthGuidanceCheckBox': _buildHealthGuidanceCheckBox,
- };
- Widget Function(FormObject) builder =
- widgetMap[currentFormObject?.type] ?? _buildInput;
- return builder(currentFormObject!);
- }
- Widget flowCardList() {
- int itemCount = 0;
- bool currentTemplateOptionsIsNotEmpty = false;
- if (currentTemplate.isNotEmpty) {
- itemCount = currentTemplate[currentTitleIndex].children?.length ?? 0;
- currentTemplateOptionsIsNotEmpty =
- currentTemplate[currentTitleIndex].options?.isNotEmpty ?? false;
- }
- List<Widget> items = List.generate(itemCount, (index) {
- FormObject? currentFormObject =
- currentTemplate[currentTitleIndex].children?[index];
- int span = currentFormObject?.span ?? 12;
-
-
- if (currentTemplateOptionsIsNotEmpty) {
- if (currentFormObject!.options!.isEmpty)
- currentFormObject.options =
- currentTemplate[currentTitleIndex].options;
- }
- return buildSingleItem(buildWidget(currentFormObject), span);
- });
- final ScrollController scrollController = ScrollController();
- return Scrollbar(
- controller: scrollController,
-
-
- child: ListView(
- controller: scrollController,
- padding: EdgeInsets.symmetric(horizontal: 50),
- children: [
- Container(
- alignment: Alignment.topCenter,
- child: Wrap(
- runSpacing: currentTitleIndex == 1 ? 5 : 10,
- alignment: WrapAlignment.start,
- children: items,
- ),
- ),
- if (currentTitleIndex == 1)
- Text(
- getHealthGuidance(currentResult.key),
- style: TextStyle(fontSize: 18),
- ),
- ],
- ),
- );
- }
-
- _buildCompute() {
- var questionsAnsweredNumber = formValue.entries
- .where((entry) => entry.key.contains("qusition"))
- .length;
- unansweredQuestions.clear();
- if (widget.cardKey == 'LNRZYYJKGLFWJL' &&
- currentTitleIndex == 0 &&
- questionsAnsweredNumber >= 33) {
- List<MapEntry<String, dynamic>> result = caculationConclusion();
- String? guidanceResult = hasGuidanceBeenProvided();
- String message = '';
- String title = '';
- bool isExistConflict = false;
- if (result.length == 1) {
- currentResult = result.first;
- formValue["PhysicalConclusion"] = currentResult.key;
-
- setState(() {
- compatibleResult = calculateAllResylts();
- currentTitleIndex = 1;
- });
- } else {
- if (result.length > 1) {
-
- isExistConflict = result
- .where((entry) =>
- entry.key == "Yang_Score" || entry.key == "Yin_Score")
- .length ==
- 2;
- if (isExistConflict) {
- message = '判定结果既是阴虚又是阳虚的矛盾判定结果,需重新填写问题:10、11、12、13、21、26、29、31';
- title = '体质冲突';
- var list = [10, 11, 12, 13, 21, 26, 29, 31];
- for (var element in list) {
- unansweredQuestions.add('qusition$element');
- }
- } else {
- message = '根据答题情况,计算出多个体质,请选择其中一个';
- title = '体质选择';
- }
- }
- if (result.isEmpty) {
-
- message = '请重新完成体质问询或2周后重新采集填写';
- title = '无法判断体质';
- }
- Get.dialog(
- VAlertDialog(
- title: title,
- width: 700,
- showCancel: false,
- content: Container(
- padding: const EdgeInsets.symmetric(horizontal: 24),
- height: result.length > 1 && !isExistConflict
- ? result.length / 3 * 150
- : 150,
- alignment: Alignment.center,
- child: Column(
- children: [
- Text(
- message,
- style: const TextStyle(fontSize: 24),
- ),
- SizedBox(
- height: 10,
- ),
- if (result.length > 1 && !isExistConflict)
- Expanded(
- child: SelectResult(
- result: result,
- guidanceResult: guidanceResult,
- selectCheckBoxChange: (value) {
- selectedIndex = value;
- currentResult = result[value];
- formValue["PhysicalConclusion"] = currentResult.key;
- },
- ),
- ),
- ],
- ),
- ),
- onConfirm: () {
- if (selectedIndex != -1) {
- compatibleResult = calculateAllResylts();
- currentTitleIndex = 1;
- }
- Get.back();
- setState(() {});
- },
- ),
- barrierDismissible: false,
- barrierColor: Colors.black.withOpacity(.4),
- );
- }
- } else {
- for (var i = 1; i < 34; i++) {
- var isExitsQuestion = formValue.entries
- .where((element) => element.key == 'qusition$i')
- .isNotEmpty;
- if (!isExitsQuestion) {
- unansweredQuestions.add('qusition$i');
- }
- }
- setState(() {});
- PromptBox.toast('题目未答完整,无法计算体质');
- }
- }
-
- List<MapEntry<String, dynamic>> caculationConclusion() {
- var formValues = formValue.entries
- .where((entry) =>
- storeTypeList.contains(entry.key) && entry.key != "Ping_Score")
- .toList();
- var pingResult = jsonDecode(formValue["Ping_Score"])["Result"];
-
-
- if (["是", "基本是", "倾向是"].contains(pingResult)) {
- return formValue.entries
- .where((element) => element.key == 'Ping_Score')
- .toList();
- } else {
- dynamic maxValue = formValues
- .map((entry) => jsonDecode(entry.value)["Value"])
- .reduce((a, b) =>
- int.parse(a.toString()) > int.parse(b.toString()) ? a : b);
- if (int.parse(maxValue.toString()) > 8) {
- List<MapEntry<String, dynamic>> keyValuePairs = formValues
- .where((entry) => jsonDecode(entry.value)["Value"] == maxValue)
- .toList();
- return keyValuePairs;
- } else {
- return List.empty();
- }
- }
- }
- String? hasGuidanceBeenProvided() {
- var formValues = formValue.entries
- .where((entry) => entry.key == 'PhysicalConclusion')
- .toList();
- if (formValues.isNotEmpty) {
- return formValues.first.value;
- }
- return "";
- }
- Widget _buildInput(FormObject currentFormObject) {
- String currentInputValue = formValue[currentFormObject.key!] ?? '';
- Future<void> commonInput() async {
- String? result = await VDialogInput(
- title: currentFormObject.label,
- initialValue: formValue[currentFormObject.key],
- ).show();
- if (result?.isNotEmpty ?? false) {
- formValue[currentFormObject.key!] = result;
- currentInputValue = formValue[currentFormObject.key!];
- setState(() {});
- }
- }
- return ExamInput(
- currentInputValue: currentInputValue,
- commonInput: commonInput,
- currentFormObject: currentFormObject,
- );
- }
-
- List<MapEntry<String, dynamic>> calculateAllResylts() {
- List<MapEntry<String, dynamic>> compatibleResults =
- <MapEntry<String, dynamic>>[];
- for (var key in storeTypeList) {
- var result = jsonDecode(formValue[key])["Result"];
- if (["是", "基本是", "倾向是"].contains(result)) {
- compatibleResults.add(MapEntry(key, formValue[key]));
- }
- }
- compatibleResults = compatibleResults
- .where((element) => element.key != currentResult.key)
- .toList();
- return compatibleResults;
- }
-
- Widget _buildHealthGuidanceCheckBox(FormObject currentFormObject) {
- List<Option> options = currentFormObject.options ?? [];
- List<dynamic> currentSelectedCheckBox = formValue["HealthGuidance"] ?? [];
- var currentScoreKey = currentFormObject.groupKeys != null
- ? currentFormObject.groupKeys![0]
- : '';
- if (currentResult.key != currentScoreKey) {
- return Container();
- }
- int score = jsonDecode(formValue[currentScoreKey])["Value"];
- String judgmentResult = jsonDecode(formValue[currentScoreKey])["Result"];
- void selectCheckBoxChange(Option e) {
- if (currentSelectedCheckBox.contains(e.value)) {
- currentSelectedCheckBox.remove(e.value);
- } else {
- currentSelectedCheckBox.add(e.value ?? '');
- }
- formValue["HealthGuidance"] = currentSelectedCheckBox;
- saveCachedRecord();
- setState(() {});
- }
- return ExamHealthGuidanceWidget(
- options: options,
- currentSelectedCheckBox: currentSelectedCheckBox,
- currentFormObject: currentFormObject,
- selectCheckBoxChange: selectCheckBoxChange,
- score: score,
- judgmentResult: judgmentResult,
- );
- }
-
- String getJudgmentResult(String storeKey, int score) {
- if (storeKey == 'Ping_Score') {
- if (score >= 17) {
- bool is8 = true;
- bool is10 = true;
- for (var e in storeTypeList) {
- if (formValue[e] != null && e != 'Ping_Score') {
- var otherScore = jsonDecode(formValue[e])["Value"];
- if (otherScore > 8) {
- if (is8) {
- is8 = false;
- }
- if (otherScore > 10) {
- is10 = false;
- }
- }
- if (!is10) {
- break;
- }
- }
- }
- if (is8) {
- return '是';
- } else if (is10) {
- return '基本是';
- }
- }
- return '否';
- } else {
- if (score >= 11) {
- return '是';
- } else if (9 == score || score == 10) {
- return '倾向是';
- } else {
- return '否';
- }
- }
- }
-
- Widget _buildRadio(FormObject currentFormObject) {
- List<Option> options = currentFormObject.options ?? [];
- String currentSelected = formValue[currentFormObject.key!] ?? "";
- void selectRaidoChange(Option e) {
- currentSelected = e.value ?? '';
- setState(() {
- optionUpdate(currentFormObject, currentSelected);
- });
- }
- var decoration = unansweredQuestions.contains(currentFormObject.key!)
- ? BoxDecoration(
- border: Border.all(color: Colors.red, width: 2),
- borderRadius: GlobalStyles.borderRadius,
- )
- : null;
- return Container(
- decoration: decoration,
- child: ExamRadio(
- options: options,
- currentFormObject: currentFormObject,
- selectRaidoChange: selectRaidoChange,
- currentSelected: currentSelected,
- ),
- );
- }
- Future<void> optionUpdate(
- FormObject formObject, String currentSelected) async {
- formValue[formObject.key!] = currentSelected;
- if (widget.cardKey == 'LNRZYYJKGLFWJL') {
- var pingScore = [
- 'qusition1',
- 'qusition2',
- 'qusition4',
- 'qusition5',
- 'qusition13'
- ];
- var isPingScore = pingScore.contains(formObject.key);
- int store =
- calculatePhysicalFitnessScore(formObject.groupKeys?[0], false);
- formValue[formObject.groupKeys?[0]] = jsonEncode({
- "Value": store,
- "Result": getJudgmentResult(formObject.groupKeys?[0], store),
- });
- if (isPingScore) {
- int store = calculatePhysicalFitnessScore('Ping_Score', true);
- formValue['Ping_Score'] = jsonEncode({
- "Value": store,
- "Result": getJudgmentResult('Ping_Score', store),
- });
- }
- }
- saveCachedRecord();
- }
-
- int calculatePhysicalFitnessScore(String currentScoreKey, bool isPingScore) {
- int score = 0;
- var currentTemplateStoreList = currentTemplate[0].children?.where(
- (element) =>
- element.groupKeys != null &&
- element.groupKeys!.contains(currentScoreKey));
- if (!isPingScore) {
- for (var element in currentTemplateStoreList!) {
- if (formValue[element.key!] != null) {
- score += int.parse(formValue[element.key!]!);
- }
- }
- } else {
- int index = 0;
- for (var element in currentTemplateStoreList!) {
- if (index == 0) {
- if (formValue[element.key!] != null) {
- score += int.parse(formValue[element.key!]!);
- }
- } else {
- score += formValue[element.key!] != null
- ? (6 - int.parse(formValue[element.key!]!))
- : 0;
- }
- index++;
- }
- }
- return score;
- }
- Widget _buildRadioScore(FormObject currentFormObject) {
- print(currentFormObject.toJson());
- List<Option> options = currentFormObject.options ?? [];
- String currentSelected =
- formValue[currentFormObject.childrenKey!.first] ?? "";
- String currentScore = formValue[currentFormObject.childrenKey!.last] ?? "";
- void selectRaidoChange(Option e) {
- currentSelected = e.value ?? '';
- formValue[currentFormObject.childrenKey!.first] = currentSelected;
- setState(() {});
- }
- void changeScore(String? score) {
- currentScore = score ?? '';
- formValue[currentFormObject.childrenKey!.last] = currentScore;
- setState(() {});
- }
- return ExamRadioScore(
- options: options,
- currentFormObject: currentFormObject,
- selectRaidoChange: selectRaidoChange,
- currentSelected: currentSelected,
- changeScore: changeScore,
- currentScore: currentScore,
- );
- }
- }
- class SelectResult extends StatefulWidget {
- final List<MapEntry<String, dynamic>> result;
- final Function selectCheckBoxChange;
- final String? guidanceResult;
- const SelectResult(
- {super.key,
- required this.result,
- required this.selectCheckBoxChange,
- this.guidanceResult});
- @override
- State<SelectResult> createState() => _SelectResultState();
- }
- class _SelectResultState extends State<SelectResult> {
- Map<String, dynamic> storeTypeMap = {
- "Qi_Score": '气虚质',
- "Yang_Score": '阳虚质',
- "Yin_Score": '阴虚质',
- "Tan_Score": '痰虚质',
- "Shi_Score": '湿热质',
- "Xue_Score": '血瘀质',
- "Qiyu_Score": '气郁质',
- "Te_Score": '特禀质',
- "Ping_Score": '平和质',
- };
- late int? selectedIndex = -1;
- @override
- void initState() {
- super.initState();
- selectedIndex = -1;
- }
- @override
- Widget build(BuildContext context) {
- return GridView.builder(
- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 3,
- crossAxisSpacing: 10,
- mainAxisSpacing: 10,
- childAspectRatio: 3,
- ),
- itemCount: widget.result.length,
- itemBuilder: (context, index) {
- if (widget.result[index].key == widget.guidanceResult) {
- widget.selectCheckBoxChange(index);
- selectedIndex = index;
- }
- return Row(
- children: [
- Radio(
- value: index,
- groupValue: selectedIndex,
- onChanged: (value) {
- widget.selectCheckBoxChange(value);
- setState(() {
- selectedIndex = value;
- });
- }),
- Text(
- "${storeTypeMap[widget.result[index].key]} (${jsonDecode(widget.result[index].value)["Result"]} ${jsonDecode(widget.result[index].value)["Value"]}分)",
- style: TextStyle(fontSize: 22),
- ),
- SizedBox(
- width: 5,
- ),
- ],
- );
- });
- }
- @override
- void dispose() {
- super.dispose();
- }
- }
- class TCMData {
- String key;
- String value;
- TCMData({required this.key, required this.value});
- factory TCMData.fromJson(Map<String, dynamic> json) {
- return TCMData(
- key: json['Key'],
- value: json['Value'],
- );
- }
- }
|