|
|
@@ -0,0 +1,140 @@
|
|
|
+<template>
|
|
|
+ <view class="lifestyle-step">
|
|
|
+ <view class="step-title-row">
|
|
|
+ <text class="step-title">生活方式与肠道健康</text>
|
|
|
+ <text class="step-sub">问卷核心:心情/睡眠/排便/抗生素/过敏,帮助精准识别肠道状态</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 心情状态 -->
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head">
|
|
|
+ <text class="card-title">心情状态</text>
|
|
|
+ <text class="card-hint">单选</text>
|
|
|
+ </view>
|
|
|
+ <view class="chip-row">
|
|
|
+ <view v-for="opt in moodOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.mood === opt }" @click="setField('mood', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 睡眠 -->
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head"><text class="card-title">睡眠时长</text><text class="card-hint">单选</text></view>
|
|
|
+ <view class="chip-row">
|
|
|
+ <view v-for="opt in sleepOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.sleepDuration === opt }" @click="setField('sleepDuration', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head"><text class="card-title">入睡时间</text><text class="card-hint">单选</text></view>
|
|
|
+ <view class="chip-row">
|
|
|
+ <view v-for="opt in bedtimeOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.bedtime === opt }" @click="setField('bedtime', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 排便情况 -->
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head"><text class="card-title">排便频率</text><text class="card-hint">单选</text></view>
|
|
|
+ <view class="chip-row">
|
|
|
+ <view v-for="opt in bowelFreqOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.bowelFrequency === opt }" @click="setField('bowelFrequency', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head"><text class="card-title">粪便性状</text><text class="card-hint">单选</text></view>
|
|
|
+ <view class="chip-row">
|
|
|
+ <view v-for="opt in bowelFormOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.bowelForm === opt }" @click="setField('bowelForm', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 抗生素用药史 -->
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head"><text class="card-title">近 2 年抗生素用药史</text><text class="card-hint">单选</text></view>
|
|
|
+ <view class="chip-row">
|
|
|
+ <view v-for="opt in antibioticOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.antibioticHistory === opt }" @click="setField('antibioticHistory', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 过敏表现 -->
|
|
|
+ <view class="form-card">
|
|
|
+ <view class="card-head"><text class="card-title">过敏表现</text><text class="card-hint">多选(可多个)</text></view>
|
|
|
+ <view class="chip-row-wrap">
|
|
|
+ <view v-for="opt in allergyOptions" :key="opt" class="chip-item-wrap" :class="{ 'chip-active': inner.allergySymptoms && inner.allergySymptoms.indexOf(opt) >= 0 }" @click="toggleChip('allergySymptoms', opt)"><text>{{ opt }}</text></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: 'LifestyleStep',
|
|
|
+ props: {
|
|
|
+ value: { type: Object, default: function() { return {} } }
|
|
|
+ },
|
|
|
+ data: function() {
|
|
|
+ return {
|
|
|
+ inner: { mood: '', sleepDuration: '', bedtime: '', bowelFrequency: '', bowelForm: '', antibioticHistory: '', allergySymptoms: [] }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ moodOptions: function() { return ['良好', '一般', '低落', '焦虑'] },
|
|
|
+ sleepOptions: function() { return ['<6小时', '6-7小时', '7-8小时', '>8小时'] },
|
|
|
+ bedtimeOptions: function() { return ['22:00前', '22:00-24:00', '24:00后'] },
|
|
|
+ bowelFreqOptions: function() { return ['每天1次(正常)', '隔天1次', '每周2-3次', '每周<2次'] },
|
|
|
+ bowelFormOptions: function() { return ['干硬颗粒', '条状干硬', '正常香蕉状', '软便', '水样'] },
|
|
|
+ antibioticOptions: function() { return ['无', '曾使用过(未用完疗程)', '按疗程使用完', '频繁使用(近2年≥3次)'] },
|
|
|
+ allergyOptions: function() { return ['无', '反复皮疹', '鼻痒/打喷嚏', '眼痒/流泪', '哮喘样症状', '食物过敏'] }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value: { deep: true, handler: function(val) { this.syncFromValue(val) } }
|
|
|
+ },
|
|
|
+ created: function() { this.syncFromValue(this.value) },
|
|
|
+ methods: {
|
|
|
+ syncFromValue: function(val) {
|
|
|
+ if (!val) return
|
|
|
+ this.inner.mood = val.mood || ''
|
|
|
+ this.inner.sleepDuration = val.sleepDuration || ''
|
|
|
+ this.inner.bedtime = val.bedtime || ''
|
|
|
+ this.inner.bowelFrequency = val.bowelFrequency || ''
|
|
|
+ this.inner.bowelForm = val.bowelForm || ''
|
|
|
+ this.inner.antibioticHistory = val.antibioticHistory || ''
|
|
|
+ this.inner.allergySymptoms = Array.isArray(val.allergySymptoms) ? val.allergySymptoms.slice() : []
|
|
|
+ },
|
|
|
+ setField: function(field, value) {
|
|
|
+ this.inner[field] = value
|
|
|
+ this.emitInput()
|
|
|
+ },
|
|
|
+ toggleChip: function(field, value) {
|
|
|
+ var list = this.inner[field] || []
|
|
|
+ var idx = list.indexOf(value)
|
|
|
+ if (idx >= 0) { this.inner[field] = list.slice(0, idx).concat(list.slice(idx + 1)) } else { this.inner[field] = list.concat([value]) }
|
|
|
+ this.emitInput()
|
|
|
+ },
|
|
|
+ emitInput: function() {
|
|
|
+ this.$emit('input', {
|
|
|
+ mood: this.inner.mood,
|
|
|
+ sleepDuration: this.inner.sleepDuration,
|
|
|
+ bedtime: this.inner.bedtime,
|
|
|
+ bowelFrequency: this.inner.bowelFrequency,
|
|
|
+ bowelForm: this.inner.bowelForm,
|
|
|
+ antibioticHistory: this.inner.antibioticHistory,
|
|
|
+ allergySymptoms: (this.inner.allergySymptoms || []).slice()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.lifestyle-step { padding: 10rpx 0 30rpx; }
|
|
|
+.step-title-row { margin-bottom: 20rpx; }
|
|
|
+.step-title { font-size: 34rpx; font-weight: 700; color: #333; }
|
|
|
+.step-sub { display: block; font-size: 24rpx; color: #999; margin-top: 8rpx; }
|
|
|
+.form-card { background: #fff; border-radius: 20rpx; padding: 24rpx; margin-bottom: 20rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.04); }
|
|
|
+.card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16rpx; }
|
|
|
+.card-title { font-size: 28rpx; font-weight: 600; color: #333; }
|
|
|
+.card-hint { font-size: 22rpx; color: #94A3B8; }
|
|
|
+.chip-row { display: flex; flex-wrap: wrap; }
|
|
|
+.chip-row-wrap { display: flex; flex-wrap: wrap; }
|
|
|
+.chip-item, .chip-item-wrap { padding: 12rpx 28rpx; border-radius: 999rpx; background: #F1F5F9; font-size: 24rpx; color: #334155; margin: 0 16rpx 14rpx 0; }
|
|
|
+.chip-active { background: #FFF3E0; color: #F97316; font-weight: 600; }
|
|
|
+.custom-row { margin-top: 10rpx; }
|
|
|
+.custom-hint { font-size: 22rpx; color: #F97316; }
|
|
|
+</style>
|