rentease-app/pages/profile/profile.vue

493 lines
12 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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="profile-page">
<!-- 顶部用户信息卡片 - 简洁现代风格 -->
<view class="profile-header">
<view class="header-bg">
<view class="bg-circle circle-1"></view>
<view class="bg-circle circle-2"></view>
</view>
<view class="header-content">
<!-- 左侧用户信息 -->
<view class="user-info-section">
<view class="user-avatar">
<text class="avatar-text">{{getAvatarText(userInfo.nickname)}}</text>
</view>
<view class="user-details">
<text class="user-name">{{userInfo.nickname || '未设置昵称'}}</text>
<text class="user-phone">{{maskPhone(userInfo.phone)}}</text>
<view class="user-badge">
<uni-icons type="vip" size="12" color="#F59E0B"></uni-icons>
<text>房东版</text>
</view>
</view>
</view>
<!-- 右侧编辑按钮 -->
<view class="edit-btn" @click="editProfile">
<uni-icons type="compose" size="18" color="#667eea"></uni-icons>
</view>
</view>
</view>
<!-- 主体内容 -->
<scroll-view scroll-y class="content-area">
<!-- 计费中心 -->
<view class="section-card">
<view class="card-title">计费中心</view>
<view class="menu-list">
<view class="menu-item" @click="navigateTo('/pages/billing/billing-center')">
<view class="menu-icon primary">
<uni-icons type="vip" size="20" color="#FFFFFF"></uni-icons>
</view>
<text class="menu-label">我的套餐</text>
<view class="menu-extra">
<text class="status-tag" :class="billingStatusClass">{{billingStatusText}}</text>
</view>
<uni-icons type="right" size="14" color="#94A3B8"></uni-icons>
</view>
<view class="menu-item" @click="navigateTo('/pages/billing/order-list')">
<view class="menu-icon success">
<uni-icons type="list" size="20" color="#FFFFFF"></uni-icons>
</view>
<text class="menu-label">我的订单</text>
<uni-icons type="right" size="14" color="#94A3B8"></uni-icons>
</view>
<view class="menu-item" @click="navigateTo('/pages/billing/payment-record')">
<view class="menu-icon info">
<uni-icons type="wallet" size="20" color="#FFFFFF"></uni-icons>
</view>
<text class="menu-label">支付记录</text>
<uni-icons type="right" size="14" color="#94A3B8"></uni-icons>
</view>
</view>
</view>
<!-- 系统设置 -->
<view class="section-card">
<view class="card-title">系统设置</view>
<view class="menu-list">
<view class="menu-item" @click="navigateTo('/pages/settings/settings')">
<view class="menu-icon setting">
<uni-icons type="gear" size="20" color="#FFFFFF"></uni-icons>
</view>
<text class="menu-label">账号设置</text>
<uni-icons type="right" size="14" color="#94A3B8"></uni-icons>
</view>
<view class="menu-item" @click="navigateTo('/pages/settings/categories')">
<view class="menu-icon category">
<uni-icons type="folder-add" size="20" color="#FFFFFF"></uni-icons>
</view>
<text class="menu-label">收支类目</text>
<uni-icons type="right" size="14" color="#94A3B8"></uni-icons>
</view>
<view class="menu-item" @click="showAbout">
<view class="menu-icon about">
<uni-icons type="info" size="20" color="#FFFFFF"></uni-icons>
</view>
<text class="menu-label">关于我们</text>
<view class="menu-extra">
<text class="version-text">v{{version}}</text>
</view>
<uni-icons type="right" size="14" color="#94A3B8"></uni-icons>
</view>
</view>
</view>
<!-- 退出登录 -->
<view class="logout-area">
<button class="logout-btn" @click="logout">退出登录</button>
</view>
<view class="safe-area-bottom"></view>
</scroll-view>
</view>
</template>
<script>
import { billingApi } from '../../api/index.js'
export default {
data() {
return {
userInfo: {},
billingInfo: null,
version: '1.0.0'
}
},
onLoad() {
this.loadUserInfo()
this.loadBillingInfo()
},
onShow() {
this.loadUserInfo()
this.loadBillingInfo()
},
onPullDownRefresh() {
this.loadBillingInfo().finally(() => {
uni.stopPullDownRefresh()
})
},
computed: {
billingStatusText() {
if (!this.billingInfo) return '加载中'
const status = this.billingInfo.billingStatus
if (status === 'trial_active') return '试用期'
if (status === 'paid_active') return '付费期'
if (status === 'trial_expired' || status === 'paid_expired') return '已过期'
return '未知'
},
billingStatusClass() {
if (!this.billingInfo) return ''
const status = this.billingInfo.billingStatus
if (status === 'trial_active') return 'status-trial'
if (status === 'paid_active') return 'status-active'
if (status === 'trial_expired' || status === 'paid_expired') return 'status-expired'
return ''
}
},
methods: {
// 加载用户信息
loadUserInfo() {
const userInfo = uni.getStorageSync('userInfo') || {}
this.userInfo = userInfo
},
// 获取头像文字
getAvatarText(nickname) {
if (!nickname) return '用'
return nickname.charAt(0).toUpperCase()
},
// 掩码手机号
maskPhone(phone) {
if (!phone) return '未绑定手机号'
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
},
// 编辑个人资料
editProfile() {
uni.navigateTo({
url: '/pages/settings/settings'
})
},
// 页面导航
navigateTo(url) {
uni.navigateTo({ url })
},
// 显示关于
showAbout() {
uni.showModal({
title: '关于 RentEase',
content: `RentEase 智能租赁管理平台\n版本: v${this.version}\n\n让租赁管理更简单、更高效`,
showCancel: false
})
},
// 退出登录
logout() {
uni.showModal({
title: '确认退出',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
uni.removeStorageSync('token')
uni.removeStorageSync('userInfo')
uni.reLaunch({ url: '/pages/login/login' })
}
}
})
},
// 加载计费信息
async loadBillingInfo() {
try {
const res = await billingApi.getInfo()
if (res.code === 200) {
this.billingInfo = res.data.tenant
}
} catch (error) {
console.error('加载计费信息失败:', error)
}
}
}
}
</script>
<style scoped>
.profile-page {
min-height: 100vh;
background: #F1F5F9;
display: flex;
flex-direction: column;
}
/* 顶部 Header - 简洁现代风格 */
.profile-header {
position: relative;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 60rpx 32rpx 40rpx;
border-radius: 0 0 32rpx 32rpx;
}
.header-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
border-radius: 0 0 32rpx 32rpx;
}
.bg-circle {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.08);
}
.circle-1 {
width: 300rpx;
height: 300rpx;
top: -100rpx;
right: -80rpx;
}
.circle-2 {
width: 200rpx;
height: 200rpx;
bottom: -60rpx;
left: -60rpx;
}
.header-content {
position: relative;
z-index: 1;
display: flex;
justify-content: space-between;
align-items: center;
}
.user-info-section {
display: flex;
align-items: center;
gap: 24rpx;
}
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10rpx);
display: flex;
align-items: center;
justify-content: center;
border: 4rpx solid rgba(255, 255, 255, 0.3);
}
.avatar-text {
font-size: 48rpx;
font-weight: 700;
color: #FFFFFF;
}
.user-details {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.user-name {
font-size: 36rpx;
font-weight: 600;
color: #FFFFFF;
}
.user-phone {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.7);
}
.user-badge {
display: inline-flex;
align-items: center;
gap: 6rpx;
background: rgba(255, 255, 255, 0.2);
padding: 6rpx 16rpx;
border-radius: 20rpx;
align-self: flex-start;
}
.user-badge text {
font-size: 22rpx;
color: #FFFFFF;
font-weight: 500;
}
.edit-btn {
width: 72rpx;
height: 72rpx;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
}
.edit-btn:active {
transform: scale(0.95);
opacity: 0.9;
}
/* 内容区域 */
.content-area {
flex: 1;
padding: 24rpx;
}
/* 卡片样式 */
.section-card {
background: #FFFFFF;
border-radius: 24rpx;
padding: 28rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.card-title {
font-size: 28rpx;
font-weight: 600;
color: #1E293B;
margin-bottom: 24rpx;
padding-left: 8rpx;
}
/* 菜单列表 */
.menu-list {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.menu-item {
display: flex;
align-items: center;
padding: 24rpx 20rpx;
border-radius: 12rpx;
transition: all 0.2s ease;
}
.menu-item:active {
background: #F8FAFC;
}
.menu-icon {
width: 64rpx;
height: 64rpx;
border-radius: 14rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
flex-shrink: 0;
}
.menu-icon.primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.menu-icon.success {
background: linear-gradient(135deg, #10B981 0%, #34D399 100%);
}
.menu-icon.info {
background: linear-gradient(135deg, #3B82F6 0%, #60A5FA 100%);
}
.menu-icon.setting {
background: linear-gradient(135deg, #8B5CF6 0%, #A78BFA 100%);
}
.menu-icon.category {
background: linear-gradient(135deg, #F59E0B 0%, #FBBF24 100%);
}
.menu-icon.about {
background: linear-gradient(135deg, #6B7280 0%, #9CA3AF 100%);
}
.menu-label {
flex: 1;
font-size: 30rpx;
color: #1E293B;
font-weight: 500;
}
.menu-extra {
margin-right: 16rpx;
}
.status-tag {
font-size: 22rpx;
padding: 6rpx 16rpx;
border-radius: 8rpx;
font-weight: 500;
}
.status-trial {
background: #FEF3C7;
color: #D97706;
}
.status-active {
background: #D1FAE5;
color: #059669;
}
.status-expired {
background: #FEE2E2;
color: #DC2626;
}
.version-text {
font-size: 24rpx;
color: #94A3B8;
}
/* 退出登录 */
.logout-area {
margin-top: 32rpx;
}
.logout-btn {
width: 100%;
height: 96rpx;
background: #FFFFFF;
color: #EF4444;
font-size: 32rpx;
font-weight: 600;
border-radius: 16rpx;
border: none;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.logout-btn:active {
background: #FEF2F2;
}
.safe-area-bottom {
height: 40rpx;
}
</style>