xlx_teacher_app/src/pages/mine/index.vue

243 lines
7.1 KiB
Vue
Raw 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.

<script setup lang="ts">
import { computed } from 'vue'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
// 获取屏幕边界到安全区域距离
let safeAreaInsets
let systemInfo
// #ifdef MP-WEIXIN
// 微信小程序使用新的API
systemInfo = uni.getWindowInfo()
safeAreaInsets = systemInfo.safeArea
? {
top: systemInfo.safeArea.top,
right: systemInfo.windowWidth - systemInfo.safeArea.right,
bottom: systemInfo.windowHeight - systemInfo.safeArea.bottom,
left: systemInfo.safeArea.left,
}
: null
// #endif
// #ifndef MP-WEIXIN
// 其他平台继续使用uni API
systemInfo = uni.getSystemInfoSync()
safeAreaInsets = systemInfo.safeAreaInsets
// #endif
// 获取用户信息
const userInfo = computed(() => userStore.getUserInfo)
// 功能菜单项
const menuItems = [
{
icon: 'i-carbon:locked',
title: '修改密码',
action: () => handleMenuClick('password'),
},
{
icon: 'i-carbon:security',
title: '隐私政策',
action: () => handleMenuClick('privacy'),
},
{
icon: 'i-carbon:chat',
title: '联系客服',
action: () => handleMenuClick('service'),
},
]
// 菜单点击处理
function handleMenuClick(type: string) {
switch (type) {
case 'password':
uni.showToast({
title: '修改密码功能开发中',
icon: 'none',
})
break
case 'privacy':
uni.showToast({
title: '隐私政策功能开发中',
icon: 'none',
})
break
case 'service':
uni.showToast({
title: '联系客服功能开发中',
icon: 'none',
})
break
}
}
// 退出登录
function handleLogout() {
uni.showModal({
title: '提示',
content: '确定要退出登录吗?',
confirmColor: '#3B82F6',
success: (res) => {
if (res.confirm) {
userStore.logOut()
uni.reLaunch({
url: '/pages/auth/index',
})
}
},
})
}
// 获取用户角色显示文本
const getRoleText = computed(() => {
const roles = userInfo.value.roles
if (roles && roles.length > 0) {
return roles[0].name || '教师/班主任'
}
return '教师/班主任'
})
// 获取用户头像
const getAvatarSrc = computed(() => {
return '/static/images/default-avatar.png'
})
// 获取图标背景颜色类
function getIconBgClass(index: number) {
const bgClasses = [
'bg-blue-50', // 修改密码
'bg-cyan-50', // 隐私政策
'bg-sky-50', // 联系客服
]
return bgClasses[index] || 'bg-blue-50'
}
// 获取图标颜色类
function getIconColorClass(index: number) {
const colorClasses = [
'text-blue-500', // 修改密码
'text-cyan-500', // 隐私政策
'text-sky-500', // 联系客服
]
return colorClasses[index] || 'text-blue-500'
}
</script>
<template>
<view class="bg-slate-50">
<!-- 顶部背景装饰 -->
<div class="absolute left-0 right-0 top-0 z-0 h-200px rounded-b-2xl from-cyan-400 to-blue-500 bg-gradient-to-br" />
<!-- 顶部用户信息区域 -->
<view class="relative px-4 pb-4 pt-2" :style="{ paddingTop: `${(safeAreaInsets?.top || 0) + 8}px` }">
<!-- 用户信息容器 -->
<view class="relative z-10 flex flex-col items-center">
<!-- 头像容器 -->
<view class="mb-3 h-80px w-80px overflow-hidden">
<view class="h-full w-full rounded-2xl bg-white shadow-lg">
<image :src="getAvatarSrc" class="h-full w-full rounded-xl" mode="aspectFill" />
</view>
</view>
<!-- 用户名 -->
<text class="mb-2 text-xl text-white font-semibold drop-shadow-sm">
{{ userInfo.nickname || "王**" }}
</text>
<!-- 角色信息 -->
<view class="rounded-full bg-white/20 px-3 py-1 backdrop-blur-sm">
<text class="text-sm text-white/90">角色{{ getRoleText }}</text>
</view>
</view>
</view>
<!-- 主要内容区域 -->
<view class="relative z-10 mx-2 min-h-[calc(100vh-200px)] rounded-t-3xl bg-white px-2 pt-4">
<!-- 账号和学校信息卡片 -->
<view class="grid grid-cols-2 mx-2 mb-4 gap-3">
<!-- 账号信息 -->
<view class="border border-blue-100 rounded-xl from-white to-blue-50 bg-gradient-to-br p-4 shadow-blue-50 shadow-sm">
<view class="mb-1 flex items-center">
<view class="i-mingcute:user-line mr-1 text-base text-blue-500" />
<text class="text-xs text-slate-600">账号信息</text>
</view>
<text class="text-base text-slate-800 font-bold">
{{ userInfo.phone || "17622222222" }}
</text>
</view>
<!-- 所属学校 -->
<view class="border border-cyan-100 rounded-xl from-white to-cyan-50 bg-gradient-to-br p-4 shadow-cyan-50 shadow-sm">
<view class="mb-1 flex items-center">
<view class="i-mingcute:school-line mr-1 text-base text-cyan-500" />
<text class="text-xs text-slate-600">所属学校</text>
</view>
<text class="text-base text-slate-800 font-bold">
{{ userInfo.schools?.[0]?.name || "光谷四小" }}
</text>
</view>
</view>
<!-- 功能菜单标题 -->
<view class="mx-2 mb-3">
<text class="text-lg text-slate-800 font-semibold">功能菜单</text>
</view>
<!-- 功能菜单 -->
<view class="mx-2 mb-4 overflow-hidden border border-blue-100 rounded-2xl bg-white shadow-blue-50 shadow-sm">
<view
v-for="(item, index) in menuItems"
:key="index"
class="flex items-center px-4 py-4 transition-colors active:bg-blue-50"
:class="{ 'border-b border-blue-100': index < menuItems.length - 1 }"
@tap="item.action"
>
<!-- 图标 -->
<view
class="mr-3 h-10 w-10 flex items-center justify-center rounded-xl transition-all"
:class="getIconBgClass(index)"
>
<view class="text-18px" :class="[item.icon, getIconColorClass(index)]" />
</view>
<!-- 标题 -->
<text class="flex-1 text-base text-slate-800 font-medium">
{{ item.title }}
</text>
<!-- 右箭头 -->
<view class="i-carbon:chevron-right text-16px text-blue-400 transition-transform active:scale-110" />
</view>
</view>
<!-- 退出登录按钮 -->
<view class="mx-2 mt-6">
<button
class="h-52px w-full rounded-xl from-blue-500 to-cyan-500 bg-gradient-to-r text-white font-semibold shadow-blue-200 shadow-lg transition-all active:scale-98 !border-none active:shadow-md !outline-none"
@tap="handleLogout"
>
退出登录
</button>
</view>
<!-- 版本信息 -->
<view class="mt-8 pb-6 text-center">
<text class="text-xs text-slate-400">版本号 v1.0.0</text>
</view>
</view>
</view>
</template>
<route lang="jsonc" type="home">
{
"layout": "tabbar",
"style": {
// 'custom' 表示开启自定义导航栏默认 'default'
"navigationStyle": "custom",
"navigationBarTitleText": "我的"
}
}
</route>