From c7566bba45e6f90594d36ec4b80ac4ff89f577ee Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 08 十月 2026 14:19:36 +0800
Subject: [PATCH] 项目重构
---
src/layout/components/Navbar.vue | 311 +++++++++++++++------------------------------------
1 files changed, 92 insertions(+), 219 deletions(-)
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index 20221b5..6db7c89 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -1,112 +1,44 @@
<template>
- <div class="navbar" :class="'nav' + settingsStore.navType">
+ <div class="navbar">
<hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
- <breadcrumb v-if="settingsStore.navType == 1" id="breadcrumb-container" class="breadcrumb-container" />
- <top-nav v-if="settingsStore.navType == 2" id="topmenu-container" class="topmenu-container" />
- <template v-if="settingsStore.navType == 3">
- <logo v-show="settingsStore.sidebarLogo" :collapse="false"></logo>
- <top-bar id="topbar-container" class="topbar-container" />
- </template>
-
+ <div class="center-menu">
+ <span class="label">LIMS瀹為獙瀹ょ鐞嗙郴缁�</span>
+ </div>
<div class="right-menu">
- <template v-if="appStore.device !== 'mobile'">
- <header-search id="header-search" class="right-menu-item" />
-
- <el-tooltip content="婧愮爜鍦板潃" effect="dark" placement="bottom">
- <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
- </el-tooltip>
-
- <el-tooltip content="鏂囨。鍦板潃" effect="dark" placement="bottom">
- <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
- </el-tooltip>
-
- <screenfull id="screenfull" class="right-menu-item hover-effect" />
-
- <el-tooltip content="涓婚妯″紡" effect="dark" placement="bottom">
- <div class="right-menu-item hover-effect theme-switch-wrapper" @click="toggleTheme">
- <svg-icon v-if="settingsStore.isDark" icon-class="sunny" />
- <svg-icon v-if="!settingsStore.isDark" icon-class="moon" />
+ <div class="avatar-wrapper">
+ <el-avatar shape="square" :size="30">{{ avatarText }}</el-avatar>
+ <span class="userName">{{ userStore.nickName }}</span>
+ <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
+ <div class="avatar-wrapper">
+ <lims-icon name="el-icon-caret-bottom" />
</div>
- </el-tooltip>
-
- <el-tooltip content="甯冨眬澶у皬" effect="dark" placement="bottom">
- <size-select id="size-select" class="right-menu-item hover-effect" />
- </el-tooltip>
-
- <el-tooltip content="娑堟伅閫氱煡" effect="dark" placement="bottom">
- <header-notice id="header-notice" class="right-menu-item hover-effect" />
- </el-tooltip>
- </template>
-
- <el-dropdown @command="handleCommand" class="avatar-container right-menu-item hover-effect" trigger="hover">
- <div class="avatar-wrapper">
- <img :src="userStore.avatar" class="user-avatar" />
- <span class="user-nickname"> {{ userStore.nickName }} </span>
- </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 command="lockScreen">
- <span>閿佸畾灞忓箷</span>
- </el-dropdown-item>
- <el-dropdown-item divided command="logout">
- <span>閫�鍑虹櫥褰�</span>
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
+ <template #dropdown>
+ <el-dropdown-menu>
+ <router-link to="/user/profile">
+ <el-dropdown-item>涓汉涓績</el-dropdown-item>
+ </router-link>
+ </el-dropdown-menu>
+ </template>
+ </el-dropdown>
+ <img class="logoout" src="@/assets/images/logoout.png" @click="logout" title="閫�鍑鸿处鍙�" />
+ </div>
</div>
</div>
</template>
<script setup>
import { ElMessageBox } from 'element-plus'
-import Breadcrumb from '@/components/Breadcrumb'
-import TopNav from './TopNav'
-import TopBar from './TopBar'
-import Logo from './Sidebar/Logo'
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 useAppStore from '@/store/modules/app'
import useUserStore from '@/store/modules/user'
-import useLockStore from '@/store/modules/lock'
-import useSettingsStore from '@/store/modules/settings'
-import HeaderNotice from './HeaderNotice'
-const route = useRoute()
-const router = useRouter()
const appStore = useAppStore()
const userStore = useUserStore()
-const lockStore = useLockStore()
-const settingsStore = useSettingsStore()
+
+const avatarText = computed(() => (userStore.nickName || '').substring(0, 1))
function toggleSideBar() {
appStore.toggleSideBar()
-}
-
-function handleCommand(command) {
- switch (command) {
- case "setLayout":
- setLayout()
- break
- case "lockScreen":
- lockScreen()
- break
- case "logout":
- logout()
- break
- default:
- break
- }
}
function logout() {
@@ -120,109 +52,65 @@
})
}).catch(() => { })
}
-
-const emits = defineEmits(['setLayout'])
-function setLayout() {
- emits('setLayout')
-}
-
-function lockScreen() {
- const currentPath = route.fullPath
- lockStore.lockScreen(currentPath)
- router.push('/lock')
-}
-
-async function toggleTheme(event) {
- const x = event?.clientX || window.innerWidth / 2
- const y = event?.clientY || window.innerHeight / 2
- const wasDark = settingsStore.isDark
-
- const isReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches
- const isSupported = document.startViewTransition && !isReducedMotion
-
- if (!isSupported) {
- settingsStore.toggleTheme()
- return
- }
-
- try {
- const transition = document.startViewTransition(async () => {
- await new Promise((resolve) => setTimeout(resolve, 10))
- settingsStore.toggleTheme()
- await nextTick()
- })
- await transition.ready
-
- const endRadius = Math.hypot(Math.max(x, window.innerWidth - x), Math.max(y, window.innerHeight - y))
- const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`]
- document.documentElement.animate(
- {
- clipPath: !wasDark ? [...clipPath].reverse() : clipPath
- }, {
- duration: 650,
- easing: "cubic-bezier(0.4, 0, 0.2, 1)",
- fill: "forwards",
- pseudoElement: !wasDark ? "::view-transition-old(root)" : "::view-transition-new(root)"
- }
- )
- await transition.finished
- } catch (error) {
- console.warn("View transition failed, falling back to immediate toggle:", error)
- settingsStore.toggleTheme()
- }
-}
</script>
-<style lang='scss' scoped>
-.navbar.nav3 {
- .hamburger-container {
- display: none !important;
- }
-}
-
+<style lang="scss" scoped>
.navbar {
height: 50px;
overflow: hidden;
- position: relative;
- background: var(--navbar-bg);
- box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+ background: var(--lims-surface);
+ border-bottom: 1px solid var(--lims-divider);
+ box-shadow: none;
+ position: fixed; /* 灏嗗ご閮ㄥ浐瀹� */
+ top: 0; /* 鍦ㄩ《閮ㄥ浐瀹� */
+ width: 100%; /* 瀹藉害100%锛岃鐩栨暣涓鍙� */
+ z-index: 1000; /* 纭繚澶撮儴鍦ㄥ叾浠栧唴瀹逛箣涓� */
display: flex;
align-items: center;
- // padding: 0 8px;
- box-sizing: border-box;
+ justify-content: space-between;
.hamburger-container {
line-height: 46px;
height: 100%;
cursor: pointer;
- transition: background 0.3s;
+ transition: background 0.2s;
-webkit-tap-highlight-color: transparent;
display: flex;
align-items: center;
flex-shrink: 0;
- margin-right: 8px;
+ margin-left: 8px;
+ border-radius: var(--lims-radius-sm);
&:hover {
- background: rgba(0, 0, 0, 0.025);
+ background: var(--lims-surface-hover);
}
}
- .breadcrumb-container {
- flex-shrink: 0;
- }
-
- .topmenu-container {
- position: absolute;
- left: 50px;
- }
-
- .topbar-container {
- flex: 1;
- min-width: 0;
+ .center-menu {
+ height: 100%;
+ line-height: 50px;
+ margin-right: auto;
+ margin-left: 8px;
display: flex;
align-items: center;
- overflow: hidden;
- margin-left: 8px;
+
+ /* 鏍囬宸︿晶鐨勪富鑹茬粏鏉★紝鍛煎簲寮圭獥鏍囬鐨勮瑙夎瑷� */
+ &::before {
+ content: '';
+ display: inline-block;
+ width: 3px;
+ height: 15px;
+ border-radius: 2px;
+ background: var(--el-color-primary);
+ margin-right: 10px;
+ }
+
+ .label {
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--lims-text);
+ letter-spacing: 0.2px;
+ }
}
.right-menu {
@@ -230,10 +118,38 @@
line-height: 50px;
display: flex;
align-items: center;
- margin-left: auto;
&:focus {
outline: none;
+ }
+
+ .avatar-wrapper {
+ display: flex;
+ align-items: center;
+
+ :deep(.el-avatar) {
+ background: var(--el-color-primary);
+ border-radius: var(--lims-radius-sm);
+ font-size: 14px;
+ font-weight: 600;
+ }
+
+ .userName {
+ font-size: 14px;
+ color: var(--lims-text-2);
+ margin-left: 10px;
+ }
+ .logoout {
+ margin: 0 40px;
+ cursor: pointer;
+ width: 14px;
+ opacity: 0.6;
+ transition: opacity 0.2s;
+
+ &:hover {
+ opacity: 1;
+ }
+ }
}
.right-menu-item {
@@ -241,65 +157,22 @@
padding: 0 8px;
height: 100%;
font-size: 18px;
- color: #5a5e66;
+ color: var(--lims-text-2);
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
- transition: background 0.3s;
+ transition: background 0.2s;
&: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);
- }
+ background: var(--lims-surface-hover);
}
}
}
.avatar-container {
- margin-right: 0px;
- padding-right: 0px;
-
- .avatar-wrapper {
- margin-top: 10px;
- right: 8px;
- position: relative;
-
- .user-avatar {
- cursor: pointer;
- width: 30px;
- height: 30px;
- margin-right: 8px;
- border-radius: 50%;
- }
-
- .user-nickname{
- position: relative;
- left: 0px;
- bottom: 10px;
- font-size: 14px;
- font-weight: bold;
- }
-
- i {
- cursor: pointer;
- position: absolute;
- right: -20px;
- top: 25px;
- font-size: 12px;
- }
- }
+ display: flex;
+ align-items: center;
}
}
}
--
Gitblit v1.9.3