优化多个页面样式及组件功能,优化课程、发现、训练、首页等核心页面样式
This commit is contained in:
@@ -1,25 +1,37 @@
|
||||
/**
|
||||
* ============================================
|
||||
* 健身房管理系统小程序 - 全局配色变量
|
||||
* 主题:活力运动风格
|
||||
* 主色调:深蓝专业 + 活力橙热情
|
||||
* 主题:清新健康运动风格
|
||||
* 主色调:浅蓝渐变 + 活力橙点缀
|
||||
* 兼容暗色/浅色模式基础,保证可访问性
|
||||
* ============================================
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* ========== 主品牌色 ========== */
|
||||
--primary-dark: #0B2B4B; /* 深蓝主色 - 用于头部导航栏、重要按钮、品牌标识,体现专业信赖感 */
|
||||
--primary-deep: #1A4A6F; /* 中深蓝色 - 用于hover状态、次级按钮、图标点缀,增加层次感 */
|
||||
--primary-light: #2C6288; /* 浅蓝色(预留)- 用于选中态或辅助背景,保持和谐渐变 */
|
||||
/* ========== 主品牌色(清新浅蓝色系)========== */
|
||||
--primary-dark: #0B2B4B; /* 深蓝主色 - 用于重要文字、品牌标识,体现专业信赖感 */
|
||||
--primary-deep: #1A4A6F; /* 中深蓝色 - 用于hover状态、次级按钮、图标点缀,增加层次感 */
|
||||
|
||||
/* ========== 强调/行动色 ========== */
|
||||
/* 主页主题浅蓝渐变色系 */
|
||||
--primary-sky-100: #D6EEF8; /* 最浅蓝 - 渐变起始色,清新自然 */
|
||||
--primary-sky-200: #E4F2FA; /* 浅蓝 - 渐变第二层 */
|
||||
--primary-sky-300: #EEF6FB; /* 淡蓝 - 渐变第三层 */
|
||||
--primary-sky-400: #F5FAFD; /* 微蓝 - 渐变第四层 */
|
||||
--primary-sky-500: #FAFCFE; /* 极浅蓝 - 渐变第五层,接近白色 */
|
||||
|
||||
/* 光晕效果色 */
|
||||
--glow-blue-1: rgba(160, 210, 235, 0.35); /* 蓝绿色光晕 */
|
||||
--glow-blue-2: rgba(180, 220, 240, 0.3); /* 浅蓝色光晕 */
|
||||
--glow-blue-3: rgba(170, 215, 238, 0.25); /* 浅蓝绿色光晕 */
|
||||
|
||||
/* ========== 强调/行动色(活力橙)========== */
|
||||
--accent-orange: #FF6B35; /* 活力橙 - 主要CTA按钮、会员标识、高亮徽章、关键数据,刺激行动力 */
|
||||
--accent-orange-light: #FF8C5A; /* 浅橙色 - hover轻量背景、渐变辅助,带来温暖运动感 */
|
||||
--accent-orange-dark: #E55A2B; /* 深橙色 - 按压状态或重要警告,保持色彩体系完整 */
|
||||
|
||||
/* ========== 背景色系 ========== */
|
||||
--bg-light: #F9FAFE; /* 全局浅灰蓝背景 - 柔和且提升深蓝/橙色的视觉舒适度 */
|
||||
/* ========== 背景色系(主页主题)========== */
|
||||
--bg-gradient-primary: linear-gradient(180deg, #D6EEF8 0%, #E4F2FA 15%, #EEF6FB 30%, #F5FAFD 50%, #FAFCFE 70%, #FFFFFF 100%); /* 主页主渐变背景 */
|
||||
--bg-light: #F5FAFD; /* 全局浅蓝背景 - 柔和且提升蓝色/橙色的视觉舒适度 */
|
||||
--bg-white: #FFFFFF; /* 纯白卡片背景 - 用于内容卡片、表单区域,提高可读性与层次感 */
|
||||
--bg-gray: #F2F5F9; /* 浅灰辅助背景 - 分割区域或禁用态背景 */
|
||||
|
||||
@@ -42,6 +54,7 @@
|
||||
/* ========== 渐变色 (提升活力感) ========== */
|
||||
--gradient-orange: linear-gradient(135deg, #FF6B35 0%, #FF8C5A 100%); /* 橙色渐变 - 会员按钮、重要徽章 */
|
||||
--gradient-blue: linear-gradient(135deg, #0B2B4B 0%, #1A4A6F 100%); /* 深蓝渐变 - 头部banner或特别卡片 */
|
||||
--gradient-sky: linear-gradient(180deg, #D6EEF8 0%, #E4F2FA 15%, #EEF6FB 30%, #F5FAFD 50%, #FAFCFE 70%, #FFFFFF 100%); /* 主页天空渐变 - 全局背景 */
|
||||
--gradient-subtle: linear-gradient(120deg, #F9FAFE 0%, #FFFFFF 100%); /* 微弱渐变 - 增加细节精致度 */
|
||||
|
||||
/* ========== 阴影层级 ========== */
|
||||
@@ -49,6 +62,7 @@
|
||||
--shadow-md: 0 12px 28px rgba(0, 0, 0, 0.08); /* 中等阴影 - 弹窗或下拉菜单 */
|
||||
--shadow-lg: 0 20px 35px rgba(0, 0, 0, 0.12); /* 大阴影 - 模态框、悬浮元素 */
|
||||
--shadow-orange-glow: 0 4px 12px rgba(255, 107, 53, 0.25); /* 橙色光晕 - 增强CTA吸引力 */
|
||||
--shadow-sky-glow: 0 4px 12px rgba(160, 210, 235, 0.2); /* 蓝色光晕 - 主页效果增强 */
|
||||
|
||||
/* ========== 圆角规范 (柔和运动风) ========== */
|
||||
--radius-sm: 12px; /* 小组件、标签圆角 */
|
||||
@@ -95,18 +109,62 @@
|
||||
}
|
||||
|
||||
/* ========== 辅助类 (方便开发直接复用) ========== */
|
||||
|
||||
/* 背景色类 */
|
||||
.bg-primary {
|
||||
background-color: var(--primary-dark);
|
||||
}
|
||||
.bg-accent {
|
||||
background-color: var(--accent-orange);
|
||||
}
|
||||
.bg-gradient-sky {
|
||||
background: var(--gradient-sky);
|
||||
}
|
||||
.bg-gradient-primary {
|
||||
background: var(--bg-gradient-primary);
|
||||
}
|
||||
.bg-sky-100 {
|
||||
background-color: var(--primary-sky-100);
|
||||
}
|
||||
.bg-sky-200 {
|
||||
background-color: var(--primary-sky-200);
|
||||
}
|
||||
.bg-sky-300 {
|
||||
background-color: var(--primary-sky-300);
|
||||
}
|
||||
.bg-sky-400 {
|
||||
background-color: var(--primary-sky-400);
|
||||
}
|
||||
.bg-sky-500 {
|
||||
background-color: var(--primary-sky-500);
|
||||
}
|
||||
|
||||
/* 文字色类 */
|
||||
.text-primary {
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
.text-accent {
|
||||
color: var(--accent-orange);
|
||||
}
|
||||
.text-sky-100 {
|
||||
color: var(--primary-sky-100);
|
||||
}
|
||||
.text-sky-200 {
|
||||
color: var(--primary-sky-200);
|
||||
}
|
||||
|
||||
/* 光晕效果类 */
|
||||
.glow-blue-1 {
|
||||
background: radial-gradient(circle, var(--glow-blue-1) 0%, transparent 70%);
|
||||
}
|
||||
.glow-blue-2 {
|
||||
background: radial-gradient(circle, var(--glow-blue-2) 0%, transparent 70%);
|
||||
}
|
||||
.glow-blue-3 {
|
||||
background: radial-gradient(circle, var(--glow-blue-3) 0%, transparent 70%);
|
||||
}
|
||||
|
||||
/* 按钮类 */
|
||||
.btn-orange {
|
||||
background: var(--gradient-orange);
|
||||
color: white;
|
||||
@@ -121,10 +179,35 @@
|
||||
transform: scale(0.97);
|
||||
background: var(--accent-orange-dark);
|
||||
}
|
||||
|
||||
/* 卡片类 */
|
||||
.card-default {
|
||||
background: var(--bg-white);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-sm);
|
||||
border: 1px solid var(--border-light);
|
||||
padding: var(--spacing-md);
|
||||
}
|
||||
.card-sky {
|
||||
background: var(--gradient-sky);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
/* 阴影类 */
|
||||
.shadow-sky {
|
||||
box-shadow: var(--shadow-sky-glow);
|
||||
}
|
||||
|
||||
/* 通用页面容器 */
|
||||
.page-container-sky {
|
||||
min-height: 100vh;
|
||||
background: var(--gradient-sky);
|
||||
}
|
||||
|
||||
/* 滚动容器 */
|
||||
.scroll-container-sky {
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
background: var(--gradient-sky);
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
background: var(--gradient-sky);
|
||||
--spacing-xs: 4px;
|
||||
--spacing-sm: 8px;
|
||||
--spacing-md: 16px;
|
||||
@@ -36,7 +37,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
background-color: var(--bg-light);
|
||||
background: var(--gradient-sky);
|
||||
box-sizing: border-box;
|
||||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
@@ -10,14 +10,27 @@
|
||||
@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-content" @click="previewImage(index)">
|
||||
<!-- 添加 lazy-load 属性实现懒加载 -->
|
||||
<image
|
||||
:src="banner.image"
|
||||
mode="aspectFill"
|
||||
class="banner-image"
|
||||
lazy-load
|
||||
:show-menu-by-longpress="false"
|
||||
@load="onImageLoad(index)"
|
||||
@error="onImageError(index)"
|
||||
/>
|
||||
<view class="banner-overlay"></view>
|
||||
<view class="banner-text">
|
||||
<text class="banner-title">{{ banner.title }}</text>
|
||||
<text class="banner-subtitle">{{ banner.subtitle }}</text>
|
||||
<text class="banner-desc">{{ banner.desc }}</text>
|
||||
</view>
|
||||
<!-- 可选:添加加载占位符 -->
|
||||
<view v-if="!imageLoaded[index]" class="image-placeholder">
|
||||
<view class="loading-spinner"></view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
@@ -56,10 +69,35 @@ const banners = [
|
||||
]
|
||||
|
||||
const currentIndex = ref(0)
|
||||
// 记录每张图片的加载状态
|
||||
const imageLoaded = ref(banners.map(() => false))
|
||||
|
||||
const onSwiperChange = (e) => {
|
||||
currentIndex.value = e.detail.current
|
||||
}
|
||||
|
||||
const previewImage = (index) => {
|
||||
const urls = banners.map(banner => banner.image)
|
||||
uni.previewImage({
|
||||
urls: urls,
|
||||
current: urls[index],
|
||||
indicator: 'default',
|
||||
loop: true
|
||||
})
|
||||
}
|
||||
|
||||
// 图片加载成功回调
|
||||
const onImageLoad = (index) => {
|
||||
imageLoaded.value[index] = true
|
||||
console.log(`图片 ${index} 加载完成`)
|
||||
}
|
||||
|
||||
// 图片加载失败回调
|
||||
const onImageError = (index) => {
|
||||
console.error(`图片 ${index} 加载失败`)
|
||||
// 可选:设置默认占位图
|
||||
// banners[index].image = '默认图片URL'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -86,58 +124,50 @@ const onSwiperChange = (e) => {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 添加图片占位符样式 */
|
||||
.image-placeholder {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
||||
border-top: 4rpx solid #7AB5CC;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.banner-overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 2; /* 确保遮罩层在占位符上面 */
|
||||
}
|
||||
|
||||
.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: 36rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
|
||||
@@ -126,7 +126,7 @@ function goMyCourses() {
|
||||
<style lang="scss" scoped>
|
||||
.tab-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f0f4f8;
|
||||
background: $gradient-sky;
|
||||
padding-bottom: 160rpx;
|
||||
}
|
||||
|
||||
@@ -137,15 +137,15 @@ function goMyCourses() {
|
||||
.tab-page__title {
|
||||
display: block;
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #1a202c;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
.tab-page__subtitle {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.tab-page__actions {
|
||||
@@ -157,26 +157,34 @@ function goMyCourses() {
|
||||
.tab-page__btn {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border-radius: 999rpx;
|
||||
background: linear-gradient(135deg, #ff6b35 0%, #ff8c5a 100%);
|
||||
border-radius: $radius-full;
|
||||
background: $gradient-orange;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: $shadow-orange-glow;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.tab-page__btn:active {
|
||||
transform: scale(0.97);
|
||||
background: $accent-orange-dark;
|
||||
}
|
||||
|
||||
.tab-page__btn--ghost {
|
||||
background: #fff;
|
||||
border: 1px solid #e2e8f0;
|
||||
background: $bg-white;
|
||||
border: 1px solid $border-light;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.tab-page__btn-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-inverse;
|
||||
}
|
||||
|
||||
.tab-page__btn-text--ghost {
|
||||
color: #1a4a6f;
|
||||
color: $primary-deep;
|
||||
}
|
||||
|
||||
.bottom-placeholder {
|
||||
@@ -191,8 +199,9 @@ function goMyCourses() {
|
||||
.skeleton-item {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
background: $bg-white;
|
||||
border-radius: $radius-md;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.skeleton-img {
|
||||
@@ -201,7 +210,7 @@ function goMyCourses() {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite;
|
||||
border-radius: 16rpx;
|
||||
border-radius: $radius-sm;
|
||||
}
|
||||
|
||||
.skeleton-text {
|
||||
|
||||
@@ -48,7 +48,7 @@ function goPointsMall() {
|
||||
<style lang="scss" scoped>
|
||||
.tab-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f0f4f8;
|
||||
background: $gradient-sky;
|
||||
padding-bottom: 160rpx;
|
||||
}
|
||||
|
||||
@@ -59,15 +59,15 @@ function goPointsMall() {
|
||||
.tab-page__title {
|
||||
display: block;
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #1a202c;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
.tab-page__subtitle {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.discover-links {
|
||||
@@ -79,23 +79,29 @@ function goPointsMall() {
|
||||
|
||||
.discover-link {
|
||||
padding: 24rpx 28rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #fff;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
border-radius: $radius-md;
|
||||
background: $bg-white;
|
||||
box-shadow: $shadow-sm;
|
||||
border: 1px solid $border-light;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.discover-link:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.discover-link__title {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #1e2a3a;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
.discover-link__desc {
|
||||
display: block;
|
||||
margin-top: 6rpx;
|
||||
font-size: 22rpx;
|
||||
color: #64748b;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.bottom-placeholder {
|
||||
|
||||
@@ -116,7 +116,7 @@ onMounted(() => {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ onMounted(() => {
|
||||
z-index: 1;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
background: linear-gradient(180deg, #D6EEF8 0%, #E4F2FA 15%, #EEF6FB 30%, #F5FAFD 50%, #FAFCFE 70%, #FFFFFF 100%);
|
||||
// background: linear-gradient(180deg, #D6EEF8 0%, #E4F2FA 15%, #EEF6FB 30%, #F5FAFD 50%, #FAFCFE 70%, #FFFFFF 100%);
|
||||
}
|
||||
|
||||
/* 主内容区域 */
|
||||
|
||||
@@ -53,7 +53,7 @@ function goCheckIn() {
|
||||
<style lang="scss" scoped>
|
||||
.tab-page {
|
||||
min-height: 100vh;
|
||||
background-color: #f0f4f8;
|
||||
background: $gradient-sky;
|
||||
padding-bottom: 160rpx;
|
||||
}
|
||||
|
||||
@@ -64,15 +64,15 @@ function goCheckIn() {
|
||||
.tab-page__title {
|
||||
display: block;
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: #1a202c;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
.tab-page__subtitle {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.train-cards {
|
||||
@@ -84,23 +84,29 @@ function goCheckIn() {
|
||||
|
||||
.train-card {
|
||||
padding: 28rpx 32rpx;
|
||||
border-radius: 24rpx;
|
||||
background: #fff;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
border-radius: $radius-md;
|
||||
background: $bg-white;
|
||||
box-shadow: $shadow-sm;
|
||||
border: 1px solid $border-light;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.train-card:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.train-card__title {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #1e2a3a;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
}
|
||||
|
||||
.train-card__desc {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #64748b;
|
||||
color: $text-muted;
|
||||
}
|
||||
|
||||
.bottom-placeholder {
|
||||
|
||||
Reference in New Issue
Block a user