foreign-admin-ui/src/components/layout/Header.vue

242 lines
5.6 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.

<template>
<header class="layout-header">
<!-- 左侧Logo 和系统名称 -->
<div class="header-left">
<div class="logo">
<img src="@/assets/images/logo.webp" alt="logo" />
<span class="system-name">Admin System</span>
</div>
</div>
<!-- 右侧功能按钮和用户信息 -->
<div class="header-right">
<!-- 全屏 -->
<el-tooltip :content="isFullscreen ? '退出全屏' : '全屏'">
<el-button :icon="isFullscreen ? Crop : FullScreen" circle @click="toggleFullscreen" />
</el-tooltip>
<!-- 语言选择 -->
<LanguageSelect v-model="languageStore.lang" @change="languageStore.changeLang" />
<!-- 用户信息下拉菜单 -->
<el-dropdown @command="handleCommand" class="user-dropdown">
<div class="user-info">
<el-avatar :size="32" class="user-avatar">
<el-icon :size="20"><User /></el-icon>
</el-avatar>
<span class="username">{{ activeUserName }}</span>
<el-icon class="dropdown-icon"><ArrowDown /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="profile">
<el-icon><User /></el-icon>
个人中心
</el-dropdown-item>
<el-dropdown-item command="password">
<el-icon><Lock /></el-icon>
修改密码
</el-dropdown-item>
<el-dropdown-item divided command="logout">
<el-icon><SwitchButton /></el-icon>
退出登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</header>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import {
Bell,
Sunny,
Moon,
FullScreen,
Crop,
User,
Lock,
SwitchButton,
ArrowDown
} from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/modules/user'
import { useLanguageStore } from '@/stores/modules/language'
import LanguageSelect from '@/components/LanguageSelect/index.vue'
import { getStorage } from '@/utils/storage'
const router = useRouter()
const userStore = useUserStore()
const languageStore = useLanguageStore()
// 用户信息 - 使用 userStore 的响应式数据
const activeUserName = computed(() => userStore.userInfo?.username || '-')
const unreadCount = ref(3) // 未读消息数量
// 全屏相关
const isFullscreen = ref(false)
const toggleFullscreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen()
isFullscreen.value = true
} else {
if (document.exitFullscreen) {
document.exitFullscreen()
isFullscreen.value = false
}
}
}
// 监听全屏变化
onMounted(() => {
document.addEventListener('fullscreenchange', () => {
isFullscreen.value = !!document.fullscreenElement
})
})
// 消息通知
const handleNotification = () => {
ElMessage.info('暂无新消息')
unreadCount.value = 0
}
// 用户操作
const handleCommand = (command: string) => {
switch (command) {
case 'profile':
router.push('/profile/personal-center')
break
case 'password':
router.push('/user/change-password')
break
case 'logout':
handleLogout()
break
}
}
// 退出登录
const handleLogout = () => {
ElMessageBox.confirm('确定要退出登录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const deviceNo = getStorage('device_no') as string
userStore.logout({ device_no: String(deviceNo) })
}).catch(() => {
// 取消退出
})
}
</script>
<style scoped lang="scss">
.layout-header {
height: 60px;
background: #fff;
border-bottom: 1px solid var(--el-border-color-light);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
.header-left {
display: flex;
align-items: center;
gap: 20px;
.logo {
display: flex;
align-items: center;
gap: 10px;
img {
height: 32px;
width: auto;
}
.system-name {
font-size: 18px;
font-weight: 600;
color: var(--el-text-color-primary);
}
}
}
.header-right {
display: flex;
align-items: center;
gap: 12px;
.notification-badge {
:deep(.el-badge__content) {
transform: translateY(-50%) translateX(50%);
}
}
.el-button {
border: none;
background: transparent;
padding: 8px;
color: var(--el-text-color-regular);
&:hover {
background: var(--el-fill-color-light);
color: var(--el-color-primary);
}
}
.user-dropdown {
margin-left: 8px;
cursor: pointer;
.user-info {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 8px;
border-radius: 4px;
transition: background 0.3s;
&:hover {
background: var(--el-fill-color-light);
}
.user-avatar {
background: var(--el-color-primary);
}
.username {
font-size: 14px;
color: var(--el-text-color-primary);
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropdown-icon {
font-size: 12px;
color: var(--el-text-color-regular);
}
}
}
}
}
// 暗色模式适配
:deep(.dark) {
.layout-header {
background: var(--el-bg-color);
border-bottom-color: var(--el-border-color-darker);
}
}
</style>