重写会员端,初步完善首页

This commit is contained in:
2026-07-15 17:26:07 +08:00
parent cacc8997ec
commit 7e45ecd144
26 changed files with 3405 additions and 199 deletions
+171
View File
@@ -0,0 +1,171 @@
<template>
<view class="home-page">
<!-- 状态栏 + 胶囊按钮占位 -->
<view class="header-wrap" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-bar" :style="{ height: navBarHeight + 'px' }">
<text class="nav-title">&#10031; 今日训练</text>
</view>
</view>
<scroll-view class="content" scroll-y :style="{ height: 'calc(100vh - ' + totalHeaderHeight + 'px)' }">
<view class="content-inner">
<!-- 个人信息卡片深色+ 轮播图 -->
<view class="greeting-card">
<view class="greeting-header">
<view class="member-info">
<text class="member-name">你好{{ memberInfo.nickname }}</text>
<text class="member-no">{{ memberInfo.memberNo }}</text>
</view>
<view class="checkin-badge" v-if="memberInfo.checkedInToday">
<text class="checkin-icon">&#10003;</text>
<text>今日已签到</text>
</view>
</view>
<view class="stats">
<view class="stat-item">
<text class="stat-number">{{ memberInfo.totalSignDays }}</text>
<text class="stat-label">累计签到()</text>
</view>
<view class="stat-item">
<text class="stat-number">{{ memberInfo.pendingBookings }}</text>
<text class="stat-label">待上团课</text>
</view>
</view>
<!-- 轮播图 -->
<swiper class="banner-swiper" :indicator-dots="true" :autoplay="true" :interval="4000" :duration="500" circular>
<swiper-item v-for="(banner, idx) in banners" :key="idx">
<view class="banner-slide" :style="{ backgroundImage: 'url(' + banner.imageUrl + ')' }">
<text class="banner-title">{{ banner.title }}</text>
<text class="banner-subtitle">{{ banner.subtitle }}</text>
</view>
</swiper-item>
</swiper>
</view>
<!-- 今日推荐 -->
<view class="recommend-section">
<view class="section-header">
<text class="section-title">&#10031; 今日推荐</text>
<text class="section-more" @click="goToSearch">查看全部 &#8250;</text>
</view>
<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-body">
<text class="card-name">{{ course.courseName }}</text>
<text class="card-reason">{{ course.recommendReason }}</text>
<view class="card-bottom">
<text class="card-price">{{ course.priceLabel }}</text>
<text class="card-count">{{ course.bookedCount }}人已预约</text>
</view>
</view>
</view>
</view>
</view>
<view class="bottom-safe"></view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
statusBarHeight: 0,
navBarHeight: 44,
totalHeaderHeight: 44,
memberInfo: {
nickname: 'Jason',
memberNo: 'MEM20260715001',
checkedInToday: true,
totalSignDays: 128,
pendingBookings: 3
},
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 }
]
}
},
onLoad() {
const systemInfo = uni.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 20
let navBarHeight = 44
// 获取胶囊按钮信息,对齐导航栏高度
// #ifdef MP-WEIXIN
const menuButton = uni.getMenuButtonBoundingClientRect()
if (menuButton) {
navBarHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height
}
// #endif
this.statusBarHeight = statusBarHeight
this.navBarHeight = navBarHeight
this.totalHeaderHeight = statusBarHeight + navBarHeight
},
methods: {
goToCourseDetail(id) { uni.navigateTo({ url: '/pages/course-detail/course-detail?id=' + id }) },
goToSearch() { uni.switchTab({ url: '/pages/search/search' }) }
}
}
</script>
<style scoped>
.home-page { min-height: 100vh; background: #F5F7FA; overflow-x: hidden; }
.header-wrap { background: #1A1A1A; }
.nav-bar { background: #1A1A1A; padding: 0 20px; display: flex; align-items: center; }
.nav-title { font-size: 18px; font-weight: 700; color: #FFFFFF; }
.content-inner { padding: 16px; }
/* 个人信息卡片 */
.greeting-card { background: #1A1A1A; border-radius: 20px; padding: 18px 20px 0; color: #FFFFFF; margin-bottom: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.06); overflow: hidden; }
.greeting-header { display: flex; justify-content: space-between; align-items: flex-start; }
.member-info { display: flex; flex-direction: column; }
.member-name { font-size: 18px; font-weight: 600; }
.member-no { font-size: 11px; color: rgba(255,255,255,0.5); margin-top: 2px; }
.checkin-badge { background: rgba(0,230,118,0.2); color: #00E676; font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 12px; display: flex; align-items: center; }
.checkin-icon { font-size: 11px; margin-right: 3px; }
.stats { display: flex; margin-top: 16px; }
.stat-item { display: flex; flex-direction: column; margin-right: 24px; }
.stat-number { font-size: 22px; font-weight: 700; color: #00E676; }
.stat-label { font-size: 12px; color: rgba(255,255,255,0.6); margin-top: 2px; }
/* 轮播图 */
.banner-swiper { height: 160px; margin: 14px -20px 0; }
.banner-slide { height: 100%; background-size: cover; background-position: center; background-color: #2A2A2A; display: flex; flex-direction: column; justify-content: flex-end; padding: 16px 20px; }
.banner-title { font-size: 20px; font-weight: 700; color: #FFFFFF; text-shadow: 0 2px 6px rgba(0,0,0,0.5); }
.banner-subtitle { font-size: 14px; color: rgba(255,255,255,0.9); margin-top: 6px; text-shadow: 0 1px 4px rgba(0,0,0,0.5); }
/* 今日推荐 */
.recommend-section { margin-bottom: 16px; }
.section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.section-title { font-size: 18px; font-weight: 700; color: #1E1E1E; }
.section-more { font-size: 13px; color: #00C853; }
.recommend-list { display: flex; flex-wrap: wrap; justify-content: space-between; }
.recommend-card { width: calc(50% - 6px); background: #FFFFFF; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.06); margin-bottom: 12px; }
.card-cover { height: 130px; background-size: cover; background-position: center; background-color: #E8E8E8; display: flex; align-items: flex-start; justify-content: flex-end; padding: 8px; }
.card-tag { background: #00E676; color: #1A1A1A; font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 20px; }
.card-body { padding: 10px 12px 14px; }
.card-name { font-size: 14px; font-weight: 600; color: #1E1E1E; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; margin-bottom: 4px; }
.card-reason { font-size: 12px; color: #7A7E84; display: block; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 2px; }
.card-price { font-size: 14px; font-weight: 700; color: #00C853; }
.card-count { font-size: 11px; color: #BDBDBD; }
.bottom-safe { height: 20px; }
</style>