310 lines
8.1 KiB
Vue
310 lines
8.1 KiB
Vue
<template>
|
||
<view class="mine-page">
|
||
<!-- 自定义导航栏 -->
|
||
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||
<view class="custom-navbar__content" :style="{ height: navBarHeight + 'px' }">
|
||
<text class="custom-navbar__title">我的</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 顶部用户卡片 -->
|
||
<view class="user-card" @click="handleUserCardClick">
|
||
<image class="user-card__avatar" :src="userStore.user?.avatar || '/static/logo.png'" mode="aspectFill" />
|
||
<view class="user-card__info">
|
||
<text class="user-card__name">{{ isLoggedIn ? (userStore.user?.nickname || '微信用户') : '点击注册/登录' }}</text>
|
||
<text v-if="isLoggedIn" class="user-card__id">ID: {{ userStore.user?.id }}</text>
|
||
</view>
|
||
<text class="user-card__arrow">›</text>
|
||
</view>
|
||
|
||
<!-- 我的订单 -->
|
||
<view class="order-entry" @click="navigateTo('/pages/order/list')">
|
||
<image class="order-entry__icon" src="/static/tab/me_s.png" mode="aspectFit" />
|
||
<text class="order-entry__text">我的订单 {{ orderCount }}</text>
|
||
<text class="order-entry__arrow">›</text>
|
||
</view>
|
||
|
||
<!-- 功能菜单 -->
|
||
<view class="menu-group">
|
||
<view class="menu-item" @click="navigateTo('/pages/address/index')">
|
||
<image class="menu-item__icon" src="/static/ic_address.png" mode="aspectFit" />
|
||
<text class="menu-item__label">收货地址</text>
|
||
<text class="menu-item__arrow">›</text>
|
||
</view>
|
||
<view class="menu-item" @click="showQrCode = true">
|
||
<image class="menu-item__icon" src="/static/ic_customer.png" mode="aspectFit" />
|
||
<text class="menu-item__label">联系客服</text>
|
||
<text class="menu-item__arrow">›</text>
|
||
</view>
|
||
<view class="menu-item" @click="showAbout = true">
|
||
<image class="menu-item__icon" src="/static/ic_about.png" mode="aspectFit" />
|
||
<text class="menu-item__label">关于我们</text>
|
||
<text class="menu-item__arrow">›</text>
|
||
</view>
|
||
<view class="menu-item" @click="showAgreement('user')">
|
||
<image class="menu-item__icon" src="/static/ic_agreement1.png" mode="aspectFit" />
|
||
<text class="menu-item__label">用户协议</text>
|
||
<text class="menu-item__arrow">›</text>
|
||
</view>
|
||
<view class="menu-item" @click="showAgreement('privacy')">
|
||
<image class="menu-item__icon" src="/static/ic_agreement2.png" mode="aspectFit" />
|
||
<text class="menu-item__label">隐私协议</text>
|
||
<text class="menu-item__arrow">›</text>
|
||
</view>
|
||
<view v-if="isLoggedIn" class="menu-item" @click="handleLogout">
|
||
<image class="menu-item__icon" src="/static/ic_loginout.png" mode="aspectFit" />
|
||
<text class="menu-item__label">退出登录</text>
|
||
<text class="menu-item__arrow">›</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 客服二维码弹窗 -->
|
||
<CustomerServiceBtn v-if="showQrCode" mode="qrcode" @close="showQrCode = false" />
|
||
|
||
<!-- 关于我们弹窗 -->
|
||
<view class="modal-mask" v-if="showAbout" @click="showAbout = false">
|
||
<view class="modal-popup" @click.stop>
|
||
<text class="modal-popup__title">关于我们</text>
|
||
<text class="modal-popup__content">珠宝商城 —— 专注珠宝零售,为您提供优质珠宝商品和贴心服务。</text>
|
||
<view class="modal-popup__close" @click="showAbout = false">关闭</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref } from 'vue'
|
||
import { onShow } from '@dcloudio/uni-app'
|
||
import { useUserStore } from '../../store/user'
|
||
import { getOrderList } from '../../api/order'
|
||
import CustomerServiceBtn from '../../components/CustomerServiceBtn.vue'
|
||
|
||
const userStore = useUserStore()
|
||
const showQrCode = ref(false)
|
||
const showAbout = ref(false)
|
||
const orderCount = ref(0)
|
||
const isLoggedIn = ref(false)
|
||
|
||
const statusBarHeight = ref(20)
|
||
const navBarHeight = ref(44)
|
||
try {
|
||
const sysInfo = uni.getSystemInfoSync()
|
||
statusBarHeight.value = sysInfo.statusBarHeight || 20
|
||
// #ifdef MP-WEIXIN
|
||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||
navBarHeight.value = (menuBtn.top - (sysInfo.statusBarHeight || 20)) * 2 + menuBtn.height
|
||
// #endif
|
||
} catch { /* fallback */ }
|
||
|
||
function refreshData() {
|
||
const token = uni.getStorageSync('token')
|
||
isLoggedIn.value = !!token
|
||
if (token) {
|
||
userStore.fetchProfile()
|
||
getOrderList().then((data: any) => {
|
||
orderCount.value = Array.isArray(data) ? data.length : (data?.total || 0)
|
||
}).catch(() => {})
|
||
}
|
||
}
|
||
|
||
onShow(() => {
|
||
refreshData()
|
||
})
|
||
|
||
function handleUserCardClick() {
|
||
if (!isLoggedIn.value) {
|
||
uni.navigateTo({ url: '/pages/login/index' })
|
||
}
|
||
}
|
||
|
||
function navigateTo(url: string) {
|
||
const token = uni.getStorageSync('token')
|
||
if (!token) {
|
||
uni.navigateTo({ url: '/pages/login/index' })
|
||
return
|
||
}
|
||
uni.navigateTo({ url })
|
||
}
|
||
|
||
function showAgreement(type: 'user' | 'privacy') {
|
||
const title = type === 'user' ? '用户协议' : '隐私协议'
|
||
uni.showModal({
|
||
title,
|
||
content: type === 'user'
|
||
? '欢迎使用珠宝商城小程序。使用本小程序即表示您同意遵守相关服务条款。'
|
||
: '我们重视您的隐私保护。我们仅收集必要的信息以提供服务,不会向第三方泄露您的个人信息。',
|
||
showCancel: false,
|
||
confirmText: '我知道了',
|
||
})
|
||
}
|
||
|
||
function handleLogout() {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '确定要退出登录吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
userStore.logout()
|
||
isLoggedIn.value = false
|
||
orderCount.value = 0
|
||
uni.showToast({ title: '已退出登录', icon: 'success' })
|
||
setTimeout(() => {
|
||
uni.switchTab({ url: '/pages/index/index' })
|
||
}, 1000)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.mine-page {
|
||
min-height: 100vh;
|
||
background: #f5f5f5;
|
||
}
|
||
.custom-navbar {
|
||
background: linear-gradient(to right, #FFCFDE, #FFA6C4);
|
||
}
|
||
.custom-navbar__content {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.custom-navbar__title {
|
||
font-size: 34rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
/* 用户卡片 */
|
||
.user-card {
|
||
display: flex;
|
||
align-items: center;
|
||
background: #fff;
|
||
margin: 0 24rpx;
|
||
padding: 32rpx;
|
||
border-radius: 16rpx;
|
||
}
|
||
.user-card__avatar {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 50%;
|
||
background: #f0f0f0;
|
||
flex-shrink: 0;
|
||
}
|
||
.user-card__info {
|
||
flex: 1;
|
||
margin-left: 24rpx;
|
||
}
|
||
.user-card__name {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
font-weight: bold;
|
||
}
|
||
.user-card__id {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-top: 8rpx;
|
||
display: block;
|
||
}
|
||
.user-card__arrow {
|
||
font-size: 36rpx;
|
||
color: #ccc;
|
||
}
|
||
|
||
/* 我的订单入口 */
|
||
.order-entry {
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 20rpx 24rpx 0;
|
||
padding: 24rpx 32rpx;
|
||
background: linear-gradient(135deg, #fce4ec, #f8bbd0);
|
||
border-radius: 16rpx;
|
||
}
|
||
.order-entry__icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
.order-entry__text {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: bold;
|
||
}
|
||
.order-entry__arrow {
|
||
font-size: 32rpx;
|
||
color: #999;
|
||
}
|
||
|
||
/* 功能菜单 */
|
||
.menu-group {
|
||
background: #fff;
|
||
margin: 20rpx 24rpx 0;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
}
|
||
.menu-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 30rpx 32rpx;
|
||
border-bottom: 1rpx solid #f5f5f5;
|
||
}
|
||
.menu-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
.menu-item__icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
margin-right: 20rpx;
|
||
}
|
||
.menu-item__label {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
.menu-item__arrow {
|
||
font-size: 32rpx;
|
||
color: #ccc;
|
||
}
|
||
|
||
/* 弹窗 */
|
||
.modal-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 999;
|
||
}
|
||
.modal-popup {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 40rpx;
|
||
text-align: center;
|
||
width: 560rpx;
|
||
}
|
||
.modal-popup__title {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
font-weight: bold;
|
||
display: block;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.modal-popup__content {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
line-height: 44rpx;
|
||
display: block;
|
||
}
|
||
.modal-popup__close {
|
||
margin-top: 28rpx;
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
</style>
|