394 lines
8.0 KiB
Vue
394 lines
8.0 KiB
Vue
<template>
|
||
<view class="page">
|
||
<!-- 头部:风景图 + 用户信息 -->
|
||
<image
|
||
class="hero-bg"
|
||
src="https://aliyunoss.hn12301.net/sd/pingxiang_wo_bj.png"
|
||
mode="widthFix"
|
||
/>
|
||
<view class="profile-hero">
|
||
|
||
<view class="hero-overlay" />
|
||
<view class="hero-content">
|
||
<view class="avatar-wrap">
|
||
<image class="avatar" src="/static/logo.png" mode="aspectFill" />
|
||
</view>
|
||
<view class="user-info">
|
||
<text class="nickname">{{ userStore.isLogin ? formatPhone(userStore.userInfo?.phone) : '未登录' }}</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-section">
|
||
<view class="menu-card">
|
||
<view class="menu-item" @click="goOrders">
|
||
<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" @click="goUsageGuide">
|
||
<view class="menu-icon-wrap menu-icon-wrap--primary">
|
||
<view class="icon-rule" />
|
||
</view>
|
||
<text class="menu-text">使用说明</text>
|
||
<view class="menu-chevron" />
|
||
</view>
|
||
<view class="menu-item" @click="goFaq">
|
||
<view class="menu-icon-wrap menu-icon-wrap--success">
|
||
<view class="icon-faq" />
|
||
</view>
|
||
<text class="menu-text">常见问题</text>
|
||
<view class="menu-chevron" />
|
||
</view>
|
||
<view class="menu-item menu-item--last" @click="callService">
|
||
<view class="menu-icon-wrap menu-icon-wrap--error">
|
||
<view class="icon-phone" />
|
||
</view>
|
||
<text class="menu-text">客服热线</text>
|
||
<view class="menu-chevron" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 退出登录 -->
|
||
<view class="btn-area" v-if="userStore.isLogin">
|
||
<view class="btn-logout" @click="handleLogout">
|
||
<text>退出登录</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { useUserStore } from '../../store/user'
|
||
|
||
const userStore = useUserStore()
|
||
|
||
/** 跳转到登录页 */
|
||
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 })
|
||
}
|
||
|
||
/** 退出登录(弹窗确认后清除 token) */
|
||
function handleLogout() {
|
||
uni.showModal({
|
||
title: '提示', content: '确定要退出登录吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
userStore.logout()
|
||
uni.showToast({ title: '已退出', icon: 'success' })
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
/** 显示「即将上线」提示 */
|
||
function showComingSoon() { uni.showToast({ title: '即将上线,敬请期待', icon: 'none' }) }
|
||
|
||
/** 跳转 FAQ */
|
||
function goFaq() { uni.navigateTo({ url: '/packages/content/pages/faq' }) }
|
||
|
||
/** 跳转使用说明 */
|
||
function goUsageGuide() { uni.navigateTo({ url: '/packages/content/pages/usage-guide' }) }
|
||
|
||
/** 跳转订单列表 */
|
||
function goOrders() { uni.navigateTo({ url: '/packages/user/pages/order/list' }) }
|
||
|
||
/** 拨打客服热线 */
|
||
function callService() { uni.makePhoneCall({ phoneNumber: '400-123-0101' }) }
|
||
|
||
/** 手机号脱敏显示(138****5678) */
|
||
function formatPhone(phone?: string) {
|
||
if (!phone) return '已登录'
|
||
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
|
||
}
|
||
</script>
|
||
<style>
|
||
page{
|
||
background: #fff;
|
||
}
|
||
</style>
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
min-height: 100vh;
|
||
|
||
}
|
||
|
||
/* Hero header */
|
||
.profile-hero {
|
||
position: relative;
|
||
height: 380rpx;
|
||
overflow: hidden;
|
||
padding-top: 120rpx;
|
||
|
||
}
|
||
|
||
.hero-bg {
|
||
position: absolute;
|
||
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.hero-overlay {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
|
||
}
|
||
|
||
.hero-content {
|
||
position: relative;
|
||
z-index: 2;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: $spacing-10 $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-title;
|
||
font-weight: $font-weight-bold;
|
||
color: #1B1613;
|
||
margin-bottom: $spacing-1;
|
||
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
.user-desc {
|
||
font-size: $font-size-sm;
|
||
color: #403D3A;
|
||
|
||
&--link {
|
||
color: $uv-warning;
|
||
}
|
||
}
|
||
|
||
/* Menu section */
|
||
.menu-section {
|
||
padding: $spacing-3;
|
||
margin-top: -25rpx;
|
||
position: relative;
|
||
z-index: 3;
|
||
}
|
||
|
||
.menu-card {
|
||
background: $color-card;
|
||
border-radius: $radius-lg;
|
||
box-shadow: 0 4rpx 16rpx rgba(15, 23, 42, 0.15);
|
||
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;
|
||
}
|
||
|
||
&--error {
|
||
background: $uv-error-light;
|
||
}
|
||
}
|
||
|
||
/* CSS icons */
|
||
.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-rule {
|
||
width: 22rpx;
|
||
height: 26rpx;
|
||
border: 3rpx solid $uv-primary;
|
||
border-radius: 4rpx;
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 5rpx;
|
||
left: 4rpx;
|
||
width: 10rpx;
|
||
height: 3rpx;
|
||
background: $uv-primary;
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 12rpx;
|
||
left: 4rpx;
|
||
width: 10rpx;
|
||
height: 3rpx;
|
||
background: $uv-primary;
|
||
}
|
||
}
|
||
|
||
.icon-faq {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
border: 3rpx solid $uv-success;
|
||
border-radius: 50%;
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '?';
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
font-size: 16rpx;
|
||
font-weight: $font-weight-bold;
|
||
color: $uv-success;
|
||
line-height: 1;
|
||
}
|
||
}
|
||
|
||
.icon-phone {
|
||
width: 18rpx;
|
||
height: 26rpx;
|
||
border: 3rpx solid $uv-error;
|
||
border-radius: 6rpx;
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 3rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 8rpx;
|
||
height: 3rpx;
|
||
background: $uv-error;
|
||
border-radius: 2rpx;
|
||
}
|
||
}
|
||
|
||
.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>
|