| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- <!-- DEPRECATED: 已由 ComprehensiveSurvey.vue 替代,待确认无引用后清理(2026-10-16 标记) -->
- <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 v-if="isFemale">
- <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 menstrualOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.menstrualCycle === opt }" @click="setField('menstrualCycle', 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 specialPeriodOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.specialPeriod === opt }" @click="setField('specialPeriod', opt)"><text>{{ opt }}</text></view>
- </view>
- </view>
- </view>
- <!-- ===== 按年龄动态:儿童专属 ===== -->
- <view v-if="isChild">
- <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 growthOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.growthDevelopment === opt }" @click="setField('growthDevelopment', 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 pickyEatingOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.pickyEating === opt }" @click="setField('pickyEating', opt)"><text>{{ opt }}</text></view>
- </view>
- </view>
- </view>
- <!-- ===== 按年龄动态:老年专属 ===== -->
- <view v-if="isElderly">
- <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 osteoporosisOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.osteoporosisRisk === opt }" @click="setField('osteoporosisRisk', 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 fallRiskOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.fallRisk === opt }" @click="setField('fallRisk', opt)"><text>{{ opt }}</text></view>
- </view>
- </view>
- </view>
- <!-- ===== 按年龄动态:青少年专属 ===== -->
- <view v-if="isTeenager">
- <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 screenTimeOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.screenTime === opt }" @click="setField('screenTime', 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 teenMoodOptions" :key="opt" class="chip-item" :class="{ 'chip-active': inner.teenMood === opt }" @click="setField('teenMood', opt)"><text>{{ opt }}</text></view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- export default {
- name: 'LifestyleStep',
- props: {
- value: { type: Object, default: function() { return {} } },
- profile: { type: Object, default: function() { return {} } }
- },
- data: function() {
- return {
- inner: {
- mood: '', sleepDuration: '', bedtime: '', bowelFrequency: '', bowelForm: '', antibioticHistory: '', allergySymptoms: [],
- menstrualCycle: '', specialPeriod: '', growthDevelopment: '', pickyEating: '', osteoporosisRisk: '', fallRisk: '', screenTime: '', teenMood: ''
- }
- }
- },
- computed: {
- isFemale: function() {
- var g = this.profile && this.profile.gender
- return g === 'female' || g === '女'
- },
- isChild: function() {
- var age = this.profile && this.profile.age
- return age != null && Number(age) > 0 && Number(age) < 12
- },
- isTeenager: function() {
- var age = this.profile && this.profile.age
- return age != null && Number(age) >= 12 && Number(age) < 18
- },
- isElderly: function() {
- var age = this.profile && this.profile.age
- return age != null && Number(age) >= 60
- },
- 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 ['无', '反复皮疹', '鼻痒/打喷嚏', '眼痒/流泪', '哮喘样症状', '食物过敏'] },
- menstrualOptions: function() { return ['规律(28-32天)', '不规律', '已停经', '尚未开始'] },
- specialPeriodOptions: function() { return ['无', '备孕中', '怀孕', '哺乳期'] },
- growthOptions: function() { return ['正常(在生长曲线内)', '偏慢', '偏快', '不清楚'] },
- pickyEatingOptions: function() { return ['无挑食', '轻微挑食', '明显挑食', '严重挑食'] },
- osteoporosisOptions: function() { return ['无风险', '有风险(曾骨折/骨密度低)', '不清楚'] },
- fallRiskOptions: function() { return ['近1年无跌倒', '近1年跌倒1次', '近1年跌倒2次及以上'] },
- screenTimeOptions: function() { return ['<1小时/天', '1-3小时/天', '3-5小时/天', '>5小时/天'] },
- teenMoodOptions: function() { return ['开朗', '一般', '易怒', '低落'] }
- },
- watch: {
- value: { deep: true, handler: function(val) { this.syncFromValue(val) } },
- profile: { deep: true, handler: function(val) { this.syncProfile(val) } }
- },
- created: function() {
- this.syncFromValue(this.value)
- this.syncProfile(this.profile)
- },
- methods: {
- // 切换成员/更新 profile 时:仅清除当前性别/年龄不再适用的专属字段,
- // 保留适用字段的已存答案(先由 syncFromValue 回填,这里只做减法)
- syncProfile: function(p) {
- if (!p) return
- var g = p.gender
- var age = p.age != null ? Number(p.age) : null
- var isFemale = g === 'female' || g === '女'
- var isChild = age != null && age > 0 && age < 12
- var isTeen = age != null && age >= 12 && age < 18
- var isElderly = age != null && age >= 60
- if (!isFemale) {
- this.inner.menstrualCycle = ''
- this.inner.specialPeriod = ''
- }
- if (!isChild) {
- this.inner.growthDevelopment = ''
- this.inner.pickyEating = ''
- }
- if (!isTeen) {
- this.inner.screenTime = ''
- this.inner.teenMood = ''
- }
- if (!isElderly) {
- this.inner.osteoporosisRisk = ''
- this.inner.fallRisk = ''
- }
- },
- 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() : []
- // 兼容:按成员加载时若已有答案则回填(不在此处重置)
- this.inner.menstrualCycle = val.menstrualCycle || ''
- this.inner.specialPeriod = val.specialPeriod || ''
- this.inner.growthDevelopment = val.growthDevelopment || ''
- this.inner.pickyEating = val.pickyEating || ''
- this.inner.osteoporosisRisk = val.osteoporosisRisk || ''
- this.inner.fallRisk = val.fallRisk || ''
- this.inner.screenTime = val.screenTime || ''
- this.inner.teenMood = val.teenMood || ''
- },
- 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(),
- menstrualCycle: this.inner.menstrualCycle,
- specialPeriod: this.inner.specialPeriod,
- growthDevelopment: this.inner.growthDevelopment,
- pickyEating: this.inner.pickyEating,
- osteoporosisRisk: this.inner.osteoporosisRisk,
- fallRisk: this.inner.fallRisk,
- screenTime: this.inner.screenTime,
- teenMood: this.inner.teenMood
- })
- }
- }
- }
- </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; }
- </style>
|