优化会员信息模块及首页组件,清理冗余图片资源
@@ -5,7 +5,7 @@ export const memberCenterMock = {
|
||||
name: '张小芳',
|
||||
phone: '13812345678 已绑定微信',
|
||||
memberLevel: '黄金会员',
|
||||
avatar: '/static/images/AvatarEditWrap.png'
|
||||
avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AvatarEditWrap.png'
|
||||
},
|
||||
stats: {
|
||||
checkInCount: 128,
|
||||
@@ -75,7 +75,7 @@ export const userInfoMock = {
|
||||
height: '165',
|
||||
weight: '63.5',
|
||||
fitnessGoals: ['减脂', '塑形'],
|
||||
avatar: '/static/images/AvatarEditWrap.png'
|
||||
avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AvatarEditWrap.png'
|
||||
}
|
||||
|
||||
export const fitnessGoalOptions = ['减脂', '塑形', '增肌', '提升耐力', '改善体态']
|
||||
@@ -102,7 +102,7 @@ export const memberCardMock = {
|
||||
time: '2024-07-12 09:05',
|
||||
value: '-1次',
|
||||
valueType: 'negative',
|
||||
icon: '/static/images/dumbbell.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/dumbbell.png',
|
||||
iconTheme: 'orange'
|
||||
},
|
||||
{
|
||||
@@ -112,7 +112,7 @@ export const memberCardMock = {
|
||||
time: '2024-07-11 18:30',
|
||||
value: '-1天',
|
||||
valueType: 'negative',
|
||||
icon: '/static/images/mappin.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/mappin.png',
|
||||
iconTheme: 'green'
|
||||
},
|
||||
{
|
||||
@@ -122,7 +122,7 @@ export const memberCardMock = {
|
||||
time: '2024-07-01 10:00',
|
||||
value: '+90天',
|
||||
valueType: 'positive',
|
||||
icon: '/static/images/pluscircle.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/pluscircle.png',
|
||||
iconTheme: 'orange'
|
||||
}
|
||||
],
|
||||
@@ -156,14 +156,14 @@ export const bodyTestMock = {
|
||||
{ step: 3, title: '确认连接', desc: '点击下方按钮搜索并配对设备' }
|
||||
],
|
||||
metricDefs: [
|
||||
{ key: 'weight', label: '体重', unit: 'kg', icon: '/static/images/target.png' },
|
||||
{ key: 'bmi', label: 'BMI', unit: '', icon: '/static/images/activity.png' },
|
||||
{ key: 'bodyFat', label: '体脂率', unit: '%', icon: '/static/images/trendingdown.png' },
|
||||
{ key: 'muscleMass', label: '肌肉量', unit: 'kg', icon: '/static/images/dumbbell.png' },
|
||||
{ key: 'visceralFat', label: '内脏脂肪', unit: '级', icon: '/static/images/alertcircle.png' },
|
||||
{ key: 'bmr', label: '基础代谢', unit: 'kcal', icon: '/static/images/clock.png' },
|
||||
{ key: 'bodyWater', label: '体水分', unit: '%', icon: '/static/images/shield.png' },
|
||||
{ key: 'boneMass', label: '骨量', unit: 'kg', icon: '/static/images/user.png' }
|
||||
{ key: 'weight', label: '体重', unit: 'kg', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/target.png' },
|
||||
{ key: 'bmi', label: 'BMI', unit: '', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/activity.png' },
|
||||
{ key: 'bodyFat', label: '体脂率', unit: '%', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/trendingdown.png' },
|
||||
{ key: 'muscleMass', label: '肌肉量', unit: 'kg', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/dumbbell.png' },
|
||||
{ key: 'visceralFat', label: '内脏脂肪', unit: '级', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/alertcircle.png' },
|
||||
{ key: 'bmr', label: '基础代谢', unit: 'kcal', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock.png' },
|
||||
{ key: 'bodyWater', label: '体水分', unit: '%', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/shield.png' },
|
||||
{ key: 'boneMass', label: '骨量', unit: 'kg', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user.png' }
|
||||
],
|
||||
radarLabels: [
|
||||
{ key: 'weight', label: '体重控制' },
|
||||
@@ -185,7 +185,7 @@ export const bodyTestMock = {
|
||||
title: '燃脂 HIIT 团课',
|
||||
coach: '李明教练',
|
||||
schedule: '每周二、四 19:00',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
tag: '减脂推荐'
|
||||
},
|
||||
{
|
||||
@@ -193,7 +193,7 @@ export const bodyTestMock = {
|
||||
title: '核心力量塑形',
|
||||
coach: '王强教练',
|
||||
schedule: '每周一、三 18:30',
|
||||
banner: '/static/images/AC2Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC2Banner.png',
|
||||
tag: '塑形推荐'
|
||||
}
|
||||
],
|
||||
@@ -352,7 +352,7 @@ export const bookingMock = {
|
||||
{
|
||||
id: 1,
|
||||
title: '瑜伽基础班',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
status: 'booked',
|
||||
statusLabel: '已预约',
|
||||
schedule: '07月15日 09:00-10:00',
|
||||
@@ -368,7 +368,7 @@ export const bookingMock = {
|
||||
{
|
||||
id: 2,
|
||||
title: '私教健身课',
|
||||
banner: '/static/images/AC2Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC2Banner.png',
|
||||
status: 'pending',
|
||||
statusLabel: '待上课',
|
||||
schedule: '07月18日 14:00-15:00',
|
||||
@@ -386,7 +386,7 @@ export const bookingMock = {
|
||||
{
|
||||
id: 3,
|
||||
title: '动感单车',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
status: 'completed',
|
||||
statusLabel: '已完成',
|
||||
schedule: '07月10日 19:00-20:00',
|
||||
@@ -397,7 +397,7 @@ export const bookingMock = {
|
||||
{
|
||||
id: 4,
|
||||
title: '普拉提进阶',
|
||||
banner: '/static/images/AC2Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC2Banner.png',
|
||||
status: 'cancelled',
|
||||
statusLabel: '已取消',
|
||||
schedule: '07月05日 10:00-11:00',
|
||||
@@ -428,7 +428,7 @@ export const courseCatalogMock = {
|
||||
title: '瑜伽基础班',
|
||||
type: 'group',
|
||||
coach: '李明教练',
|
||||
coachAvatar: '/static/images/user0.png',
|
||||
coachAvatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user0.png',
|
||||
date: '2024-07-15',
|
||||
startTime: '09:00',
|
||||
endTime: '10:00',
|
||||
@@ -438,7 +438,7 @@ export const courseCatalogMock = {
|
||||
price: '次卡扣 1 次',
|
||||
payType: 'session',
|
||||
period: 'morning',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
intro: '适合零基础学员,重点提升柔韧性与呼吸控制。',
|
||||
suitable: '久坐办公族、初学者、想改善体态者',
|
||||
coachBio: '国家一级瑜伽指导员,5年教学经验',
|
||||
@@ -454,7 +454,7 @@ export const courseCatalogMock = {
|
||||
title: 'HIIT 燃脂团课',
|
||||
type: 'group',
|
||||
coach: '赵敏教练',
|
||||
coachAvatar: '/static/images/user1.png',
|
||||
coachAvatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user1.png',
|
||||
date: '2024-07-15',
|
||||
startTime: '19:00',
|
||||
endTime: '20:00',
|
||||
@@ -464,7 +464,7 @@ export const courseCatalogMock = {
|
||||
price: '时长卡',
|
||||
payType: 'duration',
|
||||
period: 'evening',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
intro: '高强度间歇训练,快速燃脂提升心肺。',
|
||||
suitable: '有一定运动基础、目标减脂者',
|
||||
coachBio: 'ACE 认证教练,擅长 HIIT 与动感单车',
|
||||
@@ -477,7 +477,7 @@ export const courseCatalogMock = {
|
||||
title: '私教 · 力量训练',
|
||||
type: 'private',
|
||||
coach: '王强教练',
|
||||
coachAvatar: '/static/images/user2.png',
|
||||
coachAvatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user2.png',
|
||||
date: '2024-07-16',
|
||||
startTime: '14:00',
|
||||
endTime: '15:00',
|
||||
@@ -487,7 +487,7 @@ export const courseCatalogMock = {
|
||||
price: '私教课时卡',
|
||||
payType: 'private',
|
||||
period: 'afternoon',
|
||||
banner: '/static/images/AC2Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC2Banner.png',
|
||||
intro: '一对一力量训练,定制训练计划。',
|
||||
suitable: '增肌塑形、康复训练',
|
||||
coachBio: 'NSCA 认证私教,8年从业经验',
|
||||
@@ -500,7 +500,7 @@ export const courseCatalogMock = {
|
||||
title: '普拉提进阶',
|
||||
type: 'group',
|
||||
coach: '李明教练',
|
||||
coachAvatar: '/static/images/user0.png',
|
||||
coachAvatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user0.png',
|
||||
date: '2024-07-17',
|
||||
startTime: '10:30',
|
||||
endTime: '11:30',
|
||||
@@ -510,7 +510,7 @@ export const courseCatalogMock = {
|
||||
price: '次卡扣 1 次',
|
||||
payType: 'session',
|
||||
period: 'morning',
|
||||
banner: '/static/images/AC2Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC2Banner.png',
|
||||
intro: '核心稳定与体态矫正进阶课程。',
|
||||
suitable: '有普拉提基础者',
|
||||
coachBio: '国家一级瑜伽指导员',
|
||||
@@ -523,7 +523,7 @@ export const courseCatalogMock = {
|
||||
title: '动感单车',
|
||||
type: 'group',
|
||||
coach: '赵敏教练',
|
||||
coachAvatar: '/static/images/user1.png',
|
||||
coachAvatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user1.png',
|
||||
date: '2024-07-18',
|
||||
startTime: '18:30',
|
||||
endTime: '19:30',
|
||||
@@ -533,7 +533,7 @@ export const courseCatalogMock = {
|
||||
price: '储值卡 ¥39',
|
||||
payType: 'stored',
|
||||
period: 'evening',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
intro: '音乐骑行,团队氛围燃脂。',
|
||||
suitable: '所有级别,可调节阻力',
|
||||
coachBio: 'ACE 认证教练',
|
||||
@@ -720,10 +720,10 @@ export const moduleMock = {
|
||||
rule: '签到、训练、邀请好友、购课均可获得积分;积分可用于商城兑换。'
|
||||
},
|
||||
pointsRewards: [
|
||||
{ id: 1, name: '团课体验券', cost: 500, stock: 12, icon: '/static/images/ticket.png' },
|
||||
{ id: 2, name: '运动毛巾', cost: 800, stock: 5, icon: '/static/images/dumbbell.png' },
|
||||
{ id: 3, name: '私教体验30分钟', cost: 2000, stock: 3, icon: '/static/images/usercheck.png' },
|
||||
{ id: 4, name: '蛋白粉小样', cost: 350, stock: 20, icon: '/static/images/star.png' }
|
||||
{ id: 1, name: '团课体验券', cost: 500, stock: 12, icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/ticket.png' },
|
||||
{ id: 2, name: '运动毛巾', cost: 800, stock: 5, icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/dumbbell.png' },
|
||||
{ id: 3, name: '私教体验30分钟', cost: 2000, stock: 3, icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/usercheck.png' },
|
||||
{ id: 4, name: '蛋白粉小样', cost: 350, stock: 20, icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/star.png' }
|
||||
],
|
||||
pointsHistory: [
|
||||
{ id: 1, type: 'earn', title: '团课签到', amount: 50, time: '2024-07-12 09:10', balance: 1250 },
|
||||
@@ -739,11 +739,11 @@ export const moduleMock = {
|
||||
'积分可用于兑换课程体验券及周边礼品'
|
||||
],
|
||||
referralRecords: [
|
||||
{ id: 1, name: '李**', avatar: '/static/images/user0.png', status: 'purchased', statusLabel: '已购课', time: '2024-07-05', reward: '+300积分', rewardStatus: '已发放' },
|
||||
{ id: 2, name: '王**', avatar: '/static/images/user1.png', status: 'registered', statusLabel: '已注册', time: '2024-06-20', reward: '+100积分', rewardStatus: '已发放' },
|
||||
{ id: 3, name: '陈**', avatar: '/static/images/user2.png', status: 'invited', statusLabel: '已邀请', time: '2024-06-15', reward: '待注册', rewardStatus: '待发放' },
|
||||
{ id: 4, name: '赵**', avatar: '/static/images/user3.png', status: 'purchased', statusLabel: '已购课', time: '2024-06-01', reward: '+300积分', rewardStatus: '已发放' },
|
||||
{ id: 5, name: '刘**', avatar: '/static/images/user0.png', status: 'registered', statusLabel: '已注册', time: '2024-05-28', reward: '+100积分', rewardStatus: '已发放' }
|
||||
{ id: 1, name: '李**', avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user0.png', status: 'purchased', statusLabel: '已购课', time: '2024-07-05', reward: '+300积分', rewardStatus: '已发放' },
|
||||
{ id: 2, name: '王**', avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user1.png', status: 'registered', statusLabel: '已注册', time: '2024-06-20', reward: '+100积分', rewardStatus: '已发放' },
|
||||
{ id: 3, name: '陈**', avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user2.png', status: 'invited', statusLabel: '已邀请', time: '2024-06-15', reward: '待注册', rewardStatus: '待发放' },
|
||||
{ id: 4, name: '赵**', avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user3.png', status: 'purchased', statusLabel: '已购课', time: '2024-06-01', reward: '+300积分', rewardStatus: '已发放' },
|
||||
{ id: 5, name: '刘**', avatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user0.png', status: 'registered', statusLabel: '已注册', time: '2024-05-28', reward: '+100积分', rewardStatus: '已发放' }
|
||||
],
|
||||
referralRewardSummary: {
|
||||
totalPoints: 800,
|
||||
@@ -763,7 +763,7 @@ export const moduleMock = {
|
||||
id: 1,
|
||||
title: '瑜伽基础班',
|
||||
coach: '李明教练',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
progress: 6,
|
||||
total: 12,
|
||||
schedule: '每周二、四 09:00',
|
||||
@@ -778,7 +778,7 @@ export const moduleMock = {
|
||||
id: 3,
|
||||
title: '动感单车入门',
|
||||
coach: '赵敏教练',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
progress: 8,
|
||||
total: 8,
|
||||
schedule: '已结课',
|
||||
@@ -791,7 +791,7 @@ export const moduleMock = {
|
||||
private: {
|
||||
remaining: 7,
|
||||
coach: '王强教练',
|
||||
coachAvatar: '/static/images/user2.png',
|
||||
coachAvatar: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user2.png',
|
||||
nextClass: '07月15日 14:00',
|
||||
bookings: [
|
||||
{ id: 2, title: '私教 · 力量训练', time: '07月18日 14:00', status: '已预约', location: 'B区私教室' }
|
||||
@@ -804,7 +804,7 @@ export const moduleMock = {
|
||||
{
|
||||
id: 201,
|
||||
title: '居家核心训练',
|
||||
cover: '/static/images/AC2Banner.png',
|
||||
cover: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC2Banner.png',
|
||||
duration: '45分钟',
|
||||
progress: 60,
|
||||
chapters: 6,
|
||||
@@ -814,7 +814,7 @@ export const moduleMock = {
|
||||
{
|
||||
id: 202,
|
||||
title: '直播 · 晨间拉伸',
|
||||
cover: '/static/images/AC1Banner.png',
|
||||
cover: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
duration: '30分钟',
|
||||
progress: 0,
|
||||
liveTime: '07月20日 07:00',
|
||||
@@ -825,7 +825,7 @@ export const moduleMock = {
|
||||
{
|
||||
id: 301,
|
||||
title: '28天减脂训练营',
|
||||
banner: '/static/images/AC1Banner.png',
|
||||
banner: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AC1Banner.png',
|
||||
progress: 3,
|
||||
total: 10,
|
||||
coach: '李明教练',
|
||||
|
||||
@@ -275,7 +275,7 @@ export function renewMemberCard(store, addDays = 90) {
|
||||
time: formatRecordTime(new Date()),
|
||||
value: `+${addDays}天`,
|
||||
valueType: 'positive',
|
||||
icon: '/static/images/pluscircle.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/pluscircle.png',
|
||||
iconTheme: 'orange'
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id */
|
||||
src: url('tabbar.ttf?t=1780818759010') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-home:before {
|
||||
content: "\e666";
|
||||
}
|
||||
|
||||
.icon-course:before {
|
||||
content: "\e692";
|
||||
}
|
||||
|
||||
.icon-train:before {
|
||||
content: "\e8be";
|
||||
}
|
||||
|
||||
.icon-discover:before {
|
||||
content: "\e726";
|
||||
}
|
||||
|
||||
.icon-profile:before {
|
||||
content: "\e501";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<view class="skeleton" :style="{ padding: padding }">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
padding: {
|
||||
type: String,
|
||||
default: '20rpx'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.skeleton {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
:deep(.skeleton-shimmer) {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
:deep(.skeleton-line) {
|
||||
height: 32rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
:deep(.skeleton-block) {
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
:deep(.skeleton-circle) {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
</style>
|
||||
@@ -8,11 +8,13 @@
|
||||
hover-class="tab-item--hover"
|
||||
@tap.stop="onTabTap(index)"
|
||||
>
|
||||
<image
|
||||
:src="currentActiveIndex === index ? tab.iconActive : tab.icon"
|
||||
mode="aspectFit"
|
||||
class="tab-icon"
|
||||
/>
|
||||
<!-- 判断是否使用字体图标(我的页面用字体,其他用图片) -->
|
||||
<text
|
||||
v-if="tab.useFontIcon"
|
||||
:class="['iconfont', tab.icon]"
|
||||
class="tab-icon-font"
|
||||
:style="{ fontSize: tab.fontSize}"
|
||||
></text>
|
||||
<text class="tab-label">{{ tab.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -34,32 +36,27 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['update:active', 'tab-change'])
|
||||
|
||||
// 当前激活的索引 - 默认从路由获取
|
||||
const currentActiveIndex = ref(-1)
|
||||
|
||||
// 是否需要显示 TabBar
|
||||
const shouldShowTabBar = ref(true)
|
||||
|
||||
// 不需要显示 TabBar 的页面路径列表(注意:不要带开头的 /)
|
||||
const HIDE_TABBAR_PAGES = [
|
||||
'pages/memberInfo/courseList', // 预约课程
|
||||
'pages/memberInfo/courseDetail', // 课程详情
|
||||
'pages/memberInfo/booking', // 我的预约
|
||||
'pages/memberInfo/bodyTestReport', // 体测报告
|
||||
'pages/groupCourse/list', // 团课列表
|
||||
'pages/groupCourse/detail', // 团课详情
|
||||
'pages/searchCourse/searchCourse', // 搜索课程
|
||||
'pages/checkIn/checkIn', // 会员签到
|
||||
'pages/memberInfo/myCourses', // 我的课程
|
||||
'pages/memberInfo/coupons', // 我的优惠券
|
||||
'pages/memberInfo/points', // 我的积分
|
||||
'pages/memberInfo/pointsMall', // 积分商城
|
||||
'pages/memberInfo/referral', // 邀请好友
|
||||
'pages/memberInfo/userInfo', // 个人信息
|
||||
'pages/memberInfo/memberCard', // 我的会员卡
|
||||
'pages/memberInfo/courseList',
|
||||
'pages/memberInfo/courseDetail',
|
||||
'pages/memberInfo/booking',
|
||||
'pages/memberInfo/bodyTestReport',
|
||||
'pages/groupCourse/list',
|
||||
'pages/groupCourse/detail',
|
||||
'pages/searchCourse/searchCourse',
|
||||
'pages/checkIn/checkIn',
|
||||
'pages/memberInfo/myCourses',
|
||||
'pages/memberInfo/coupons',
|
||||
'pages/memberInfo/points',
|
||||
'pages/memberInfo/pointsMall',
|
||||
'pages/memberInfo/referral',
|
||||
'pages/memberInfo/userInfo',
|
||||
'pages/memberInfo/memberCard',
|
||||
]
|
||||
|
||||
// 从路由获取当前激活的 tab
|
||||
function getActiveIndexFromRoute() {
|
||||
const routePath = getCurrentRoutePath()
|
||||
const index = getTabIndexByRoute(routePath)
|
||||
@@ -67,16 +64,12 @@ function getActiveIndexFromRoute() {
|
||||
return index >= 0 ? index : 0
|
||||
}
|
||||
|
||||
// 同步激活状态(高优先级:路由 > props)
|
||||
function syncActiveState() {
|
||||
// 优先从路由获取(最准确)
|
||||
const routeIndex = getActiveIndexFromRoute()
|
||||
if (routeIndex >= 0) {
|
||||
currentActiveIndex.value = routeIndex
|
||||
return
|
||||
}
|
||||
|
||||
// 其次使用 props
|
||||
if (props.active >= 0) {
|
||||
currentActiveIndex.value = props.active
|
||||
} else if (props.activeTab >= 0) {
|
||||
@@ -86,23 +79,16 @@ function syncActiveState() {
|
||||
}
|
||||
}
|
||||
|
||||
// 检查当前页面是否需要隐藏 TabBar
|
||||
function checkShouldShow() {
|
||||
let routePath = getCurrentRoutePath()
|
||||
|
||||
// 标准化路径:去掉开头的 /
|
||||
if (routePath.startsWith('/')) {
|
||||
routePath = routePath.slice(1)
|
||||
}
|
||||
// 去掉查询参数(?后面的内容)
|
||||
if (routePath.includes('?')) {
|
||||
routePath = routePath.split('?')[0]
|
||||
}
|
||||
|
||||
// 检查是否在隐藏列表中
|
||||
const shouldHide = HIDE_TABBAR_PAGES.includes(routePath)
|
||||
shouldShowTabBar.value = !shouldHide
|
||||
|
||||
console.log('=== TabBar 显示控制 ===')
|
||||
console.log('原始路径:', getCurrentRoutePath())
|
||||
console.log('标准化路径:', routePath)
|
||||
@@ -110,25 +96,19 @@ function checkShouldShow() {
|
||||
console.log('是否显示 TabBar:', shouldShowTabBar.value)
|
||||
}
|
||||
|
||||
// 监听路由变化(页面切换时自动同步)
|
||||
let routeWatcher = null
|
||||
let appRouteCallback = null
|
||||
|
||||
onMounted(() => {
|
||||
// 初始同步
|
||||
syncActiveState()
|
||||
checkShouldShow()
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// App 端:监听页面显示
|
||||
routeWatcher = setInterval(() => {
|
||||
syncActiveState()
|
||||
checkShouldShow()
|
||||
}, 300)
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
// 小程序端:监听路由变化
|
||||
if (typeof uni.onAppRoute === 'function') {
|
||||
appRouteCallback = () => {
|
||||
setTimeout(() => {
|
||||
@@ -143,11 +123,8 @@ onMounted(() => {
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
// #ifdef APP-PLUS
|
||||
if (routeWatcher) {
|
||||
clearInterval(routeWatcher)
|
||||
}
|
||||
if (routeWatcher) { clearInterval(routeWatcher) }
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
if (appRouteCallback && typeof uni.offAppRoute === 'function') {
|
||||
uni.offAppRoute(appRouteCallback)
|
||||
@@ -155,44 +132,48 @@ onBeforeUnmount(() => {
|
||||
// #endif
|
||||
})
|
||||
|
||||
// 监听 props 变化
|
||||
watch(() => props.active, () => {
|
||||
const routeIndex = getActiveIndexFromRoute()
|
||||
if (routeIndex !== currentActiveIndex.value) {
|
||||
syncActiveState()
|
||||
}
|
||||
if (routeIndex !== currentActiveIndex.value) { syncActiveState() }
|
||||
})
|
||||
|
||||
// tabs 配置:只有"我的"用字体图标
|
||||
const tabs = [
|
||||
{
|
||||
path: PAGE.INDEX,
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/home.png',
|
||||
iconActive: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/active/home.png',
|
||||
label: '首页'
|
||||
icon: 'icon-home',
|
||||
label: '首页',
|
||||
useFontIcon: true,
|
||||
fontSize:"36rpx"
|
||||
},
|
||||
{
|
||||
path: PAGE.COURSE,
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/course.png',
|
||||
iconActive: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/active/course.png',
|
||||
label: '课程'
|
||||
icon: 'icon-course',
|
||||
iconActive: '/static/tabBar/active/course.png',
|
||||
label: '课程',
|
||||
useFontIcon: true,
|
||||
fontSize:"36rpx"
|
||||
},
|
||||
{
|
||||
path: PAGE.TRAIN,
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/train.png',
|
||||
iconActive: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/active/train.png',
|
||||
label: '训练'
|
||||
icon: 'icon-train',
|
||||
label: '训练',
|
||||
useFontIcon: true,
|
||||
fontSize:"48rpx"
|
||||
},
|
||||
{
|
||||
path: PAGE.DISCOVER,
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/discover.png',
|
||||
iconActive: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/active/discover.png',
|
||||
label: '发现'
|
||||
icon: 'icon-discover',
|
||||
label: '发现',
|
||||
useFontIcon: true,
|
||||
fontSize:"48rpx"
|
||||
},
|
||||
{
|
||||
path: PAGE.MEMBER,
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/profile.png',
|
||||
iconActive: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/tabBar/active/profile.png',
|
||||
label: '我的'
|
||||
icon: 'icon-profile',
|
||||
label: '我的',
|
||||
useFontIcon: true,
|
||||
fontSize:"36rpx"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -200,37 +181,22 @@ let isSwitching = false
|
||||
|
||||
function onTabTap(index) {
|
||||
if (isSwitching) return
|
||||
|
||||
const targetPath = TAB_ROUTES[index]
|
||||
const currentPath = TAB_ROUTES[currentActiveIndex.value]
|
||||
|
||||
if (targetPath === currentPath) return
|
||||
|
||||
console.log('Tab 点击:', index, targetPath)
|
||||
|
||||
// 1. 立即更新 UI 高亮
|
||||
currentActiveIndex.value = index
|
||||
|
||||
// 2. 通知父组件
|
||||
emit('update:active', index)
|
||||
emit('tab-change', index)
|
||||
|
||||
// 3. 显示 loading(可选)
|
||||
let timer = setTimeout(() => {
|
||||
uni.showLoading({ title: '加载中...', mask: true })
|
||||
}, 50)
|
||||
|
||||
isSwitching = true
|
||||
|
||||
// 4. 执行跳转
|
||||
uni.switchTab({
|
||||
url: targetPath,
|
||||
success: () => {
|
||||
console.log('switchTab 成功:', targetPath)
|
||||
},
|
||||
success: () => { console.log('switchTab 成功:', targetPath) },
|
||||
fail: (err) => {
|
||||
console.error('switchTab 失败:', err)
|
||||
// 降级
|
||||
uni.reLaunch({ url: targetPath })
|
||||
},
|
||||
complete: () => {
|
||||
@@ -238,7 +204,6 @@ function onTabTap(index) {
|
||||
uni.hideLoading()
|
||||
setTimeout(() => {
|
||||
isSwitching = false
|
||||
// 跳转完成后,再次同步确保高亮正确
|
||||
syncActiveState()
|
||||
checkShouldShow()
|
||||
}, 100)
|
||||
@@ -248,19 +213,24 @@ function onTabTap(index) {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 引入字体图标 CSS(定义 @font-face)
|
||||
@import '/common/style/tabbar_icon/tabbar.css';
|
||||
|
||||
.tab-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 120rpx;
|
||||
background: #1A4A6F;
|
||||
background: rgba(200, 225, 238, 0.8);
|
||||
backdrop-filter: blur(24px);
|
||||
-webkit-backdrop-filter: blur(24px);
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
|
||||
box-shadow: 0 -4rpx 24rpx rgba(120, 185, 215, 0.2);
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
z-index: 999;
|
||||
}
|
||||
@@ -278,18 +248,34 @@ function onTabTap(index) {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
// 图片图标样式
|
||||
.tab-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
// 字体图标样式
|
||||
.tab-icon-font {
|
||||
font-size: 44rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
// 字体图标颜色控制(根据选中状态)
|
||||
.tab-item .iconfont {
|
||||
color: gray; // 未选中颜色
|
||||
}
|
||||
|
||||
.tab-item.active .iconfont {
|
||||
color: #5A98B0; // 选中颜色
|
||||
}
|
||||
|
||||
.tab-label {
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
}
|
||||
|
||||
.tab-item.active .tab-label {
|
||||
color: #f97316;
|
||||
color: #5A98B0;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,85 @@
|
||||
<!-- components/GlobalLoading.vue -->
|
||||
<template>
|
||||
<view v-if="visible" class="global-loading">
|
||||
<view class="loading-mask"></view>
|
||||
<view class="loading-content">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="loading-text">{{ text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const visible = ref(false)
|
||||
const text = ref('加载中...')
|
||||
|
||||
// 显示
|
||||
function show(loadingText = '加载中...') {
|
||||
visible.value = true
|
||||
text.value = loadingText
|
||||
}
|
||||
|
||||
// 隐藏
|
||||
function hide() {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
// 挂载到全局
|
||||
if (typeof uni !== 'undefined') {
|
||||
uni.$globalLoading = { show, hide }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.global-loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
position: relative;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx 48rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
||||
border-top-color: #fff;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<!-- 轮播图容器 -->
|
||||
<view class="banner-container">
|
||||
<!-- 轮播图组件 -->
|
||||
<swiper
|
||||
class="banner-swiper"
|
||||
:circular="true"
|
||||
@@ -11,15 +9,10 @@
|
||||
:indicator-dots="false"
|
||||
@change="onSwiperChange"
|
||||
>
|
||||
<!-- 轮播项 -->
|
||||
<swiper-item v-for="(banner, index) in banners" :key="index">
|
||||
<!-- 轮播内容 -->
|
||||
<view class="banner-content">
|
||||
<!-- 轮播图片 -->
|
||||
<image :src="banner.image" mode="aspectFill" class="banner-image" />
|
||||
<!-- 图片遮罩层 -->
|
||||
<view class="banner-overlay"></view>
|
||||
<!-- 轮播文字信息 -->
|
||||
<view class="banner-text">
|
||||
<text class="banner-title">{{ banner.title }}</text>
|
||||
<text class="banner-subtitle">{{ banner.subtitle }}</text>
|
||||
@@ -28,7 +21,6 @@
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<!-- 轮播指示器点 -->
|
||||
<view class="banner-dots">
|
||||
<view
|
||||
v-for="(_, index) in banners"
|
||||
@@ -42,7 +34,6 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 轮播图数据列表
|
||||
const banners = [
|
||||
{
|
||||
image: 'https://images.unsplash.com/photo-1534438327276-14e5300c3a48?w=800&q=80',
|
||||
@@ -64,29 +55,25 @@ const banners = [
|
||||
}
|
||||
]
|
||||
|
||||
// 当前轮播索引,用于控制指示器激活状态
|
||||
const currentIndex = ref(0)
|
||||
|
||||
// 轮播图切换时的回调函数,更新当前索引
|
||||
const onSwiperChange = (e) => {
|
||||
currentIndex.value = e.detail.current
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 轮播图容器样式 */
|
||||
.banner-container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 轮播图组件样式 */
|
||||
.banner-swiper {
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
height: 480rpx;
|
||||
}
|
||||
|
||||
/* 轮播内容容器样式 */
|
||||
.banner-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -94,78 +81,108 @@ const onSwiperChange = (e) => {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 轮播图片样式 */
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 图片遮罩层样式,添加渐变效果 */
|
||||
.banner-overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(135deg, rgba(11, 43, 75, 0.85) 0%, rgba(26, 74, 111, 0.6) 100%);
|
||||
}
|
||||
|
||||
/* 轮播文字信息容器样式 */
|
||||
.wave-transition {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -2rpx;
|
||||
height: 100rpx;
|
||||
z-index: 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wt-layer {
|
||||
position: absolute;
|
||||
left: -10%;
|
||||
width: 120%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wt-layer-1 {
|
||||
bottom: 0;
|
||||
background: #C0DDE9;
|
||||
border-radius: 45% 55% 0 0;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.wt-layer-2 {
|
||||
bottom: -10rpx;
|
||||
background: #D4EAF2;
|
||||
border-radius: 55% 45% 0 0;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.wt-layer-3 {
|
||||
bottom: -20rpx;
|
||||
background: #E8F4F9;
|
||||
border-radius: 40% 60% 0 0;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.banner-text {
|
||||
position: absolute;
|
||||
left: 32rpx;
|
||||
left: 36rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* 轮播标题样式 */
|
||||
.banner-title {
|
||||
display: block;
|
||||
font-size: 48rpx;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
margin-bottom: 8rpx;
|
||||
text-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 4rpx 16rpx rgba(80, 150, 190, 0.4);
|
||||
}
|
||||
|
||||
/* 轮播副标题样式 */
|
||||
.banner-subtitle {
|
||||
display: block;
|
||||
font-size: 56rpx;
|
||||
font-weight: 800;
|
||||
color: #f97316;
|
||||
color: #E0F0FA;
|
||||
margin-bottom: 16rpx;
|
||||
text-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 4rpx 16rpx rgba(80, 150, 190, 0.4);
|
||||
}
|
||||
|
||||
/* 轮播描述文字样式 */
|
||||
.banner-desc {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
/* 轮播指示器容器样式 */
|
||||
.banner-dots {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 16rpx;
|
||||
margin-top: 24rpx;
|
||||
margin-top: -100rpx;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/* 轮播指示器点样式 */
|
||||
.dot {
|
||||
width: 48rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 9999rpx;
|
||||
background: #d1d5db;
|
||||
background: #D0E4EE;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* 轮播指示器激活状态样式 */
|
||||
.dot.active {
|
||||
width: 64rpx;
|
||||
background: #f97316;
|
||||
background: linear-gradient(90deg, #7AB5CC, #9CCFDF);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,21 +1,15 @@
|
||||
<template>
|
||||
<!-- 快捷入口容器 -->
|
||||
<view class="quick-entry">
|
||||
<!-- 快捷入口项 -->
|
||||
<view
|
||||
v-for="(item, index) in entries"
|
||||
:key="index"
|
||||
class="entry-item"
|
||||
@tap="QEClick(item.path)"
|
||||
>
|
||||
<!-- 入口图标容器 -->
|
||||
<view :class="['entry-icon', { accent: item.accent }]">
|
||||
<!-- 入口图标图片 -->
|
||||
<image :src="item.icon" mode="aspectFit" class="icon-img" />
|
||||
</view>
|
||||
<!-- 入口标题 -->
|
||||
<text class="entry-title">{{ item.title }}</text>
|
||||
<!-- 入口描述 -->
|
||||
<text class="entry-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -28,7 +22,6 @@ const QEClick = path => {
|
||||
url:path
|
||||
})
|
||||
}
|
||||
// 快捷入口数据列表
|
||||
const entries = [
|
||||
{
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/icons/course.png',
|
||||
@@ -66,18 +59,21 @@ const entries = [
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 快捷入口容器样式 */
|
||||
.quick-entry {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 32rpx 24rpx;
|
||||
background: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(24px);
|
||||
-webkit-backdrop-filter: blur(24px);
|
||||
margin: 24rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
border-radius: 28rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(120, 185, 215, 0.18);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.7);
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
/* 快捷入口项样式 */
|
||||
.entry-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -85,40 +81,36 @@ const entries = [
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 入口图标容器样式 */
|
||||
.entry-icon {
|
||||
width: 104rpx;
|
||||
height: 104rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #072A4E;
|
||||
border-radius: 24rpx;
|
||||
background: linear-gradient(135deg, #7AB5CC 0%, #9CCFDF 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16rpx;
|
||||
box-shadow: 0 6rpx 20rpx rgba(122, 181, 204, 0.35);
|
||||
}
|
||||
|
||||
/* 入口图标图片样式 */
|
||||
.icon-img {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
}
|
||||
|
||||
/* 入口图标强调色样式(橙色背景) */
|
||||
.entry-icon.accent {
|
||||
background: #FC5A15;
|
||||
background: linear-gradient(135deg, #6BA8C0 0%, #8CC5D5 100%);
|
||||
}
|
||||
|
||||
/* 入口标题样式 */
|
||||
.entry-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #1a202c;
|
||||
color: #2D4A5A;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
/* 入口描述文字样式 */
|
||||
.entry-desc {
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
<view class="view-more">
|
||||
<text>查看更多</text>
|
||||
<text class="arrow">
|
||||
<uni-icons type="right" size="20" color="#94a3b8"/>
|
||||
<uni-icons type="right" size="20" color="#8CA0B0"/>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -94,41 +94,21 @@ const getCourseTypeName = (type) => {
|
||||
|
||||
// 根据课程信息获取标签文本
|
||||
const getTag = (course) => {
|
||||
// 满员标签
|
||||
if (course.currentMembers >= course.maxMembers) {
|
||||
return '已满员'
|
||||
}
|
||||
// 已结束的课程
|
||||
if (course.status === '2') {
|
||||
return '已结束'
|
||||
}
|
||||
// 高人气标签(参与人数超过最大人数的80%)
|
||||
if (course.currentMembers / course.maxMembers >= 0.8) {
|
||||
return '热门'
|
||||
}
|
||||
// 课程类型标签
|
||||
if (course.currentMembers >= course.maxMembers) return '已满员'
|
||||
if (course.status === '2') return '已结束'
|
||||
if (course.currentMembers / course.maxMembers >= 0.8) return '热门'
|
||||
return getCourseTypeName(course.courseType)
|
||||
}
|
||||
|
||||
// 根据课程信息获取标签样式类型
|
||||
const getTagType = (course) => {
|
||||
// 满员标签样式
|
||||
if (course.currentMembers >= course.maxMembers) {
|
||||
return 'full'
|
||||
}
|
||||
// 已结束标签样式
|
||||
if (course.status === '2') {
|
||||
return 'ended'
|
||||
}
|
||||
// 热门标签样式
|
||||
if (course.currentMembers / course.maxMembers >= 0.8) {
|
||||
return 'hot'
|
||||
}
|
||||
// 默认样式
|
||||
if (course.currentMembers >= course.maxMembers) return 'full'
|
||||
if (course.status === '2') return 'ended'
|
||||
if (course.currentMembers / course.maxMembers >= 0.8) return 'hot'
|
||||
return 'default'
|
||||
}
|
||||
|
||||
// 计算课程时长(从startTime和endTime计算)
|
||||
// 计算课程时长
|
||||
const calculateDuration = (startTime, endTime) => {
|
||||
if (!startTime || !endTime) return '60分钟'
|
||||
const start = new Date(startTime)
|
||||
@@ -137,9 +117,8 @@ const calculateDuration = (startTime, endTime) => {
|
||||
return `${durationMinutes}分钟`
|
||||
}
|
||||
|
||||
// 获取课程难度(基于课程类型和描述简单判断)
|
||||
// 获取课程难度
|
||||
const getCourseLevel = (course) => {
|
||||
// 可以根据实际需求调整逻辑
|
||||
if (course.courseType === '2') return '中级'
|
||||
if (course.courseType === '3') return '高级'
|
||||
if (course.courseType === '1') return '初级'
|
||||
@@ -148,169 +127,61 @@ const getCourseLevel = (course) => {
|
||||
|
||||
// 处理图片URL
|
||||
const getImageUrl = (coverImage) => {
|
||||
if (!coverImage) {
|
||||
return 'https://images.unsplash.com/photo-1534438327276-14e5300c3a48?w=400&q=80'
|
||||
}
|
||||
// 如果已经是完整URL直接返回,否则拼接基础路径
|
||||
if (coverImage.startsWith('http')) {
|
||||
return coverImage
|
||||
}
|
||||
// 这里需要根据您的实际图片基础路径配置
|
||||
if (!coverImage) return 'https://images.unsplash.com/photo-1534438327276-14e5300c3a48?w=400&q=80'
|
||||
if (coverImage.startsWith('http')) return coverImage
|
||||
return `https://your-domain.com${coverImage}`
|
||||
}
|
||||
|
||||
// 获取推荐课程(按最火排序,返回5条)
|
||||
// 获取推荐课程
|
||||
const fetchRecommendCourses = async () => {
|
||||
try {
|
||||
const res = await getGroupCoursePage({
|
||||
page: 0,
|
||||
size: 5,
|
||||
sort: 'current_members', // 按参与人数排序
|
||||
order: 'desc' // 降序,即最火的在前
|
||||
page: 0, size: 5, sort: 'current_members', order: 'desc'
|
||||
}, { cache: true, cacheTime: 5 * 60 * 1000 })
|
||||
|
||||
if (res && res.content && Array.isArray(res.content)) {
|
||||
// 将后端数据转换为组件所需格式
|
||||
courses.value = res.content.map(course => ({
|
||||
id: course.id,
|
||||
image: getImageUrl(course.coverImage),
|
||||
tag: getTag(course),
|
||||
tagType: getTagType(course),
|
||||
name: course.courseName || '未知课程',
|
||||
id: course.id, image: getImageUrl(course.coverImage), tag: getTag(course),
|
||||
tagType: getTagType(course), name: course.courseName || '未知课程',
|
||||
duration: calculateDuration(course.startTime, course.endTime),
|
||||
level: getCourseLevel(course),
|
||||
participants: course.currentMembers || 0,
|
||||
// 保存原始数据供点击事件使用
|
||||
rawData: course
|
||||
level: getCourseLevel(course), participants: course.currentMembers || 0, rawData: course
|
||||
}))
|
||||
} else {
|
||||
// 如果没有数据,使用提供的示例数据作为fallback
|
||||
useFallbackData()
|
||||
}
|
||||
} catch (err) {
|
||||
// console.error('获取推荐课程失败:', err)
|
||||
// 使用提供的示例数据作为fallback
|
||||
useFallbackData()
|
||||
}
|
||||
} else { useFallbackData() }
|
||||
} catch (err) { useFallbackData() }
|
||||
}
|
||||
|
||||
// 使用提供的响应数据作为默认数据
|
||||
const useFallbackData = () => {
|
||||
const fallbackContent = [
|
||||
{
|
||||
id: "3",
|
||||
courseName: "燃脂搏击",
|
||||
courseType: "2",
|
||||
startTime: "2026-06-10T18:30:00",
|
||||
endTime: "2026-06-10T19:30:00",
|
||||
maxMembers: 20,
|
||||
currentMembers: 20,
|
||||
status: "0",
|
||||
coverImage: "/images/kickboxing.jpg",
|
||||
description: "高强度间歇训练,配合音乐快速燃脂,释放压力。名额已满,无法预约。"
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
courseName: "清晨流瑜伽",
|
||||
courseType: "1",
|
||||
startTime: "2026-06-12T09:00:00",
|
||||
endTime: "2026-06-12T10:30:00",
|
||||
maxMembers: 15,
|
||||
currentMembers: 5,
|
||||
status: "0",
|
||||
coverImage: "/images/yoga_flow.jpg",
|
||||
description: "适合有一定基础的学员,通过流畅的体式连接呼吸,唤醒身体能量。"
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
courseName: "哈他瑜伽",
|
||||
courseType: "1",
|
||||
startTime: "2026-06-01T15:20:00",
|
||||
endTime: "2026-06-01T16:50:00",
|
||||
maxMembers: 12,
|
||||
currentMembers: 3,
|
||||
status: "0",
|
||||
coverImage: "/images/hatha_yoga.jpg",
|
||||
description: "基础哈他瑜伽,适合所有级别。距开始不足30分钟,已停止预约。"
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
courseName: "蜜桃臀塑造",
|
||||
courseType: "3",
|
||||
startTime: "2026-05-30T19:00:00",
|
||||
endTime: "2026-05-30T20:00:00",
|
||||
maxMembers: 10,
|
||||
currentMembers: 8,
|
||||
status: "2",
|
||||
coverImage: "/images/glute.jpg",
|
||||
description: "针对性训练臀部肌肉群,课程已于5月30日结束,无法预约。"
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
courseName: "午间冥想放松",
|
||||
courseType: "1",
|
||||
startTime: "2026-05-31T12:00:00",
|
||||
endTime: "2026-05-31T13:00:00",
|
||||
maxMembers: 15,
|
||||
currentMembers: 6,
|
||||
status: "2",
|
||||
coverImage: "/images/meditation_noon.jpg",
|
||||
description: "午间冥想课程,已于5月31日结束。"
|
||||
}
|
||||
{ id: "3", courseName: "燃脂搏击", courseType: "2", startTime: "2026-06-10T18:30:00", endTime: "2026-06-10T19:30:00", maxMembers: 20, currentMembers: 20, status: "0", coverImage: "/images/kickboxing.jpg", description: "高强度间歇训练" },
|
||||
{ id: "2", courseName: "清晨流瑜伽", courseType: "1", startTime: "2026-06-12T09:00:00", endTime: "2026-06-12T10:30:00", maxMembers: 15, currentMembers: 5, status: "0", coverImage: "/images/yoga_flow.jpg", description: "流畅体式" },
|
||||
{ id: "4", courseName: "哈他瑜伽", courseType: "1", startTime: "2026-06-01T15:20:00", endTime: "2026-06-01T16:50:00", maxMembers: 12, currentMembers: 3, status: "0", coverImage: "/images/hatha_yoga.jpg", description: "基础瑜伽" },
|
||||
{ id: "6", courseName: "蜜桃臀塑造", courseType: "3", startTime: "2026-05-30T19:00:00", endTime: "2026-05-30T20:00:00", maxMembers: 10, currentMembers: 8, status: "2", coverImage: "/images/glute.jpg", description: "臀部训练" },
|
||||
{ id: "7", courseName: "午间冥想放松", courseType: "1", startTime: "2026-05-31T12:00:00", endTime: "2026-05-31T13:00:00", maxMembers: 15, currentMembers: 6, status: "2", coverImage: "/images/meditation_noon.jpg", description: "冥想" }
|
||||
]
|
||||
|
||||
courses.value = fallbackContent.map(course => ({
|
||||
id: course.id,
|
||||
image: getImageUrl(course.coverImage),
|
||||
tag: getTag(course),
|
||||
tagType: getTagType(course),
|
||||
name: course.courseName || '未知课程',
|
||||
id: course.id, image: getImageUrl(course.coverImage), tag: getTag(course),
|
||||
tagType: getTagType(course), name: course.courseName || '未知课程',
|
||||
duration: calculateDuration(course.startTime, course.endTime),
|
||||
level: getCourseLevel(course),
|
||||
participants: course.currentMembers || 0,
|
||||
rawData: course
|
||||
level: getCourseLevel(course), participants: course.currentMembers || 0, rawData: course
|
||||
}))
|
||||
}
|
||||
|
||||
// 处理参与课程点击
|
||||
const handleJoinCourse = (course) => {
|
||||
// 根据课程状态判断是否可以参与
|
||||
if (course.rawData.status === '2') {
|
||||
uni.showToast({
|
||||
title: '课程已结束',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (course.rawData.currentMembers >= course.rawData.maxMembers) {
|
||||
uni.showToast({
|
||||
title: '课程已满员',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 跳转到课程详情页
|
||||
uni.navigateTo({
|
||||
url: `/pages/course/detail?id=${course.id}`
|
||||
})
|
||||
if (course.rawData.status === '2') { uni.showToast({ title: '课程已结束', icon: 'none' }); return }
|
||||
if (course.rawData.currentMembers >= course.rawData.maxMembers) { uni.showToast({ title: '课程已满员', icon: 'none' }); return }
|
||||
uni.navigateTo({ url: `/pages/course/detail?id=${course.id}` })
|
||||
}
|
||||
|
||||
// 组件挂载时获取数据
|
||||
onMounted(() => {
|
||||
fetchRecommendCourses()
|
||||
})
|
||||
onMounted(() => { fetchRecommendCourses() })
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 推荐课程容器样式 */
|
||||
.recommend-courses {
|
||||
padding: 0 24rpx;
|
||||
margin-bottom: 32rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 区域标题栏样式 */
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -318,50 +189,46 @@ onMounted(() => {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
/* 区域标题样式 */
|
||||
.section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #1a202c;
|
||||
color: #2D4A5A;
|
||||
}
|
||||
|
||||
/* 查看更多按钮样式 */
|
||||
.view-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4rpx;
|
||||
font-size: 26rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
}
|
||||
|
||||
/* 箭头图标样式 */
|
||||
.arrow {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
/* 课程横向滚动容器样式 */
|
||||
.courses-scroll {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 课程列表样式 */
|
||||
.courses-list {
|
||||
display: inline-flex;
|
||||
gap: 48rpx;
|
||||
}
|
||||
|
||||
/* 课程卡片样式 */
|
||||
.course-card {
|
||||
width: 320rpx;
|
||||
background: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 8rpx 28rpx rgba(120, 185, 215, 0.18);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.6);
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* 课程图片区域样式 */
|
||||
.course-image {
|
||||
height: 280rpx;
|
||||
position: relative;
|
||||
@@ -371,7 +238,6 @@ onMounted(() => {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
/* 课程封面图片样式 */
|
||||
.img {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -380,17 +246,15 @@ onMounted(() => {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 图片渐变遮罩样式 */
|
||||
.course-overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, transparent 60%);
|
||||
background: linear-gradient(to top, rgba(45, 74, 90, 0.7) 0%, transparent 60%);
|
||||
}
|
||||
|
||||
/* 课程标签样式 */
|
||||
.course-tag {
|
||||
position: absolute;
|
||||
top: 16rpx;
|
||||
@@ -400,47 +264,33 @@ onMounted(() => {
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
background: #f97316;
|
||||
background: linear-gradient(135deg, #7AB5CC, #9CCFDF);
|
||||
z-index: 2;
|
||||
|
||||
/* 热门标签 */
|
||||
&.hot {
|
||||
background: #ef4444;
|
||||
background: linear-gradient(135deg, #6BA8C0, #8CC5D5);
|
||||
}
|
||||
|
||||
/* 新课标签 */
|
||||
&.new {
|
||||
background: #10b981;
|
||||
background: linear-gradient(135deg, #6DB5C8, #90CEDD);
|
||||
}
|
||||
|
||||
/* 免费标签 */
|
||||
&.free {
|
||||
background: #3b82f6;
|
||||
background: linear-gradient(135deg, #7AB5CC, #9CCFDF);
|
||||
}
|
||||
|
||||
/* 满员标签 */
|
||||
&.full {
|
||||
background: #64748b;
|
||||
background: linear-gradient(135deg, #A0B8C8, #B8CCD8);
|
||||
}
|
||||
|
||||
/* 已结束标签 */
|
||||
&.ended {
|
||||
background: #94a3b8;
|
||||
background: linear-gradient(135deg, #B0C0CC, #C4D2DC);
|
||||
}
|
||||
|
||||
/* 默认标签 */
|
||||
&.default {
|
||||
background: #f97316;
|
||||
background: linear-gradient(135deg, #7AB5CC, #9CCFDF);
|
||||
}
|
||||
}
|
||||
|
||||
/* 课程信息区域样式 */
|
||||
.course-info {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* 课程名称样式 */
|
||||
.course-name {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
@@ -449,14 +299,12 @@ onMounted(() => {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
/* 课程元信息容器样式 */
|
||||
.course-meta {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 课程元信息项样式 */
|
||||
.meta-item {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
@@ -465,7 +313,6 @@ onMounted(() => {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
/* 元信息图标样式 */
|
||||
.meta-icon {
|
||||
font-size: 20rpx;
|
||||
image{
|
||||
@@ -476,7 +323,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 课程底部区域样式 */
|
||||
.course-footer {
|
||||
padding: 16rpx 10rpx;
|
||||
display: flex;
|
||||
@@ -484,16 +330,14 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 参与人数信息样式 */
|
||||
.participants {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6rpx;
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
}
|
||||
|
||||
/* 火热图标样式 */
|
||||
.fire-icon {
|
||||
font-size: 24rpx;
|
||||
image{
|
||||
@@ -504,14 +348,14 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 去参与按钮样式 */
|
||||
.join-btn {
|
||||
padding: 12rpx 28rpx;
|
||||
background: transparent;
|
||||
border: 2rpx solid #f97316;
|
||||
background: linear-gradient(135deg, #7AB5CC 0%, #9CCFDF 100%);
|
||||
border: none;
|
||||
border-radius: 9999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
color: #f97316;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 6rpx 16rpx rgba(122, 181, 204, 0.35);
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
<view class="view-more">
|
||||
<text>查看更多</text>
|
||||
<text class="arrow">
|
||||
<uni-icons type="right" size="20" color="#94a3b8"></uni-icons>
|
||||
<uni-icons type="right" size="20" color="#8CA0B0"></uni-icons>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -77,12 +77,12 @@ const recommends = [
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 今日推荐容器样式 */
|
||||
.today-recommend {
|
||||
padding: 0 24rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 区域标题栏样式 */
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -90,45 +90,42 @@ const recommends = [
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
/* 区域标题样式 */
|
||||
.section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #1a202c;
|
||||
color: #2D4A5A;
|
||||
}
|
||||
|
||||
/* 查看更多按钮样式 */
|
||||
.view-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4rpx;
|
||||
font-size: 26rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
}
|
||||
|
||||
/* 箭头图标样式 */
|
||||
.arrow {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
/* 推荐列表样式 */
|
||||
.recommend-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
/* 推荐项卡片样式 */
|
||||
.recommend-item {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
background: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border-radius: 24rpx;
|
||||
padding: 20rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 8rpx 28rpx rgba(120, 185, 215, 0.18);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
/* 推荐项图片样式 */
|
||||
.item-image {
|
||||
width: 200rpx;
|
||||
height: 160rpx;
|
||||
@@ -136,7 +133,6 @@ const recommends = [
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 推荐项内容区域样式 */
|
||||
.item-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
@@ -145,40 +141,35 @@ const recommends = [
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* 推荐项标题样式 */
|
||||
.item-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #1a202c;
|
||||
color: #2D4A5A;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
/* 推荐项标签列表样式 */
|
||||
.item-tags {
|
||||
display: flex;
|
||||
gap: 12rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
/* 推荐项标签样式 */
|
||||
.tag {
|
||||
padding: 6rpx 16rpx;
|
||||
background: #f1f5f9;
|
||||
background: rgba(122, 181, 204, 0.12);
|
||||
border-radius: 8rpx;
|
||||
font-size: 22rpx;
|
||||
color: #64748b;
|
||||
color: #6BA8C0;
|
||||
}
|
||||
|
||||
/* 推荐项描述文字样式 */
|
||||
.item-desc {
|
||||
font-size: 24rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 推荐项操作区域样式 */
|
||||
.item-action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -188,15 +179,13 @@ const recommends = [
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 开始训练按钮样式 */
|
||||
.start-btn {
|
||||
padding: 16rpx 28rpx;
|
||||
background: linear-gradient(135deg, #f97316 0%, #fb923c 100%);
|
||||
background: linear-gradient(135deg, #7AB5CC 0%, #9CCFDF 100%);
|
||||
border-radius: 9999rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(249, 115, 22, 0.4);
|
||||
box-shadow: 0 6rpx 20rpx rgba(122, 181, 204, 0.4);
|
||||
}
|
||||
|
||||
/* 开始训练按钮文字样式 */
|
||||
.start-btn-text {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
@@ -204,10 +193,9 @@ const recommends = [
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 参与人数文字样式 */
|
||||
.participants {
|
||||
font-size: 22rpx;
|
||||
color: #94a3b8;
|
||||
color: #8AABBB;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -13,7 +13,7 @@
|
||||
<text class="body-report-section__history-link">历史记录</text>
|
||||
<image
|
||||
class="body-report-section__link-arrow"
|
||||
src="/static/images/chevronright3.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright3.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -34,7 +34,7 @@
|
||||
>
|
||||
<image
|
||||
class="body-report-section__view-icon"
|
||||
src="/static/images/filetext.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/filetext.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="body-report-section__view-report">查看报告</text>
|
||||
@@ -77,7 +77,7 @@
|
||||
<view class="body-report-section__goal">
|
||||
<image
|
||||
class="body-report-section__goal-icon"
|
||||
src="/static/images/target.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/target.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="body-report-section__goal-text">
|
||||
@@ -87,7 +87,7 @@
|
||||
<view class="body-report-section__change">
|
||||
<image
|
||||
class="body-report-section__change-icon"
|
||||
src="/static/images/trendingdown.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/trendingdown.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="body-report-section__metric-value-2">
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<text class="booking-section__view-all">预约记录</text>
|
||||
<image
|
||||
class="booking-section__link-arrow"
|
||||
src="/static/images/chevronright4.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright4.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -41,13 +41,13 @@
|
||||
<view class="booking-section__meta-inner">
|
||||
<image
|
||||
class="booking-section__icon-coach"
|
||||
src="/static/images/user2.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user2.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="booking-section__coach">教练:{{ item.coach }}</text>
|
||||
<image
|
||||
class="booking-section__icon-location"
|
||||
src="/static/images/mappin1.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/mappin1.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="booking-section__text">{{ item.location }}</text>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<text class="checkin-section__view-all">查看全部</text>
|
||||
<image
|
||||
class="checkin-section__link-arrow"
|
||||
src="/static/images/chevronright2.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright2.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<text class="coupon-section__view-all">更多详情</text>
|
||||
<image
|
||||
class="coupon-section__link-arrow"
|
||||
src="/static/images/chevronright5.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright5.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
<view class="profile-header__nav-left">
|
||||
<image
|
||||
class="profile-header__icon-bell"
|
||||
src="/static/images/bell.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/bell.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="profile-header__icon-settings"
|
||||
src="/static/images/settings.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/settings.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -37,7 +37,7 @@
|
||||
<view class="profile-header__avatar-badge">
|
||||
<image
|
||||
class="profile-header__avatar-badge-icon"
|
||||
src="/static/images/camera.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/camera.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -49,7 +49,7 @@
|
||||
<view class="profile-header__badge">
|
||||
<image
|
||||
class="profile-header__badge-icon"
|
||||
src="/static/images/crown0.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/crown0.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="profile-header__level">{{ userInfo.memberLevel }}</text>
|
||||
@@ -100,7 +100,7 @@ export default {
|
||||
emits: ['user-info'],
|
||||
computed: {
|
||||
displayAvatar() {
|
||||
return this.userInfo.avatar || '/static/images/AvatarEditWrap.png'
|
||||
return this.userInfo.avatar || 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AvatarEditWrap.png'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
>
|
||||
<image
|
||||
class="logout-section__icon"
|
||||
src="/static/images/logout.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/logout.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="logout-section__text">退出登录</text>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
>
|
||||
查看全部
|
||||
</text>
|
||||
<image class="member-card-section__link-arrow" src="/static/images/chevronright12.png" mode="aspectFit" />
|
||||
<image class="member-card-section__link-arrow" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright12.png" mode="aspectFit" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -46,7 +46,7 @@
|
||||
class="member-card-preview__icon-stroke"
|
||||
></view>
|
||||
</view>
|
||||
<image class="member-card-preview__icon-line" src="/static/images/Line_2_468.png" mode="aspectFill" />
|
||||
<image class="member-card-preview__icon-line" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Line_2_468.png" mode="aspectFill" />
|
||||
</view>
|
||||
<text
|
||||
class="member-card-preview__name"
|
||||
@@ -101,7 +101,7 @@
|
||||
<view class="member-card-tip">
|
||||
<view class="member-card-tip__inner">
|
||||
<view class="member-card-tip__content">
|
||||
<image class="member-card-tip__icon" src="/static/images/clock1.png" mode="aspectFit" />
|
||||
<image class="member-card-tip__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock1.png" mode="aspectFit" />
|
||||
<text
|
||||
class="member-card-tip__text"
|
||||
>
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
<view v-if="item.key === 'booking'" class="quick-actions__icon">
|
||||
<image
|
||||
class="quick-actions__icon-part"
|
||||
src="/static/images/Vector_2_490.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Vector_2_490.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="quick-actions__icon-part"
|
||||
src="/static/images/Vector_2_491.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Vector_2_491.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<view class="quick-actions__border-wrap">
|
||||
@@ -31,12 +31,12 @@
|
||||
</view>
|
||||
<image
|
||||
class="quick-actions__icon-part"
|
||||
src="/static/images/Vector_2_493.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Vector_2_493.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<image
|
||||
class="quick-actions__icon-part"
|
||||
src="/static/images/Vector_2_494.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Vector_2_494.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -94,15 +94,15 @@ export default {
|
||||
return {
|
||||
row1: [
|
||||
{ key: 'booking', label: '预约课程', textClass: 'quick-actions__title', icon: '' },
|
||||
{ key: 'bodyTest', label: '智能体测', textClass: 'quick-actions__title-2', icon: '/static/images/mappin2.png' },
|
||||
{ key: 'bodyReport', label: '体测报告', textClass: 'quick-actions__title-3', icon: '/static/images/activity.png' },
|
||||
{ key: 'trainReport', label: '训练报告', textClass: 'quick-actions__coach', icon: '/static/images/usercheck.png' }
|
||||
{ key: 'bodyTest', label: '智能体测', textClass: 'quick-actions__title-2', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/mappin2.png' },
|
||||
{ key: 'bodyReport', label: '体测报告', textClass: 'quick-actions__title-3', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/activity.png' },
|
||||
{ key: 'trainReport', label: '训练报告', textClass: 'quick-actions__coach', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/usercheck.png' }
|
||||
],
|
||||
row2: [
|
||||
{ key: 'coupon', label: '我的优惠券', textClass: 'quick-actions__text', icon: '/static/images/ticket.png' },
|
||||
{ key: 'points', label: '我的积分', textClass: 'quick-actions__points-desc', icon: '/static/images/star.png' },
|
||||
{ key: 'referral', label: '邀请好友', textClass: 'quick-actions__title-4', icon: '/static/images/share2.png' },
|
||||
{ key: 'course', label: '我的课程', textClass: 'quick-actions__text-2', icon: '/static/images/play.png' }
|
||||
{ key: 'coupon', label: '我的优惠券', textClass: 'quick-actions__text', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/ticket.png' },
|
||||
{ key: 'points', label: '我的积分', textClass: 'quick-actions__points-desc', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/star.png' },
|
||||
{ key: 'referral', label: '邀请好友', textClass: 'quick-actions__title-4', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/share2.png' },
|
||||
{ key: 'course', label: '我的课程', textClass: 'quick-actions__text-2', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/play.png' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<text class="referral-section__records-link">规则说明</text>
|
||||
<image
|
||||
class="referral-section__link-arrow"
|
||||
src="/static/images/chevronright11.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright11.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</text>
|
||||
<image
|
||||
class="settings-section__item-arrow"
|
||||
src="/static/images/chevronright10.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright10.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -68,32 +68,32 @@ export default {
|
||||
{
|
||||
key: 'notify',
|
||||
label: '通知设置',
|
||||
icon: '/static/images/bell.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/bell.png',
|
||||
iconWrapClass: ''
|
||||
},
|
||||
{
|
||||
key: 'password',
|
||||
label: '修改密码',
|
||||
icon: '/static/images/Vector_2_727.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/Vector_2_727.png',
|
||||
iconWrapClass: 'settings-section__item-icon-wrap--blue'
|
||||
},
|
||||
{
|
||||
key: 'privacy',
|
||||
label: '隐私政策',
|
||||
icon: '/static/images/shield.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/shield.png',
|
||||
iconWrapClass: 'settings-section__item-icon-wrap--green'
|
||||
},
|
||||
{
|
||||
key: 'nfc',
|
||||
label: 'NFC 门禁卡',
|
||||
subtitle: '已绑定',
|
||||
icon: '/static/images/ticket.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/ticket.png',
|
||||
iconWrapClass: ''
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
label: '注销账户',
|
||||
icon: '/static/images/userx.png',
|
||||
icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/userx.png',
|
||||
iconWrapClass: 'settings-section__item-icon-wrap--red',
|
||||
labelClass: 'settings-section__item-label--danger'
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<view class="sub-nav__back" @tap.stop="$emit('back')">
|
||||
<image
|
||||
class="sub-nav__back-icon"
|
||||
src="/static/images/chevronleft.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronleft.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationStyle":"custom",
|
||||
"navigationBarTitleText": "健身房",
|
||||
"app-plus": {
|
||||
"animationType": "fade-in",
|
||||
|
||||
@@ -1,28 +1,43 @@
|
||||
<template>
|
||||
<view class="home-page">
|
||||
<!-- 骨架屏 -->
|
||||
<HomeSkeleton v-if="loading" />
|
||||
<!-- 水波纹背景 - 顶层显示 -->
|
||||
<view class="bg-wrapper">
|
||||
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_top.png" mode="widthFix" class="wave-bg wave-top" />
|
||||
<image src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/wave_bottom.png" mode="widthFix" class="wave-bg wave-bottom" />
|
||||
</view>
|
||||
<!-- 固定白色块(滚动时显示) -->
|
||||
<view class="hand" :style="{height : handHeight + 'rpx'}" v-show="isShow"></view>
|
||||
|
||||
<!-- 滚动内容区域 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
refresher-enabled
|
||||
:refresher-triggered="isRefreshing"
|
||||
refresher-default-style="none"
|
||||
@refresherrefresh="onRefresh"
|
||||
@scroll="handleScroll"
|
||||
class="scroll-container"
|
||||
>
|
||||
|
||||
<!-- 实际内容 -->
|
||||
<template v-else>
|
||||
<!-- Banner轮播 -->
|
||||
<BannerSwiper />
|
||||
|
||||
<!-- 功能入口 -->
|
||||
<QuickEntry />
|
||||
|
||||
<!-- 推荐课程 -->
|
||||
<RecommendCourses />
|
||||
|
||||
<!-- 今日推荐 -->
|
||||
<TodayRecommend />
|
||||
|
||||
<!-- 底部占位 -->
|
||||
<view class="bottom-placeholder"></view>
|
||||
|
||||
<!-- TabBar -->
|
||||
<TabBar />
|
||||
</template>
|
||||
<!-- 主内容 -->
|
||||
<view class="home-page">
|
||||
<!-- 骨架屏 -->
|
||||
<HomeSkeleton v-if="loading" />
|
||||
|
||||
<!-- 实际内容 -->
|
||||
<template v-else>
|
||||
<BannerSwiper />
|
||||
<QuickEntry />
|
||||
<RecommendCourses />
|
||||
<TodayRecommend />
|
||||
<!-- 底部占位,给 TabBar 留出空间 -->
|
||||
<view class="bottom-placeholder"></view>
|
||||
</template>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- TabBar 固定在底部,不参与滚动 -->
|
||||
<view class="tabbar-fixed">
|
||||
<TabBar />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -36,23 +51,161 @@ import TabBar from '@/components/TabBar.vue'
|
||||
import HomeSkeleton from '@/components/Skeleton/HomeSkeleton.vue'
|
||||
|
||||
const loading = ref(true)
|
||||
const isShow = ref(false)
|
||||
const handHeight = ref(0)
|
||||
const scrollDistance = ref(0)
|
||||
const isRefreshing = ref(false)
|
||||
|
||||
// 滚动监听
|
||||
const handleScroll = (e) => {
|
||||
const distance = e.detail.scrollTop
|
||||
scrollDistance.value = distance
|
||||
|
||||
// 控制白色块显示/隐藏
|
||||
isShow.value = distance > 238
|
||||
}
|
||||
|
||||
// 下拉刷新处理
|
||||
const onRefresh = async () => {
|
||||
console.log('开始下拉刷新')
|
||||
isRefreshing.value = true
|
||||
|
||||
try {
|
||||
await refreshData()
|
||||
isRefreshing.value = false
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('刷新失败', error)
|
||||
isRefreshing.value = false
|
||||
uni.showToast({
|
||||
title: '刷新失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新数据
|
||||
const refreshData = () => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
console.log('数据已刷新')
|
||||
resolve()
|
||||
}, 1500)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
loading.value = false
|
||||
}, 1500)
|
||||
// 获取胶囊按钮高度
|
||||
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
|
||||
const navTotalHeight = menuButtonInfo.top + menuButtonInfo.height
|
||||
handHeight.value = navTotalHeight * 2
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 背景包装器 - 固定在最底层 */
|
||||
.bg-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.wave-bg {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.wave-top {
|
||||
top: 0;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.wave-bottom {
|
||||
bottom: 100rpx;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
/* 滚动容器 */
|
||||
.scroll-container {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
background: linear-gradient(180deg, #D6EEF8 0%, #E4F2FA 15%, #EEF6FB 30%, #F5FAFD 50%, #FAFCFE 70%, #FFFFFF 100%);
|
||||
}
|
||||
|
||||
/* 主内容区域 */
|
||||
.home-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f0f4f8;
|
||||
padding-bottom: 160rpx;
|
||||
padding-bottom: 160rpx; /* 为 TabBar 留出空间 */
|
||||
}
|
||||
|
||||
/* 固定白色块 */
|
||||
.hand {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
background-color: white;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 固定 TabBar */
|
||||
.tabbar-fixed {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bottom-placeholder {
|
||||
height: 40rpx;
|
||||
height: 120rpx; /* 调整高度,避免内容被 TabBar 遮挡 */
|
||||
}
|
||||
|
||||
</style>
|
||||
/* 其他样式保持不变 */
|
||||
.glow {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.glow-1 {
|
||||
width: 400rpx;
|
||||
height: 400rpx;
|
||||
top: 60rpx;
|
||||
right: -100rpx;
|
||||
background: radial-gradient(circle, rgba(160, 210, 235, 0.35) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
.glow-2 {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
top: 500rpx;
|
||||
left: -80rpx;
|
||||
background: radial-gradient(circle, rgba(180, 220, 240, 0.3) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
.glow-3 {
|
||||
width: 250rpx;
|
||||
height: 250rpx;
|
||||
top: 900rpx;
|
||||
right: -60rpx;
|
||||
background: radial-gradient(circle, rgba(170, 215, 238, 0.25) 0%, transparent 70%);
|
||||
}
|
||||
</style>
|
||||
@@ -35,7 +35,7 @@
|
||||
<view v-if="connected" class="bt-card">
|
||||
<view class="bt-device">
|
||||
<view class="bt-device__icon-wrap">
|
||||
<image class="bt-device__icon" src="/static/images/shield.png" mode="aspectFit" />
|
||||
<image class="bt-device__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/shield.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="bt-device__info">
|
||||
<text class="bt-device__name">连接成功</text>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
:hover-stay-time="150"
|
||||
@tap="startMeasure"
|
||||
>
|
||||
<image class="bt-btn__icon" src="/static/images/activity.png" mode="aspectFit" />
|
||||
<image class="bt-btn__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/activity.png" mode="aspectFit" />
|
||||
<text class="bt-btn__text">开始体测</text>
|
||||
</view>
|
||||
<view
|
||||
@@ -53,7 +53,7 @@
|
||||
<text class="bt-card__title">设备状态</text>
|
||||
<view class="bt-device">
|
||||
<view class="bt-device__icon-wrap">
|
||||
<image class="bt-device__icon" src="/static/images/mappin2.png" mode="aspectFit" />
|
||||
<image class="bt-device__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/mappin2.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="bt-device__info">
|
||||
<text class="bt-device__name">{{ device.name }}</text>
|
||||
@@ -121,10 +121,10 @@ export default {
|
||||
latest: null,
|
||||
device: {},
|
||||
quickLinks: [
|
||||
{ key: 'history', label: '历史记录', icon: '/static/images/clock.png' },
|
||||
{ key: 'compare', label: '历史对比', icon: '/static/images/trendingdown.png' },
|
||||
{ key: 'trend', label: '趋势分析', icon: '/static/images/activity.png' },
|
||||
{ key: 'report', label: '体测报告', icon: '/static/images/filetext.png' }
|
||||
{ key: 'history', label: '历史记录', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock.png' },
|
||||
{ key: 'compare', label: '历史对比', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/trendingdown.png' },
|
||||
{ key: 'trend', label: '趋势分析', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/activity.png' },
|
||||
{ key: 'report', label: '体测报告', icon: 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/filetext.png' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
<text class="bt-trend-link__text">查看完整趋势分析</text>
|
||||
<image
|
||||
class="bt-trend-link__arrow"
|
||||
src="/static/images/chevronright3.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright3.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -140,7 +140,7 @@
|
||||
:hover-stay-time="150"
|
||||
@tap="exportReport"
|
||||
>
|
||||
<image class="bt-btn__icon" src="/static/images/filetext.png" mode="aspectFit" />
|
||||
<image class="bt-btn__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/filetext.png" mode="aspectFit" />
|
||||
<text class="bt-btn__text">导出 PDF</text>
|
||||
</view>
|
||||
<view
|
||||
@@ -149,7 +149,7 @@
|
||||
:hover-stay-time="150"
|
||||
@tap="shareReport"
|
||||
>
|
||||
<image class="bt-btn__icon" src="/static/images/share2.png" mode="aspectFit" />
|
||||
<image class="bt-btn__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/share2.png" mode="aspectFit" />
|
||||
<text class="bt-btn__text">分享</text>
|
||||
</view>
|
||||
<view
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<text class="bt-card__title">设备管理</text>
|
||||
<view class="bt-device">
|
||||
<view class="bt-device__icon-wrap">
|
||||
<image class="bt-device__icon" src="/static/images/mappin2.png" mode="aspectFit" />
|
||||
<image class="bt-device__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/mappin2.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="bt-device__info">
|
||||
<text class="bt-device__name">{{ device.name }}</text>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
>
|
||||
<image
|
||||
class="booking-page__alert-icon"
|
||||
src="/static/images/clock1.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock1.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="booking-page__alert-text">{{ upcomingAlert }}</text>
|
||||
@@ -82,7 +82,7 @@
|
||||
<view class="bk-card__meta-row">
|
||||
<image
|
||||
class="bk-card__meta-icon"
|
||||
src="/static/images/clock0.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock0.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="bk-card__meta-text">{{ item.schedule }}</text>
|
||||
@@ -90,7 +90,7 @@
|
||||
<view class="bk-card__meta-row">
|
||||
<image
|
||||
class="bk-card__meta-icon"
|
||||
src="/static/images/user0.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/user0.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="bk-card__meta-text">{{ item.coach }}</text>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
@tap="showDetail(item)"
|
||||
>
|
||||
<view class="mi-mod-checkin-row__icon" :class="'mi-mod-checkin-row__icon--' + item.tagTheme">
|
||||
<image class="mi-mod-checkin-row__icon-img" src="/static/images/usercheck.png" mode="aspectFit" />
|
||||
<image class="mi-mod-checkin-row__icon-img" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/usercheck.png" mode="aspectFit" />
|
||||
</view>
|
||||
<view class="mi-mod-checkin-row__info">
|
||||
<text class="mi-mod-checkin-row__title">{{ item.title }}</text>
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
<picker :range="coaches" @change="onCoachChange">
|
||||
<view class="mi-course-list__picker">
|
||||
<text>{{ coach }}</text>
|
||||
<image class="mi-course-list__arrow" src="/static/images/chevronright3.png" mode="aspectFit" />
|
||||
<image class="mi-course-list__arrow" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright3.png" mode="aspectFit" />
|
||||
</view>
|
||||
</picker>
|
||||
<picker :range="periodLabels" @change="onPeriodChange">
|
||||
<view class="mi-course-list__picker">
|
||||
<text>{{ periodLabel }}</text>
|
||||
<image class="mi-course-list__arrow" src="/static/images/chevronright3.png" mode="aspectFit" />
|
||||
<image class="mi-course-list__arrow" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright3.png" mode="aspectFit" />
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
@@ -103,7 +103,7 @@
|
||||
hover-class="mi-tap-btn--hover"
|
||||
@tap="goMyBooking"
|
||||
>
|
||||
<image class="mi-course-list__fab-icon" src="/static/images/clock.png" mode="aspectFit" />
|
||||
<image class="mi-course-list__fab-icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock.png" mode="aspectFit" />
|
||||
<text class="mi-course-list__fab-text">我的预约</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<view class="mc-hero__title-row">
|
||||
<image
|
||||
class="mc-hero__crown"
|
||||
src="/static/images/crown.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/crown.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="mc-hero__name">{{ card.name }}</text>
|
||||
@@ -31,7 +31,7 @@
|
||||
>
|
||||
<image
|
||||
class="mc-hero__renew-icon"
|
||||
src="/static/images/refreshcw.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/refreshcw.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="mc-hero__renew-text">立即续费</text>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<view class="bt-card">
|
||||
<text class="bt-card__title">视频播放</text>
|
||||
<view class="mi-online-player">
|
||||
<image class="mi-online-player__play" src="/static/images/play.png" mode="aspectFit" />
|
||||
<image class="mi-online-player__play" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/play.png" mode="aspectFit" />
|
||||
<text class="mi-online-player__hint">点击播放(支持倍速与拖拽)</text>
|
||||
</view>
|
||||
<view class="mi-online-controls">
|
||||
|
||||
@@ -13,19 +13,19 @@
|
||||
<text class="bt-card__title">快捷入口</text>
|
||||
<view class="bt-grid">
|
||||
<view class="bt-grid__item" hover-class="mi-tap--hover" @tap="goMall">
|
||||
<image class="bt-grid__icon" src="/static/images/star.png" mode="aspectFit" />
|
||||
<image class="bt-grid__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/star.png" mode="aspectFit" />
|
||||
<text class="bt-grid__label">积分商城</text>
|
||||
</view>
|
||||
<view class="bt-grid__item" hover-class="mi-tap--hover" @tap="goHistory">
|
||||
<image class="bt-grid__icon" src="/static/images/clock.png" mode="aspectFit" />
|
||||
<image class="bt-grid__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/clock.png" mode="aspectFit" />
|
||||
<text class="bt-grid__label">积分明细</text>
|
||||
</view>
|
||||
<view class="bt-grid__item" hover-class="mi-tap--hover" @tap="checkIn">
|
||||
<image class="bt-grid__icon" src="/static/images/usercheck.png" mode="aspectFit" />
|
||||
<image class="bt-grid__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/usercheck.png" mode="aspectFit" />
|
||||
<text class="bt-grid__label">签到赚积分</text>
|
||||
</view>
|
||||
<view class="bt-grid__item" hover-class="mi-tap--hover" @tap="goReferral">
|
||||
<image class="bt-grid__icon" src="/static/images/share2.png" mode="aspectFit" />
|
||||
<image class="bt-grid__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/share2.png" mode="aspectFit" />
|
||||
<text class="bt-grid__label">邀请赚积分</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
:hover-stay-time="150"
|
||||
@tap="shareInvite"
|
||||
>
|
||||
<image class="bt-btn__icon" src="/static/images/share2.png" mode="aspectFit" />
|
||||
<image class="bt-btn__icon" src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/share2.png" mode="aspectFit" />
|
||||
<text class="bt-btn__text">分享给好友</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
>
|
||||
<image
|
||||
class="avatar-block__icon"
|
||||
src="/static/images/camera.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/camera.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="avatar-block__text">更换</text>
|
||||
@@ -41,7 +41,7 @@
|
||||
<text class="Pixso-paragraph-2_813">{{ name }}</text>
|
||||
<image
|
||||
class="Pixso-vector-2_814"
|
||||
src="/static/images/chevronright1.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright1.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -70,7 +70,7 @@
|
||||
</view>
|
||||
<image
|
||||
class="Pixso-vector-2_823"
|
||||
src="/static/images/chevronright.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -90,7 +90,7 @@
|
||||
>
|
||||
<image
|
||||
class="gender-btn__icon"
|
||||
src="/static/images/venus.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/venus.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="gender-btn__text">女</text>
|
||||
@@ -104,7 +104,7 @@
|
||||
>
|
||||
<image
|
||||
class="gender-btn__icon"
|
||||
src="/static/images/mars.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/mars.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<text class="gender-btn__text">男</text>
|
||||
@@ -125,7 +125,7 @@
|
||||
<text class="Pixso-paragraph-2_844">{{ birthday }}</text>
|
||||
<image
|
||||
class="Pixso-vector-2_845"
|
||||
src="/static/images/chevronright0.png"
|
||||
src="https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/chevronright0.png"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</view>
|
||||
@@ -228,7 +228,7 @@ import {
|
||||
showValidationError
|
||||
} from '@/common/memberInfo/validate.js'
|
||||
|
||||
const DEFAULT_AVATAR = '/static/images/AvatarEditWrap.png'
|
||||
const DEFAULT_AVATAR = 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/AvatarEditWrap.png'
|
||||
|
||||
export default {
|
||||
components: { MemberInfoSubNav },
|
||||
|
||||
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 764 KiB |
|
Before Width: | Height: | Size: 561 KiB |
|
Before Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 310 B |
|
Before Width: | Height: | Size: 428 B |
|
Before Width: | Height: | Size: 428 B |
|
Before Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 773 B |
|
Before Width: | Height: | Size: 749 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 391 B |
|
Before Width: | Height: | Size: 391 B |
|
Before Width: | Height: | Size: 314 B |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |