872 lines
24 KiB
Vue
872 lines
24 KiB
Vue
<template>
|
||
<view class="profile-page">
|
||
<!-- 用户信息卡片 -->
|
||
<view class="user-card">
|
||
<view class="user-bg"></view>
|
||
<view class="user-content">
|
||
<view class="user-avatar" @click="editAvatar">
|
||
<image v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||
<view v-else class="avatar-placeholder">
|
||
<text class="avatar-text">{{getAvatarText(userInfo.nickname)}}</text>
|
||
</view>
|
||
<view class="edit-badge">
|
||
<uni-icons type="camera-filled" size="16" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
</view>
|
||
<view class="user-info" @click="editProfile">
|
||
<text class="user-name">{{userInfo.nickname || '未设置昵称'}}</text>
|
||
<text class="user-phone">{{maskPhone(userInfo.phone)}}</text>
|
||
<view class="edit-hint">
|
||
<uni-icons type="compose" size="12" color="rgba(255,255,255,0.6)"></uni-icons>
|
||
<text>点击编辑资料</text>
|
||
</view>
|
||
</view>
|
||
<view class="user-level">
|
||
<view class="level-badge">
|
||
<uni-icons type="vip-filled" size="16" color="#F59E0B"></uni-icons>
|
||
<text>房东版</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view scroll-y class="page-content" @scrolltolower="loadMoreStats">
|
||
<!-- 数据概览 -->
|
||
<view class="stats-section">
|
||
<view class="stats-card">
|
||
<view class="stat-item" @click="navigateTo('/pages/apartments/apartments')">
|
||
<text class="stat-num">{{userStats.apartments}}</text>
|
||
<text class="stat-label">公寓</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-item" @click="navigateTo('/pages/rooms/rooms')">
|
||
<text class="stat-num">{{userStats.rooms}}</text>
|
||
<text class="stat-label">房源</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-item" @click="navigateTo('/pages/renters/renters')">
|
||
<text class="stat-num">{{userStats.renters}}</text>
|
||
<text class="stat-label">租客</text>
|
||
</view>
|
||
<view class="stat-divider"></view>
|
||
<view class="stat-item" @click="navigateTo('/pages/rentals/rentals')">
|
||
<text class="stat-num">{{userStats.rentals}}</text>
|
||
<text class="stat-label">租约</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 快捷操作 -->
|
||
<view class="quick-actions">
|
||
<view class="action-grid">
|
||
<view class="action-item" @click="navigateTo('/pages/add-record/add-record')">
|
||
<view class="action-icon add">
|
||
<uni-icons type="plus-filled" size="28" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="action-text">新增租约</text>
|
||
</view>
|
||
<view class="action-item" @click="navigateTo('/pages/room-add/room-add')">
|
||
<view class="action-icon room">
|
||
<uni-icons type="home-filled" size="28" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="action-text">添加房源</text>
|
||
</view>
|
||
<view class="action-item" @click="navigateTo('/pages/bills/bills')">
|
||
<view class="action-icon bill">
|
||
<uni-icons type="wallet-filled" size="28" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="action-text">记一笔</text>
|
||
</view>
|
||
<view class="action-item" @click="navigateTo('/pages/stats/stats')">
|
||
<view class="action-icon stats">
|
||
<uni-icons type="chart-filled" size="28" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="action-text">收支统计</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 功能菜单 -->
|
||
<view class="menu-section">
|
||
<view class="menu-group">
|
||
<view class="menu-title">财务管理</view>
|
||
<view class="menu-list">
|
||
<view class="menu-item" @click="navigateTo('/pages/bills/bills')">
|
||
<view class="menu-icon bill">
|
||
<uni-icons type="list" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">账单管理</text>
|
||
<view class="menu-extra" v-if="userStats.unpaidBills > 0">
|
||
<text class="badge">{{userStats.unpaidBills}}</text>
|
||
</view>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/rentals/rentals')">
|
||
<view class="menu-icon contract">
|
||
<uni-icons type="compose" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">租约管理</text>
|
||
<view class="menu-extra" v-if="userStats.expiringRentals > 0">
|
||
<text class="badge orange">{{userStats.expiringRentals}}</text>
|
||
</view>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/meter-readings/meter-readings')">
|
||
<view class="menu-icon meter">
|
||
<uni-icons type="settings-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">抄表记录</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="menu-group">
|
||
<view class="menu-title">房源管理</view>
|
||
<view class="menu-list">
|
||
<view class="menu-item" @click="navigateTo('/pages/apartments/apartments')">
|
||
<view class="menu-icon property">
|
||
<uni-icons type="home-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">公寓管理</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/rooms/rooms')">
|
||
<view class="menu-icon room">
|
||
<uni-icons type="shop-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">房源管理</text>
|
||
<view class="menu-extra">
|
||
<text class="extra-text">{{userStats.emptyRooms}}间空房</text>
|
||
</view>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/renters/renters')">
|
||
<view class="menu-icon tenant">
|
||
<uni-icons type="personadd-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">租客管理</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="menu-group">
|
||
<view class="menu-title">计费中心</view>
|
||
<view class="menu-list">
|
||
<view class="menu-item" @click="navigateTo('/pages/billing/billing-center')">
|
||
<view class="menu-icon billing">
|
||
<uni-icons type="vip-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">我的套餐</text>
|
||
<view class="menu-extra">
|
||
<text class="billing-status" :class="billingStatusClass">{{billingStatusText}}</text>
|
||
</view>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/billing/order-list')">
|
||
<view class="menu-icon order">
|
||
<uni-icons type="list-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">我的订单</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/billing/payment-record')">
|
||
<view class="menu-icon payment">
|
||
<uni-icons type="wallet-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">支付记录</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="menu-group">
|
||
<view class="menu-title">系统设置</view>
|
||
<view class="menu-list">
|
||
<view class="menu-item" @click="navigateTo('/pages/settings/settings')">
|
||
<view class="menu-icon setting">
|
||
<uni-icons type="gear-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">账号设置</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="navigateTo('/pages/settings/categories')">
|
||
<view class="menu-icon category">
|
||
<uni-icons type="folder-add-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">收支类目</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
<view class="menu-item" @click="showAbout">
|
||
<view class="menu-icon about">
|
||
<uni-icons type="info-filled" size="24" color="#FFFFFF"></uni-icons>
|
||
</view>
|
||
<text class="menu-text">关于我们</text>
|
||
<view class="menu-extra">
|
||
<text class="version">v{{version}}</text>
|
||
<uni-icons type="right" size="16" color="#94A3B8"></uni-icons>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 退出登录 -->
|
||
<view class="logout-section">
|
||
<button class="logout-btn" @click="logout">退出登录</button>
|
||
</view>
|
||
|
||
<view class="safe-area-bottom" style="height: 40rpx;"></view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { apartmentApi, roomApi, renterApi, rentalApi, billApi, billingApi } from '../../api/index.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
userInfo: {},
|
||
userStats: {
|
||
apartments: 0,
|
||
rooms: 0,
|
||
renters: 0,
|
||
rentals: 0,
|
||
emptyRooms: 0,
|
||
unpaidBills: 0,
|
||
expiringRentals: 0
|
||
},
|
||
billingInfo: null,
|
||
version: '1.0.0',
|
||
isLoading: false
|
||
}
|
||
},
|
||
onLoad() {
|
||
this.loadUserInfo()
|
||
this.loadUserStats()
|
||
this.loadBillingInfo()
|
||
},
|
||
onShow() {
|
||
this.loadUserInfo()
|
||
this.loadUserStats()
|
||
this.loadBillingInfo()
|
||
},
|
||
onPullDownRefresh() {
|
||
this.loadUserStats().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 'trial'
|
||
if (status === 'paid_active') return 'active'
|
||
if (status === 'trial_expired' || status === 'paid_expired') return 'expired'
|
||
return ''
|
||
}
|
||
},
|
||
methods: {
|
||
// 加载用户信息
|
||
loadUserInfo() {
|
||
const userInfo = uni.getStorageSync('userInfo') || {}
|
||
this.userInfo = userInfo
|
||
},
|
||
|
||
// 加载用户统计数据
|
||
async loadUserStats() {
|
||
if (this.isLoading) return
|
||
this.isLoading = true
|
||
|
||
try {
|
||
// 并行加载所有统计数据
|
||
const [apartmentRes, roomRes, renterRes, rentalRes, billRes] = await Promise.all([
|
||
apartmentApi.list(),
|
||
roomApi.list(),
|
||
renterApi.list(),
|
||
rentalApi.list(),
|
||
billApi.list({ status: 'unpaid' })
|
||
])
|
||
|
||
const apartments = apartmentRes.data || []
|
||
const rooms = roomRes.data || []
|
||
const renters = renterRes.data || []
|
||
const rentals = rentalRes.data || []
|
||
const unpaidBills = billRes.data || []
|
||
|
||
// 计算空房数量
|
||
const emptyRooms = rooms.filter(r => r.status === 'empty').length
|
||
|
||
// 计算即将到期的租约(30天内)
|
||
const now = new Date()
|
||
const thirtyDaysLater = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)
|
||
const expiringRentals = rentals.filter(r => {
|
||
if (r.status !== 'active') return false
|
||
const endDate = new Date(r.endDate)
|
||
return endDate <= thirtyDaysLater && endDate >= now
|
||
}).length
|
||
|
||
this.userStats = {
|
||
apartments: apartments.length,
|
||
rooms: rooms.length,
|
||
renters: renters.length,
|
||
rentals: rentals.length,
|
||
emptyRooms,
|
||
unpaidBills: unpaidBills.length,
|
||
expiringRentals
|
||
}
|
||
} catch (error) {
|
||
console.error('加载统计数据失败:', error)
|
||
} finally {
|
||
this.isLoading = false
|
||
}
|
||
},
|
||
|
||
// 获取头像文字
|
||
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')
|
||
},
|
||
|
||
// 编辑头像
|
||
editAvatar() {
|
||
uni.showActionSheet({
|
||
itemList: ['拍照', '从相册选择'],
|
||
success: (res) => {
|
||
const sourceType = res.tapIndex === 0 ? ['camera'] : ['album']
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sourceType,
|
||
success: (res) => {
|
||
this.uploadAvatar(res.tempFilePaths[0])
|
||
}
|
||
})
|
||
}
|
||
})
|
||
},
|
||
|
||
// 上传头像
|
||
async uploadAvatar(filePath) {
|
||
uni.showLoading({ title: '上传中...' })
|
||
try {
|
||
// 这里应该调用实际上传接口
|
||
// const uploadRes = await uploadFile(filePath)
|
||
// this.userInfo.avatar = uploadRes.url
|
||
|
||
// 模拟上传成功
|
||
this.userInfo.avatar = filePath
|
||
uni.setStorageSync('userInfo', this.userInfo)
|
||
|
||
uni.showToast({ title: '头像更新成功', icon: 'success' })
|
||
} catch (error) {
|
||
uni.showToast({ title: '上传失败', icon: 'none' })
|
||
} finally {
|
||
uni.hideLoading()
|
||
}
|
||
},
|
||
|
||
// 编辑个人资料
|
||
editProfile() {
|
||
uni.navigateTo({
|
||
url: '/pages/profile-edit/profile-edit'
|
||
})
|
||
},
|
||
|
||
// 页面导航
|
||
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' })
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
// 加载更多统计
|
||
loadMoreStats() {
|
||
// 可以在这里加载更多历史统计数据
|
||
},
|
||
|
||
// 加载计费信息
|
||
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: #F8FAFC;
|
||
display: flex;
|
||
flex-direction: column;
|
||
width: 100%;
|
||
max-width: 100vw;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
/* 用户卡片 */
|
||
.user-card {
|
||
position: relative;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
padding: 40rpx 32rpx 80rpx;
|
||
border-radius: 0 0 40rpx 40rpx;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.user-bg {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
overflow: hidden;
|
||
border-radius: 0 0 40rpx 40rpx;
|
||
}
|
||
|
||
.user-bg::before {
|
||
content: '';
|
||
position: absolute;
|
||
width: 400rpx;
|
||
height: 400rpx;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
border-radius: 50%;
|
||
top: -100rpx;
|
||
right: -100rpx;
|
||
}
|
||
|
||
.user-bg::after {
|
||
content: '';
|
||
position: absolute;
|
||
width: 300rpx;
|
||
height: 300rpx;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
border-radius: 50%;
|
||
bottom: -50rpx;
|
||
left: -50rpx;
|
||
}
|
||
|
||
.user-content {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
.user-avatar {
|
||
position: relative;
|
||
width: 160rpx;
|
||
height: 160rpx;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
border: 6rpx solid rgba(255, 255, 255, 0.3);
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.user-avatar image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.avatar-placeholder {
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.avatar-text {
|
||
font-size: 64rpx;
|
||
font-weight: 700;
|
||
color: #FFFFFF;
|
||
}
|
||
|
||
.edit-badge {
|
||
position: absolute;
|
||
bottom: 0;
|
||
right: 0;
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
background: #667eea;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: 4rpx solid #FFFFFF;
|
||
}
|
||
|
||
.user-info {
|
||
text-align: center;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.user-name {
|
||
display: block;
|
||
font-size: 40rpx;
|
||
font-weight: 700;
|
||
color: #FFFFFF;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.user-phone {
|
||
display: block;
|
||
font-size: 26rpx;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.edit-hint {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8rpx;
|
||
font-size: 22rpx;
|
||
color: rgba(255, 255, 255, 0.6);
|
||
}
|
||
|
||
.level-badge {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8rpx;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
padding: 12rpx 24rpx;
|
||
border-radius: 30rpx;
|
||
font-size: 24rpx;
|
||
color: #FFFFFF;
|
||
}
|
||
|
||
/* 页面内容 */
|
||
.page-content {
|
||
flex: 1;
|
||
padding: 0 32rpx;
|
||
margin-top: -50rpx;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 统计区域 */
|
||
.stats-section {
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.stats-card {
|
||
background: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
padding: 32rpx 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.stat-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 0 16rpx;
|
||
}
|
||
|
||
.stat-num {
|
||
font-size: 40rpx;
|
||
font-weight: 700;
|
||
color: #667eea;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 24rpx;
|
||
color: #64748B;
|
||
}
|
||
|
||
.stat-divider {
|
||
width: 2rpx;
|
||
height: 60rpx;
|
||
background: #E2E8F0;
|
||
}
|
||
|
||
/* 快捷操作 */
|
||
.quick-actions {
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.action-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 24rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
padding: 32rpx 24rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.action-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.action-icon {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.action-icon.add {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
}
|
||
|
||
.action-icon.room {
|
||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||
}
|
||
|
||
.action-icon.bill {
|
||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||
}
|
||
|
||
.action-icon.stats {
|
||
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
|
||
}
|
||
|
||
.action-text {
|
||
font-size: 24rpx;
|
||
color: #1E293B;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 菜单区域 */
|
||
.menu-section {
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.menu-group {
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.menu-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #94A3B8;
|
||
margin-bottom: 16rpx;
|
||
padding-left: 16rpx;
|
||
}
|
||
|
||
.menu-list {
|
||
background: #FFFFFF;
|
||
border-radius: 24rpx;
|
||
overflow: hidden;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.menu-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 28rpx 32rpx;
|
||
border-bottom: 2rpx solid #F8FAFC;
|
||
}
|
||
|
||
.menu-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.menu-item:active {
|
||
background: #F8FAFC;
|
||
}
|
||
|
||
.menu-icon {
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
border-radius: 14rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 24rpx;
|
||
}
|
||
|
||
.menu-icon.bill {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
}
|
||
|
||
.menu-icon.contract {
|
||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||
}
|
||
|
||
.menu-icon.meter {
|
||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||
}
|
||
|
||
.menu-icon.property {
|
||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||
}
|
||
|
||
.menu-icon.room {
|
||
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
|
||
}
|
||
|
||
.menu-icon.tenant {
|
||
background: linear-gradient(135deg, #30cfd0 0%, #330867 100%);
|
||
}
|
||
|
||
.menu-icon.setting {
|
||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||
}
|
||
|
||
.menu-icon.category {
|
||
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
|
||
}
|
||
|
||
.menu-icon.about {
|
||
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
|
||
}
|
||
|
||
.menu-icon.billing {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
}
|
||
|
||
.menu-icon.order {
|
||
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
|
||
}
|
||
|
||
.menu-icon.payment {
|
||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||
}
|
||
|
||
.billing-status {
|
||
font-size: 24rpx;
|
||
padding: 6rpx 16rpx;
|
||
border-radius: 8rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.billing-status.trial {
|
||
background: #FEF3C7;
|
||
color: #D97706;
|
||
}
|
||
|
||
.billing-status.active {
|
||
background: #D1FAE5;
|
||
color: #059669;
|
||
}
|
||
|
||
.billing-status.expired {
|
||
background: #FEE2E2;
|
||
color: #DC2626;
|
||
}
|
||
|
||
.menu-text {
|
||
flex: 1;
|
||
font-size: 30rpx;
|
||
color: #1E293B;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.menu-extra {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.extra-text {
|
||
font-size: 26rpx;
|
||
color: #667eea;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.badge {
|
||
min-width: 36rpx;
|
||
height: 36rpx;
|
||
background: #EF4444;
|
||
color: #FFFFFF;
|
||
font-size: 20rpx;
|
||
font-weight: 600;
|
||
border-radius: 18rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0 10rpx;
|
||
}
|
||
|
||
.badge.orange {
|
||
background: #F59E0B;
|
||
}
|
||
|
||
.version {
|
||
font-size: 26rpx;
|
||
color: #94A3B8;
|
||
}
|
||
|
||
/* 退出登录 */
|
||
.logout-section {
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.logout-btn {
|
||
width: 100%;
|
||
height: 96rpx;
|
||
background: #FEE2E2;
|
||
color: #EF4444;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
border-radius: 16rpx;
|
||
border: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.logout-btn:active {
|
||
background: #FECACA;
|
||
}
|
||
</style>
|