mirror of
https://gitee.com/fantastic-admin/basic.git
synced 2024-12-02 03:57:37 +08:00
refactor: 工具栏文件目录结构调整
This commit is contained in:
parent
75d815d315
commit
30a303195f
@ -176,6 +176,21 @@ function handleCopy() {
|
||||
<div class="divider">
|
||||
工具栏
|
||||
</div>
|
||||
<div v-if="settingsStore.mode === 'pc'" class="setting-item">
|
||||
<div class="label">
|
||||
面包屑导航
|
||||
</div>
|
||||
<HToggle v-model="settingsStore.settings.toolbar.breadcrumb" />
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="label">
|
||||
导航搜索
|
||||
<HTooltip text="对导航进行快捷搜索">
|
||||
<SvgIcon name="ri:question-line" />
|
||||
</HTooltip>
|
||||
</div>
|
||||
<HToggle v-model="settingsStore.settings.toolbar.navSearch" />
|
||||
</div>
|
||||
<div v-if="settingsStore.mode === 'pc'" class="setting-item">
|
||||
<div class="label">
|
||||
全屏
|
||||
@ -200,15 +215,6 @@ function handleCopy() {
|
||||
</div>
|
||||
<HToggle v-model="settingsStore.settings.toolbar.colorScheme" />
|
||||
</div>
|
||||
<div v-if="settingsStore.mode === 'pc'" class="divider">
|
||||
面包屑导航
|
||||
</div>
|
||||
<div v-if="settingsStore.mode === 'pc'" class="setting-item">
|
||||
<div class="label">
|
||||
是否启用
|
||||
</div>
|
||||
<HToggle v-model="settingsStore.settings.toolbar.breadcrumb" />
|
||||
</div>
|
||||
<div class="divider">
|
||||
页面
|
||||
</div>
|
||||
@ -221,15 +227,6 @@ function handleCopy() {
|
||||
<div class="divider">
|
||||
导航搜索
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="label">
|
||||
是否启用
|
||||
<HTooltip text="对导航进行快捷搜索">
|
||||
<SvgIcon name="ri:question-line" />
|
||||
</HTooltip>
|
||||
</div>
|
||||
<HToggle v-model="settingsStore.settings.toolbar.navSearch" />
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="label">
|
||||
是否启用快捷键
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import Logo from '../Logo/index.vue'
|
||||
import Tools from '../Tools/index.vue'
|
||||
import ToolbarRightSide from '../Topbar/Toolbar/rightSide.vue'
|
||||
import useMenuStore from '@/store/modules/menu'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
@ -55,7 +55,7 @@ function handlerMouserScroll(event: WheelEvent) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Tools />
|
||||
<ToolbarRightSide />
|
||||
</div>
|
||||
</header>
|
||||
</Transition>
|
||||
|
@ -1,104 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
defineOptions({
|
||||
name: 'Tools',
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const mainPage = useMainPage()
|
||||
const { isFullscreen, toggle } = useFullscreen()
|
||||
|
||||
function toggleColorScheme(event: MouseEvent) {
|
||||
const { startViewTransition } = useViewTransition(() => {
|
||||
settingsStore.setColorScheme(settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark')
|
||||
})
|
||||
startViewTransition()?.ready.then(() => {
|
||||
const x = event.clientX
|
||||
const y = event.clientY
|
||||
const endRadius = Math.hypot(
|
||||
Math.max(x, innerWidth - x),
|
||||
Math.max(y, innerHeight - y),
|
||||
)
|
||||
const clipPath = [
|
||||
`circle(0px at ${x}px ${y}px)`,
|
||||
`circle(${endRadius}px at ${x}px ${y}px)`,
|
||||
]
|
||||
document.documentElement.animate(
|
||||
{
|
||||
clipPath: settingsStore.settings.app.colorScheme !== 'dark' ? clipPath : clipPath.reverse(),
|
||||
},
|
||||
{
|
||||
duration: 300,
|
||||
easing: 'ease-out',
|
||||
pseudoElement: settingsStore.settings.app.colorScheme !== 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const avatarError = ref(false)
|
||||
watch(() => userStore.avatar, () => {
|
||||
if (avatarError.value) {
|
||||
avatarError.value = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tools flex items-center gap-4 whitespace-nowrap px-4">
|
||||
<span v-if="settingsStore.settings.toolbar.navSearch && settingsStore.mode === 'pc'" class="group inline-flex cursor-pointer items-center gap-1 rounded-2 bg-stone-1 px-2 py-1.5 text-dark ring-stone-3 ring-inset transition dark:bg-stone-9 dark:text-white hover:ring-1 dark:ring-stone-7" @click="eventBus.emit('global-search-toggle')">
|
||||
<SvgIcon name="ri:search-line" />
|
||||
<span class="text-sm text-stone-5 transition group-hover:text-dark dark:group-hover:text-white">搜索</span>
|
||||
<HKbd v-if="settingsStore.settings.navSearch.enableHotkeys" class="ml-2">{{ settingsStore.os === 'mac' ? '⌥' : 'Alt' }} S</HKbd>
|
||||
</span>
|
||||
<div class="flex items-center empty:hidden">
|
||||
<span v-if="settingsStore.settings.toolbar.navSearch && settingsStore.mode === 'mobile'" class="item" @click="eventBus.emit('global-search-toggle')">
|
||||
<SvgIcon name="ri:search-line" />
|
||||
</span>
|
||||
<span v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.fullscreen" class="item" @click="toggle">
|
||||
<SvgIcon :name="isFullscreen ? 'ri:fullscreen-exit-line' : 'ri:fullscreen-line'" />
|
||||
</span>
|
||||
<span v-if="settingsStore.settings.toolbar.pageReload" class="item" @click="mainPage.reload()">
|
||||
<SvgIcon name="iconoir:refresh-double" />
|
||||
</span>
|
||||
<span v-if="settingsStore.settings.toolbar.colorScheme" class="item" @click="toggleColorScheme">
|
||||
<SvgIcon :name="settingsStore.settings.app.colorScheme === 'light' ? 'ri:sun-line' : 'ri:moon-line'" />
|
||||
</span>
|
||||
</div>
|
||||
<HDropdownMenu
|
||||
:items="[
|
||||
[
|
||||
{ label: settingsStore.settings.home.title, handle: () => router.push({ path: settingsStore.settings.home.fullPath }), hide: !settingsStore.settings.home.enable },
|
||||
{ label: '个人设置', handle: () => router.push({ name: 'personalSetting' }) },
|
||||
],
|
||||
[
|
||||
{ label: '快捷键介绍', handle: () => eventBus.emit('global-hotkeys-intro-toggle'), hide: settingsStore.mode !== 'pc' },
|
||||
],
|
||||
[
|
||||
{ label: '退出登录', handle: () => userStore.logout() },
|
||||
],
|
||||
]"
|
||||
>
|
||||
<div flex-center cursor-pointer gap-1>
|
||||
<img v-if="userStore.avatar && !avatarError" :src="userStore.avatar" :onerror="() => (avatarError = true)" class="h-[24px] w-[24px] rounded-full">
|
||||
<SvgIcon v-else name="carbon:user-avatar-filled-alt" :size="24" class="text-gray-400" />
|
||||
{{ userStore.account }}
|
||||
<SvgIcon name="ep:caret-bottom" />
|
||||
</div>
|
||||
</HDropdownMenu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.item {
|
||||
--at-apply: flex px-2 py-1 cursor-pointer;
|
||||
}
|
||||
</style>
|
58
src/layouts/components/Topbar/Toolbar/Breadcrumb/index.vue
Normal file
58
src/layouts/components/Topbar/Toolbar/Breadcrumb/index.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import { compile } from 'path-to-regexp'
|
||||
import Breadcrumb from '../../../Breadcrumb/index.vue'
|
||||
import BreadcrumbItem from '../../../Breadcrumb/item.vue'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const breadcrumbList = computed(() => {
|
||||
const breadcrumbList = []
|
||||
if (settingsStore.settings.home.enable) {
|
||||
breadcrumbList.push({
|
||||
path: settingsStore.settings.home.fullPath,
|
||||
title: settingsStore.settings.home.title,
|
||||
})
|
||||
}
|
||||
if (route.meta.breadcrumbNeste) {
|
||||
route.meta.breadcrumbNeste.forEach((item) => {
|
||||
if (item.hide === false) {
|
||||
breadcrumbList.push({
|
||||
path: item.path,
|
||||
title: item.title,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return breadcrumbList
|
||||
})
|
||||
|
||||
function pathCompile(path: string) {
|
||||
const toPath = compile(path)
|
||||
return toPath(route.params)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb v-if="settingsStore.mode === 'pc' && settingsStore.settings.app.routeBaseOn !== 'filesystem'" class="breadcrumb whitespace-nowrap px-2">
|
||||
<TransitionGroup name="breadcrumb">
|
||||
<BreadcrumbItem v-for="(item, index) in breadcrumbList" :key="`${index}_${item.path}_${item.title}`" :to="index < breadcrumbList.length - 1 && item.path !== '' ? pathCompile(item.path) : ''">
|
||||
{{ item.title }}
|
||||
</BreadcrumbItem>
|
||||
</TransitionGroup>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// 面包屑动画
|
||||
.breadcrumb-enter-active {
|
||||
transition: transform 0.3s, opacity 0.3s;
|
||||
}
|
||||
|
||||
.breadcrumb-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(30px) skewX(-50deg);
|
||||
}
|
||||
</style>
|
43
src/layouts/components/Topbar/Toolbar/ColorScheme/index.vue
Normal file
43
src/layouts/components/Topbar/Toolbar/ColorScheme/index.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
defineOptions({
|
||||
name: 'ColorScheme',
|
||||
})
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
function toggleColorScheme(event: MouseEvent) {
|
||||
const { startViewTransition } = useViewTransition(() => {
|
||||
settingsStore.setColorScheme(settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark')
|
||||
})
|
||||
startViewTransition()?.ready.then(() => {
|
||||
const x = event.clientX
|
||||
const y = event.clientY
|
||||
const endRadius = Math.hypot(
|
||||
Math.max(x, innerWidth - x),
|
||||
Math.max(y, innerHeight - y),
|
||||
)
|
||||
const clipPath = [
|
||||
`circle(0px at ${x}px ${y}px)`,
|
||||
`circle(${endRadius}px at ${x}px ${y}px)`,
|
||||
]
|
||||
document.documentElement.animate(
|
||||
{
|
||||
clipPath: settingsStore.settings.app.colorScheme !== 'dark' ? clipPath : clipPath.reverse(),
|
||||
},
|
||||
{
|
||||
duration: 300,
|
||||
easing: 'ease-out',
|
||||
pseudoElement: settingsStore.settings.app.colorScheme !== 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="flex-center cursor-pointer px-2 py-1" @click="toggleColorScheme">
|
||||
<SvgIcon :name="settingsStore.settings.app.colorScheme === 'light' ? 'ri:sun-line' : 'ri:moon-line'" />
|
||||
</span>
|
||||
</template>
|
18
src/layouts/components/Topbar/Toolbar/Fullscreen/index.vue
Normal file
18
src/layouts/components/Topbar/Toolbar/Fullscreen/index.vue
Normal file
@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { useFullscreen } from '@vueuse/core'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
defineOptions({
|
||||
name: 'Fullscreen',
|
||||
})
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const { isFullscreen, toggle } = useFullscreen()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span v-if="settingsStore.mode === 'pc'" class="flex-center cursor-pointer px-2 py-1" @click="toggle">
|
||||
<SvgIcon :name="isFullscreen ? 'ri:fullscreen-exit-line' : 'ri:fullscreen-line'" />
|
||||
</span>
|
||||
</template>
|
21
src/layouts/components/Topbar/Toolbar/NavSearch/index.vue
Normal file
21
src/layouts/components/Topbar/Toolbar/NavSearch/index.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
defineOptions({
|
||||
name: 'ToolbarRightSide',
|
||||
})
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="flex-center cursor-pointer px-2 py-1" @click="eventBus.emit('global-search-toggle')">
|
||||
<SvgIcon v-if="settingsStore.mode === 'mobile'" name="ri:search-line" />
|
||||
<span v-else class="group inline-flex cursor-pointer items-center gap-1 whitespace-nowrap rounded-2 bg-stone-1 px-2 py-1.5 text-dark ring-stone-3 ring-inset transition dark:bg-stone-9 dark:text-white hover:ring-1 dark:ring-stone-7">
|
||||
<SvgIcon name="ri:search-line" />
|
||||
<span class="text-sm text-stone-5 transition group-hover:text-dark dark:group-hover:text-white">搜索</span>
|
||||
<HKbd v-if="settingsStore.settings.navSearch.enableHotkeys" class="ml-2">{{ settingsStore.os === 'mac' ? '⌥' : 'Alt' }} S</HKbd>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
13
src/layouts/components/Topbar/Toolbar/PageReload/index.vue
Normal file
13
src/layouts/components/Topbar/Toolbar/PageReload/index.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: 'PageReload',
|
||||
})
|
||||
|
||||
const mainPage = useMainPage()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="flex-center cursor-pointer px-2 py-1" @click="mainPage.reload()">
|
||||
<SvgIcon name="iconoir:refresh-double" />
|
||||
</span>
|
||||
</template>
|
@ -1,98 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { compile } from 'path-to-regexp'
|
||||
import Breadcrumb from '../../Breadcrumb/index.vue'
|
||||
import BreadcrumbItem from '../../Breadcrumb/item.vue'
|
||||
import Tools from '../../Tools/index.vue'
|
||||
import LeftSide from './leftSide.vue'
|
||||
import RightSide from './rightSide.vue'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
defineOptions({
|
||||
name: 'Toolbar',
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const enableSubMenuCollapseButton = computed(() => {
|
||||
return settingsStore.mode === 'mobile' || settingsStore.settings.menu.enableSubMenuCollapseButton
|
||||
})
|
||||
|
||||
const breadcrumbList = computed(() => {
|
||||
const breadcrumbList = []
|
||||
if (settingsStore.settings.home.enable) {
|
||||
breadcrumbList.push({
|
||||
path: settingsStore.settings.home.fullPath,
|
||||
title: settingsStore.settings.home.title,
|
||||
})
|
||||
}
|
||||
if (route.meta.breadcrumbNeste) {
|
||||
route.meta.breadcrumbNeste.forEach((item) => {
|
||||
if (item.hide === false) {
|
||||
breadcrumbList.push({
|
||||
path: item.path,
|
||||
title: item.title,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return breadcrumbList
|
||||
})
|
||||
|
||||
function pathCompile(path: string) {
|
||||
const toPath = compile(path)
|
||||
return toPath(route.params)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="toolbar-container">
|
||||
<div class="left-box">
|
||||
<div v-if="enableSubMenuCollapseButton" class="flex-center cursor-pointer px-2 py-1 transition-transform" :class="{ '-rotate-z-180': settingsStore.settings.menu.subMenuCollapse }" @click="settingsStore.toggleSidebarCollapse()">
|
||||
<SvgIcon name="toolbar-collapse" />
|
||||
</div>
|
||||
<Breadcrumb v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.breadcrumb && settingsStore.settings.app.routeBaseOn !== 'filesystem'" class="breadcrumb">
|
||||
<TransitionGroup name="breadcrumb">
|
||||
<BreadcrumbItem v-for="(item, index) in breadcrumbList" :key="`${index}_${item.path}_${item.title}`" :to="index < breadcrumbList.length - 1 && item.path !== '' ? pathCompile(item.path) : ''">
|
||||
{{ item.title }}
|
||||
</BreadcrumbItem>
|
||||
</TransitionGroup>
|
||||
</Breadcrumb>
|
||||
<div class="toolbar-container flex items-center justify-between">
|
||||
<div class="h-full flex items-center of-hidden pl-2 pr-16" style="mask-image: linear-gradient(90deg, #000 0%, #000 calc(100% - 50px), transparent);">
|
||||
<LeftSide />
|
||||
</div>
|
||||
<div v-show="['side', 'single'].includes(settingsStore.settings.menu.menuMode)" class="h-full flex items-center px-2">
|
||||
<RightSide />
|
||||
</div>
|
||||
<Tools />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.toolbar-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: var(--g-toolbar-height);
|
||||
background-color: var(--g-container-bg);
|
||||
transition: background-color 0.3s;
|
||||
|
||||
.left-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 50px;
|
||||
padding-left: 10px;
|
||||
overflow: hidden;
|
||||
mask-image: linear-gradient(90deg, #000 0%, #000 calc(100% - 50px), transparent);
|
||||
|
||||
.breadcrumb {
|
||||
padding-left: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 面包屑动画
|
||||
.breadcrumb-enter-active {
|
||||
transition: transform 0.3s, opacity 0.3s;
|
||||
}
|
||||
|
||||
.breadcrumb-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateX(30px) skewX(-50deg);
|
||||
}
|
||||
</style>
|
||||
|
23
src/layouts/components/Topbar/Toolbar/leftSide.vue
Normal file
23
src/layouts/components/Topbar/Toolbar/leftSide.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import Breadcrumb from './Breadcrumb/index.vue'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
|
||||
defineOptions({
|
||||
name: 'ToolbarLeftSide',
|
||||
})
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
const enableSubMenuCollapseButton = computed(() => {
|
||||
return settingsStore.mode === 'mobile' || settingsStore.settings.menu.enableSubMenuCollapseButton
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center">
|
||||
<div v-if="enableSubMenuCollapseButton" class="flex-center cursor-pointer px-2 py-1 transition-transform" :class="{ '-rotate-z-180': settingsStore.settings.menu.subMenuCollapse }" @click="settingsStore.toggleSidebarCollapse()">
|
||||
<SvgIcon name="toolbar-collapse" />
|
||||
</div>
|
||||
<Breadcrumb v-if="settingsStore.settings.toolbar.breadcrumb" />
|
||||
</div>
|
||||
</template>
|
54
src/layouts/components/Topbar/Toolbar/rightSide.vue
Normal file
54
src/layouts/components/Topbar/Toolbar/rightSide.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<script setup lang="ts">
|
||||
import NavSearch from './NavSearch/index.vue'
|
||||
import Fullscreen from './Fullscreen/index.vue'
|
||||
import PageReload from './PageReload/index.vue'
|
||||
import ColorScheme from './ColorScheme/index.vue'
|
||||
import eventBus from '@/utils/eventBus'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
|
||||
defineOptions({
|
||||
name: 'Tools',
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const avatarError = ref(false)
|
||||
watch(() => userStore.avatar, () => {
|
||||
if (avatarError.value) {
|
||||
avatarError.value = false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center">
|
||||
<NavSearch v-if="settingsStore.settings.toolbar.navSearch" />
|
||||
<Fullscreen v-if="settingsStore.settings.toolbar.fullscreen" />
|
||||
<PageReload v-if="settingsStore.settings.toolbar.pageReload" />
|
||||
<ColorScheme v-if="settingsStore.settings.toolbar.colorScheme" />
|
||||
<HDropdownMenu
|
||||
:items="[
|
||||
[
|
||||
{ label: settingsStore.settings.home.title, handle: () => router.push({ path: settingsStore.settings.home.fullPath }), hide: !settingsStore.settings.home.enable },
|
||||
],
|
||||
[
|
||||
{ label: '快捷键介绍', handle: () => eventBus.emit('global-hotkeys-intro-toggle'), hide: settingsStore.mode !== 'pc' },
|
||||
],
|
||||
[
|
||||
{ label: '退出登录', handle: () => userStore.logout() },
|
||||
],
|
||||
]" class="flex-center cursor-pointer px-2"
|
||||
>
|
||||
<div class="flex-center gap-1">
|
||||
<img v-if="userStore.avatar && !avatarError" :src="userStore.avatar" :onerror="() => (avatarError = true)" class="h-[24px] w-[24px] rounded-full">
|
||||
<SvgIcon v-else name="carbon:user-avatar-filled-alt" :size="24" class="text-gray-400" />
|
||||
{{ userStore.account }}
|
||||
<SvgIcon name="ep:caret-bottom" />
|
||||
</div>
|
||||
</HDropdownMenu>
|
||||
</div>
|
||||
</template>
|
@ -222,10 +222,6 @@ header:not(.header-leave-active) + .wrapper {
|
||||
.main-container {
|
||||
.topbar-container {
|
||||
top: var(--g-header-height);
|
||||
|
||||
:deep(.tools) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user