|
|
@@ -0,0 +1,169 @@
|
|
|
+<template>
|
|
|
+ <view class="profile-page">
|
|
|
+ <view class="header">
|
|
|
+ <text class="title">我的</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="section" v-if="!activeGoal">
|
|
|
+ <view class="section-title">设置减脂目标</view>
|
|
|
+ <view class="form">
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">起始体重(kg)</text>
|
|
|
+ <input class="input" type="digit" v-model="goal.startWeight" placeholder="请输入起始体重" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">目标体重(kg)</text>
|
|
|
+ <input class="input" type="digit" v-model="goal.targetWeight" placeholder="请输入目标体重" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">目标体脂率(%)</text>
|
|
|
+ <input class="input" type="digit" v-model="goal.targetBodyFat" placeholder="选填" />
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">开始日期</text>
|
|
|
+ <picker mode="date" :value="goal.startDate" @change="onStartDateChange">
|
|
|
+ <view class="picker">{{ goal.startDate }}</view>
|
|
|
+ </picker>
|
|
|
+ </view>
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">目标日期</text>
|
|
|
+ <picker mode="date" :value="goal.targetDate" @change="onTargetDateChange">
|
|
|
+ <view class="picker">{{ goal.targetDate }}</view>
|
|
|
+ </picker>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <button class="submit-btn" @click="createGoal">保存目标</button>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="section" v-else>
|
|
|
+ <view class="section-title">当前目标</view>
|
|
|
+ <view class="goal-info">
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">起始体重</text>
|
|
|
+ <text class="info-value">{{ activeGoal.startWeight }} kg</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">目标体重</text>
|
|
|
+ <text class="info-value">{{ activeGoal.targetWeight }} kg</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="activeGoal.targetBodyFat">
|
|
|
+ <text class="info-label">目标体脂率</text>
|
|
|
+ <text class="info-value">{{ activeGoal.targetBodyFat }} %</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">开始日期</text>
|
|
|
+ <text class="info-value">{{ formatDate(activeGoal.startDate) }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row" v-if="activeGoal.targetDate">
|
|
|
+ <text class="info-label">目标日期</text>
|
|
|
+ <text class="info-value">{{ formatDate(activeGoal.targetDate) }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="btn-group">
|
|
|
+ <button class="btn" size="mini" @click="complete">完成目标</button>
|
|
|
+ <button class="btn btn-abandon" size="mini" @click="abandon">放弃目标</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getActiveGoal, createGoal, completeGoal, abandonGoal } from '../../utils/api.js'
|
|
|
+import { today, formatDate } from '../../utils/format.js'
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ activeGoal: null,
|
|
|
+ goal: {
|
|
|
+ startWeight: '',
|
|
|
+ targetWeight: '',
|
|
|
+ targetBodyFat: '',
|
|
|
+ startDate: today(),
|
|
|
+ targetDate: today()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onShow() {
|
|
|
+ this.loadGoal()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ formatDate(date) {
|
|
|
+ return formatDate(date)
|
|
|
+ },
|
|
|
+ loadGoal() {
|
|
|
+ getActiveGoal().then(res => {
|
|
|
+ if (res.data) this.activeGoal = res.data
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onStartDateChange(e) {
|
|
|
+ this.goal.startDate = e.detail.value
|
|
|
+ },
|
|
|
+ onTargetDateChange(e) {
|
|
|
+ this.goal.targetDate = e.detail.value
|
|
|
+ },
|
|
|
+ createGoal() {
|
|
|
+ if (!this.goal.startWeight || !this.goal.targetWeight) {
|
|
|
+ uni.showToast({ title: '请填写必填项', icon: 'none' })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var data = {
|
|
|
+ startWeight: this.goal.startWeight,
|
|
|
+ targetWeight: this.goal.targetWeight,
|
|
|
+ startDate: this.goal.startDate
|
|
|
+ }
|
|
|
+ if (this.goal.targetBodyFat) data.targetBodyFat = this.goal.targetBodyFat
|
|
|
+ if (this.goal.targetDate) data.targetDate = this.goal.targetDate
|
|
|
+ createGoal(data).then(() => {
|
|
|
+ uni.showToast({ title: '保存成功', icon: 'success' })
|
|
|
+ this.loadGoal()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ complete() {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '确定完成当前目标吗?',
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm && this.activeGoal) {
|
|
|
+ completeGoal(this.activeGoal.id).then(() => {
|
|
|
+ this.loadGoal()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ abandon() {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '确定放弃当前目标吗?',
|
|
|
+ success: (res) => {
|
|
|
+ if (res.confirm && this.activeGoal) {
|
|
|
+ abandonGoal(this.activeGoal.id).then(() => {
|
|
|
+ this.loadGoal()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+.profile-page { padding: 30rpx; }
|
|
|
+.header { margin-bottom: 30rpx; }
|
|
|
+.title { font-size: 36rpx; font-weight: 600; }
|
|
|
+.section { background: #fff; padding: 30rpx; border-radius: 16rpx; margin-bottom: 30rpx; }
|
|
|
+.section-title { font-size: 32rpx; font-weight: 600; margin-bottom: 30rpx; }
|
|
|
+.form-item { display: flex; align-items: center; padding: 24rpx 0; border-bottom: 1rpx solid #f5f5f5; }
|
|
|
+.label { width: 220rpx; color: #333; }
|
|
|
+.input { flex: 1; text-align: right; }
|
|
|
+.picker { flex: 1; text-align: right; color: #333; }
|
|
|
+.submit-btn { background: #F97316; color: #fff; border-radius: 40rpx; margin-top: 30rpx; }
|
|
|
+.goal-info { margin-bottom: 30rpx; }
|
|
|
+.info-row { display: flex; justify-content: space-between; padding: 20rpx 0; border-bottom: 1rpx solid #f5f5f5; }
|
|
|
+.info-label { color: #666; }
|
|
|
+.info-value { color: #333; font-weight: 600; }
|
|
|
+.btn-group { display: flex; gap: 20rpx; }
|
|
|
+.btn { flex: 1; background: #F97316; color: #fff; border-radius: 40rpx; }
|
|
|
+.btn-abandon { background: #999; }
|
|
|
+</style>
|