整合api请求、添加购买会员卡页面、登陆页面
This commit is contained in:
@@ -169,7 +169,8 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import MemberInfoSubNav from '@/components/memberInfo/MemberInfoSubNav.vue'
|
||||
import BodyTestRadarChart from '@/components/memberInfo/BodyTestRadarChart.vue'
|
||||
import BodyTestTrendChart from '@/components/memberInfo/BodyTestTrendChart.vue'
|
||||
@@ -180,127 +181,139 @@ import {
|
||||
getBodyTestTrendData,
|
||||
getRecommendedCourses,
|
||||
computeChanges,
|
||||
formatChangeValue,
|
||||
bodyTestMock
|
||||
formatChangeValue
|
||||
} from '@/common/memberInfo/bodyTestStore.js'
|
||||
|
||||
export default {
|
||||
components: { MemberInfoSubNav, BodyTestRadarChart, BodyTestTrendChart },
|
||||
data() {
|
||||
const recordId = ref(null)
|
||||
const record = ref(null)
|
||||
const previous = ref(null)
|
||||
const chartWidth = ref(300)
|
||||
|
||||
const radarLabels = computed(() => {
|
||||
return ['体重', 'BMI', '体脂率', '肌肉量', '内脏脂肪', '基础代谢']
|
||||
})
|
||||
|
||||
const radarKeys = ['weight', 'bmi', 'bodyFat', 'muscleMass', 'visceralFat', 'bmr']
|
||||
|
||||
const radarValues = computed(() => {
|
||||
if (!record.value?.radar) return []
|
||||
return radarKeys.map((k) => record.value.radar[k] || 0)
|
||||
})
|
||||
|
||||
const metricDefs = [
|
||||
{ key: 'weight', label: '体重', unit: 'kg' },
|
||||
{ key: 'bmi', label: 'BMI' },
|
||||
{ key: 'bodyFat', label: '体脂率', unit: '%' },
|
||||
{ key: 'muscleMass', label: '肌肉量', unit: 'kg' },
|
||||
{ key: 'visceralFat', label: '内脏脂肪', unit: '级' },
|
||||
{ key: 'bmr', label: '基础代谢', unit: 'kcal' },
|
||||
{ key: 'bodyWater', label: '体水分', unit: '%' },
|
||||
{ key: 'boneMass', label: '骨量', unit: 'kg' }
|
||||
]
|
||||
|
||||
const metricCards = computed(() => {
|
||||
if (!record.value?.metrics) return []
|
||||
const changesVal = changes.value
|
||||
const defs = metricDefs.slice(0, 8)
|
||||
return defs.map((def) => {
|
||||
const val = record.value.metrics[def.key]
|
||||
const diff = changesVal[def.key]
|
||||
let changeText = ''
|
||||
let changeClass = ''
|
||||
if (diff !== undefined && diff !== null) {
|
||||
changeText = formatChangeValue(def.key, diff)
|
||||
const lowerBetter = ['weight', 'bodyFat', 'visceralFat'].includes(def.key)
|
||||
const isGood = lowerBetter ? diff < 0 : diff > 0
|
||||
changeClass = isGood ? 'bt-metric__change--down' : 'bt-metric__change--up'
|
||||
}
|
||||
const display = def.unit ? `${val}${def.unit === '%' ? '%' : def.unit === 'kg' ? '' : ` ${def.unit}`}` : val
|
||||
return {
|
||||
recordId: null,
|
||||
record: null,
|
||||
previous: null,
|
||||
chartWidth: 300
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
radarLabels() {
|
||||
return bodyTestMock.radarLabels.map((l) => l.label)
|
||||
},
|
||||
radarValues() {
|
||||
if (!this.record?.radar) return []
|
||||
const keys = bodyTestMock.radarLabels.map((l) => l.key)
|
||||
return keys.map((k) => this.record.radar[k] || 0)
|
||||
},
|
||||
metricCards() {
|
||||
if (!this.record?.metrics) return []
|
||||
const changes = this.changes
|
||||
const defs = bodyTestMock.metricDefs.slice(0, 8)
|
||||
return defs.map((def) => {
|
||||
const val = this.record.metrics[def.key]
|
||||
const diff = changes[def.key]
|
||||
let changeText = ''
|
||||
let changeClass = ''
|
||||
if (diff !== undefined && diff !== null) {
|
||||
changeText = formatChangeValue(def.key, diff)
|
||||
const lowerBetter = ['weight', 'bodyFat', 'visceralFat'].includes(def.key)
|
||||
const isGood = lowerBetter ? diff < 0 : diff > 0
|
||||
changeClass = isGood ? 'bt-metric__change--down' : 'bt-metric__change--up'
|
||||
}
|
||||
const display = def.unit ? `${val}${def.unit === '%' ? '%' : def.unit === 'kg' ? '' : ` ${def.unit}`}` : val
|
||||
return {
|
||||
key: def.key,
|
||||
label: def.label + (def.unit && def.unit !== '%' && def.unit !== 'kg' ? `(${def.unit})` : def.unit === 'kg' ? '(kg)' : def.unit === '%' ? '(%)' : ''),
|
||||
display: def.key === 'bodyFat' ? `${val}%` : def.key === 'bodyWater' ? `${val}%` : def.unit === 'kg' ? val : def.unit ? `${val}` : val,
|
||||
changeText,
|
||||
changeClass
|
||||
}
|
||||
})
|
||||
},
|
||||
changes() {
|
||||
if (this.record?.changes) return this.record.changes
|
||||
if (this.previous) return computeChanges(this.record, this.previous)
|
||||
return {}
|
||||
},
|
||||
trendPreview() {
|
||||
const store = loadMemberStore()
|
||||
return getBodyTestTrendData(store, 'weight', 4)
|
||||
},
|
||||
courses() {
|
||||
return getRecommendedCourses(this.record)
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.recordId = options?.id ? Number(options.id) : null
|
||||
this.chartWidth = uni.getSystemInfoSync().windowWidth - 64
|
||||
this.loadRecord()
|
||||
},
|
||||
methods: {
|
||||
loadRecord() {
|
||||
const store = loadMemberStore()
|
||||
const records = store.bodyTest.records
|
||||
if (this.recordId) {
|
||||
this.record = getBodyTestRecordById(store, this.recordId)
|
||||
} else {
|
||||
this.record = records.length ? { ...records[0] } : null
|
||||
}
|
||||
if (this.record) {
|
||||
const idx = records.findIndex((r) => r.id === this.record.id)
|
||||
this.previous = idx >= 0 && records[idx + 1] ? records[idx + 1] : null
|
||||
}
|
||||
},
|
||||
onBack() {
|
||||
goBackOrTab(PAGE.BODY_TEST_HOME)
|
||||
},
|
||||
goTrend() {
|
||||
navigateToPage(`${PAGE.BODY_TEST_TREND}?metric=weight`)
|
||||
},
|
||||
exportReport() {
|
||||
uni.showLoading({ title: '生成中…' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '报告已保存到相册', icon: 'success' })
|
||||
}, 1200)
|
||||
},
|
||||
shareReport() {
|
||||
uni.showActionSheet({
|
||||
itemList: ['分享给微信好友', '生成分享海报', '复制报告链接'],
|
||||
success: (res) => {
|
||||
const msgs = ['已唤起微信分享', '海报已生成', '链接已复制']
|
||||
uni.showToast({ title: msgs[res.tapIndex] || '分享成功', icon: 'none' })
|
||||
}
|
||||
})
|
||||
},
|
||||
onCourseTap(course) {
|
||||
uni.showModal({
|
||||
title: course.title,
|
||||
content: `${course.coach}\n${course.schedule}\n\n是否前往预约?`,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
navigateToPage(PAGE.COURSE_LIST)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
retest() {
|
||||
navigateToPage(PAGE.BODY_TEST_HOME)
|
||||
key: def.key,
|
||||
label: def.label + (def.unit && def.unit !== '%' && def.unit !== 'kg' ? `(${def.unit})` : def.unit === 'kg' ? '(kg)' : def.unit === '%' ? '(%)' : ''),
|
||||
display: def.key === 'bodyFat' ? `${val}%` : def.key === 'bodyWater' ? `${val}%` : def.unit === 'kg' ? val : def.unit ? `${val}` : val,
|
||||
changeText,
|
||||
changeClass
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const changes = computed(() => {
|
||||
if (record.value?.changes) return record.value.changes
|
||||
if (previous.value) return computeChanges(record.value, previous.value)
|
||||
return {}
|
||||
})
|
||||
|
||||
const trendPreview = computed(() => {
|
||||
const store = loadMemberStore()
|
||||
return getBodyTestTrendData(store, 'weight', 4)
|
||||
})
|
||||
|
||||
const courses = computed(() => {
|
||||
return getRecommendedCourses(record.value)
|
||||
})
|
||||
|
||||
function loadRecord() {
|
||||
const store = loadMemberStore()
|
||||
const records = store.bodyTest.records
|
||||
if (recordId.value) {
|
||||
record.value = getBodyTestRecordById(store, recordId.value)
|
||||
} else {
|
||||
record.value = records.length ? { ...records[0] } : null
|
||||
}
|
||||
if (record.value) {
|
||||
const idx = records.findIndex((r) => r.id === record.value.id)
|
||||
previous.value = idx >= 0 && records[idx + 1] ? records[idx + 1] : null
|
||||
}
|
||||
}
|
||||
|
||||
function onBack() {
|
||||
goBackOrTab(PAGE.BODY_TEST_HOME)
|
||||
}
|
||||
|
||||
function goTrend() {
|
||||
navigateToPage(`${PAGE.BODY_TEST_TREND}?metric=weight`)
|
||||
}
|
||||
|
||||
function exportReport() {
|
||||
uni.showLoading({ title: '生成中…' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '报告已保存到相册', icon: 'success' })
|
||||
}, 1200)
|
||||
}
|
||||
|
||||
function shareReport() {
|
||||
uni.showActionSheet({
|
||||
itemList: ['分享给微信好友', '生成分享海报', '复制报告链接'],
|
||||
success: (res) => {
|
||||
const msgs = ['已唤起微信分享', '海报已生成', '链接已复制']
|
||||
uni.showToast({ title: msgs[res.tapIndex] || '分享成功', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onCourseTap(course) {
|
||||
uni.showModal({
|
||||
title: course.title,
|
||||
content: `${course.coach}\n${course.schedule}\n\n是否前往预约?`,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
navigateToPage(PAGE.COURSE_LIST)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function retest() {
|
||||
navigateToPage(PAGE.BODY_TEST_HOME)
|
||||
}
|
||||
|
||||
// Initialize
|
||||
chartWidth.value = uni.getSystemInfoSync().windowWidth - 64
|
||||
loadRecord()
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style lang="scss">
|
||||
@import '@/common/style/base.css';
|
||||
@import '@/common/style/memberInfo/pages/page-reset.css';
|
||||
@import '@/common/style/memberInfo/pages/sub-page-base.css';
|
||||
|
||||
Reference in New Issue
Block a user