|
@@ -3,12 +3,14 @@ import 'dart:convert';
|
|
|
import 'package:fis_jsonrpc/rpc.dart';
|
|
|
import 'package:flutter/material.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/dynamic_drawer.dart';
|
|
|
+import 'package:vitalapp/consts/styles.dart';
|
|
|
import 'package:vitalapp/managers/interfaces/cachedRecord.dart';
|
|
|
import 'package:vitalapp/managers/interfaces/template.dart';
|
|
|
import 'package:vitalapp/pages/check/models/form.dart';
|
|
@@ -57,6 +59,11 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
final _templateManager = Get.find<ITemplateManager>();
|
|
|
final _cachedRecordManager = Get.find<ICachedRecordManager>();
|
|
|
Map currentTable = {};
|
|
|
+ late MapEntry<String, dynamic> currentResult;
|
|
|
+
|
|
|
+ late List<MapEntry<String, dynamic>> compatibleResult;
|
|
|
+
|
|
|
+ late List<String> unansweredQuestions = <String>[];
|
|
|
|
|
|
List<String> storeTypeList = [
|
|
|
'Qi_Score',
|
|
@@ -70,13 +77,40 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
'Ping_Score'
|
|
|
];
|
|
|
|
|
|
- String resultConstitution = "";
|
|
|
+ Map<String, dynamic> storeTypeMap = {
|
|
|
+ "Qi_Score": '气虚质',
|
|
|
+ "Yang_Score": '阳虚质',
|
|
|
+ "Yin_Score": '阴虚质',
|
|
|
+ "Tan_Score": '痰虚质',
|
|
|
+ "Shi_Score": '湿热质',
|
|
|
+ "Xue_Score": '血瘀质',
|
|
|
+ "Qiyu_Score": '气郁质',
|
|
|
+ "Te_Score": '特禀质',
|
|
|
+ "Ping_Score": '平和质',
|
|
|
+ };
|
|
|
|
|
|
+ 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() {
|
|
|
Get.put(DeviceController());
|
|
|
-
|
|
|
+ selectedIndex = -1;
|
|
|
super.initState();
|
|
|
+ initReadCached();
|
|
|
+ unansweredQuestions.clear();
|
|
|
+ compatibleResult.clear();
|
|
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
|
if (mounted) {
|
|
|
initTemplate();
|
|
@@ -84,54 +118,185 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ Future<void> initReadCached() async {
|
|
|
+ // if (patientCode.isNotEmpty) {
|
|
|
+ // logger
|
|
|
+ // .i('MedicalController initReadCached fail,patientCod e:$patientCode');
|
|
|
+ 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 {
|
|
|
+ // if (patientCode.isEmpty) {
|
|
|
+ // logger.i(
|
|
|
+ // 'MedicalController saveCachedRecord fail,patientCode:$patientCode');
|
|
|
+ // return false;
|
|
|
+ // }
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
+ int index = 0;
|
|
|
return Scaffold(
|
|
|
key: scaffoldKey,
|
|
|
appBar: widget.isEdit! ? VAppBar(titleText: "中医体质") : null,
|
|
|
endDrawer: VDynamicDrawerWrapper(scaffoldKey: scaffoldKey),
|
|
|
resizeToAvoidBottomInset: false,
|
|
|
body: (!widget.isEdit!) && isFirstEnter
|
|
|
- ? Column(
|
|
|
- children: [
|
|
|
- const SizedBox(
|
|
|
- height: 50,
|
|
|
+ ? Container(
|
|
|
+ decoration: const BoxDecoration(
|
|
|
+ image: DecorationImage(
|
|
|
+ image:
|
|
|
+ AssetImage("assets/images/healthGuidanceBackground.png"),
|
|
|
+ fit: BoxFit.cover,
|
|
|
),
|
|
|
- const Center(
|
|
|
- child: SizedBox(
|
|
|
- width: 900,
|
|
|
- child: Text(
|
|
|
- '《中医体质分类与判定标准》于2009年4月9日发布,由中华中医药学会正式发布,该标准旨在为体质辨识及中医体质相关疾病的防治、养生保健、健康管理提供依据,使体质分类科学化、规范化,是我国第一部指导和规范中医体质研究及应用的文件。适用于从事中医体质研究的中医临床医生、科研人员及相关管理人员,并可作为临床实践、判定规范及质量评定的重要参考依据。其中将中国人的体制分为九种,是体质分类的一种规范。具体有平和质、阳虚质、气虚质、痰湿质、湿热质、气郁质、血瘀质、特禀质。',
|
|
|
- style: TextStyle(fontSize: 24),
|
|
|
+ ),
|
|
|
+ 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: 50,
|
|
|
- ),
|
|
|
- VButton(
|
|
|
- label: "开始检测",
|
|
|
- onTap: () {
|
|
|
- setState(() {
|
|
|
- isFirstEnter = false;
|
|
|
- });
|
|
|
- },
|
|
|
- ),
|
|
|
- ],
|
|
|
+ const SizedBox(
|
|
|
+ height: 150,
|
|
|
+ ),
|
|
|
+ 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]} 得分:${currentResult.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]} 得分:${compatibleResult[i].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: [
|
|
|
- const SizedBox(width: 50),
|
|
|
+ SizedBox(width: widget.isEdit! ? 90 : 50),
|
|
|
_buildContent(),
|
|
|
- const SizedBox(width: 50),
|
|
|
+ SizedBox(width: widget.isEdit! ? 90 : 50),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
@@ -144,8 +309,13 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
onTap: _buildCompute,
|
|
|
child: Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- children: const [
|
|
|
- Text("查看体质", style: TextStyle(fontSize: 20)),
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ widget.isEdit! ? "查看体质辨识结果" : "计算体质辨识结果",
|
|
|
+ style: const TextStyle(
|
|
|
+ fontSize: 20,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
@@ -174,8 +344,9 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
VButton(
|
|
|
child: Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- children: const [
|
|
|
- Text("提交", style: TextStyle(fontSize: 20)),
|
|
|
+ children: [
|
|
|
+ Text(widget.isEdit! ? "修改" : "提交",
|
|
|
+ style: const TextStyle(fontSize: 20)),
|
|
|
],
|
|
|
),
|
|
|
onTap: () async {
|
|
@@ -188,17 +359,28 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
setState(() {
|
|
|
if (!widget.isEdit!) formValue.clear();
|
|
|
currentTitleIndex = 0;
|
|
|
+ deleteDirectory();
|
|
|
});
|
|
|
}
|
|
|
},
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
+ const SizedBox(
|
|
|
+ height: 10,
|
|
|
+ ),
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ /// 主页面
|
|
|
+ Widget _buildContent() {
|
|
|
+ return Expanded(
|
|
|
+ child: flowCardList(),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
@override
|
|
|
void dispose() {
|
|
|
super.dispose();
|
|
@@ -342,6 +524,7 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
currentTemplate[currentTitleIndex].options;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return buildSingleItem(buildWidget(currentFormObject), span);
|
|
|
});
|
|
|
|
|
@@ -352,7 +535,7 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
alignment: Alignment.topCenter,
|
|
|
padding: const EdgeInsets.all(15),
|
|
|
child: Wrap(
|
|
|
- runSpacing: 20, // 纵向元素间距
|
|
|
+ runSpacing: currentTitleIndex == 1 ? 5 : 10, // 纵向元素间距
|
|
|
alignment: WrapAlignment.start,
|
|
|
children: items,
|
|
|
),
|
|
@@ -363,93 +546,201 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
|
|
|
/// title标签
|
|
|
_buildCompute() {
|
|
|
- // currentTemplate.asMap().entries.map((e) {
|
|
|
+ var questionsAnsweredNumber = formValue.entries
|
|
|
+ .where((entry) => entry.key.contains("qusition"))
|
|
|
+ .length; //获取已完成答题数量
|
|
|
if (widget.cardKey == 'LNRZYYJKGLFWJL' &&
|
|
|
currentTitleIndex == 0 &&
|
|
|
- formValue.length >= 33) {
|
|
|
+ questionsAnsweredNumber >= 33) {
|
|
|
List<MapEntry<String, dynamic>> result = caculationConclusion();
|
|
|
+ String? guidanceResult = hasGuidanceBeenProvided();
|
|
|
String message = '';
|
|
|
String title = '';
|
|
|
- setState(() {
|
|
|
- currentTitleIndex = 1;
|
|
|
- });
|
|
|
- // if (result.length == 1) {
|
|
|
- // //直接进入中医药保健指导
|
|
|
- // setState(() {
|
|
|
- // currentTitleIndex = 1;
|
|
|
- // });
|
|
|
- // } else {
|
|
|
- // if (result.length > 1) {
|
|
|
- // //弹出选择框
|
|
|
- // message = '存在多个结果';
|
|
|
- // title = '存在多个结果';
|
|
|
- // }
|
|
|
- // if (result.isEmpty) {
|
|
|
- // //无法断体质
|
|
|
- // message = '请重新完成体质问询或2周后重新采集填写';
|
|
|
- // title = '无法判断体质';
|
|
|
- // }
|
|
|
-
|
|
|
- // Get.dialog(
|
|
|
- // VAlertDialog(
|
|
|
- // title: title,
|
|
|
- // width: 450,
|
|
|
- // showCancel: false,
|
|
|
- // content: Container(
|
|
|
- // height: 100,
|
|
|
- // padding: const EdgeInsets.symmetric(horizontal: 24),
|
|
|
- // alignment: Alignment.center,
|
|
|
- // child: Column(
|
|
|
- // children: [
|
|
|
- // Text(
|
|
|
- // message,
|
|
|
- // style: const TextStyle(fontSize: 20),
|
|
|
- // ),
|
|
|
- // if (result.length > 1)
|
|
|
- // Row(
|
|
|
- // mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- // crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
- // children: [
|
|
|
- // const Text('阳虚质'),
|
|
|
- // Checkbox(value: false, onChanged: (value) {}),
|
|
|
- // const Text('湿热质'),
|
|
|
- // Checkbox(value: false, onChanged: (value) {}),
|
|
|
- // ],
|
|
|
- // ),
|
|
|
- // ],
|
|
|
- // ),
|
|
|
- // ),
|
|
|
- // onConfirm: () {
|
|
|
- // Get.back();
|
|
|
- // },
|
|
|
- // ),
|
|
|
- // barrierDismissible: false,
|
|
|
- // barrierColor: Colors.black.withOpacity(.4),
|
|
|
- // );
|
|
|
- // }
|
|
|
+ bool isExistConflict = false;
|
|
|
+ if (result.length == 1) {
|
|
|
+ currentResult = result.first;
|
|
|
+ //直接进入中医药保健指导
|
|
|
+ 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 = '体质冲突';
|
|
|
+ } else {
|
|
|
+ message = '请选择一个体质';
|
|
|
+ title = '多个体质';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (result.isEmpty) {
|
|
|
+ //无法断体质
|
|
|
+ message = '请重新完成体质问询或2周后重新采集填写';
|
|
|
+ title = '无法判断体质';
|
|
|
+ }
|
|
|
+
|
|
|
+ Get.dialog(
|
|
|
+ VAlertDialog(
|
|
|
+ title: title,
|
|
|
+ width: 500,
|
|
|
+ showCancel: false,
|
|
|
+ content: Container(
|
|
|
+ padding: const EdgeInsets.symmetric(horizontal: 24),
|
|
|
+ height: result.length > 1 && !isExistConflict
|
|
|
+ ? result.length / 3 * 100
|
|
|
+ : 100,
|
|
|
+ alignment: Alignment.center,
|
|
|
+ child: Column(
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ message,
|
|
|
+ style: const TextStyle(fontSize: 20),
|
|
|
+ ),
|
|
|
+ if (result.length > 1 && !isExistConflict)
|
|
|
+ Expanded(
|
|
|
+ child: SelectResult(
|
|
|
+ result: result,
|
|
|
+ guidanceResult: guidanceResult,
|
|
|
+ selectCheckBoxChange: (value) {
|
|
|
+ // setState(() {
|
|
|
+ selectedIndex = value;
|
|
|
+ currentResult = result[value];
|
|
|
+ // });
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ onConfirm: () {
|
|
|
+ if (selectedIndex != -1) {
|
|
|
+ setState(() {
|
|
|
+ compatibleResult = calculateAllResylts();
|
|
|
+ currentTitleIndex = 1;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ Get.back();
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ barrierDismissible: false,
|
|
|
+ barrierColor: Colors.black.withOpacity(.4),
|
|
|
+ );
|
|
|
+ }
|
|
|
} else {
|
|
|
+ unansweredQuestions.clear();
|
|
|
+ for (var i = 1; i < 34; i++) {
|
|
|
+ var isExitsQuestion = formValue.entries
|
|
|
+ .where((element) => element.key.contains('qusition$i'))
|
|
|
+ .isNotEmpty;
|
|
|
+ if (!isExitsQuestion) {
|
|
|
+ unansweredQuestions.add('qusition$i');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ setState(() {});
|
|
|
PromptBox.toast('题目未答完整,无法计算体质');
|
|
|
}
|
|
|
- // });
|
|
|
}
|
|
|
|
|
|
+ //验证体质
|
|
|
List<MapEntry<String, dynamic>> caculationConclusion() {
|
|
|
- dynamic maxValue = formValue.values.reduce((value, element) =>
|
|
|
- int.parse(value.toString()) > int.parse(element.toString())
|
|
|
- ? value
|
|
|
- : element);
|
|
|
-
|
|
|
- List<MapEntry<String, dynamic>> keyValuePairs =
|
|
|
- formValue.entries.where((entry) => entry.value == maxValue).toList();
|
|
|
- return keyValuePairs;
|
|
|
+ var formValues = formValue.entries
|
|
|
+ .where((entry) =>
|
|
|
+ entry.key != 'Ping_Score' &&
|
|
|
+ entry.key != 'Peaceful_Quality' &&
|
|
|
+ entry.key != "Yang_Deficiency_Substance" &&
|
|
|
+ entry.key != "Idiosyncratic_Quality" &&
|
|
|
+ entry.key != "Qi_Stagnation_Constitution" &&
|
|
|
+ entry.key != "Blood_Stasis_Substance" &&
|
|
|
+ entry.key != "Damp-heat_constitution" &&
|
|
|
+ entry.key != "Phlegm-dampness_constitution" &&
|
|
|
+ entry.key != "Yin_Deficiency_Substance" &&
|
|
|
+ entry.key != "Qi_Deficiency_Constitution")
|
|
|
+ .toList();
|
|
|
+ var pingResult = getJudgmentResult('Ping_Score');
|
|
|
+ if (["是", "基本是", "倾向是"].contains(pingResult)) {
|
|
|
+ return formValue.entries
|
|
|
+ .where((element) => element.key == 'Ping_Score')
|
|
|
+ .toList();
|
|
|
+ } else {
|
|
|
+ dynamic maxValue = formValues.map((entry) => entry.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 = formValue.entries
|
|
|
+ .where((entry) => entry.value == maxValue)
|
|
|
+ .toList();
|
|
|
+ return keyValuePairs;
|
|
|
+ } else {
|
|
|
+ return List.empty();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /// 主页面
|
|
|
- Widget _buildContent() {
|
|
|
- return Expanded(
|
|
|
- flex: 2,
|
|
|
- child: flowCardList(),
|
|
|
- );
|
|
|
+ String? hasGuidanceBeenProvided() {
|
|
|
+ var formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == 'Peaceful_Quality')
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Peaceful_Quality"];
|
|
|
+ }
|
|
|
+
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Yang_Deficiency_Substance")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Yang_Deficiency_Substance"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Idiosyncratic_Quality")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Idiosyncratic_Quality"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Qi_Stagnation_Constitution")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Qi_Stagnation_Constitution"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Blood_Stasis_Substance")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Blood_Stasis_Substance"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Damp-heat_constitution")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Damp-heat_constitution"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Phlegm-dampness_constitution")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Phlegm-dampness_constitution"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Yin_Deficiency_Substance")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Yin_Deficiency_Substance"];
|
|
|
+ }
|
|
|
+ formValues = formValue.entries
|
|
|
+ .where((entry) => entry.key == "Qi_Deficiency_Constitution")
|
|
|
+ .toList();
|
|
|
+ if (formValues.isNotEmpty) {
|
|
|
+ return typeMap["Qi_Deficiency_Constitution"];
|
|
|
+ }
|
|
|
+
|
|
|
+ return "";
|
|
|
}
|
|
|
|
|
|
Widget _buildInput(FormObject currentFormObject) {
|
|
@@ -473,6 +764,22 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ ///计算满足的所有体质类型
|
|
|
+ List<MapEntry<String, dynamic>> calculateAllResylts() {
|
|
|
+ List<MapEntry<String, dynamic>> compatibleResults =
|
|
|
+ <MapEntry<String, dynamic>>[];
|
|
|
+ for (var key in storeTypeMap.keys) {
|
|
|
+ var result = getJudgmentResult(key);
|
|
|
+ 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 ?? [];
|
|
@@ -481,6 +788,9 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
var currentScoreKey = currentFormObject.groupKeys != null
|
|
|
? currentFormObject.groupKeys![0]
|
|
|
: '';
|
|
|
+ if (currentResult.key != currentScoreKey) {
|
|
|
+ return Container();
|
|
|
+ }
|
|
|
int score = formValue[currentScoreKey] ?? 0;
|
|
|
String judgmentResult = getJudgmentResult(currentScoreKey);
|
|
|
void selectCheckBoxChange(Option e) {
|
|
@@ -490,22 +800,18 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
currentSelectedCheckBox.add(e.value ?? '');
|
|
|
}
|
|
|
formValue[currentFormObject.key!] = currentSelectedCheckBox;
|
|
|
-
|
|
|
+ saveCachedRecord();
|
|
|
setState(() {});
|
|
|
}
|
|
|
|
|
|
- if (["是", "基本是", "倾向是"].contains(judgmentResult)) {
|
|
|
- return ExamHealthGuidanceCheckBox(
|
|
|
- options: options,
|
|
|
- currentSelectedCheckBox: currentSelectedCheckBox,
|
|
|
- currentFormObject: currentFormObject,
|
|
|
- selectCheckBoxChange: selectCheckBoxChange,
|
|
|
- score: score,
|
|
|
- judgmentResult: judgmentResult,
|
|
|
- );
|
|
|
- } else {
|
|
|
- return Container();
|
|
|
- }
|
|
|
+ return ExamHealthGuidanceWidget(
|
|
|
+ options: options,
|
|
|
+ currentSelectedCheckBox: currentSelectedCheckBox,
|
|
|
+ currentFormObject: currentFormObject,
|
|
|
+ selectCheckBoxChange: selectCheckBoxChange,
|
|
|
+ score: score,
|
|
|
+ judgmentResult: judgmentResult,
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
///识别体质
|
|
@@ -574,14 +880,25 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
calculatePhysicalFitnessScore('Ping_Score', isPingScore);
|
|
|
}
|
|
|
}
|
|
|
+ saveCachedRecord();
|
|
|
setState(() {});
|
|
|
}
|
|
|
|
|
|
- return ExamRadio(
|
|
|
- options: options,
|
|
|
- currentFormObject: currentFormObject,
|
|
|
- selectRaidoChange: selectRaidoChange,
|
|
|
- currentSelected: 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,
|
|
|
+ ),
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -646,3 +963,75 @@ class _ConfigurableFormState extends State<ConfigurableCard> {
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+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: [
|
|
|
+ Text(
|
|
|
+ "${storeTypeMap[widget.result[index].key]}:${widget.result[index].value}"),
|
|
|
+ Radio(
|
|
|
+ value: index,
|
|
|
+ groupValue: selectedIndex,
|
|
|
+ onChanged: (value) {
|
|
|
+ widget.selectCheckBoxChange(value);
|
|
|
+ setState(() {
|
|
|
+ selectedIndex = value;
|
|
|
+ });
|
|
|
+ })
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void dispose() {
|
|
|
+ super.dispose();
|
|
|
+ }
|
|
|
+}
|