Files
gym-manage/gym-manage-uniapp/pages/memberInfo/bodyTestCompare.vue
T
2026-06-11 08:33:19 +08:00

163 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="历史对比" @back="onBack" />
<view class="bt-page__body">
<view class="bt-card">
<text class="bt-card__title">选择对比记录</text>
<view class="bt-compare-header">
<view
class="bt-compare-picker"
hover-class="mi-tap--hover"
:hover-stay-time="150"
@tap="pickRecord('a')"
>
<text class="bt-compare-picker__label">记录 A较新</text>
<text class="bt-compare-picker__date">{{ recordA?.date || '点击选择' }}</text>
</view>
<view
class="bt-compare-picker"
hover-class="mi-tap--hover"
:hover-stay-time="150"
@tap="pickRecord('b')"
>
<text class="bt-compare-picker__label">记录 B较旧</text>
<text class="bt-compare-picker__date">{{ recordB?.date || '点击选择' }}</text>
</view>
</view>
</view>
<view v-if="compareData" class="bt-card">
<text class="bt-card__title">指标对比</text>
<view class="bt-compare-row">
<text class="bt-compare-row__label">指标</text>
<text class="bt-compare-row__val">A</text>
<text class="bt-compare-row__val">B</text>
<text class="bt-compare-row__diff">差值</text>
</view>
<view
v-for="row in compareData.metrics"
:key="row.key"
class="bt-compare-row"
>
<text class="bt-compare-row__label">{{ row.label }}</text>
<text class="bt-compare-row__val">{{ row.valueA }}</text>
<text class="bt-compare-row__val">{{ row.valueB }}</text>
<text
class="bt-compare-row__diff"
:style="{ color: diffColor(row) }"
>
{{ formatDiff(row.diff, row.key) }}
</text>
</view>
</view>
<view v-if="compareData" class="bt-card">
<text class="bt-card__title">评分变化</text>
<view class="bt-metrics">
<view class="bt-metric">
<text class="bt-metric__value">{{ compareData.recordA.score }}</text>
<text class="bt-metric__label">记录 A 评分</text>
</view>
<view class="bt-metric">
<text class="bt-metric__value">{{ compareData.recordB.score }}</text>
<text class="bt-metric__label">记录 B 评分</text>
</view>
</view>
<text class="bt-card__desc" style="margin-top: 12px;">
综合评分变化 {{ scoreDiff > 0 ? '+' : '' }}{{ scoreDiff }}
{{ scoreDiff > 0 ? ',整体趋势向好' : scoreDiff < 0 ? ',建议加强训练' : '' }}
</text>
</view>
</view>
</view>
</view>
</template>
<script>
import MemberInfoSubNav from '@/components/memberInfo/MemberInfoSubNav.vue'
import { PAGE, goBackOrTab } from '@/common/constants/routes.js'
import { loadMemberStore } from '@/common/memberInfo/store.js'
import { getBodyTestHistory, getCompareData } from '@/common/memberInfo/bodyTestStore.js'
export default {
components: { MemberInfoSubNav },
data() {
return {
records: [],
recordA: null,
recordB: null,
compareData: null
}
},
computed: {
scoreDiff() {
if (!this.compareData) return 0
return this.compareData.recordA.score - this.compareData.recordB.score
}
},
onShow() {
const store = loadMemberStore()
this.records = getBodyTestHistory(store)
if (this.records.length >= 2 && !this.recordA) {
this.recordA = this.records[0]
this.recordB = this.records[1]
this.refreshCompare()
}
},
methods: {
onBack() {
goBackOrTab(PAGE.BODY_TEST_HISTORY)
},
pickRecord(which) {
const labels = this.records.map(
(r) => `${r.date} · ${r.score}分 · ${r.gradeLabel}`
)
uni.showActionSheet({
itemList: labels,
success: (res) => {
const picked = this.records[res.tapIndex]
if (which === 'a') this.recordA = picked
else this.recordB = picked
this.refreshCompare()
}
})
},
refreshCompare() {
if (!this.recordA || !this.recordB) {
this.compareData = null
return
}
if (this.recordA.id === this.recordB.id) {
uni.showToast({ title: '请选择两条不同记录', icon: 'none' })
this.compareData = null
return
}
const store = loadMemberStore()
this.compareData = getCompareData(store, this.recordA.id, this.recordB.id)
},
formatDiff(diff, key) {
const sign = diff > 0 ? '+' : ''
const units = { bodyFat: '%', weight: '', bmi: '', muscleMass: '', visceralFat: '', bmr: '' }
return `${sign}${diff}${units[key] || ''}`
},
diffColor(row) {
const lowerBetter = ['weight', 'bodyFat', 'visceralFat'].includes(row.key)
const good = lowerBetter ? row.diff < 0 : row.diff > 0
if (row.diff === 0) return '#8A99B4'
return good ? '#2ECC71' : '#F39C12'
}
}
}
</script>
<style>
@import '@/common/style/base.css';
@import '@/common/style/memberInfo/pages/page-reset.css';
@import '@/common/style/memberInfo/pages/sub-page-base.css';
@import '@/common/style/memberInfo/member-info-component-reset.css';
@import '@/common/style/memberInfo/member-info-sub-nav.css';
@import '@/common/style/memberInfo/member-info-tap.css';
@import '@/common/style/memberInfo/pages/body-test-common.css';
</style>