profile.vue 8.04 KB
<template>
	<view class="page-shell profile-page">
		<view class="page-blur"></view>
		<view class="page-blur-secondary"></view>
		<view class="page-blur-tertiary"></view>

		<view class="page-content">
			<view class="profile-header">
				<text class="profile-title">我的</text>
			</view>

			<view class="user-card glass-card">
				<image class="user-art" src="/static/images/art-profile.png" mode="aspectFill" />
				<view class="user-overlay"></view>
				<view class="user-row">
					<view class="avatar">
						<view class="avatar-core"></view>
					</view>
					<view class="user-info">
						<view class="user-name-row">
							<text class="user-name">林小姐</text>
							<text class="level-badge">A++</text>
						</view>
						<text class="user-phone">138****5628</text>
						<text class="user-desc">已开启预约优先安排与到店礼宾提醒</text>
					</view>
				</view>
			</view>

			<view class="section-block">
				<view class="section-head">
					<text class="section-title">我的订单</text>
					<text class="section-link" @tap="goOrderList()">查看全部</text>
				</view>
				<view class="orders-card glass-card">
					<view v-for="item in orderEntries" :key="item.title" class="order-item" @tap="goOrderList(item.status)">
						<image class="order-icon" :src="item.icon" mode="aspectFit" />
						<text class="order-title">{{ item.title }}</text>
					</view>
				</view>
			</view>

			<view class="section-block">
				<view class="section-head">
					<text class="section-title">常用功能</text>
					<text class="section-link">会员中心</text>
				</view>
				<view class="menu-card glass-card">
					<view v-for="item in menuEntries" :key="item.title" class="menu-item" @tap="handleMenu(item)">
						<view class="menu-left">
							<image class="menu-icon" :src="item.icon" mode="aspectFit" />
							<text class="menu-title">{{ item.title }}</text>
						</view>
						<text class="menu-arrow">›</text>
					</view>
				</view>
			</view>

			<view class="logout-button" @tap="logout">退出登录</view>
			<view class="safe-bottom-space"></view>
		</view>

		<view class="lf-tabbar-wrap">
			<view class="lf-tabbar-panel">
				<view v-for="item in tabs" :key="item.key" class="lf-tabbar-item"
					:class="{ active: item.key === 'profile' }" @tap="goTab(item)">
					<view class="lf-tabbar-icon-shell">
						<image class="lf-tabbar-icon" :src="item.key === 'profile' ? item.activeIcon : item.icon"
							mode="aspectFit" />
					</view>
					<text class="lf-tabbar-label">{{ item.label }}</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				tabs: [{
						key: 'home',
						label: '首页',
						path: '/pages/home/home',
						icon: '/static/images/tab-home.png',
						activeIcon: '/static/images/tab-home-active.png'
					},
					{
						key: 'booking',
						label: '预约',
						path: '/pages/booking/booking',
						icon: '/static/images/tab-booking.png',
						activeIcon: '/static/images/tab-booking-active.png'
					},
					{
						key: 'mall',
						label: '商城',
						path: '/packageMall/main/main',
						icon: '/static/images/tab-mall.png',
						activeIcon: '/static/images/tab-mall-active.png'
					},
					{
						key: 'profile',
						label: '我的',
						path: '/pages/profile/profile',
						icon: '/static/images/tab-profile.png',
						activeIcon: '/static/images/tab-profile-active.png'
					}
				],
				orderEntries: [{
						title: '待付款',
						icon: '/static/images/order-pay.png',
						status: 'pay'
					},
					{
						title: '待发货',
						icon: '/static/images/order-ship.png',
						status: 'ship'
					},
					{
						title: '待收货',
						icon: '/static/images/order-receive.png',
						status: 'receive'
					},
					{
						title: '待评价',
						icon: '/static/images/order-review.png',
						status: 'review'
					}
				],
				menuEntries: [{
						title: '预约记录',
						icon: '/static/images/menu-booking.png',
						path: '/packageBooking/record/record'
					},
					{
						title: '心愿单',
						icon: '/static/images/order-review.png',
						path: '/packageMall/wishlist/wishlist'
					},
					{
						title: '地址管理',
						icon: '/static/images/menu-address.png',
						path: '/packageProfile/address-list/address-list'
					},
					{
						title: '关于我们',
						icon: '/static/images/menu-about.png',
						path: '/packageProfile/about/about'
					},
					{
						title: '设置',
						icon: '/static/images/menu-setting.png',
						path: '/packageProfile/settings/settings'
					}
				]
			}
		},
		methods: {
			goOrderList(status) {
				const query = status ? `?status=${status}` : ''
				uni.navigateTo({
					url: `/packageProfile/order-list/order-list${query}`
				})
			},
			handleMenu(item) {
				if (item.path) {
					uni.navigateTo({
						url: item.path
					})
					return
				}
				uni.showToast({
					title: `${item.title} 功能演示中`,
					icon: 'none'
				})
			},
			logout() {
				uni.showToast({
					title: '已安全退出',
					icon: 'none'
				})
				setTimeout(() => {
					uni.reLaunch({
						url: '/pages/login/login'
					})
				}, 320)
			},
			goTab(item) {
				if (item.key === 'profile') {
					return
				}
				uni.redirectTo({
					url: item.path
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	@import '@/styles/mixins.scss';

	.profile-header {
		display: flex;
		align-items: center;
		margin-bottom: 28rpx;
	}

	.profile-title {
		font-size: 44rpx;
		font-weight: 700;
	}

	.user-card,
	.orders-card,
	.menu-card {
		padding: 34rpx;
	}

	.user-card {
		position: relative;
		overflow: hidden;
		margin-bottom: 28rpx;
	}

	.user-art,
	.user-overlay {
		position: absolute;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
	}

	.user-overlay {
		background: linear-gradient(140deg, rgba(255, 255, 255, 0.06), rgba(36, 74, 61, 0.14));
	}

	.user-row,
	.user-name-row,
	.menu-left,
	.menu-item {
		display: flex;
		align-items: center;
	}

	.user-row {
		position: relative;
		z-index: 2;
	}

	.avatar {
		position: relative;
		width: 112rpx;
		height: 112rpx;
		border-radius: 50%;
		background: rgba(255, 255, 255, 0.24);
		border: 2rpx solid rgba(255, 255, 255, 0.32);
	}

	.avatar::before,
	.avatar::after {
		content: '';
		position: absolute;
		left: 50%;
		background: rgba(255, 255, 255, 0.86);
	}

	.avatar::before {
		top: 24rpx;
		width: 30rpx;
		height: 30rpx;
		margin-left: -15rpx;
		border-radius: 50%;
	}

	.avatar::after {
		bottom: 20rpx;
		width: 56rpx;
		height: 30rpx;
		margin-left: -28rpx;
		border-radius: 28rpx 28rpx 20rpx 20rpx;
	}

	.avatar-core {
		position: absolute;
		inset: 10rpx;
		border-radius: 50%;
		border: 2rpx solid rgba(255, 255, 255, 0.28);
	}

	.user-info {
		flex: 1;
		margin-left: 24rpx;
	}

	.user-name {
		font-size: 36rpx;
		font-weight: 700;
		color: #fff;
	}

	.level-badge {
		margin-left: 16rpx;
		@include chip-soft;
		font-weight: 600;
	}

	.user-phone,
	.user-desc,
	.order-title,
	.menu-arrow {
		color: $text-secondary;
	}

	.user-phone {
		display: block;
		margin-top: 12rpx;
		font-size: 26rpx;
		color: rgba(255, 255, 255, 0.88);
	}

	.user-desc {
		display: block;
		margin-top: 10rpx;
		font-size: 24rpx;
		line-height: 1.6;
		color: rgba(255, 255, 255, 0.82);
	}

	.section-block {
		margin-bottom: 28rpx;
	}

	.orders-card {
		@include outlined-card(0.9);
		display: flex;
		justify-content: space-between;
	}

	.order-item {
		width: 25%;
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.order-icon,
	.menu-icon {
		width: 72rpx;
		height: 72rpx;
	}

	.menu-icon {
		filter: sepia(0.28) saturate(0.78) hue-rotate(286deg) brightness(0.96);
	}

	.order-title {
		margin-top: 16rpx;
		font-size: 24rpx;
		color: $text-primary;
	}

	.menu-item {
		justify-content: space-between;
		padding: 22rpx 0;
		border-bottom: 1rpx solid rgba(100, 140, 118, 0.08);

		&:last-child {
			border-bottom: 0;
			padding-bottom: 0;
		}
	}

	.menu-title {
		margin-left: 18rpx;
		font-size: 28rpx;
		color: $text-primary;
	}

	.menu-card {
		@include outlined-card(0.9);
	}

	.menu-arrow {
		font-size: 36rpx;
	}

	.logout-button {
		@include primary-button;
		width: 100%;
	}
</style>