- 实现未登录/已登录两种状态样式 - 添加常用功能入口:我的订单、往期测评、联系我们、邀请新用户 - 添加其他功能入口:关于、用户协议、隐私政策、退出登录 - 实现退出登录二次确认弹窗 - 修复 uni.scss 中 SCSS 导入路径问题 - 整理 .gitignore 文件,移除 unpackage 构建目录
607 lines
13 KiB
Vue
607 lines
13 KiB
Vue
<template>
|
||
<view class="mine-page">
|
||
<!-- 自定义导航栏 -->
|
||
<view class="custom-navbar" :style="navbarStyle">
|
||
<view class="navbar-content" :style="{ height: navbarHeight + 'px' }">
|
||
<text class="navbar-title">我的</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 导航栏占位 -->
|
||
<view class="navbar-placeholder" :style="{ height: totalNavbarHeight + 'px' }"></view>
|
||
|
||
<!-- 页面内容 -->
|
||
<view class="page-content">
|
||
<!-- 用户信息区域 -->
|
||
<view class="user-section">
|
||
<!-- 未登录状态 -->
|
||
<view v-if="!isLoggedIn" class="user-card not-logged">
|
||
<view class="avatar-wrapper">
|
||
<image class="avatar" src="/static/logo.png" mode="aspectFill" />
|
||
</view>
|
||
<view class="user-info">
|
||
<text class="login-tip">登录后体验更多功能</text>
|
||
<button class="btn-login" @click="handleLogin">立即登录</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 已登录状态 -->
|
||
<view v-else class="user-card logged" @click="goProfile">
|
||
<view class="avatar-wrapper">
|
||
<image
|
||
class="avatar"
|
||
:src="userInfo.avatar || '/static/logo.png'"
|
||
mode="aspectFill"
|
||
/>
|
||
</view>
|
||
<view class="user-info">
|
||
<text class="nickname">{{ userInfo.nickname || '用户' }}</text>
|
||
<text class="uid">UID: {{ userInfo.uid || '--' }}</text>
|
||
</view>
|
||
<view class="arrow-icon">
|
||
<text class="iconfont">›</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 常用功能区域 -->
|
||
<view class="menu-section" v-if="isLoggedIn">
|
||
<view class="section-title">常用功能</view>
|
||
<view class="menu-grid">
|
||
<view class="menu-grid-item" @click="goOrderList">
|
||
<view class="menu-icon-wrapper order">
|
||
<text class="menu-icon-text">📋</text>
|
||
</view>
|
||
<text class="menu-text">我的订单</text>
|
||
</view>
|
||
<view class="menu-grid-item" @click="goAssessmentHistory">
|
||
<view class="menu-icon-wrapper history">
|
||
<text class="menu-icon-text">📊</text>
|
||
</view>
|
||
<text class="menu-text">往期测评</text>
|
||
</view>
|
||
<view class="menu-grid-item" @click="handleContactUs">
|
||
<view class="menu-icon-wrapper contact">
|
||
<text class="menu-icon-text">📞</text>
|
||
</view>
|
||
<text class="menu-text">联系我们</text>
|
||
</view>
|
||
<view class="menu-grid-item" v-if="isPartner" @click="goInvite">
|
||
<view class="menu-icon-wrapper invite">
|
||
<text class="menu-icon-text">👥</text>
|
||
</view>
|
||
<text class="menu-text">邀请新用户</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 其他功能区域 -->
|
||
<view class="menu-section">
|
||
<view class="section-title">其他</view>
|
||
<view class="menu-list">
|
||
<view class="menu-item" @click="goAbout">
|
||
<text class="menu-title">关于</text>
|
||
<text class="menu-arrow">›</text>
|
||
</view>
|
||
<view class="menu-item" @click="goUserAgreement">
|
||
<text class="menu-title">用户协议</text>
|
||
<text class="menu-arrow">›</text>
|
||
</view>
|
||
<view class="menu-item" @click="goPrivacyPolicy">
|
||
<text class="menu-title">隐私政策</text>
|
||
<text class="menu-arrow">›</text>
|
||
</view>
|
||
<view class="menu-item logout-item" v-if="isLoggedIn" @click="showLogoutPopup">
|
||
<text class="menu-title logout-text">退出登录</text>
|
||
<text class="menu-arrow">›</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部安全区域 -->
|
||
<view class="safe-bottom"></view>
|
||
</view>
|
||
|
||
<!-- 退出登录确认弹窗 -->
|
||
<view v-if="logoutPopupVisible" class="popup-mask" @click="hideLogoutPopup">
|
||
<view class="popup-container" @click.stop>
|
||
<view class="popup-content">
|
||
<text class="popup-title">提示</text>
|
||
<text class="popup-message">确定要退出登录吗?</text>
|
||
</view>
|
||
<view class="popup-buttons">
|
||
<view class="popup-btn cancel" @click="hideLogoutPopup">
|
||
<text>取消</text>
|
||
</view>
|
||
<view class="popup-btn confirm" @click="handleLogout">
|
||
<text>确定</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
/**
|
||
* 我的页面
|
||
* 展示用户信息和功能入口
|
||
*/
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import { onShow } from '@dcloudio/uni-app'
|
||
import { useUserStore } from '@/store/user.js'
|
||
import { useNavbar } from '@/composables/useNavbar.js'
|
||
|
||
const userStore = useUserStore()
|
||
const { statusBarHeight, navbarHeight, totalNavbarHeight } = useNavbar()
|
||
|
||
// 退出登录弹窗状态
|
||
const logoutPopupVisible = ref(false)
|
||
|
||
// 计算属性
|
||
const isLoggedIn = computed(() => userStore.isLoggedIn)
|
||
const isPartner = computed(() => userStore.isPartner)
|
||
|
||
const userInfo = computed(() => ({
|
||
userId: userStore.userId,
|
||
uid: userStore.uid,
|
||
nickname: userStore.nickname,
|
||
avatar: userStore.avatar
|
||
}))
|
||
|
||
// 导航栏样式
|
||
const navbarStyle = computed(() => ({
|
||
paddingTop: statusBarHeight.value + 'px',
|
||
height: totalNavbarHeight.value + 'px'
|
||
}))
|
||
|
||
/**
|
||
* 跳转登录页
|
||
*/
|
||
function handleLogin() {
|
||
uni.navigateTo({
|
||
url: '/pages/login/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转个人资料页
|
||
*/
|
||
function goProfile() {
|
||
uni.navigateTo({
|
||
url: '/pages/mine/profile/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转我的订单
|
||
*/
|
||
function goOrderList() {
|
||
uni.navigateTo({
|
||
url: '/pages/order/list/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转往期测评
|
||
*/
|
||
function goAssessmentHistory() {
|
||
uni.navigateTo({
|
||
url: '/pages/assessment/history/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 联系我们
|
||
*/
|
||
function handleContactUs() {
|
||
// 调用微信客服
|
||
// 如果没有配置客服,可以显示联系方式
|
||
uni.showModal({
|
||
title: '联系我们',
|
||
content: '如有问题,请联系客服微信:xxxxxx',
|
||
showCancel: false,
|
||
confirmText: '我知道了'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转邀请新用户
|
||
*/
|
||
function goInvite() {
|
||
uni.navigateTo({
|
||
url: '/pages/invite/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转关于页
|
||
*/
|
||
function goAbout() {
|
||
uni.navigateTo({
|
||
url: '/pages/about/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转用户协议
|
||
*/
|
||
function goUserAgreement() {
|
||
uni.navigateTo({
|
||
url: '/pages/agreement/user/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 跳转隐私政策
|
||
*/
|
||
function goPrivacyPolicy() {
|
||
uni.navigateTo({
|
||
url: '/pages/agreement/privacy/index'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 显示退出登录弹窗
|
||
*/
|
||
function showLogoutPopup() {
|
||
logoutPopupVisible.value = true
|
||
}
|
||
|
||
/**
|
||
* 隐藏退出登录弹窗
|
||
*/
|
||
function hideLogoutPopup() {
|
||
logoutPopupVisible.value = false
|
||
}
|
||
|
||
/**
|
||
* 处理退出登录
|
||
*/
|
||
function handleLogout() {
|
||
userStore.logout()
|
||
logoutPopupVisible.value = false
|
||
uni.showToast({
|
||
title: '已退出登录',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 页面显示时恢复用户状态
|
||
*/
|
||
onShow(() => {
|
||
userStore.restoreFromStorage()
|
||
})
|
||
|
||
/**
|
||
* 页面加载
|
||
*/
|
||
onMounted(() => {
|
||
userStore.restoreFromStorage()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import '@/styles/variables.scss';
|
||
|
||
.mine-page {
|
||
min-height: 100vh;
|
||
background-color: $bg-color;
|
||
}
|
||
|
||
// 自定义导航栏
|
||
.custom-navbar {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background-color: $bg-white;
|
||
z-index: 999;
|
||
|
||
.navbar-content {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.navbar-title {
|
||
font-size: 34rpx;
|
||
font-weight: $font-weight-medium;
|
||
color: $text-color;
|
||
}
|
||
}
|
||
}
|
||
|
||
.navbar-placeholder {
|
||
width: 100%;
|
||
}
|
||
|
||
// 页面内容
|
||
.page-content {
|
||
padding: $spacing-lg;
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
// 用户信息区域
|
||
.user-section {
|
||
margin-bottom: $spacing-lg;
|
||
|
||
.user-card {
|
||
background-color: $bg-white;
|
||
border-radius: $border-radius-lg;
|
||
padding: $spacing-lg;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.avatar-wrapper {
|
||
margin-right: $spacing-lg;
|
||
|
||
.avatar {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
border-radius: 50%;
|
||
background-color: $bg-gray;
|
||
}
|
||
}
|
||
|
||
.user-info {
|
||
flex: 1;
|
||
}
|
||
|
||
// 未登录状态
|
||
&.not-logged {
|
||
.user-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
|
||
.login-tip {
|
||
font-size: $font-size-md;
|
||
color: $text-secondary;
|
||
margin-bottom: $spacing-sm;
|
||
}
|
||
|
||
.btn-login {
|
||
width: 180rpx;
|
||
height: 64rpx;
|
||
line-height: 64rpx;
|
||
background-color: $primary-color;
|
||
border-radius: 32rpx;
|
||
font-size: $font-size-sm;
|
||
color: $text-white;
|
||
border: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
|
||
&::after {
|
||
border: none;
|
||
}
|
||
|
||
&:active {
|
||
opacity: 0.8;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 已登录状态
|
||
&.logged {
|
||
.user-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
|
||
.nickname {
|
||
font-size: $font-size-lg;
|
||
font-weight: $font-weight-medium;
|
||
color: $text-color;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.uid {
|
||
font-size: $font-size-sm;
|
||
color: $text-placeholder;
|
||
}
|
||
}
|
||
|
||
.arrow-icon {
|
||
.iconfont {
|
||
font-size: 40rpx;
|
||
color: $text-placeholder;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 菜单区域
|
||
.menu-section {
|
||
background-color: $bg-white;
|
||
border-radius: $border-radius-lg;
|
||
margin-bottom: $spacing-lg;
|
||
overflow: hidden;
|
||
|
||
.section-title {
|
||
font-size: $font-size-md;
|
||
font-weight: $font-weight-medium;
|
||
color: $text-color;
|
||
padding: $spacing-lg $spacing-lg $spacing-sm;
|
||
}
|
||
|
||
// 网格菜单
|
||
.menu-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
padding: $spacing-sm $spacing-lg $spacing-lg;
|
||
|
||
.menu-grid-item {
|
||
width: 25%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: $spacing-md 0;
|
||
|
||
&:active {
|
||
opacity: 0.7;
|
||
}
|
||
|
||
.menu-icon-wrapper {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: $spacing-xs;
|
||
|
||
&.order {
|
||
background-color: rgba(74, 144, 226, 0.1);
|
||
}
|
||
|
||
&.history {
|
||
background-color: rgba(82, 196, 26, 0.1);
|
||
}
|
||
|
||
&.contact {
|
||
background-color: rgba(250, 173, 20, 0.1);
|
||
}
|
||
|
||
&.invite {
|
||
background-color: rgba(255, 77, 79, 0.1);
|
||
}
|
||
|
||
.menu-icon-text {
|
||
font-size: 40rpx;
|
||
}
|
||
}
|
||
|
||
.menu-icon {
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
margin-bottom: $spacing-xs;
|
||
}
|
||
|
||
.menu-text {
|
||
font-size: $font-size-xs;
|
||
color: $text-color;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 列表菜单
|
||
.menu-list {
|
||
.menu-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: $spacing-lg;
|
||
border-bottom: 1rpx solid $border-light;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
&:active {
|
||
background-color: $bg-gray;
|
||
}
|
||
|
||
.menu-title {
|
||
font-size: $font-size-md;
|
||
color: $text-color;
|
||
}
|
||
|
||
.menu-arrow {
|
||
font-size: 32rpx;
|
||
color: $text-placeholder;
|
||
}
|
||
|
||
&.logout-item {
|
||
.logout-text {
|
||
color: $error-color;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 底部安全区域
|
||
.safe-bottom {
|
||
height: 40rpx;
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
// 退出登录弹窗
|
||
.popup-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: $bg-mask;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 1000;
|
||
}
|
||
|
||
.popup-container {
|
||
width: 560rpx;
|
||
background-color: $bg-white;
|
||
border-radius: $border-radius-lg;
|
||
overflow: hidden;
|
||
|
||
.popup-content {
|
||
padding: 60rpx 40rpx 40rpx;
|
||
text-align: center;
|
||
|
||
.popup-title {
|
||
display: block;
|
||
font-size: $font-size-lg;
|
||
font-weight: $font-weight-medium;
|
||
color: $text-color;
|
||
margin-bottom: $spacing-md;
|
||
}
|
||
|
||
.popup-message {
|
||
display: block;
|
||
font-size: $font-size-md;
|
||
color: $text-secondary;
|
||
}
|
||
}
|
||
|
||
.popup-buttons {
|
||
display: flex;
|
||
border-top: 1rpx solid $border-light;
|
||
|
||
.popup-btn {
|
||
flex: 1;
|
||
height: 100rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
&:active {
|
||
background-color: $bg-gray;
|
||
}
|
||
|
||
text {
|
||
font-size: $font-size-lg;
|
||
}
|
||
|
||
&.cancel {
|
||
border-right: 1rpx solid $border-light;
|
||
|
||
text {
|
||
color: $text-secondary;
|
||
}
|
||
}
|
||
|
||
&.confirm {
|
||
text {
|
||
color: $primary-color;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|