269 lines
6.2 KiB
Vue
269 lines
6.2 KiB
Vue
<template>
|
|
<div :class="['navbar-actions', navbarActionsClass]">
|
|
<!-- 桌面端工具项 -->
|
|
<template v-if="isDesktop">
|
|
<!-- 搜索 -->
|
|
<div class="navbar-actions__item">
|
|
<MenuSearch />
|
|
</div>
|
|
|
|
<!-- 全屏 -->
|
|
<div class="navbar-actions__item">
|
|
<Fullscreen />
|
|
</div>
|
|
|
|
<!-- 布局大小 -->
|
|
<div class="navbar-actions__item">
|
|
<SizeSelect />
|
|
</div>
|
|
|
|
<!-- 语言选择 -->
|
|
<div class="navbar-actions__item">
|
|
<LangSelect />
|
|
</div>
|
|
|
|
<!-- 通知 -->
|
|
<div class="navbar-actions__item">
|
|
<Notification />
|
|
</div>
|
|
</template>
|
|
|
|
<!-- 用户菜单 -->
|
|
<div class="navbar-actions__item">
|
|
<el-dropdown trigger="click">
|
|
<div class="user-profile">
|
|
<img class="user-profile__avatar" :src="userStore.userInfo.avatar" />
|
|
<span class="user-profile__name">{{ userStore.userInfo.username }}</span>
|
|
</div>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item @click="handleProfileClick">
|
|
{{ t("navbar.profile") }}
|
|
</el-dropdown-item>
|
|
<el-dropdown-item divided @click="logout">
|
|
{{ t("navbar.logout") }}
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
|
|
<!-- 系统设置 -->
|
|
<div
|
|
v-if="defaultSettings.showSettings"
|
|
class="navbar-actions__item"
|
|
@click="settingStore.settingsVisible = true"
|
|
>
|
|
<div class="i-svg:setting" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useI18n } from "vue-i18n";
|
|
import { useRoute, useRouter } from "vue-router";
|
|
import defaultSettings from "@/settings";
|
|
import { DeviceEnum } from "@/enums/settings/device.enum";
|
|
import { useAppStore, useSettingsStore, useUserStore } from "@/store";
|
|
import { SidebarColor, ThemeMode } from "@/enums/settings/theme.enum";
|
|
import { LayoutMode } from "@/enums";
|
|
|
|
const { t } = useI18n();
|
|
const appStore = useAppStore();
|
|
const settingStore = useSettingsStore();
|
|
const userStore = useUserStore();
|
|
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
|
|
// 是否为桌面设备
|
|
const isDesktop = computed(() => appStore.device === DeviceEnum.DESKTOP);
|
|
|
|
/**
|
|
* 打开个人中心页面
|
|
*/
|
|
function handleProfileClick() {
|
|
router.push({ name: "Profile" });
|
|
}
|
|
|
|
// 根据主题和侧边栏配色方案选择样式类
|
|
const navbarActionsClass = computed(() => {
|
|
const { theme, sidebarColorScheme, layout } = settingStore;
|
|
|
|
// 暗黑主题下,所有布局都使用白色文字
|
|
if (theme === ThemeMode.DARK) {
|
|
return "navbar-actions--white-text";
|
|
}
|
|
|
|
// 明亮主题下
|
|
if (theme === ThemeMode.LIGHT) {
|
|
// 顶部布局和混合布局的顶部区域:
|
|
// - 如果侧边栏是经典蓝色,使用白色文字
|
|
// - 如果侧边栏是极简白色,使用深色文字
|
|
if (layout === LayoutMode.TOP || layout === LayoutMode.MIX) {
|
|
if (sidebarColorScheme === SidebarColor.CLASSIC_BLUE) {
|
|
return "navbar-actions--white-text";
|
|
} else {
|
|
return "navbar-actions--dark-text";
|
|
}
|
|
}
|
|
}
|
|
|
|
return "navbar-actions--dark-text";
|
|
});
|
|
|
|
/**
|
|
* 退出登录
|
|
*/
|
|
function logout() {
|
|
ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
|
|
confirmButtonText: "确定",
|
|
cancelButtonText: "取消",
|
|
type: "warning",
|
|
lockScroll: false,
|
|
}).then(() => {
|
|
userStore.logout().then(() => {
|
|
router.push(`/login?redirect=${route.fullPath}`);
|
|
});
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.navbar-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 100%;
|
|
|
|
&__item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 36px;
|
|
height: 100%;
|
|
padding: 0 8px;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
|
|
// 确保直接子元素也居中
|
|
> * {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
// 确保 el-dropdown 也居中
|
|
:deep(.el-dropdown) {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
}
|
|
|
|
// 修复可能的 SVG 图标容器
|
|
:deep(.icon-container),
|
|
:deep(.action-icon) {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
}
|
|
|
|
// 默认图标样式(明亮模式 + 左侧布局)
|
|
:deep([class^="i-svg:"]) {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 18px;
|
|
line-height: 1;
|
|
color: var(--el-text-color-regular);
|
|
transition: color 0.3s;
|
|
}
|
|
|
|
&:hover {
|
|
background: rgba(0, 0, 0, 0.04);
|
|
|
|
:deep([class^="i-svg:"]) {
|
|
color: var(--el-color-primary);
|
|
}
|
|
}
|
|
}
|
|
|
|
.user-profile {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
padding: 0 8px;
|
|
|
|
&__avatar {
|
|
flex-shrink: 0;
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
&__name {
|
|
margin-left: 8px;
|
|
color: var(--el-text-color-regular);
|
|
white-space: nowrap;
|
|
transition: color 0.3s;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 白色文字样式(用于深色背景:暗黑主题、顶部布局、混合布局)
|
|
.navbar-actions--white-text {
|
|
.navbar-actions__item {
|
|
:deep([class^="i-svg:"]) {
|
|
color: rgba(255, 255, 255, 0.85);
|
|
}
|
|
|
|
&:hover {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
|
|
:deep([class^="i-svg:"]) {
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.user-profile__name {
|
|
color: rgba(255, 255, 255, 0.85);
|
|
}
|
|
}
|
|
|
|
// 深色文字样式(用于浅色背景:明亮主题下的左侧布局)
|
|
.navbar-actions--dark-text {
|
|
.navbar-actions__item {
|
|
:deep([class^="i-svg:"]) {
|
|
color: var(--el-text-color-regular) !important;
|
|
}
|
|
|
|
&:hover {
|
|
background: rgba(0, 0, 0, 0.04);
|
|
|
|
:deep([class^="i-svg:"]) {
|
|
color: var(--el-color-primary) !important;
|
|
}
|
|
}
|
|
}
|
|
|
|
.user-profile__name {
|
|
color: var(--el-text-color-regular) !important;
|
|
}
|
|
}
|
|
|
|
// 确保下拉菜单中的图标不受影响
|
|
:deep(.el-dropdown-menu) {
|
|
[class^="i-svg:"] {
|
|
color: var(--el-text-color-regular) !important;
|
|
|
|
&:hover {
|
|
color: var(--el-color-primary) !important;
|
|
}
|
|
}
|
|
}
|
|
</style>
|