| | |
| | | <template>
|
| | | <div class="navbar">
|
| | | <div>
|
| | | <div class="left-menu">
|
| | | <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container"
|
| | | @toggleClick="toggleSideBar" />
|
| | | <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
|
| | | </div>
|
| | | <!-- <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />-->
|
| | | <div class="right-menu">
|
| | | <!-- 消息通知 -->
|
| | | <el-popover
|
| | |
| | | <template #reference>
|
| | | <div class="notification-container right-menu-item hover-effect">
|
| | | <el-badge :value="unreadCount" :hidden="unreadCount === 0" class="notification-badge">
|
| | | <el-icon :size="20" style="cursor: pointer;">
|
| | | <el-icon :size="20">
|
| | | <Bell />
|
| | | </el-icon>
|
| | | </el-badge>
|
| | |
| | | ref="notificationCenterRef"
|
| | | />
|
| | | </el-popover>
|
| | | <div class="avatar-container">
|
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
| | | <div class="avatar-wrapper">
|
| | | <img :src="userStore.avatar" class="user-avatar" />
|
| | | <el-icon><caret-bottom /></el-icon>
|
| | | </div>
|
| | | <template #dropdown>
|
| | | <el-dropdown-menu>
|
| | | <router-link to="/user/profile">
|
| | | <el-dropdown-item>个人中心</el-dropdown-item>
|
| | | </router-link>
|
| | | <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
| | | <span>布局设置</span>
|
| | | </el-dropdown-item>
|
| | | <el-dropdown-item divided command="logout">
|
| | | <span>退出登录</span>
|
| | | </el-dropdown-item>
|
| | | </el-dropdown-menu>
|
| | | </template>
|
| | | </el-dropdown>
|
| | | </div>
|
| | | <el-dropdown @command="handleCommand" trigger="click">
|
| | | <div class="avatar-container right-menu-item hover-effect">
|
| | | <img :src="userStore.avatar" class="user-avatar" />
|
| | | <span class="user-name">{{ userStore.nickName || userStore.name }}</span>
|
| | | <el-icon class="user-caret"><caret-bottom /></el-icon>
|
| | | </div>
|
| | | <template #dropdown>
|
| | | <el-dropdown-menu>
|
| | | <router-link to="/user/profile">
|
| | | <el-dropdown-item>个人中心</el-dropdown-item>
|
| | | </router-link>
|
| | | <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
|
| | | <span>布局设置</span>
|
| | | </el-dropdown-item>
|
| | | <el-dropdown-item divided command="logout">
|
| | | <span>退出登录</span>
|
| | | </el-dropdown-item>
|
| | | </el-dropdown-menu>
|
| | | </template>
|
| | | </el-dropdown>
|
| | | </div>
|
| | | </div>
|
| | | </template>
|
| | |
| | | import { ElMessageBox } from 'element-plus'
|
| | | import { Bell } from '@element-plus/icons-vue'
|
| | | import Breadcrumb from '@/components/Breadcrumb'
|
| | | import TopNav from '@/components/TopNav'
|
| | | import Hamburger from '@/components/Hamburger'
|
| | | import Screenfull from '@/components/Screenfull'
|
| | | import SizeSelect from '@/components/SizeSelect'
|
| | | import HeaderSearch from '@/components/HeaderSearch'
|
| | | import RuoYiGit from '@/components/RuoYi/Git'
|
| | | import RuoYiDoc from '@/components/RuoYi/Doc'
|
| | | import NotificationCenter from './NotificationCenter/index.vue'
|
| | | import useAppStore from '@/store/modules/app'
|
| | | import useUserStore from '@/store/modules/user'
|
| | |
| | | emits('setLayout')
|
| | | }
|
| | |
|
| | | function toggleTheme() {
|
| | | settingsStore.toggleTheme()
|
| | | }
|
| | |
|
| | | // 消息通知相关
|
| | | function handleUnreadCountChange(count) {
|
| | | unreadCount.value = count
|
| | |
| | |
|
| | | <style lang='scss' scoped>
|
| | | .navbar {
|
| | | height: 50px;
|
| | | overflow: hidden;
|
| | | height: 60px;
|
| | | position: relative;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: space-between;
|
| | | padding-right: 16px;
|
| | | background: var(--navbar-bg);
|
| | | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
| | | border-bottom: 1px solid var(--navbar-border);
|
| | |
|
| | | .left-menu {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | height: 100%;
|
| | | }
|
| | |
|
| | | .hamburger-container {
|
| | | line-height: 46px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | height: 100%;
|
| | | float: left;
|
| | | padding: 0 14px;
|
| | | cursor: pointer;
|
| | | transition: background 0.3s;
|
| | | transition: background 0.2s;
|
| | | -webkit-tap-highlight-color: transparent;
|
| | |
|
| | | &:hover {
|
| | | background: rgba(0, 0, 0, 0.025);
|
| | | background: var(--app-surface-hover);
|
| | | }
|
| | | }
|
| | |
|
| | | .breadcrumb-container {
|
| | | float: left;
|
| | | }
|
| | |
|
| | | .topmenu-container {
|
| | | position: absolute;
|
| | | left: 50px;
|
| | | }
|
| | |
|
| | | .errLog-container {
|
| | | display: inline-block;
|
| | | vertical-align: top;
|
| | | }
|
| | |
|
| | | .right-menu {
|
| | | float: right;
|
| | | height: 100%;
|
| | | line-height: 50px;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | gap: 6px;
|
| | | height: 100%;
|
| | |
|
| | | &:focus {
|
| | | outline: none;
|
| | | }
|
| | |
|
| | | // 每个按钮统一的圆角悬停底
|
| | | .right-menu-item {
|
| | | display: inline-block;
|
| | | padding: 0 8px;
|
| | | height: 100%;
|
| | | display: flex;
|
| | | align-items: center;
|
| | | height: 40px;
|
| | | padding: 0 12px;
|
| | | font-size: 18px;
|
| | | color: var(--navbar-text);
|
| | | vertical-align: text-bottom;
|
| | | border-radius: 10px;
|
| | | cursor: pointer;
|
| | | transition: background 0.2s;
|
| | |
|
| | | &.hover-effect {
|
| | | cursor: pointer;
|
| | | transition: background 0.3s;
|
| | |
|
| | | &:hover {
|
| | | background: rgba(0, 0, 0, 0.025);
|
| | | }
|
| | | }
|
| | |
|
| | | &.theme-switch-wrapper {
|
| | | display: flex;
|
| | | align-items: center;
|
| | |
|
| | | svg {
|
| | | transition: transform 0.3s;
|
| | |
|
| | | &:hover {
|
| | | transform: scale(1.15);
|
| | | }
|
| | | }
|
| | | &.hover-effect:hover {
|
| | | background: var(--app-surface-hover);
|
| | | }
|
| | | }
|
| | |
|
| | | .notification-container {
|
| | | margin-right: 20px;
|
| | | .notification-badge {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | cursor: pointer;
|
| | |
|
| | | .notification-badge {
|
| | | :deep(.el-badge__content) {
|
| | | border: none;
|
| | | }
|
| | | :deep(.el-badge__content) {
|
| | | border: none;
|
| | | }
|
| | | }
|
| | |
|
| | | .avatar-container {
|
| | | margin-right: 40px;
|
| | | gap: 8px;
|
| | |
|
| | | .avatar-wrapper {
|
| | | margin-top: 5px;
|
| | | position: relative;
|
| | | .user-avatar {
|
| | | width: 32px;
|
| | | height: 32px;
|
| | | border-radius: 50%;
|
| | | object-fit: cover;
|
| | | background: var(--app-surface-hover);
|
| | | }
|
| | |
|
| | | .user-avatar {
|
| | | cursor: pointer;
|
| | | width: 40px;
|
| | | height: 40px;
|
| | | border-radius: 50px;
|
| | | }
|
| | | .user-name {
|
| | | font-size: 14px;
|
| | | font-weight: 500;
|
| | | color: var(--app-text);
|
| | | max-width: 120px;
|
| | | overflow: hidden;
|
| | | text-overflow: ellipsis;
|
| | | white-space: nowrap;
|
| | | }
|
| | |
|
| | | i {
|
| | | cursor: pointer;
|
| | | position: absolute;
|
| | | right: -20px;
|
| | | top: 14px;
|
| | | font-size: 12px;
|
| | | }
|
| | | .user-caret {
|
| | | font-size: 12px;
|
| | | color: var(--app-text-tertiary);
|
| | | }
|
| | | }
|
| | | }
|