1139 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			1139 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<template>
 | 
						||
	<view class="profile-page">
 | 
						||
		<!-- 移动设备顶部状态栏 -->
 | 
						||
		<view class="top_bar flex w-full" v-if="isMobile">
 | 
						||
			<view class="chat-header">
 | 
						||
				<view class="header-left">
 | 
						||
					<i class="fas fa-bell header-icon" @click="handleNotification"></i>
 | 
						||
				</view>
 | 
						||
				<view class="header-title">我的</view>
 | 
						||
				<view class="header-right">
 | 
						||
					<i class="fas fa-search header-icon" @click="handleSearch"></i>
 | 
						||
				</view>
 | 
						||
			</view>
 | 
						||
		</view>
 | 
						||
		<!-- 浏览器环境顶部导航栏 -->
 | 
						||
		<view class="unified-header" v-else>
 | 
						||
			<view class="header-content">
 | 
						||
				<view class="header-left">
 | 
						||
					<i class="fas fa-bell header-icon" @click="handleNotification"></i>
 | 
						||
				</view>
 | 
						||
				<view class="header-title">我的</view>
 | 
						||
				<view class="header-right">
 | 
						||
					<i class="fas fa-search header-icon" @click="handleSearch"></i>
 | 
						||
				</view>
 | 
						||
			</view>
 | 
						||
		</view>
 | 
						||
		
 | 
						||
		<!-- 页面内容 -->
 | 
						||
		<scroll-view scroll-y class="unified-content">
 | 
						||
			<!-- 个人信息卡片 -->
 | 
						||
			<view class="profile-card">
 | 
						||
				<!-- 已登录状态 -->
 | 
						||
				<view v-if="isLogin" class="profile-content">
 | 
						||
					<view class="profile-header" @click="editProfile">
 | 
						||
						<view class="profile-avatar">
 | 
						||
							<view class="avatar">
 | 
						||
								<text class="avatar-text">{{(userInfo.nickname || '未').charAt(0)}}</text>
 | 
						||
							</view>
 | 
						||
							<view class="edit-icon">
 | 
						||
								<i class="fas fa-camera"></i>
 | 
						||
							</view>
 | 
						||
						</view>
 | 
						||
						<view class="profile-info">
 | 
						||
							<text class="profile-name">{{userInfo.nickname || '未登录'}}</text>
 | 
						||
							<text class="profile-dept">{{userInfo.dept?.name || '未知部门'}}</text>
 | 
						||
							<text class="profile-id">工号:{{userInfo.employeeId || 'N/A'}}</text>
 | 
						||
						</view>
 | 
						||
						<view class="profile-arrow">
 | 
						||
							<i class="fas fa-chevron-right"></i>
 | 
						||
						</view>
 | 
						||
					</view>
 | 
						||
					<!-- {
 | 
						||
    "id": 1,
 | 
						||
    "username": "admin",
 | 
						||
    "nickname": "江苏美天智能科技",
 | 
						||
    "email": "admin@126.com",
 | 
						||
    "mobile": "18888888888",
 | 
						||
    "sex": 1,
 | 
						||
    "avatar": "http://demo1.meteteme.top/admin-api/infra/file/4/get/5d6c4478d03b3f0971269e3f13ce8984221623f089248d1fb6069dbfcd8baf5e.png",
 | 
						||
    "loginIp": "218.92.65.85",
 | 
						||
    "loginDate": 1760610192000,
 | 
						||
    "createTime": 1609837427000,
 | 
						||
    "roles": [
 | 
						||
        {
 | 
						||
            "id": 1,
 | 
						||
            "name": "超级管理员"
 | 
						||
        },
 | 
						||
        {
 | 
						||
            "id": 2,
 | 
						||
            "name": "普通角色"
 | 
						||
        },
 | 
						||
        {
 | 
						||
            "id": 3,
 | 
						||
            "name": "CRM 管理员"
 | 
						||
        }
 | 
						||
    ],
 | 
						||
    "dept": {
 | 
						||
        "id": 100,
 | 
						||
        "name": "江苏美天智能科技有限公司",
 | 
						||
        "parentId": 0
 | 
						||
    },
 | 
						||
    "posts": [
 | 
						||
        {
 | 
						||
            "id": 1,
 | 
						||
            "name": "董事长"
 | 
						||
        },
 | 
						||
        {
 | 
						||
            "id": 5,
 | 
						||
            "name": "部门主管"
 | 
						||
        }
 | 
						||
    ],
 | 
						||
    "socialUsers": []
 | 
						||
} -->
 | 
						||
 | 
						||
					<!-- 数据统计 -->
 | 
						||
					<view class="stats-grid">
 | 
						||
						<view class="stat-item" @click="goToAttendance">
 | 
						||
							<view class="stat-content">
 | 
						||
								<text class="stat-number">{{ userInfo.attendanceRate ?? 0 }}%</text>
 | 
						||
								<text class="stat-label">考勤率</text>
 | 
						||
							</view>
 | 
						||
						</view>
 | 
						||
						<view class="stat-item" @click="goToTasks">
 | 
						||
							<view class="stat-content">
 | 
						||
								<text class="stat-number">{{ userInfo.completedTasks ?? 0 }}</text>
 | 
						||
								<text class="stat-label">待完成</text>
 | 
						||
							</view>
 | 
						||
						</view>
 | 
						||
						<view class="stat-item" @click="goToReimbursement">
 | 
						||
							<view class="stat-content">
 | 
						||
								<text class="stat-number">¥{{ (userInfo.pendingAmount !== undefined && userInfo.pendingAmount !== null) ? userInfo.pendingAmount.toFixed(2) : '0.00' }}</text>
 | 
						||
								<text class="stat-label">待报销</text>
 | 
						||
							</view>
 | 
						||
						</view>
 | 
						||
					</view>
 | 
						||
				</view>
 | 
						||
 | 
						||
				<!-- 未登录状态 -->
 | 
						||
				<view v-else class="login-prompt">
 | 
						||
					<view class="login-icon">
 | 
						||
						<i class="fas fa-user-circle"></i>
 | 
						||
					</view>
 | 
						||
					<view class="login-content">
 | 
						||
						<text class="login-title">请先登录</text>
 | 
						||
						<text class="login-desc">登录后查看个人信息和工作数据</text>
 | 
						||
					</view>
 | 
						||
					<view class="login-btn" @click="goToLogin">
 | 
						||
						<text class="login-btn-text">立即登录</text>
 | 
						||
						<i class="fas fa-arrow-right"></i>
 | 
						||
					</view>
 | 
						||
				</view>
 | 
						||
			</view>
 | 
						||
 | 
						||
			<!-- 功能设置卡片 -->
 | 
						||
			<view class="functions-card">
 | 
						||
				<view class="card-header">
 | 
						||
					<text class="card-title">功能设置</text>
 | 
						||
				</view>
 | 
						||
				<view class="module-grid">
 | 
						||
					<view class="module-item" @click="toggleMessageSwitch">
 | 
						||
						<view class="module-icon" :style="getMessageIconStyle()">
 | 
						||
							<i :class="getMessageIcon()"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">消息提醒</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="themeSettings">
 | 
						||
						<view class="module-icon" :style="getThemeIconStyle()">
 | 
						||
							<i :class="getThemeIcon()"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">主题切换</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="changePassword">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #FF6B6B 0%, #e17055 100%)">
 | 
						||
							<i class="fas fa-lock"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">修改密码</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="bindPhone">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #4ECDC4 0%, #26c6da 100%)">
 | 
						||
							<i class="fas fa-mobile-alt"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">绑定手机</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="showCacheInfo">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #FECA57 0%, #f9d423 100%)">
 | 
						||
							<i class="fas fa-trash-alt"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">清除缓存</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="showVersionInfo">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #FF6B6B 0%, #e17055 100%)">
 | 
						||
							<i class="fas fa-sync-alt"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">版本更新</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item none"></view>
 | 
						||
					<view class="module-item none"></view>
 | 
						||
					<view class="module-item none"></view>
 | 
						||
					<view class="module-item none"></view>
 | 
						||
				</view>
 | 
						||
			</view>
 | 
						||
 | 
						||
			<!-- 帮助与反馈卡片 -->
 | 
						||
			<view class="help-card">
 | 
						||
				<view class="card-header">
 | 
						||
					<text class="card-title">帮助与反馈</text>
 | 
						||
				</view>
 | 
						||
				<view class="module-grid">
 | 
						||
					<view class="module-item" @click="showFAQ">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #4ECDC4 0%, #26c6da 100%)">
 | 
						||
							<i class="fas fa-question-circle"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">常见问题</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="feedback">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #45B7D1 0%, #168aad 100%)">
 | 
						||
							<i class="fas fa-comment-dots"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">意见反馈</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="contactService">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #96CEB4 0%, #3ad29f 100%)">
 | 
						||
							<i class="fas fa-headset"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">客服联系</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item none"></view>
 | 
						||
					<view class="module-item none"></view>
 | 
						||
				</view>
 | 
						||
			</view>
 | 
						||
 | 
						||
			<!-- 账号管理卡片 -->
 | 
						||
			<view class="account-card">
 | 
						||
				<view class="card-header">
 | 
						||
					<text class="card-title">账号管理</text>
 | 
						||
				</view>
 | 
						||
				<view class="module-grid">
 | 
						||
					<view class="module-item" @click="handleLogout">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #95a5a6 0%, #7f8c8d 100%)">
 | 
						||
							<i class="fas fa-sign-out-alt"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">退出登录</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item" @click="accountLogout">
 | 
						||
						<view class="module-icon" style="background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%)">
 | 
						||
							<i class="fas fa-user-slash"></i>
 | 
						||
						</view>
 | 
						||
						<text class="module-name">账号注销</text>
 | 
						||
					</view>
 | 
						||
 | 
						||
					<view class="module-item none"></view>
 | 
						||
					<view class="module-item none"></view>
 | 
						||
					<view class="module-item none"></view>
 | 
						||
				</view>
 | 
						||
			</view>
 | 
						||
		</scroll-view>
 | 
						||
	</view>
 | 
						||
</template>
 | 
						||
 | 
						||
<script>
 | 
						||
import { ref, reactive, computed, onMounted } from 'vue'
 | 
						||
import { useAuthStore } from '../../src/store/authStore.js'
 | 
						||
import { redirectAfterLogout } from '../../src/utils/routeGuard.js'
 | 
						||
 | 
						||
export default {
 | 
						||
	setup() {
 | 
						||
		const authStore = useAuthStore()
 | 
						||
		
 | 
						||
		// 响应式数据
 | 
						||
		const unreadCount = ref(2)
 | 
						||
		const messageEnabled = ref(true)
 | 
						||
		const currentTheme = ref('浅色模式')
 | 
						||
		const cacheSize = ref('12.5MB')
 | 
						||
		const appVersion = ref('v1.0.0')
 | 
						||
 | 
						||
		// 用户信息 - 从 Pinia store 获取
 | 
						||
		const userInfo = computed(() => {
 | 
						||
			return authStore.userInfo || {
 | 
						||
				nickname: '未登录',
 | 
						||
				name: '未登录',
 | 
						||
				department: '未知部门',
 | 
						||
				dept: { name: '未知部门' },
 | 
						||
				employeeId: 'N/A',
 | 
						||
				avatar: 'static\\imgs\\default_avatar.png',
 | 
						||
				attendanceRate: 0,
 | 
						||
				completedTasks: 0,
 | 
						||
				pendingAmount: '0'
 | 
						||
			}
 | 
						||
		})
 | 
						||
 | 
						||
		// 登录状态
 | 
						||
		const isLogin = computed(() => {
 | 
						||
			return authStore.isAuthenticated
 | 
						||
		})
 | 
						||
 | 
						||
		// 设备检测
 | 
						||
		const isMobile = computed(() => {
 | 
						||
			return getApp().globalData.isMobile
 | 
						||
		})
 | 
						||
 | 
						||
		// 方法
 | 
						||
		const handleSearch = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '搜索功能',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const handleNotification = () => {
 | 
						||
			uni.switchTab({
 | 
						||
				url: '/pages/message/message'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const editProfile = () => {
 | 
						||
			// 跳转到编辑个人资料页面
 | 
						||
			uni.navigateTo({
 | 
						||
				url: '/pages/profile/editprofile'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const goToAttendance = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '查看考勤详情',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const goToTasks = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '查看任务详情',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const goToReimbursement = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '查看报销详情',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const changePassword = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '修改密码',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const bindPhone = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '绑定手机',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const accountLogout = () => {
 | 
						||
			uni.showModal({
 | 
						||
				title: '确认注销',
 | 
						||
				content: '注销后账号将无法恢复,确定要注销吗?',
 | 
						||
				success: (res) => {
 | 
						||
					if (res.confirm) {
 | 
						||
						uni.showToast({
 | 
						||
							title: '账号注销成功',
 | 
						||
							icon: 'none'
 | 
						||
						})
 | 
						||
					}
 | 
						||
				}
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		// 登出功能
 | 
						||
		const handleLogout = () => {
 | 
						||
			uni.showModal({
 | 
						||
				title: '确认登出',
 | 
						||
				content: '确定要退出登录吗?',
 | 
						||
				success: (res) => {
 | 
						||
					if (res.confirm) {
 | 
						||
						// 使用 Pinia store 登出
 | 
						||
						authStore.logout()
 | 
						||
						
 | 
						||
						uni.showToast({
 | 
						||
							title: '已退出登录',
 | 
						||
							icon: 'success'
 | 
						||
						})
 | 
						||
						
 | 
						||
						// 跳转到登录页面
 | 
						||
						setTimeout(() => {
 | 
						||
							redirectAfterLogout()
 | 
						||
						}, 500)
 | 
						||
					}
 | 
						||
				}
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		// 跳转到登录页面
 | 
						||
		const goToLogin = () => {
 | 
						||
			uni.navigateTo({
 | 
						||
				url: '/pages/login/index'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const messageSettings = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '消息设置',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const toggleMessage = (value) => {
 | 
						||
			uni.showToast({
 | 
						||
				title: value ? '消息提醒已开启' : '消息提醒已关闭',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const themeSettings = () => {
 | 
						||
			uni.showActionSheet({
 | 
						||
				itemList: ['浅色模式', '深色模式', '跟随系统'],
 | 
						||
				success: (res) => {
 | 
						||
					const themes = ['浅色模式', '深色模式', '跟随系统']
 | 
						||
					currentTheme.value = themes[res.tapIndex]
 | 
						||
					uni.showToast({
 | 
						||
						title: `已切换到${themes[res.tapIndex]}`,
 | 
						||
						icon: 'none'
 | 
						||
					})
 | 
						||
				}
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const clearCache = () => {
 | 
						||
			uni.showModal({
 | 
						||
				title: '清除缓存',
 | 
						||
				content: '确定要清除应用缓存吗?',
 | 
						||
				success: (res) => {
 | 
						||
					if (res.confirm) {
 | 
						||
						cacheSize.value = '0MB'
 | 
						||
						uni.showToast({
 | 
						||
							title: '缓存清除成功',
 | 
						||
							icon: 'none'
 | 
						||
						})
 | 
						||
					}
 | 
						||
				}
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const checkUpdate = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '检查更新中...',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
			setTimeout(() => {
 | 
						||
				uni.showToast({
 | 
						||
					title: '已是最新版本',
 | 
						||
					icon: 'none'
 | 
						||
				})
 | 
						||
			}, 2000)
 | 
						||
		}
 | 
						||
 | 
						||
		const showFAQ = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '常见问题',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const feedback = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '意见反馈',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const contactService = () => {
 | 
						||
			uni.showToast({
 | 
						||
				title: '客服联系',
 | 
						||
				icon: 'none'
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		const toggleSwitch = () => {
 | 
						||
			messageEnabled.value = !messageEnabled.value
 | 
						||
			toggleMessage(messageEnabled.value)
 | 
						||
		}
 | 
						||
 | 
						||
		// 获取主题图标
 | 
						||
		const getThemeIcon = () => {
 | 
						||
			const themeIcons = {
 | 
						||
				'浅色模式': 'fas fa-sun',
 | 
						||
				'深色模式': 'fas fa-moon',
 | 
						||
				'跟随系统': 'fas fa-desktop'
 | 
						||
			}
 | 
						||
			return themeIcons[currentTheme.value] || 'fas fa-palette'
 | 
						||
		}
 | 
						||
 | 
						||
		// 获取主题图标背景样式
 | 
						||
		const getThemeIconStyle = () => {
 | 
						||
			const themeStyles = {
 | 
						||
				'浅色模式': 'background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%)', // 金黄色渐变
 | 
						||
				'深色模式': 'background: linear-gradient(135deg, #4A4A4A 0%, #2C2C2C 100%)', // 深灰色渐变
 | 
						||
				'跟随系统': 'background: linear-gradient(135deg, #96CEB4 0%, #3ad29f 100%)' // 绿色渐变
 | 
						||
			}
 | 
						||
			return themeStyles[currentTheme.value] || 'background: linear-gradient(135deg, #96CEB4 0%, #3ad29f 100%)'
 | 
						||
		}
 | 
						||
 | 
						||
		// 获取消息提醒图标
 | 
						||
		const getMessageIcon = () => {
 | 
						||
			return messageEnabled.value ? 'fas fa-bell' : 'fas fa-bell-slash'
 | 
						||
		}
 | 
						||
 | 
						||
		// 获取消息提醒图标背景样式
 | 
						||
		const getMessageIconStyle = () => {
 | 
						||
			return messageEnabled.value 
 | 
						||
				? 'background: linear-gradient(135deg, #45B7D1 0%, #168aad 100%)' // 开启状态:蓝色渐变
 | 
						||
				: 'background: linear-gradient(135deg, #95a5a6 0%, #7f8c8d 100%)' // 关闭状态:灰色渐变
 | 
						||
		}
 | 
						||
 | 
						||
		// 切换消息提醒状态
 | 
						||
		const toggleMessageSwitch = () => {
 | 
						||
			messageEnabled.value = !messageEnabled.value
 | 
						||
			toggleMessage(messageEnabled.value)
 | 
						||
		}
 | 
						||
 | 
						||
		// 显示缓存信息弹窗
 | 
						||
		const showCacheInfo = () => {
 | 
						||
			uni.showModal({
 | 
						||
				title: '缓存信息',
 | 
						||
				content: `当前缓存大小:${cacheSize.value}\n\n点击确定清除缓存`,
 | 
						||
				confirmText: '清除缓存',
 | 
						||
				cancelText: '取消',
 | 
						||
				success: (res) => {
 | 
						||
					if (res.confirm) {
 | 
						||
						clearCache()
 | 
						||
					}
 | 
						||
				}
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		// 显示版本信息弹窗
 | 
						||
		const showVersionInfo = () => {
 | 
						||
			uni.showModal({
 | 
						||
				title: '版本信息',
 | 
						||
				content: `当前版本:${appVersion.value}\n\n点击确定检查更新`,
 | 
						||
				confirmText: '检查更新',
 | 
						||
				cancelText: '取消',
 | 
						||
				success: (res) => {
 | 
						||
					if (res.confirm) {
 | 
						||
						checkUpdate()
 | 
						||
					}
 | 
						||
				}
 | 
						||
			})
 | 
						||
		}
 | 
						||
 | 
						||
		return {
 | 
						||
			unreadCount,
 | 
						||
			messageEnabled,
 | 
						||
			currentTheme,
 | 
						||
			cacheSize,
 | 
						||
			appVersion,
 | 
						||
			userInfo,
 | 
						||
			isLogin,
 | 
						||
			isMobile,
 | 
						||
			handleSearch,
 | 
						||
			handleNotification,
 | 
						||
			editProfile,
 | 
						||
			goToAttendance,
 | 
						||
			goToTasks,
 | 
						||
			goToReimbursement,
 | 
						||
			changePassword,
 | 
						||
			bindPhone,
 | 
						||
			accountLogout,
 | 
						||
			handleLogout,
 | 
						||
			goToLogin,
 | 
						||
			messageSettings,
 | 
						||
			toggleMessage,
 | 
						||
			themeSettings,
 | 
						||
			clearCache,
 | 
						||
			checkUpdate,
 | 
						||
			showFAQ,
 | 
						||
			feedback,
 | 
						||
			contactService,
 | 
						||
			toggleSwitch,
 | 
						||
			getThemeIcon,
 | 
						||
			getThemeIconStyle,
 | 
						||
			getMessageIcon,
 | 
						||
			getMessageIconStyle,
 | 
						||
			toggleMessageSwitch,
 | 
						||
			showCacheInfo,
 | 
						||
			showVersionInfo
 | 
						||
		}
 | 
						||
	}
 | 
						||
}
 | 
						||
</script>
 | 
						||
 | 
						||
<style lang="scss" scoped>
 | 
						||
.profile-page {
 | 
						||
	min-height: 100vh;
 | 
						||
	width: 100%;
 | 
						||
	background-color: var(--background);
 | 
						||
	box-sizing: border-box;
 | 
						||
}
 | 
						||
 | 
						||
/* 浏览器环境下的顶部间距 */
 | 
						||
.unified-header + .unified-content {
 | 
						||
	margin-top: calc(var(--status-bar-height) + 88rpx);
 | 
						||
	padding-top: 30rpx;
 | 
						||
}
 | 
						||
 | 
						||
/* 支持安全区域的设备 - 移动设备不需要额外的 padding-top,因为使用了 top_bar */
 | 
						||
 | 
						||
/* 移动设备顶部状态栏 */
 | 
						||
.top_bar {
 | 
						||
	background: var(--gradient-primary);
 | 
						||
	box-shadow: var(--shadow-lg);
 | 
						||
	z-index: 9999;
 | 
						||
	position: fixed;
 | 
						||
	top: 0;
 | 
						||
	left: 0;
 | 
						||
	right: 0;
 | 
						||
	height: calc(var(--status-bar-height) + 88rpx);
 | 
						||
	display: flex;
 | 
						||
	align-items: flex-end;
 | 
						||
	padding-top: var(--status-bar-height);
 | 
						||
	box-sizing: border-box;
 | 
						||
}
 | 
						||
 | 
						||
/* 支持安全区域的设备 */
 | 
						||
@supports (padding: max(0px)) {
 | 
						||
  .top_bar {
 | 
						||
    height: calc(var(--status-bar-height) + 88rpx + env(safe-area-inset-top));
 | 
						||
    padding-top: calc(var(--status-bar-height) + env(safe-area-inset-top));
 | 
						||
  }
 | 
						||
  
 | 
						||
  .top_bar + .unified-content {
 | 
						||
    margin-top: calc(var(--status-bar-height) + 88rpx + env(safe-area-inset-top));
 | 
						||
    padding-top: 30rpx;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
/* 移动设备下的导航栏样式 */
 | 
						||
.top_bar .chat-header {
 | 
						||
	background: transparent;
 | 
						||
	border-bottom: none;
 | 
						||
	box-shadow: none;
 | 
						||
	width: 100%;
 | 
						||
	height: 88rpx;
 | 
						||
	padding: 0 20rpx;
 | 
						||
	box-sizing: border-box;
 | 
						||
	display: flex;
 | 
						||
	justify-content: space-between;
 | 
						||
	align-items: center;
 | 
						||
}
 | 
						||
 | 
						||
.top_bar .header-title {
 | 
						||
	color: var(--white);
 | 
						||
	font-weight: 600;
 | 
						||
	font-size: 36rpx;
 | 
						||
}
 | 
						||
 | 
						||
.top_bar .header-left i,
 | 
						||
.top_bar .header-right i {
 | 
						||
	color: var(--white);
 | 
						||
	font-size: 32rpx;
 | 
						||
}
 | 
						||
 | 
						||
.top_bar .header-icon {
 | 
						||
	font-size: 32rpx;
 | 
						||
	color: var(--white);
 | 
						||
}
 | 
						||
 | 
						||
.header-left,
 | 
						||
.header-right {
 | 
						||
	width: 80rpx;
 | 
						||
	height: 88rpx;
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: center;
 | 
						||
	transition: background-color 0.2s ease;
 | 
						||
}
 | 
						||
 | 
						||
.top_bar .header-left:active,
 | 
						||
.top_bar .header-right:active {
 | 
						||
	background-color: rgba(255, 255, 255, 0.2);
 | 
						||
	border-radius: 8rpx;
 | 
						||
}
 | 
						||
 | 
						||
/* 移动设备下为内容添加顶部间距 */
 | 
						||
.top_bar + .unified-content {
 | 
						||
	margin-top: calc(var(--status-bar-height) + 88rpx);
 | 
						||
	padding-top: 30rpx;
 | 
						||
}
 | 
						||
 | 
						||
/* 浏览器环境顶部导航栏 */
 | 
						||
.unified-header {
 | 
						||
	background: var(--gradient-primary);
 | 
						||
	box-shadow: var(--shadow-lg);
 | 
						||
	position: fixed;
 | 
						||
	top: 0;
 | 
						||
	left: 0;
 | 
						||
	right: 0;
 | 
						||
	z-index: 9999;
 | 
						||
	height: calc(var(--status-bar-height) + 88rpx);
 | 
						||
}
 | 
						||
 | 
						||
.unified-header .header-content {
 | 
						||
	padding: 20rpx 30rpx;
 | 
						||
	padding-top: calc(var(--status-bar-height) + 20rpx);
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: space-between;
 | 
						||
	height: 100%;
 | 
						||
	box-sizing: border-box;
 | 
						||
}
 | 
						||
 | 
						||
.unified-header .header-title {
 | 
						||
	flex: 1;
 | 
						||
	text-align: center;
 | 
						||
	color: var(--white);
 | 
						||
	font-size: 32rpx;
 | 
						||
	font-weight: 600;
 | 
						||
	margin: 0 20rpx;
 | 
						||
}
 | 
						||
 | 
						||
.unified-header .header-left,
 | 
						||
.unified-header .header-right {
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	min-width: 80rpx;
 | 
						||
}
 | 
						||
 | 
						||
.unified-header .header-right {
 | 
						||
	justify-content: flex-end;
 | 
						||
}
 | 
						||
 | 
						||
.unified-header .header-icon {
 | 
						||
	color: var(--white);
 | 
						||
	font-size: 36rpx;
 | 
						||
	padding: 10rpx;
 | 
						||
	transition: all 0.3s ease;
 | 
						||
}
 | 
						||
 | 
						||
.unified-header .header-icon:active {
 | 
						||
	background: rgba(255, 255, 255, 0.2);
 | 
						||
	transform: scale(0.95);
 | 
						||
}
 | 
						||
 | 
						||
/* 支持安全区域的设备 */
 | 
						||
@supports (padding: max(0px)) {
 | 
						||
  .unified-header {
 | 
						||
    height: calc(var(--status-bar-height) + 88rpx + env(safe-area-inset-top));
 | 
						||
  }
 | 
						||
  
 | 
						||
  .unified-header .header-content {
 | 
						||
    padding-top: calc(var(--status-bar-height) + 20rpx + env(safe-area-inset-top));
 | 
						||
  }
 | 
						||
  
 | 
						||
  .unified-header + .unified-content {
 | 
						||
    margin-top: calc(var(--status-bar-height) + 88rpx + env(safe-area-inset-top));
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
.custom-navbar {
 | 
						||
	background: var(--gradient-primary);
 | 
						||
	padding: 20rpx 30rpx;
 | 
						||
	padding-top: calc(var(--status-bar-height) + 20rpx);
 | 
						||
}
 | 
						||
 | 
						||
.navbar-content {
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: space-between;
 | 
						||
}
 | 
						||
 | 
						||
.search-box {
 | 
						||
	flex: 1;
 | 
						||
	background-color: rgba(255, 255, 255, 0.2);
 | 
						||
	border-radius: 25rpx;
 | 
						||
	padding: 15rpx 20rpx;
 | 
						||
	margin-right: 20rpx;
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
}
 | 
						||
 | 
						||
.search-placeholder {
 | 
						||
	color: rgba(255, 255, 255, 0.8);
 | 
						||
	font-size: 28rpx;
 | 
						||
	margin-left: 10rpx;
 | 
						||
}
 | 
						||
 | 
						||
.notification {
 | 
						||
	position: relative;
 | 
						||
	padding: 10rpx;
 | 
						||
}
 | 
						||
 | 
						||
.page-content {
 | 
						||
	height: 100vh;
 | 
						||
	padding: 20rpx;
 | 
						||
	box-sizing: border-box;
 | 
						||
	width: 100%;
 | 
						||
}
 | 
						||
 | 
						||
/* 卡片基础样式 */
 | 
						||
.profile-card, .functions-card, .help-card, .account-card {
 | 
						||
	background: var(--white);
 | 
						||
	border-radius: 20rpx;
 | 
						||
	margin-bottom: 20rpx;
 | 
						||
	box-shadow: var(--shadow-md);
 | 
						||
	overflow: hidden;
 | 
						||
	width: 100%;
 | 
						||
	box-sizing: border-box;
 | 
						||
}
 | 
						||
 | 
						||
/* 个人信息卡片 */
 | 
						||
.profile-card {
 | 
						||
	background: var(--gradient-primary);
 | 
						||
	color: var(--white);
 | 
						||
}
 | 
						||
 | 
						||
.profile-content {
 | 
						||
	padding: 40rpx;
 | 
						||
}
 | 
						||
 | 
						||
.profile-header {
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	margin-bottom: 30rpx;
 | 
						||
}
 | 
						||
 | 
						||
.profile-avatar {
 | 
						||
	position: relative;
 | 
						||
	margin-right: 30rpx;
 | 
						||
}
 | 
						||
 | 
						||
.avatar {
 | 
						||
	width: 120rpx;
 | 
						||
	height: 120rpx;
 | 
						||
	border-radius: 60rpx;
 | 
						||
	background: rgba(255, 255, 255, 0.2);
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: center;
 | 
						||
	backdrop-filter: blur(10rpx);
 | 
						||
	border: 2rpx solid rgba(255, 255, 255, 0.3);
 | 
						||
}
 | 
						||
 | 
						||
.avatar-text {
 | 
						||
	color: var(--white);
 | 
						||
	font-size: 48rpx;
 | 
						||
	font-weight: 600;
 | 
						||
}
 | 
						||
 | 
						||
.edit-icon {
 | 
						||
	position: absolute;
 | 
						||
	bottom: 0;
 | 
						||
	right: 0;
 | 
						||
	width: 36rpx;
 | 
						||
	height: 36rpx;
 | 
						||
	background: rgba(255, 255, 255, 0.9);
 | 
						||
	border-radius: 50%;
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: center;
 | 
						||
	font-size: 20rpx;
 | 
						||
	color: #667eea;
 | 
						||
}
 | 
						||
 | 
						||
.profile-info {
 | 
						||
	flex: 1;
 | 
						||
}
 | 
						||
 | 
						||
.profile-name {
 | 
						||
	font-size: 36rpx;
 | 
						||
	font-weight: 700;
 | 
						||
	color: var(--white);
 | 
						||
	margin-bottom: 8rpx;
 | 
						||
	display: block;
 | 
						||
}
 | 
						||
 | 
						||
.profile-dept {
 | 
						||
	font-size: 28rpx;
 | 
						||
	color: rgba(255, 255, 255, 0.8);
 | 
						||
	margin-bottom: 6rpx;
 | 
						||
	display: block;
 | 
						||
}
 | 
						||
 | 
						||
.profile-id {
 | 
						||
	font-size: 24rpx;
 | 
						||
	color: rgba(255, 255, 255, 0.7);
 | 
						||
}
 | 
						||
 | 
						||
.profile-arrow {
 | 
						||
	margin-left: 20rpx;
 | 
						||
	font-size: 24rpx;
 | 
						||
	color: rgba(255, 255, 255, 0.7);
 | 
						||
}
 | 
						||
 | 
						||
/* 数据统计网格 */
 | 
						||
.stats-grid {
 | 
						||
	display: flex;
 | 
						||
	gap: 20rpx;
 | 
						||
}
 | 
						||
 | 
						||
.stat-item {
 | 
						||
	flex: 1;
 | 
						||
	background: rgba(255, 255, 255, 0.15);
 | 
						||
	border-radius: 16rpx;
 | 
						||
	padding: 24rpx;
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	backdrop-filter: blur(10rpx);
 | 
						||
	border: 1rpx solid rgba(255, 255, 255, 0.2);
 | 
						||
	transition: all 0.3s ease;
 | 
						||
}
 | 
						||
 | 
						||
.stat-item:active {
 | 
						||
	transform: scale(0.95);
 | 
						||
	background: rgba(255, 255, 255, 0.25);
 | 
						||
}
 | 
						||
 | 
						||
.stat-icon {
 | 
						||
	width: 48rpx;
 | 
						||
	height: 48rpx;
 | 
						||
	border-radius: 24rpx;
 | 
						||
	background: rgba(255, 255, 255, 0.3);
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: center;
 | 
						||
	margin-right: 16rpx;
 | 
						||
	font-size: 24rpx;
 | 
						||
	color: #fff;
 | 
						||
}
 | 
						||
 | 
						||
.stat-content {
 | 
						||
	flex: 1;
 | 
						||
}
 | 
						||
 | 
						||
.stat-number {
 | 
						||
	font-size: 28rpx;
 | 
						||
	font-weight: 700;
 | 
						||
	color: var(--white);
 | 
						||
	display: block;
 | 
						||
	margin-bottom: 4rpx;
 | 
						||
}
 | 
						||
 | 
						||
.stat-label {
 | 
						||
	font-size: 22rpx;
 | 
						||
	color: rgba(255, 255, 255, 0.8);
 | 
						||
}
 | 
						||
 | 
						||
/* 未登录提示 */
 | 
						||
.login-prompt {
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	padding: 40rpx;
 | 
						||
	background: rgba(255, 255, 255, 0.1);
 | 
						||
	border-radius: 16rpx;
 | 
						||
	border: 2rpx dashed rgba(255, 255, 255, 0.3);
 | 
						||
	backdrop-filter: blur(10rpx);
 | 
						||
}
 | 
						||
 | 
						||
.login-icon {
 | 
						||
	font-size: 80rpx;
 | 
						||
	color: rgba(255, 255, 255, 0.8);
 | 
						||
	margin-right: 24rpx;
 | 
						||
}
 | 
						||
 | 
						||
.login-content {
 | 
						||
	flex: 1;
 | 
						||
	margin-right: 20rpx;
 | 
						||
}
 | 
						||
 | 
						||
.login-title {
 | 
						||
	display: block;
 | 
						||
	font-size: 32rpx;
 | 
						||
	font-weight: 600;
 | 
						||
	color: var(--white);
 | 
						||
	margin-bottom: 8rpx;
 | 
						||
}
 | 
						||
 | 
						||
.login-desc {
 | 
						||
	font-size: 26rpx;
 | 
						||
	color: rgba(255, 255, 255, 0.8);
 | 
						||
	line-height: 1.4;
 | 
						||
}
 | 
						||
 | 
						||
.login-btn {
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	gap: 8rpx;
 | 
						||
	padding: 16rpx 24rpx;
 | 
						||
	background: rgba(255, 255, 255, 0.2);
 | 
						||
	border-radius: 25rpx;
 | 
						||
	border: 1rpx solid rgba(255, 255, 255, 0.3);
 | 
						||
	transition: all 0.3s ease;
 | 
						||
}
 | 
						||
 | 
						||
.login-btn:active {
 | 
						||
	transform: scale(0.95);
 | 
						||
	background: rgba(255, 255, 255, 0.3);
 | 
						||
}
 | 
						||
 | 
						||
.login-btn-text {
 | 
						||
	font-size: 26rpx;
 | 
						||
	font-weight: 600;
 | 
						||
	color: var(--white);
 | 
						||
}
 | 
						||
 | 
						||
.login-btn i {
 | 
						||
	font-size: 20rpx;
 | 
						||
	color: var(--white);
 | 
						||
}
 | 
						||
 | 
						||
/* 卡片头部 */
 | 
						||
.card-header {
 | 
						||
	padding: 30rpx 30rpx 20rpx;
 | 
						||
	border-bottom: 1rpx solid var(--border-light);
 | 
						||
}
 | 
						||
 | 
						||
.card-title {
 | 
						||
	font-size: 32rpx;
 | 
						||
	font-weight: 600;
 | 
						||
	color: var(--text-color);
 | 
						||
}
 | 
						||
 | 
						||
/* 模块网格布局 */
 | 
						||
.module-grid {
 | 
						||
	display: flex;
 | 
						||
	flex-wrap: wrap;
 | 
						||
	padding: 20rpx;
 | 
						||
	gap: 16rpx;
 | 
						||
	align-items: flex-start;
 | 
						||
}
 | 
						||
 | 
						||
.module-item {
 | 
						||
	width: calc(20% - 12.8rpx);
 | 
						||
	display: flex;
 | 
						||
	flex-direction: column;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: flex-start;
 | 
						||
	background: var(--gray-lighter);
 | 
						||
	border-radius: 16rpx;
 | 
						||
	padding: 20rpx 12rpx;
 | 
						||
	transition: all 0.3s ease;
 | 
						||
	position: relative;
 | 
						||
	min-height: auto;
 | 
						||
	height: auto;
 | 
						||
}
 | 
						||
 | 
						||
.module-item:active {
 | 
						||
	transform: scale(0.95);
 | 
						||
	background: var(--gray);
 | 
						||
}
 | 
						||
 | 
						||
.module-item.none {
 | 
						||
	background: transparent;
 | 
						||
	pointer-events: none;
 | 
						||
}
 | 
						||
 | 
						||
.module-icon {
 | 
						||
	width: 56rpx;
 | 
						||
	height: 56rpx;
 | 
						||
	border-radius: 14rpx;
 | 
						||
	display: flex;
 | 
						||
	align-items: center;
 | 
						||
	justify-content: center;
 | 
						||
	margin-bottom: 12rpx;
 | 
						||
	font-size: 28rpx;
 | 
						||
	color: #fff;
 | 
						||
	box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
 | 
						||
	flex-shrink: 0;
 | 
						||
}
 | 
						||
 | 
						||
.module-name {
 | 
						||
	font-size: 20rpx;
 | 
						||
	color: var(--text-color);
 | 
						||
	font-weight: 500;
 | 
						||
	text-align: center;
 | 
						||
	line-height: 1.3;
 | 
						||
	margin-bottom: 8rpx;
 | 
						||
	word-break: break-all;
 | 
						||
	hyphens: auto;
 | 
						||
}
 | 
						||
 | 
						||
.module-value {
 | 
						||
	font-size: 20rpx;
 | 
						||
	color: var(--text-secondary);
 | 
						||
	text-align: center;
 | 
						||
	line-height: 1.3;
 | 
						||
	margin-bottom: 8rpx;
 | 
						||
	word-break: break-all;
 | 
						||
}
 | 
						||
 | 
						||
.module-switch {
 | 
						||
	margin-top: 4rpx;
 | 
						||
	flex-shrink: 0;
 | 
						||
}
 | 
						||
 | 
						||
/* 开关样式 */
 | 
						||
.switch {
 | 
						||
	width: 48rpx;
 | 
						||
	height: 24rpx;
 | 
						||
	background-color: #e0e0e0;
 | 
						||
	border-radius: 12rpx;
 | 
						||
	position: relative;
 | 
						||
	transition: all 0.3s ease;
 | 
						||
}
 | 
						||
 | 
						||
.switch.active {
 | 
						||
	background-color: #3498db;
 | 
						||
}
 | 
						||
 | 
						||
.switch-handle {
 | 
						||
	width: 20rpx;
 | 
						||
	height: 20rpx;
 | 
						||
	background-color: #fff;
 | 
						||
	border-radius: 50%;
 | 
						||
	position: absolute;
 | 
						||
	top: 2rpx;
 | 
						||
	left: 2rpx;
 | 
						||
	transition: all 0.3s ease;
 | 
						||
	box-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.2);
 | 
						||
}
 | 
						||
 | 
						||
.switch.active .switch-handle {
 | 
						||
	transform: translateX(24rpx);
 | 
						||
}
 | 
						||
 | 
						||
.search-icon, .notification-icon {
 | 
						||
	font-size: 32rpx;
 | 
						||
	margin-right: 10rpx;
 | 
						||
	color: var(--white);
 | 
						||
}
 | 
						||
 | 
						||
.badge {
 | 
						||
	position: absolute;
 | 
						||
	top: 0rpx;
 | 
						||
	right: 15rpx;
 | 
						||
	background-color: var(--error);
 | 
						||
	color: var(--white);
 | 
						||
	font-size: 20rpx;
 | 
						||
	padding: 2rpx 8rpx;
 | 
						||
	border-radius: 50%;
 | 
						||
	// min-width: 30rpx;
 | 
						||
	text-align: center;
 | 
						||
	line-height: 1.2;
 | 
						||
}
 | 
						||
</style>
 |