实现部分页面前后端相通

This commit is contained in:
2026-07-16 17:29:27 +08:00
parent 7e45ecd144
commit a9ccdab421
16 changed files with 778 additions and 184 deletions
+64 -21
View File
@@ -11,10 +11,9 @@
<view class="content-inner">
<!-- 个人信息卡片深色+ 轮播图 -->
<view class="greeting-card">
<view class="greeting-header">
<view class="greeting-header" @click="goToProfile">
<view class="member-info">
<text class="member-name">你好{{ memberInfo.nickname }}</text>
<text class="member-no">{{ memberInfo.memberNo }}</text>
<text class="member-name">{{ memberInfo.nickname ? '你好,' + memberInfo.nickname : '欢迎您!点击前往更新您的信息。' }}</text>
</view>
<view class="checkin-badge" v-if="memberInfo.checkedInToday">
<text class="checkin-icon">&#10003;</text>
@@ -52,9 +51,7 @@
<view class="recommend-list">
<view v-for="(course, idx) in recommendCourses" :key="idx" class="recommend-card"
@click="goToCourseDetail(course.id)">
<view class="card-cover" :style="{ backgroundImage: 'url(' + course.imageUrl + ')' }">
<view class="card-tag" v-if="course.recommendTitle">{{ course.recommendTitle }}</view>
</view>
<view class="card-cover" :style="{ backgroundImage: 'url(' + course.imageUrl + ')' }"></view>
<view class="card-body">
<text class="card-name">{{ course.courseName }}</text>
<text class="card-reason">{{ course.recommendReason }}</text>
@@ -74,39 +71,35 @@
</template>
<script>
const store = require('../../store/index')
const memberApi = require('../../api/member')
const courseApi = require('../../api/course')
export default {
data() {
return {
statusBarHeight: 0,
navBarHeight: 44,
totalHeaderHeight: 44,
loading: true,
memberInfo: {
nickname: 'Jason',
memberNo: 'MEM20260715001',
checkedInToday: true,
totalSignDays: 128,
pendingBookings: 3
nickname: '加载中...',
checkedInToday: false,
totalSignDays: 0,
pendingBookings: 0
},
banners: [
{ imageUrl: 'https://img.zcool.cn/community/01f5c65e5d9c6ca801216518e1d2e0.jpg@1280w_1l_2o_100sh.jpg', title: '夏季燃脂计划', subtitle: 'HIIT + 动感单车,高效燃脂 7 天挑战' },
{ imageUrl: 'https://img.zcool.cn/community/01a5fe5e5d9c4ba80121985ac87c5f.jpg@1280w_1l_2o_100sh.jpg', title: '瑜伽月卡特惠', subtitle: '新人专享 5 折,流瑜伽 / 普拉提任选' },
{ imageUrl: 'https://img.zcool.cn/community/0177c85e5d9c84a8012165182ef63f.jpg@1280w_1l_2o_100sh.jpg', title: '私教一对一体验', subtitle: '免费体测 + 定制训练计划,限 30 名' }
],
recommendCourses: [
{ id: 1, courseName: '极速燃脂单车', recommendTitle: '热门', tagColor: '', imageUrl: 'https://img.zcool.cn/community/01f5c65e5d9c6ca801216518e1d2e0.jpg@1280w_1l_2o_100sh.jpg', recommendReason: '教练专业 · 燃脂效果显著', priceLabel: '¥50', bookedCount: 186 },
{ id: 2, courseName: '清晨流瑜伽', recommendTitle: '新手推荐', tagColor: '', imageUrl: 'https://img.zcool.cn/community/01a5fe5e5d9c4ba80121985ac87c5f.jpg@1280w_1l_2o_100sh.jpg', recommendReason: '教练耐心 · 节奏适中', priceLabel: '¥50', bookedCount: 142 },
{ id: 3, courseName: '核心力量训练', recommendTitle: '塑形', tagColor: '', imageUrl: 'https://img.zcool.cn/community/0165ed5e5d9c6ca80121985a0733a5.jpg@1280w_1l_2o_100sh.jpg', recommendReason: '核心专项 · 适合所有水平', priceLabel: '¥50', bookedCount: 97 },
{ id: 4, courseName: 'HIIT燃脂训练', recommendTitle: '高强度', tagColor: '', imageUrl: 'https://img.zcool.cn/community/0148fa5e5d9c4ba80121985a1b52e4.jpg@1280w_1l_2o_100sh.jpg', recommendReason: '挑战心肺极限 · 快速燃脂', priceLabel: '¥50', bookedCount: 211 },
{ id: 5, courseName: '晚间普拉提', recommendTitle: '新上', tagColor: '', imageUrl: 'https://img.zcool.cn/community/01c3b25e5d9c6ca80121985ab2b7e6.jpg@1280w_1l_2o_100sh.jpg', recommendReason: '核心力量 · 放松一天疲劳', priceLabel: '¥50', bookedCount: 68 },
{ id: 6, courseName: '周末瑜伽', recommendTitle: '进阶', tagColor: '', imageUrl: 'https://img.zcool.cn/community/0177c85e5d9c84a8012165182ef63f.jpg@1280w_1l_2o_100sh.jpg', recommendReason: '有基础的进阶课程', priceLabel: '¥50', bookedCount: 55 }
]
recommendCourses: []
}
},
onLoad() {
const systemInfo = uni.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 20
let navBarHeight = 44
// 获取胶囊按钮信息,对齐导航栏高度
// #ifdef MP-WEIXIN
const menuButton = uni.getMenuButtonBoundingClientRect()
if (menuButton) {
@@ -117,9 +110,59 @@
this.navBarHeight = navBarHeight
this.totalHeaderHeight = statusBarHeight + navBarHeight
},
onShow() {
if (!store.isLoggedIn) {
// 未登录时不重定向,登录页是首入口,只需跳过数据加载
return
}
this.loadData()
},
methods: {
goToCourseDetail(id) { uni.navigateTo({ url: '/pages/course-detail/course-detail?id=' + id }) },
goToSearch() { uni.switchTab({ url: '/pages/search/search' }) }
goToSearch() { uni.switchTab({ url: '/pages/search/search' }) },
goToProfile() { uni.switchTab({ url: '/pages/profile/profile' }) },
async loadData() {
this.loading = true
try {
// 并行获取会员信息和推荐课程
const [memberResult, recommendResult] = await Promise.allSettled([
memberApi.getMemberInfo(),
courseApi.getActiveRecommendations()
])
// 处理会员信息
if (memberResult.status === 'fulfilled') {
const info = memberResult.value
store.updateMemberInfo(info)
this.memberInfo = {
nickname: info.nickname || '',
checkedInToday: info.checkedInToday || false,
totalSignDays: info.totalSignInDays || 0,
pendingBookings: info.pendingBookings || 0
}
}
// 处理推荐课程(数据来自 group_course_recommend 表,关联 groupCourse 子对象)
if (recommendResult.status === 'fulfilled') {
this.recommendCourses = (recommendResult.value || []).map(r => {
const gc = r.groupCourse || {}
return {
id: gc.id || r.courseId,
courseName: gc.courseName || '推荐课程',
imageUrl: gc.coverImage || '',
recommendReason: r.recommendReason || '',
priceLabel: (gc.storedValueAmount > 0 ? '¥' + gc.storedValueAmount : '免费'),
bookedCount: gc.currentMembers || 0
}
})
}
} catch (e) {
console.error('首页数据加载失败:', e)
} finally {
this.loading = false
}
}
}
}
</script>