feat: UI redesign with uv-ui color system and landscape imagery
- Replace all colors with uv-ui design tokens (primary #3c9cff, warning #f9ae3d, etc.) - Hero section: Wugong Mountain landscape photo with dark overlay - Super Player card: photo background, large typography, warning-color price/CTA, value comparison (¥198 vs ¥3800+) - Spots section: landscape thumbnails instead of CSS gradients, warning-color prices - Profile page: landscape hero header, CSS menu icons, floating card layout - Card list page: landscape hero header, filter pills, empty state design - TabBar: rename '入园码' to '旅游卡', Lucide-style PNG icons (home/card/profile) - Typography: corrected font weights (semibold for prices, medium for labels) - Remove broken font-loader (lxgw-wen-kai CDN 404) - Skip wx.getPrivacySetting in devtools to avoid framework timeout - Replace all inline SVG with CSS-only icons for mini-program compatibility - Add design system files (styles/, components/, animations) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+296
-44
@@ -1,34 +1,57 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<view class="user-card">
|
||||
<view class="avatar-wrap">
|
||||
<image class="avatar" :src="userStore.userInfo?.avatarUrl || defaultAvatar" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="user-info">
|
||||
<text class="nickname">{{ userStore.userInfo?.nickname || '未登录' }}</text>
|
||||
<text class="user-desc" v-if="userStore.isLogin">欢迎使用爱上萍乡</text>
|
||||
<text class="user-desc" v-else @click="goLogin">点击登录</text>
|
||||
<!-- 头部:风景图 + 用户信息 -->
|
||||
<view class="profile-hero">
|
||||
<image
|
||||
class="hero-bg"
|
||||
src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?fm=jpg&q=80&w=750&h=400&fit=crop"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="hero-overlay" />
|
||||
<view class="hero-content">
|
||||
<view class="avatar-wrap">
|
||||
<image class="avatar" :src="userStore.userInfo?.avatarUrl || defaultAvatar" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="user-info">
|
||||
<text class="nickname">{{ userStore.userInfo?.nickname || '未登录' }}</text>
|
||||
<text class="user-desc" v-if="userStore.isLogin">欢迎使用爱上萍乡</text>
|
||||
<text class="user-desc user-desc--link" v-else @click="goLogin">点击登录 →</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="menu-card">
|
||||
<view class="menu-item" @click="goTo('/packages/user/pages/card/bind')">
|
||||
<text class="menu-icon">🎫</text>
|
||||
<text class="menu-text">我的年卡</text>
|
||||
<text class="menu-arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="showComingSoon">
|
||||
<text class="menu-icon">📦</text>
|
||||
<text class="menu-text">订单管理</text>
|
||||
<text class="menu-arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @click="showComingSoon">
|
||||
<text class="menu-icon">📋</text>
|
||||
<text class="menu-text">使用记录</text>
|
||||
<text class="menu-arrow">›</text>
|
||||
|
||||
<!-- 功能菜单 -->
|
||||
<view class="menu-section">
|
||||
<view class="menu-card">
|
||||
<view class="menu-item" @click="goTo('/packages/user/pages/card/bind')">
|
||||
<view class="menu-icon-wrap menu-icon-wrap--primary">
|
||||
<view class="icon-card" />
|
||||
</view>
|
||||
<text class="menu-text">我的年卡</text>
|
||||
<view class="menu-chevron" />
|
||||
</view>
|
||||
<view class="menu-item" @click="showComingSoon">
|
||||
<view class="menu-icon-wrap menu-icon-wrap--warning">
|
||||
<view class="icon-order" />
|
||||
</view>
|
||||
<text class="menu-text">订单管理</text>
|
||||
<view class="menu-chevron" />
|
||||
</view>
|
||||
<view class="menu-item menu-item--last" @click="showComingSoon">
|
||||
<view class="menu-icon-wrap menu-icon-wrap--success">
|
||||
<view class="icon-history" />
|
||||
</view>
|
||||
<text class="menu-text">使用记录</text>
|
||||
<view class="menu-chevron" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<view class="btn-area" v-if="userStore.isLogin">
|
||||
<button class="btn-logout" @click="handleLogout">退出登录</button>
|
||||
<view class="btn-logout" @click="handleLogout">
|
||||
<text>退出登录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -39,16 +62,13 @@ import { useUserStore } from '../../store/user'
|
||||
const userStore = useUserStore()
|
||||
const defaultAvatar = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'
|
||||
|
||||
/** 跳转登录页 */
|
||||
function goLogin() { uni.navigateTo({ url: '/pages/login/login' }) }
|
||||
|
||||
/** 需要登录的页面跳转 */
|
||||
function goTo(url: string) {
|
||||
if (!userStore.isLogin) { uni.navigateTo({ url: '/pages/login/login' }); return }
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
|
||||
/** 退出登录 */
|
||||
function handleLogout() {
|
||||
uni.showModal({
|
||||
title: '提示', content: '确定要退出登录吗?',
|
||||
@@ -62,24 +82,256 @@ function handleLogout() {
|
||||
})
|
||||
}
|
||||
|
||||
/** 即将上线提示 */
|
||||
function showComingSoon() { uni.showToast({ title: '即将上线,敬请期待', icon: 'none' }) }
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page { min-height: 100vh; background: #f5f5f5; }
|
||||
.user-card { background: linear-gradient(135deg, #4A90D9, #357ABD); padding: 50rpx 30rpx 40rpx; display: flex; align-items: center; }
|
||||
.avatar-wrap { margin-right: 24rpx; }
|
||||
.avatar { width: 120rpx; height: 120rpx; border-radius: 50%; border: 4rpx solid rgba(255,255,255,0.5); background: #eee; }
|
||||
.user-info { display: flex; flex-direction: column; }
|
||||
.nickname { font-size: 34rpx; font-weight: bold; color: #fff; margin-bottom: 8rpx; }
|
||||
.user-desc { font-size: 24rpx; color: rgba(255,255,255,0.8); }
|
||||
.menu-card { background: #fff; border-radius: 16rpx; margin: 20rpx; overflow: hidden; }
|
||||
.menu-item { display: flex; align-items: center; padding: 30rpx; border-bottom: 1rpx solid #f0f0f0; }
|
||||
.menu-item:last-child { border-bottom: none; }
|
||||
.menu-icon { font-size: 36rpx; margin-right: 20rpx; }
|
||||
.menu-text { flex: 1; font-size: 28rpx; color: #333; }
|
||||
.menu-arrow { font-size: 36rpx; color: #ccc; }
|
||||
.btn-area { padding: 40rpx 20rpx; }
|
||||
.btn-logout { width: 100%; height: 88rpx; line-height: 88rpx; background: #fff; color: #E74C3C; border-radius: 44rpx; font-size: 30rpx; border: 1rpx solid #f0f0f0; }
|
||||
<style lang="scss" scoped>
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background: $uv-bg-color;
|
||||
}
|
||||
|
||||
/* Hero header */
|
||||
.profile-hero {
|
||||
position: relative;
|
||||
height: 360rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hero-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(48, 49, 51, 0.5) 0%,
|
||||
rgba(48, 49, 51, 0.7) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $spacing-12 $spacing-4 $spacing-4;
|
||||
}
|
||||
|
||||
.avatar-wrap {
|
||||
margin-right: $spacing-3;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.4);
|
||||
background: $uv-info-light;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
font-family: $font-family-display;
|
||||
font-size: $font-size-xl;
|
||||
font-weight: $font-weight-bold;
|
||||
color: #fff;
|
||||
margin-bottom: $spacing-1;
|
||||
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.user-desc {
|
||||
font-size: $font-size-sm;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
|
||||
&--link {
|
||||
color: $uv-warning;
|
||||
}
|
||||
}
|
||||
|
||||
/* Menu section */
|
||||
.menu-section {
|
||||
padding: $spacing-3;
|
||||
margin-top: -40rpx;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.menu-card {
|
||||
background: $color-card;
|
||||
border-radius: $radius-xl;
|
||||
box-shadow: $shadow-base;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $spacing-3 $spacing-4;
|
||||
border-bottom: $border-width solid $uv-border-color;
|
||||
transition: background $transition-fast;
|
||||
|
||||
&:active {
|
||||
background: $uv-info-light;
|
||||
}
|
||||
|
||||
&--last {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-icon-wrap {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: $radius-lg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: $spacing-3;
|
||||
flex-shrink: 0;
|
||||
|
||||
&--primary {
|
||||
background: $uv-primary-light;
|
||||
}
|
||||
|
||||
&--warning {
|
||||
background: $uv-warning-light;
|
||||
}
|
||||
|
||||
&--success {
|
||||
background: $uv-success-light;
|
||||
}
|
||||
}
|
||||
|
||||
/* CSS icons */
|
||||
.icon-card {
|
||||
width: 28rpx;
|
||||
height: 20rpx;
|
||||
border: 3rpx solid $uv-primary;
|
||||
border-radius: 4rpx;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 6rpx;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3rpx;
|
||||
background: $uv-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-order {
|
||||
width: 22rpx;
|
||||
height: 26rpx;
|
||||
border: 3rpx solid $uv-warning;
|
||||
border-radius: 4rpx;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 6rpx;
|
||||
left: 4rpx;
|
||||
width: 10rpx;
|
||||
height: 3rpx;
|
||||
background: $uv-warning;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 14rpx;
|
||||
left: 4rpx;
|
||||
width: 8rpx;
|
||||
height: 3rpx;
|
||||
background: $uv-warning;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-history {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border: 3rpx solid $uv-success;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 4rpx;
|
||||
left: 8rpx;
|
||||
width: 3rpx;
|
||||
height: 8rpx;
|
||||
background: $uv-success;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 9rpx;
|
||||
left: 8rpx;
|
||||
width: 6rpx;
|
||||
height: 3rpx;
|
||||
background: $uv-success;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
flex: 1;
|
||||
font-size: $font-size-base;
|
||||
color: $uv-main-color;
|
||||
font-weight: $font-weight-medium;
|
||||
}
|
||||
|
||||
.menu-chevron {
|
||||
width: 10rpx;
|
||||
height: 10rpx;
|
||||
border-top: 2rpx solid $uv-light-color;
|
||||
border-right: 2rpx solid $uv-light-color;
|
||||
transform: rotate(45deg);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Logout button */
|
||||
.btn-area {
|
||||
padding: $spacing-5 $spacing-3;
|
||||
}
|
||||
|
||||
.btn-logout {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background: $color-card;
|
||||
border-radius: $radius-full;
|
||||
box-shadow: $shadow-sm;
|
||||
transition: transform $transition-fast;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: $font-size-base;
|
||||
color: $uv-error;
|
||||
font-weight: $font-weight-medium;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user