|
|
@@ -51,19 +51,16 @@
|
|
|
<text class="form-member-save">每个成员独立保存,切换后自动保留</text>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 分步问卷向导(体征 / 疾病史 / 饮食习惯 / 确认) -->
|
|
|
- <health-questionnaire-wizard
|
|
|
- ref="wizard"
|
|
|
- :member-form-map="memberFormMap"
|
|
|
- :diet-map="memberDietMap"
|
|
|
- :member-profile-map="memberProfileMap"
|
|
|
- :active-form-member-id="activeFormMemberId"
|
|
|
+ <!-- 综合调研(8 模块 step:组件内部管理步骤;多成员 tab 由父页切换传当前成员快照) -->
|
|
|
+ <comprehensive-survey
|
|
|
+ :modules="surveyModules"
|
|
|
+ :form="currentMemberForm"
|
|
|
+ :diet="currentDiet"
|
|
|
+ :profile="currentMemberProfile"
|
|
|
:submitting="loading"
|
|
|
- @update-vitals="onWizardVitals"
|
|
|
- @update-medical="onWizardMedical"
|
|
|
- @update-lifestyle="onWizardLifestyle"
|
|
|
- @update-diet="onWizardDiet"
|
|
|
- @submit="onWizardSubmit"
|
|
|
+ @update-form="onSurveyForm"
|
|
|
+ @update-diet="onSurveyDiet"
|
|
|
+ @submit="onSurveySubmit"
|
|
|
/>
|
|
|
|
|
|
<!-- 底部按钮 -->
|
|
|
@@ -187,10 +184,10 @@
|
|
|
import { generateHealthPlan, regenerateSection, confirmPlan, saveHealthPlan, getHealthPlanDetail } from '../../utils/api'
|
|
|
import { getHealthStatus, saveHealthStatus, getDietPreferences, saveDietPreferences, getMyMembership } from '../../utils/api'
|
|
|
import MemberChipPicker from '@/pages/health/components/MemberChipPicker.vue'
|
|
|
-import HealthQuestionnaireWizard from '@/pages/health/components/HealthQuestionnaireWizard.vue'
|
|
|
+import ComprehensiveSurvey from '@/pages/health/components/ComprehensiveSurvey.vue'
|
|
|
|
|
|
export default {
|
|
|
- components: { MemberChipPicker, HealthQuestionnaireWizard },
|
|
|
+ components: { MemberChipPicker, ComprehensiveSurvey },
|
|
|
data() {
|
|
|
return {
|
|
|
// 步骤控制
|
|
|
@@ -207,6 +204,8 @@ export default {
|
|
|
// 多成员饮食习惯:memberId → dietPreferences 对象
|
|
|
memberDietMap: {},
|
|
|
activeFormMemberId: '',
|
|
|
+ // Step2 综合调研模块(方案制定前完整调研,全量 8 模块)
|
|
|
+ surveyModules: ['basic', 'status', 'diet', 'disease', 'bowel', 'sleep', 'med', 'allergy'],
|
|
|
// 方案数据
|
|
|
planData: {},
|
|
|
// 多人方案结构化数据(common/individual),保存时原样写入 planJson
|
|
|
@@ -301,6 +300,38 @@ selectedMembers: function() {
|
|
|
}
|
|
|
})
|
|
|
return out
|
|
|
+ },
|
|
|
+ // 当前填写成员的 health 快照(memberFormMap 项:form 子对象 + 结构化兄弟 key)
|
|
|
+ currentMemberSnapshot: function() {
|
|
|
+ return this.memberFormMap[String(this.activeFormMemberId || '__account')] || null
|
|
|
+ },
|
|
|
+ // 组件 form prop:扁平体征 + 结构化字段 + lifestyle 对象(与快照同构的合并视图)
|
|
|
+ currentMemberForm: function() {
|
|
|
+ var s = this.currentMemberSnapshot
|
|
|
+ if (!s) {
|
|
|
+ return {
|
|
|
+ heightCm: '', weightKg: '', bloodPressure: '', bloodGlucose: '', notes: '',
|
|
|
+ lipidCholesterol: '', selectedDiseases: [], medRows: [], noMedication: false,
|
|
|
+ lifestyle: {}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Object.assign({}, s.form || {}, {
|
|
|
+ lipidCholesterol: s.lipidCholesterol || '',
|
|
|
+ selectedDiseases: Array.isArray(s.selectedDiseases) ? s.selectedDiseases : [],
|
|
|
+ medRows: Array.isArray(s.medRows) ? s.medRows : [],
|
|
|
+ noMedication: !!s.noMedication,
|
|
|
+ lifestyle: s.lifestyle || {}
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 当前成员的 diet 快照
|
|
|
+ currentDiet: function() {
|
|
|
+ var key = String(this.activeFormMemberId || '__account')
|
|
|
+ return this.memberDietMap[key] || this.normalizeDiet(null)
|
|
|
+ },
|
|
|
+ // 当前成员画像(复用 memberProfileMap,无数据时兜底空 → 条件渲染区隐藏)
|
|
|
+ currentMemberProfile: function() {
|
|
|
+ var key = String(this.activeFormMemberId || '__account')
|
|
|
+ return this.memberProfileMap[key] || { gender: '', age: '' }
|
|
|
}
|
|
|
},
|
|
|
onLoad: function(options) {
|
|
|
@@ -510,45 +541,52 @@ selectedMembers: function() {
|
|
|
return list
|
|
|
},
|
|
|
// ===== 向导事件:按当前成员写回快照 =====
|
|
|
- onWizardVitals: function(flat) {
|
|
|
- this.mergeWizardForm(flat)
|
|
|
- },
|
|
|
- onWizardMedical: function(flat) {
|
|
|
- this.mergeWizardForm(flat)
|
|
|
- },
|
|
|
- onWizardLifestyle: function(lifestyle) {
|
|
|
- var key = String(this.activeFormMemberId || '__account')
|
|
|
- var prev = this.memberFormMap[key] || {}
|
|
|
- this.$set(this.memberFormMap, key, Object.assign({}, prev, { lifestyle: lifestyle }))
|
|
|
- },
|
|
|
- onWizardDiet: function(diet) {
|
|
|
- var key = String(this.activeFormMemberId || '__account')
|
|
|
- this.$set(this.memberDietMap, key, diet)
|
|
|
- },
|
|
|
- onWizardSubmit: function() {
|
|
|
- this.saveAndGenerate()
|
|
|
- },
|
|
|
- // 合并向导推送的扁平体征/疾病数据到当前成员快照
|
|
|
- mergeWizardForm: function(flat) {
|
|
|
- if (!flat) return
|
|
|
+ // ===== 综合调研事件:patch 合并到当前成员快照 =====
|
|
|
+ // patch 为组件推送的结构化字段副本(扁平体征 + selectedDiseases/medRows/noMedication + lipidCholesterol)
|
|
|
+ onSurveyForm: function(patch) {
|
|
|
+ if (!patch) return
|
|
|
var key = String(this.activeFormMemberId || '__account')
|
|
|
var prev = this.memberFormMap[key] || {}
|
|
|
var pf = prev.form || {}
|
|
|
this.$set(this.memberFormMap, key, {
|
|
|
form: {
|
|
|
- heightCm: flat.heightCm != null ? flat.heightCm : (pf.heightCm || ''),
|
|
|
- weightKg: flat.weightKg != null ? flat.weightKg : (pf.weightKg || ''),
|
|
|
- bloodPressure: flat.bloodPressure != null ? flat.bloodPressure : (pf.bloodPressure || ''),
|
|
|
- bloodGlucose: flat.bloodGlucose != null ? flat.bloodGlucose : (pf.bloodGlucose || ''),
|
|
|
- notes: flat.notes != null ? flat.notes : (pf.notes || '')
|
|
|
+ heightCm: patch.heightCm != null ? patch.heightCm : (pf.heightCm || ''),
|
|
|
+ weightKg: patch.weightKg != null ? patch.weightKg : (pf.weightKg || ''),
|
|
|
+ bloodPressure: patch.bloodPressure != null ? patch.bloodPressure : (pf.bloodPressure || ''),
|
|
|
+ bloodGlucose: patch.bloodGlucose != null ? patch.bloodGlucose : (pf.bloodGlucose || ''),
|
|
|
+ notes: patch.notes != null ? patch.notes : (pf.notes || '')
|
|
|
},
|
|
|
- lipidCholesterol: flat.lipidCholesterol != null ? flat.lipidCholesterol : (prev.lipidCholesterol || ''),
|
|
|
- selectedDiseases: flat.selectedDiseases != null ? flat.selectedDiseases : (prev.selectedDiseases || []),
|
|
|
- medRows: flat.medRows != null ? flat.medRows : (prev.medRows || []),
|
|
|
- noMedication: flat.noMedication != null ? flat.noMedication : (prev.noMedication || false),
|
|
|
+ lipidCholesterol: patch.lipidCholesterol != null ? patch.lipidCholesterol : (prev.lipidCholesterol || ''),
|
|
|
+ selectedDiseases: patch.selectedDiseases != null ? patch.selectedDiseases : (prev.selectedDiseases || []),
|
|
|
+ medRows: patch.medRows != null ? patch.medRows : (prev.medRows || []),
|
|
|
+ noMedication: patch.noMedication != null ? patch.noMedication : (prev.noMedication || false),
|
|
|
+ // 用户主动清空全部疾病/用药时置位,保存时下发 '[]'(否则旧值会被回滚)
|
|
|
+ diseasesCleared: !!patch.diseasesCleared,
|
|
|
+ medsCleared: !!patch.medsCleared,
|
|
|
lifestyle: prev.lifestyle || {}
|
|
|
})
|
|
|
},
|
|
|
+ onSurveyDiet: function(patch) {
|
|
|
+ if (!patch) return
|
|
|
+ var key = String(this.activeFormMemberId || '__account')
|
|
|
+ var prev = this.memberDietMap[key] || this.normalizeDiet(null)
|
|
|
+ this.$set(this.memberDietMap, key, Object.assign({}, prev, patch))
|
|
|
+ },
|
|
|
+ // lifestyle diff 合并进当前成员快照(整体回写,未涉及 key 保留旧值)
|
|
|
+ onSurveyLifestyle: function(diff) {
|
|
|
+ var key = String(this.activeFormMemberId || '__account')
|
|
|
+ var prev = this.memberFormMap[key] || {}
|
|
|
+ var merged = Object.assign({}, prev.lifestyle || {}, diff || {})
|
|
|
+ this.$set(this.memberFormMap, key, Object.assign({}, prev, { lifestyle: merged }))
|
|
|
+ },
|
|
|
+ // 提交:合并 lifestyle diff + form/diet 最终值 → 走原 saveAndGenerate
|
|
|
+ onSurveySubmit: function(payload) {
|
|
|
+ if (!payload) { this.saveAndGenerate(); return }
|
|
|
+ if (payload.lifestyleDiff) this.onSurveyLifestyle(payload.lifestyleDiff)
|
|
|
+ if (payload.form) this.onSurveyForm(payload.form)
|
|
|
+ if (payload.diet) this.onSurveyDiet(payload.diet)
|
|
|
+ this.saveAndGenerate()
|
|
|
+ },
|
|
|
buildHealthPayload: function(snapshot) {
|
|
|
var s = snapshot || {}
|
|
|
var lipids = []
|
|
|
@@ -577,11 +615,14 @@ selectedMembers: function() {
|
|
|
if (s.form.bloodPressure) payload.bloodPressure = s.form.bloodPressure
|
|
|
if (s.form.bloodGlucose) payload.bloodGlucose = Number(s.form.bloodGlucose)
|
|
|
if (lipids.length > 0) payload.bloodLipids = JSON.stringify(lipids)
|
|
|
+ // 用户主动清空时下发 '[]'(未清空且原本为空则不发,保留旧值)
|
|
|
if (diseases.length > 0) payload.diseaseHistory = JSON.stringify(diseases)
|
|
|
+ else if (s.diseasesCleared) payload.diseaseHistory = '[]'
|
|
|
if (meds.length > 0) payload.medications = JSON.stringify(meds)
|
|
|
+ else if (s.medsCleared) payload.medications = '[]'
|
|
|
if (s.form.notes) payload.notes = s.form.notes
|
|
|
var lifestyle = s.lifestyle || {}
|
|
|
- var lifestyleKeys = ['mood', 'sleepDuration', 'bedtime', 'bowelFrequency', 'bowelForm', 'antibioticHistory', 'allergySymptoms', 'menstrualCycle', 'specialPeriod', 'growthDevelopment', 'pickyEating', 'osteoporosisRisk', 'fallRisk', 'screenTime', 'teenMood']
|
|
|
+ var lifestyleKeys = ['mood', 'sleepDuration', 'bedtime', 'bowelFrequency', 'bowelForm', 'antibioticHistory', 'allergySymptoms', 'menstrualCycle', 'specialPeriod', 'growthDevelopment', 'pickyEating', 'osteoporosisRisk', 'fallRisk', 'screenTime', 'teenMood', 'currentStatus', 'exerciseFrequency', 'exerciseDuration']
|
|
|
var hasLifestyle = lifestyleKeys.some(function(k) {
|
|
|
return lifestyle[k] && (Array.isArray(lifestyle[k]) ? lifestyle[k].length > 0 : true)
|
|
|
})
|
|
|
@@ -624,6 +665,9 @@ selectedMembers: function() {
|
|
|
obj.fallRisk = parsed.fallRisk || ''
|
|
|
obj.screenTime = parsed.screenTime || ''
|
|
|
obj.teenMood = parsed.teenMood || ''
|
|
|
+ obj.currentStatus = parsed.currentStatus || ''
|
|
|
+ obj.exerciseFrequency = parsed.exerciseFrequency || ''
|
|
|
+ obj.exerciseDuration = parsed.exerciseDuration || ''
|
|
|
}
|
|
|
} catch (e) {}
|
|
|
return obj
|