|
|
@@ -0,0 +1,239 @@
|
|
|
+<template>
|
|
|
+ <view class="page">
|
|
|
+ <view class="header">
|
|
|
+ <text class="title">我的健康方案</text>
|
|
|
+ <text class="subtitle">查看和管理健康计划</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 新建方案按钮 -->
|
|
|
+ <view class="action-bar">
|
|
|
+ <button class="btn-create" @click="goCreatePlan">+ 新建方案</button>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 加载状态 -->
|
|
|
+ <view class="loading" v-if="loading">
|
|
|
+ <text class="loading-text">加载中...</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 空状态 -->
|
|
|
+ <view class="empty" v-else-if="plans.length === 0">
|
|
|
+ <text class="empty-icon">📋</text>
|
|
|
+ <text class="empty-title">暂无健康方案</text>
|
|
|
+ <text class="empty-desc">点击下方按钮创建第一个健康方案</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 方案列表 -->
|
|
|
+ <view class="plan-list" v-else>
|
|
|
+ <view
|
|
|
+ class="plan-card"
|
|
|
+ v-for="plan in plans"
|
|
|
+ :key="plan.id"
|
|
|
+ @click="goDetail(plan.id)"
|
|
|
+ >
|
|
|
+ <view class="card-top">
|
|
|
+ <text class="plan-title">{{ plan.goal || plan.memberName || '健康方案' }}</text>
|
|
|
+ <view class="plan-status" :class="'status-' + plan.status">
|
|
|
+ <text>{{ statusText(plan.status) }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="card-meta">
|
|
|
+ <text class="meta-item" v-if="plan.memberName">成员:{{ plan.memberName }}</text>
|
|
|
+ <text class="meta-item">创建时间:{{ formatTime(plan.createdAt) }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="plan-arrow">›</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getHealthPlanList } from '@/utils/api.js'
|
|
|
+
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ plans: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad() {
|
|
|
+ this.loadPlans()
|
|
|
+ },
|
|
|
+ onShow() {
|
|
|
+ this.loadPlans()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadPlans() {
|
|
|
+ this.loading = true
|
|
|
+ var self = this
|
|
|
+ getHealthPlanList({}).then(function(res) {
|
|
|
+ self.loading = false
|
|
|
+ if (res && res.code === 200 && res.data) {
|
|
|
+ var list = res.data.list || res.data
|
|
|
+ self.plans = Array.isArray(list) ? list : []
|
|
|
+ } else {
|
|
|
+ self.plans = []
|
|
|
+ }
|
|
|
+ }).catch(function(err) {
|
|
|
+ self.loading = false
|
|
|
+ console.error('加载方案列表失败', err)
|
|
|
+ self.plans = []
|
|
|
+ })
|
|
|
+ },
|
|
|
+ goDetail(planId) {
|
|
|
+ uni.navigateTo({ url: '/pages/health/health-plan-summary?planId=' + planId })
|
|
|
+ },
|
|
|
+ goCreatePlan() {
|
|
|
+ uni.navigateTo({ url: '/pages/health/health-plan-summary' })
|
|
|
+ },
|
|
|
+ statusText(status) {
|
|
|
+ var map = {
|
|
|
+ 'draft': '待确认',
|
|
|
+ 'pending_review': '待审核',
|
|
|
+ 'confirmed': '已确认',
|
|
|
+ 'published': '已发布',
|
|
|
+ 'rejected': '已驳回'
|
|
|
+ }
|
|
|
+ return map[status] || '未知'
|
|
|
+ },
|
|
|
+ formatTime(t) {
|
|
|
+ if (!t) return '-'
|
|
|
+ return String(t).substring(0, 19).replace('T', ' ')
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #F5FAFE;
|
|
|
+ padding-bottom: 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.header {
|
|
|
+ padding: 40rpx 30rpx 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.title {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #1F2D3D;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.subtitle {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #8A94A6;
|
|
|
+ margin-top: 8rpx;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.action-bar {
|
|
|
+ padding: 0 30rpx 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-create {
|
|
|
+ width: 100%;
|
|
|
+ background: #4A9BD7;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ padding: 24rpx 0;
|
|
|
+ border-radius: 12rpx;
|
|
|
+ border: none;
|
|
|
+}
|
|
|
+
|
|
|
+.loading, .empty {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ padding: 100rpx 0;
|
|
|
+}
|
|
|
+
|
|
|
+.loading-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #8A94A6;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-icon {
|
|
|
+ font-size: 80rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-top: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-desc {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #999;
|
|
|
+ margin-top: 10rpx;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.plan-list {
|
|
|
+ padding: 0 30rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.plan-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06);
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.plan-card:active {
|
|
|
+ opacity: 0.8;
|
|
|
+}
|
|
|
+
|
|
|
+.card-top {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.plan-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.plan-status {
|
|
|
+ font-size: 22rpx;
|
|
|
+ padding: 4rpx 16rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.status-draft { background: #FFF3E0; color: #F97316; }
|
|
|
+.status-pending_review { background: #E3F2FD; color: #2196F3; }
|
|
|
+.status-confirmed { background: #E8F5E9; color: #4CAF50; }
|
|
|
+.status-published { background: #E8F5E9; color: #4CAF50; }
|
|
|
+.status-rejected { background: #FDE8E8; color: #C62828; }
|
|
|
+
|
|
|
+.card-meta {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ margin-top: 16rpx;
|
|
|
+ gap: 6rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.meta-item {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #bbb;
|
|
|
+}
|
|
|
+
|
|
|
+.plan-arrow {
|
|
|
+ position: absolute;
|
|
|
+ right: 24rpx;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ font-size: 36rpx;
|
|
|
+ color: #CCC;
|
|
|
+}
|
|
|
+</style>
|