| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- <template>
- <scroll-view class="content" scroll-y>
- <!-- 已识别指标 -->
- <view class="card">
- <view class="card-accent"></view>
- <view class="card-body">
- <text class="card-title">AI 已识别指标</text>
- <text class="card-subtitle">请确认并补充成员信息后保存</text>
- <view v-if="metrics.length === 0" class="empty-state">
- <text>未识别到指标,请重新拍照</text>
- </view>
- <view v-for="(m, i) in metrics" :key="i" class="metric-row">
- <text class="metric-name">{{ m.name }}</text>
- <view class="metric-val-wrap">
- <input class="metric-val" type="digit" v-model="m.value" placeholder="数值" />
- <text class="metric-unit">{{ m.unit || '' }}</text>
- </view>
- </view>
- </view>
- </view>
- <!-- 绑定成员 -->
- <view class="card">
- <view class="card-accent"></view>
- <view class="card-body">
- <text class="card-title">绑定成员</text>
- <picker mode="selector" :range="memberList" range-key="nickname" @change="onMemberChange">
- <view class="picker-row">
- <text class="picker-text">{{ currentMember ? currentMember.nickname : '选择成员' }}</text>
- <text class="picker-arrow">›</text>
- </view>
- </picker>
- </view>
- </view>
- <view class="save-bar">
- <button class="save-btn" :disabled="saving" @click="save">{{ saving ? '保存中...' : '保存指标' }}</button>
- </view>
- </scroll-view>
- </template>
- <script>
- import { saveBodyFatMetrics } from '../../utils/api.js'
- export default {
- data() {
- return {
- metrics: [],
- memberList: [],
- currentMember: null,
- saving: false
- }
- },
- onLoad: function(options) {
- if (options.metrics) {
- try { this.metrics = JSON.parse(decodeURIComponent(options.metrics)) } catch (e) {}
- }
- this.loadMembers()
- },
- methods: {
- loadMembers: function() {
- var self = this
- var token = uni.getStorageSync('token')
- uni.request({
- url: config.API_BASE_URL + '/api/family/member/list',
- method: 'POST',
- data: { visibleOnly: true },
- header: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token },
- success: function(res) {
- if (res.data && res.data.code === 200 && res.data.data) {
- self.memberList = res.data.data
- }
- }
- })
- },
- onMemberChange: function(e) {
- var idx = parseInt(e.detail.value)
- if (idx >= 0 && idx < this.memberList.length) {
- this.currentMember = this.memberList[idx]
- }
- },
- goBack: function() {
- uni.navigateBack()
- },
- save: function() {
- var self = this
- if (!self.currentMember) {
- uni.showToast({ title: '请选择成员', icon: 'none' })
- return
- }
- if (self.metrics.length === 0) {
- uni.showToast({ title: '无可保存的指标', icon: 'none' })
- return
- }
- self.saving = true
- saveBodyFatMetrics({
- memberId: self.currentMember.id,
- metrics: self.metrics
- }).then(function(res) {
- self.saving = false
- if (res && res.code === 200) {
- uni.showToast({ title: '保存成功', icon: 'success' })
- setTimeout(function() { uni.navigateBack() }, 1000)
- } else {
- uni.showToast({ title: (res && res.message) || '保存失败', icon: 'none' })
- }
- }).catch(function() {
- self.saving = false
- uni.showToast({ title: '网络错误', icon: 'none' })
- })
- }
- }
- }
- </script>
- <style scoped>
- .page { min-height: 100vh; background: #F5F7FA; padding-bottom: 140rpx; }
- .content { height: calc(100vh - 100rpx); }
- .card { margin: 24rpx 30rpx; background: #fff; border-radius: 16rpx; overflow: hidden; }
- .card-accent { height: 6rpx; background: linear-gradient(90deg, #F97316, #F59E0B); }
- .card-body { padding: 24rpx; }
- .card-title { font-size: 30rpx; font-weight: bold; color: #333; display: block; }
- .card-subtitle { font-size: 24rpx; color: #999; margin-top: 6rpx; display: block; }
- .empty-state { padding: 40rpx 0; text-align: center; color: #999; font-size: 26rpx; }
- .metric-row { display: flex; align-items: center; justify-content: space-between; padding: 20rpx 0; border-bottom: 1rpx solid #F0F0F0; }
- .metric-row:last-child { border-bottom: none; }
- .metric-name { font-size: 28rpx; color: #333; }
- .metric-val-wrap { display: flex; align-items: center; }
- .metric-val { height: 56rpx; background: #F5F7FA; border-radius: 10rpx; padding: 0 16rpx; font-size: 28rpx; width: 160rpx; text-align: right; }
- .metric-unit { font-size: 26rpx; color: #999; margin-left: 8rpx; }
- .picker-row { display: flex; align-items: center; justify-content: space-between; padding: 16rpx 0; }
- .picker-text { font-size: 28rpx; color: #333; }
- .picker-arrow { font-size: 28rpx; color: #999; }
- .save-bar { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 20rpx 30rpx; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); }
- .save-btn { width: 100%; background: #F97316; color: #fff; border-radius: 44rpx; height: 84rpx; line-height: 84rpx; font-size: 32rpx; }
- .save-btn[disabled] { opacity: 0.6; }
- </style>
|