|
@@ -12,14 +12,19 @@
|
|
|
<text class="step-label">提需求</text>
|
|
<text class="step-label">提需求</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="step-line" :class="{ done: step > 2 }"></view>
|
|
<view class="step-line" :class="{ done: step > 2 }"></view>
|
|
|
- <view class="step" :class="{ active: step >= 3 }">
|
|
|
|
|
|
|
+ <view class="step" :class="{ active: step >= 3, done: step > 3 }">
|
|
|
<text class="step-num">3</text>
|
|
<text class="step-num">3</text>
|
|
|
|
|
+ <text class="step-label">健康问卷</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="step-line" :class="{ done: step > 3 }"></view>
|
|
|
|
|
+ <view class="step" :class="{ active: step >= 4 }">
|
|
|
|
|
+ <text class="step-num">4</text>
|
|
|
<text class="step-label">确认方案</text>
|
|
<text class="step-label">确认方案</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<!-- Step 1: 选择家庭成员 -->
|
|
<!-- Step 1: 选择家庭成员 -->
|
|
|
- <view class="section" v-if="step <= 2">
|
|
|
|
|
|
|
+ <view class="section" v-if="step === 1">
|
|
|
<view class="section-title">选择家庭成员</view>
|
|
<view class="section-title">选择家庭成员</view>
|
|
|
<view class="hint-text">选择方案针对的家庭成员(可多选)</view>
|
|
<view class="hint-text">选择方案针对的家庭成员(可多选)</view>
|
|
|
<view class="member-list">
|
|
<view class="member-list">
|
|
@@ -61,19 +66,54 @@
|
|
|
<view class="goal-footer">
|
|
<view class="goal-footer">
|
|
|
<text class="goal-count">{{ userGoal.length }}/300</text>
|
|
<text class="goal-count">{{ userGoal.length }}/300</text>
|
|
|
<button
|
|
<button
|
|
|
- class="btn-generate"
|
|
|
|
|
|
|
+ class="btn-next btn-step-next"
|
|
|
|
|
+ :disabled="!canGenerate"
|
|
|
|
|
+ @click="step = 3"
|
|
|
|
|
+ >
|
|
|
|
|
+ 下一步
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="back-link" @click="step = 1">← 返回选择成员</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- Step 3: 健康问卷确认 -->
|
|
|
|
|
+ <view class="section" v-if="step === 3">
|
|
|
|
|
+ <view class="section-title">健康问卷</view>
|
|
|
|
|
+ <view class="hint-text">确认健康现状,方案将参考这些信息更精准</view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 已填写:带出内容确认 -->
|
|
|
|
|
+ <view v-if="healthStatus && healthStatusSummary.length > 0" class="q-summary">
|
|
|
|
|
+ <view v-for="(item, idx) in healthStatusSummary" :key="idx" class="q-row">
|
|
|
|
|
+ <text class="q-label">{{ item.label }}</text>
|
|
|
|
|
+ <text class="q-value">{{ item.value }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="q-updated" v-if="healthStatus.updatedAt">更新于 {{ formatTime(healthStatus.updatedAt) }}</view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 未填写 -->
|
|
|
|
|
+ <view v-else class="empty-state q-empty">
|
|
|
|
|
+ <text class="empty-icon">📋</text>
|
|
|
|
|
+ <text class="empty-text">尚未填写健康问卷</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="q-actions">
|
|
|
|
|
+ <button class="btn-edit" @click="goFillQuestionnaire">
|
|
|
|
|
+ {{ healthStatus ? '修改健康问卷' : '去填写健康问卷' }}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ class="btn-confirm"
|
|
|
:class="{ disabled: !canGenerate || loading }"
|
|
:class="{ disabled: !canGenerate || loading }"
|
|
|
:disabled="!canGenerate || loading"
|
|
:disabled="!canGenerate || loading"
|
|
|
@click="generatePlan"
|
|
@click="generatePlan"
|
|
|
>
|
|
>
|
|
|
- {{ loading ? '正在生成方案...' : '生成方案' }}
|
|
|
|
|
|
|
+ {{ loading ? '正在生成方案...' : '确认并生成方案' }}
|
|
|
</button>
|
|
</button>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="back-link" @click="step = 1">← 返回选择成员</view>
|
|
|
|
|
|
|
+ <view class="back-link" @click="step = 2">← 返回修改需求</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- Step 3: 方案 & 任务 -->
|
|
|
|
|
- <view class="section task-section" v-if="step === 3 && parsedTasks.length > 0 && !taskSubmitted">
|
|
|
|
|
|
|
+ <!-- Step 4: 方案 & 任务 -->
|
|
|
|
|
+ <view class="section task-section" v-if="step === 4 && parsedTasks.length > 0 && !taskSubmitted">
|
|
|
<view class="section-title">健康方案</view>
|
|
<view class="section-title">健康方案</view>
|
|
|
|
|
|
|
|
<!-- 方案原文 -->
|
|
<!-- 方案原文 -->
|
|
@@ -128,7 +168,7 @@
|
|
|
确认并生成任务单
|
|
确认并生成任务单
|
|
|
</button>
|
|
</button>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="back-link" @click="step = 2">← 返回修改需求</view>
|
|
|
|
|
|
|
+ <view class="back-link" @click="step = 3">← 返回健康问卷</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<!-- 成功 -->
|
|
<!-- 成功 -->
|
|
@@ -172,6 +212,22 @@ export default {
|
|
|
},
|
|
},
|
|
|
canConfirmTasks: function() {
|
|
canConfirmTasks: function() {
|
|
|
return this.parsedTasks.length > 0 && this.parsedTasks.every(function(t) { return t.executorId })
|
|
return this.parsedTasks.length > 0 && this.parsedTasks.every(function(t) { return t.executorId })
|
|
|
|
|
+ },
|
|
|
|
|
+ healthStatusSummary: function() {
|
|
|
|
|
+ var d = this.healthStatus || {}
|
|
|
|
|
+ var list = []
|
|
|
|
|
+ if (d.heightCm) list.push({ label: '身高', value: d.heightCm + ' cm' })
|
|
|
|
|
+ if (d.weightKg) list.push({ label: '体重', value: d.weightKg + ' kg' })
|
|
|
|
|
+ if (d.bloodPressure) list.push({ label: '血压', value: d.bloodPressure })
|
|
|
|
|
+ if (d.bloodGlucose) list.push({ label: '空腹血糖', value: d.bloodGlucose + ' mmol/L' })
|
|
|
|
|
+ var lipids = this.parseLipidText(d.bloodLipids)
|
|
|
|
|
+ if (lipids) list.push({ label: '血脂', value: lipids })
|
|
|
|
|
+ var diseases = this.parseNameList(d.diseaseHistory)
|
|
|
|
|
+ if (diseases) list.push({ label: '疾病史', value: diseases })
|
|
|
|
|
+ var meds = this.parseMedText(d.medications)
|
|
|
|
|
+ if (meds) list.push({ label: '在服药物', value: meds })
|
|
|
|
|
+ if (d.notes) list.push({ label: '其他补充', value: d.notes })
|
|
|
|
|
+ return list
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
onLoad: function(options) {
|
|
onLoad: function(options) {
|
|
@@ -227,6 +283,46 @@ export default {
|
|
|
if (idx >= 0) this.selectedMemberIds.splice(idx, 1)
|
|
if (idx >= 0) this.selectedMemberIds.splice(idx, 1)
|
|
|
else this.selectedMemberIds.push(memberId)
|
|
else this.selectedMemberIds.push(memberId)
|
|
|
},
|
|
},
|
|
|
|
|
+ parseLipidText: function(json) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var arr = JSON.parse(json || '[]')
|
|
|
|
|
+ if (arr instanceof Array) {
|
|
|
|
|
+ return arr.map(function(it) {
|
|
|
|
|
+ return (it.name || '') + (it.value ? ' ' + it.value + (it.unit || '') : '')
|
|
|
|
|
+ }).filter(function(s) { return s }).join('、')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ return ''
|
|
|
|
|
+ },
|
|
|
|
|
+ parseNameList: function(json) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var arr = JSON.parse(json || '[]')
|
|
|
|
|
+ if (arr instanceof Array) {
|
|
|
|
|
+ return arr.map(function(it) { return it.name || '' }).filter(function(s) { return s }).join('、')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ return ''
|
|
|
|
|
+ },
|
|
|
|
|
+ parseMedText: function(json) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var arr = JSON.parse(json || '[]')
|
|
|
|
|
+ if (arr instanceof Array) {
|
|
|
|
|
+ return arr.map(function(it) {
|
|
|
|
|
+ return (it.name || '') + (it.time ? '(' + it.time + ')' : '')
|
|
|
|
|
+ }).filter(function(s) { return s }).join('、')
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {}
|
|
|
|
|
+ return ''
|
|
|
|
|
+ },
|
|
|
|
|
+ formatTime: function(iso) {
|
|
|
|
|
+ if (!iso) return ''
|
|
|
|
|
+ var s = String(iso)
|
|
|
|
|
+ if (s.length >= 19) s = s.substring(0, 19)
|
|
|
|
|
+ return s.replace('T', ' ')
|
|
|
|
|
+ },
|
|
|
|
|
+ goFillQuestionnaire: function() {
|
|
|
|
|
+ uni.navigateTo({ url: '/pages/health/health-status-form' })
|
|
|
|
|
+ },
|
|
|
generatePlan: function() {
|
|
generatePlan: function() {
|
|
|
var self = this
|
|
var self = this
|
|
|
if (!self.canGenerate) return
|
|
if (!self.canGenerate) return
|
|
@@ -301,7 +397,7 @@ export default {
|
|
|
if (answer) {
|
|
if (answer) {
|
|
|
self.planContent = answer
|
|
self.planContent = answer
|
|
|
self.parseTasksFromPlan(answer)
|
|
self.parseTasksFromPlan(answer)
|
|
|
- self.step = 3
|
|
|
|
|
|
|
+ self.step = 4
|
|
|
// 自动出方案模式:方案生成后自动提交任务
|
|
// 自动出方案模式:方案生成后自动提交任务
|
|
|
if (self.autoExecute && self.parsedTasks.length > 0) {
|
|
if (self.autoExecute && self.parsedTasks.length > 0) {
|
|
|
setTimeout(function() { self.submitTasks() }, 500)
|
|
setTimeout(function() { self.submitTasks() }, 500)
|
|
@@ -350,7 +446,7 @@ export default {
|
|
|
self.parsedTasks = tasks
|
|
self.parsedTasks = tasks
|
|
|
},
|
|
},
|
|
|
regenerate: function() {
|
|
regenerate: function() {
|
|
|
- this.step = 2
|
|
|
|
|
|
|
+ this.step = 3
|
|
|
this.parsedTasks = []
|
|
this.parsedTasks = []
|
|
|
this.planContent = ''
|
|
this.planContent = ''
|
|
|
},
|
|
},
|
|
@@ -779,4 +875,56 @@ export default {
|
|
|
border: none;
|
|
border: none;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+/* 健康问卷摘要 */
|
|
|
|
|
+.q-summary {
|
|
|
|
|
+ background: #FAFAFA;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ padding: 20rpx 24rpx;
|
|
|
|
|
+ margin-bottom: 24rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.q-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ padding: 12rpx 0;
|
|
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
+}
|
|
|
|
|
+.q-row:last-child {
|
|
|
|
|
+ border-bottom: none;
|
|
|
|
|
+}
|
|
|
|
|
+.q-label {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ margin-right: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.q-value {
|
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+ word-break: break-all;
|
|
|
|
|
+}
|
|
|
|
|
+.q-updated {
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
|
+ color: #bbb;
|
|
|
|
|
+ margin-top: 12rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.q-empty {
|
|
|
|
|
+ padding: 40rpx 0;
|
|
|
|
|
+}
|
|
|
|
|
+.q-actions {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 16rpx;
|
|
|
|
|
+}
|
|
|
|
|
+.q-actions .btn-edit {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+.q-actions .btn-confirm {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+.btn-step-next {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|