170 lines
6.1 KiB
Vue
170 lines
6.1 KiB
Vue
<template>
|
|
<view class="scroll-container theme-light">
|
|
<view class="bt-page">
|
|
<MemberInfoSubNav title="测量中" @back="onCancel" />
|
|
<view class="bt-page__body">
|
|
<view class="bt-card">
|
|
<view class="bt-measure">
|
|
<view class="bt-measure__ring-wrap">
|
|
<view class="bt-measure__ring-bg"></view>
|
|
<view
|
|
class="bt-measure__ring-fill"
|
|
:style="{ transform: `rotate(${ringRotation}deg)` }"
|
|
></view>
|
|
<view class="bt-measure__center">
|
|
<text class="bt-measure__percent">{{ progress }}%</text>
|
|
<text class="bt-measure__hint">{{ phaseHint }}</text>
|
|
</view>
|
|
</view>
|
|
<text class="bt-card__desc">{{ statusText }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="bt-card">
|
|
<text class="bt-card__title">实时数据</text>
|
|
<view class="bt-measure__live">
|
|
<view
|
|
v-for="item in liveDisplay"
|
|
:key="item.key"
|
|
class="bt-measure__live-item"
|
|
>
|
|
<text class="bt-measure__live-value">{{ item.value }}</text>
|
|
<text class="bt-measure__live-label">{{ item.label }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import MemberInfoSubNav from '@/components/memberInfo/MemberInfoSubNav.vue'
|
|
import { PAGE, navigateToPage, goBackOrTab } from '@/common/constants/routes.js'
|
|
import {
|
|
loadMemberStore,
|
|
persistMemberStore
|
|
} from '@/common/memberInfo/store.js'
|
|
import {
|
|
interpolateMeasuringMetrics,
|
|
saveSimulatedBodyTestRecord
|
|
} from '@/common/memberInfo/bodyTestStore.js'
|
|
|
|
const PHASES = [
|
|
{ until: 20, hint: '校准中', text: '请保持站立姿势,双手自然下垂' },
|
|
{ until: 50, hint: '阻抗测量', text: '请勿移动,正在进行生物电阻抗分析' },
|
|
{ until: 80, hint: '数据分析', text: '正在计算体脂与肌肉分布' },
|
|
{ until: 100, hint: '即将完成', text: '生成健康报告中…' }
|
|
]
|
|
|
|
export default {
|
|
components: { MemberInfoSubNav },
|
|
data() {
|
|
return {
|
|
progress: 0,
|
|
liveMetrics: {},
|
|
timer: null,
|
|
finished: false
|
|
}
|
|
},
|
|
computed: {
|
|
ringRotation() {
|
|
return -90 + (this.progress / 100) * 360
|
|
},
|
|
phaseHint() {
|
|
const phase = PHASES.find((p) => this.progress <= p.until)
|
|
return phase?.hint || '完成'
|
|
},
|
|
statusText() {
|
|
const phase = PHASES.find((p) => this.progress <= p.until)
|
|
return phase?.text || '测量完成'
|
|
},
|
|
liveDisplay() {
|
|
const m = this.liveMetrics
|
|
return [
|
|
{ key: 'weight', label: '体重(kg)', value: m.weight ?? '--' },
|
|
{ key: 'bodyFat', label: '体脂率(%)', value: m.bodyFat ?? '--' },
|
|
{ key: 'muscleMass', label: '肌肉量(kg)', value: m.muscleMass ?? '--' },
|
|
{ key: 'bmr', label: '基础代谢', value: m.bmr ?? '--' }
|
|
]
|
|
}
|
|
},
|
|
onLoad() {
|
|
const store = loadMemberStore()
|
|
if (!store.bodyTest.device.connected) {
|
|
uni.showToast({ title: '请先连接设备', icon: 'none' })
|
|
setTimeout(() => {
|
|
navigateToPage(PAGE.BODY_TEST_CONNECT)
|
|
}, 800)
|
|
return
|
|
}
|
|
this.startMeasurement()
|
|
},
|
|
onUnload() {
|
|
this.clearTimer()
|
|
},
|
|
methods: {
|
|
clearTimer() {
|
|
if (this.timer) {
|
|
clearInterval(this.timer)
|
|
this.timer = null
|
|
}
|
|
},
|
|
startMeasurement() {
|
|
const store = loadMemberStore()
|
|
this.liveMetrics = interpolateMeasuringMetrics(0, store.profile)
|
|
this.timer = setInterval(() => {
|
|
if (this.progress >= 100) {
|
|
this.completeMeasurement()
|
|
return
|
|
}
|
|
this.progress = Math.min(100, this.progress + 2)
|
|
const s = loadMemberStore()
|
|
this.liveMetrics = interpolateMeasuringMetrics(this.progress, s.profile)
|
|
}, 120)
|
|
},
|
|
completeMeasurement() {
|
|
if (this.finished) return
|
|
this.finished = true
|
|
this.clearTimer()
|
|
const store = loadMemberStore()
|
|
const record = saveSimulatedBodyTestRecord(store, {
|
|
...this.liveMetrics,
|
|
visceralFat: 6,
|
|
boneMass: 2.42,
|
|
bodyWater: this.liveMetrics.bodyWater || 52.8,
|
|
protein: 16.4
|
|
})
|
|
persistMemberStore(store)
|
|
uni.showToast({ title: '测量完成', icon: 'success' })
|
|
setTimeout(() => {
|
|
navigateToPage(`${PAGE.BODY_TEST_REPORT}?id=${record.id}&new=1`)
|
|
}, 600)
|
|
},
|
|
onCancel() {
|
|
if (this.finished) return
|
|
uni.showModal({
|
|
title: '取消测量',
|
|
content: '确定要中断当前体测吗?',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
this.clearTimer()
|
|
goBackOrTab(PAGE.BODY_TEST_HOME)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</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>
|