Files
uni-fans-score/subPackages/user/user/index.vue
T
2026-02-06 18:09:23 +08:00

240 lines
5.5 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="container">
<!-- 用户信息卡片 -->
<view class="user-card">
<view class="avatar">
<image :src="userInfo.avatar || '/static/images/default-avatar.png'" mode="aspectFill"></image>
</view>
<view class="user-info">
<text class="nickname">{{ userInfo.nickName || $t('user.notLoggedIn') }}</text>
<text class="phone">{{ userInfo.phone || $t('user.phoneNotBound') }}</text>
</view>
</view>
<!-- 余额卡片 -->
<view class="balance-card">
<view class="balance-title">{{ $t('userProfile.balance') }}</view>
<view class="balance-amount">{{ userInfo.balanceAmount || '0.00' }}</view>
<view class="balance-desc">{{ $t('user.balanceDesc') }}</view>
</view>
<!-- 功能菜单 -->
<view class="menu-list">
<view class="menu-item" @click="navigateTo('/pages/order/index')">
<text class="menu-icon">📋</text>
<text class="menu-text">{{ $t('user.myOrders') }}</text>
<text class="menu-arrow">></text>
</view>
<view class="menu-item" @click="navigateTo('/pages/feedback/index')">
<text class="menu-icon">💬</text>
<text class="menu-text">{{ $t('user.feedback') }}</text>
<text class="menu-arrow">></text>
</view>
<view class="menu-item" @click="navigateTo('/pages/help/index')">
<text class="menu-icon"></text>
<text class="menu-text">{{ $t('help.title') }}</text>
<text class="menu-arrow">></text>
</view>
</view>
<!-- 退出登录按钮 -->
<view class="logout-btn" @click="handleLogout" v-if="isLogin">
<text>{{ $t('user.logout') }}</text>
</view>
</view>
</template>
<script>
import { getUserInfo } from '@/util/index.js'
import { URL } from '@/config/url'
export default {
data() {
return {
userInfo: {},
isLogin: false
}
},
onLoad() {
// 设置页面标题
uni.setNavigationBarTitle({
title: this.$t('user.personalCenter')
})
},
onShow() {
this.loadUserInfo()
},
methods: {
async loadUserInfo() {
try {
const res = await getUserInfo()
if (res.code === 401 || res.code === 40101) {
// 无提示跳转至登录
try {
const pages = getCurrentPages()
const current = pages && pages.length ? pages[pages.length - 1] : null
const route = current && current.route ? ('/' + current.route) : '/pages/index/index'
const query = current && current.options ? Object.keys(current.options).map(k => `${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
uni.reLaunch({ url: `/pages/login/index?redirect=${redirect}` })
} catch (e) {
uni.reLaunch({ url: '/pages/login/index' })
}
} else if (res.code === 200) {
this.userInfo = res.data
this.isLogin = true
} else {
this.isLogin = false
}
} catch (error) {
console.error('加载用户信息失败:', error)
this.isLogin = false
}
},
navigateTo(url) {
uni.navigateTo({ url })
},
handleLogout() {
uni.showModal({
title: this.$t('common.tips'),
content: this.$t('user.confirmLogout'),
success: (res) => {
if (res.confirm) {
uni.removeStorageSync('token')
uni.removeStorageSync('userInfo')
this.isLogin = false
uni.showToast({
title: this.$t('user.logoutSuccess'),
icon: 'success'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/login/index'
})
}, 500)
}
}
})
}
}
}
</script>
<style>
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.user-card {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
display: flex;
align-items: center;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 60rpx;
overflow: hidden;
margin-right: 30rpx;
}
.avatar image {
width: 100%;
height: 100%;
}
.user-info {
flex: 1;
}
.nickname {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
display: block;
}
.phone {
font-size: 28rpx;
color: #666;
}
.balance-card {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.balance-title {
font-size: 28rpx;
color: #666;
margin-bottom: 20rpx;
}
.balance-amount {
font-size: 48rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.balance-desc {
font-size: 24rpx;
color: #999;
}
.menu-list {
background-color: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.menu-item {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.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: 28rpx;
color: #999;
}
.logout-btn {
margin-top: 40rpx;
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
text-align: center;
color: #ff4d4f;
font-size: 28rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
</style>