优化平台配置导航布局

This commit is contained in:
yml2213
2026-05-26 09:39:59 +08:00
parent 5c7e145766
commit 8b1904d732
4 changed files with 313 additions and 221 deletions
@@ -2,6 +2,8 @@
import { computed, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import {
Bell,
Connection,
Monitor,
DataAnalysis,
Document,
@@ -27,6 +29,7 @@ import { formatAdminDateTime } from '@/utils/admin-time'
const route = useRoute()
const router = useRouter()
const sidebarStorageKey = 'admin-sidebar-collapsed'
const isDevMode = import.meta.env.DEV
const isSidebarCollapsed = ref(
typeof window !== 'undefined' && window.localStorage.getItem(sidebarStorageKey) === '1',
)
@@ -40,8 +43,33 @@ const roleLabel = computed(() => {
return '普通运营'
})
type AdminNavItem = {
to: string
label: string
icon: typeof DataAnalysis
children?: AdminNavItem[]
}
const platformConfigNavItems = computed<AdminNavItem[]>(() => {
const items: AdminNavItem[] = [
{ to: '/admin/platform-shops?tab=ninetyone', label: '91卡券', icon: Connection },
{ to: '/admin/platform-shops?tab=notifications', label: '内部通知', icon: Bell },
{ to: '/admin/platform-shops?tab=kuaishouEticket', label: '快手小店核销', icon: Tickets },
]
if (isDevMode) {
items.push({
to: '/admin/platform-shops?tab=cloudtentacles',
label: 'cloudtentacles',
icon: Setting,
})
}
return items
})
const navItems = computed(() => {
const items: { to: string; label: string; icon: typeof DataAnalysis }[] = [
const items: AdminNavItem[] = [
{ to: '/admin/dashboard', label: '概览', icon: DataAnalysis },
]
@@ -56,7 +84,12 @@ const navItems = computed(() => {
if (isAdmin.value) {
items.push(
{ to: '/admin/platform-shops', label: '平台配置', icon: Setting },
{
to: '/admin/platform-shops',
label: '平台配置',
icon: Setting,
children: platformConfigNavItems.value,
},
{ to: '/admin/platform-fulfillment', label: '履约配置', icon: Tickets },
{ to: '/admin/audit-logs', label: '审计', icon: Monitor },
)
@@ -65,6 +98,15 @@ const navItems = computed(() => {
return items
})
const activeNavIndex = computed(() => {
if (route.path === '/admin/platform-shops') {
const tab = typeof route.query.tab === 'string' ? route.query.tab : 'ninetyone'
return `/admin/platform-shops?tab=${tab}`
}
return route.path
})
function toggleSidebarCollapse() {
isSidebarCollapsed.value = !isSidebarCollapsed.value
if (typeof window !== 'undefined') {
@@ -112,17 +154,37 @@ async function submitLogout() {
</div>
<el-menu
:default-active="route.path"
:default-active="activeNavIndex"
:default-openeds="['/admin/platform-shops']"
router
class="sidebar-menu"
:collapse="isSidebarCollapsed"
:collapse-transition="false"
:ellipsis="false"
>
<el-menu-item v-for="item in navItems" :key="item.to" :index="item.to" :title="item.label">
<el-icon><component :is="item.icon" /></el-icon>
<span>{{ item.label }}</span>
</el-menu-item>
<template v-for="item in navItems" :key="item.to">
<el-sub-menu v-if="item.children?.length" :index="item.to">
<template #title>
<el-icon><component :is="item.icon" /></el-icon>
<span>{{ item.label }}</span>
</template>
<el-menu-item
v-for="child in item.children"
:key="child.to"
:index="child.to"
:title="child.label"
>
<el-icon><component :is="child.icon" /></el-icon>
<span>{{ child.label }}</span>
</el-menu-item>
</el-sub-menu>
<el-menu-item v-else :index="item.to" :title="item.label">
<el-icon><component :is="item.icon" /></el-icon>
<span>{{ item.label }}</span>
</el-menu-item>
</template>
</el-menu>
<el-tooltip :disabled="!isSidebarCollapsed" content="退出登录" placement="right">
@@ -235,18 +297,33 @@ async function submitLogout() {
width: 100%;
}
.sidebar-menu :deep(.el-menu-item) {
.sidebar-menu :deep(.el-menu-item),
.sidebar-menu :deep(.el-sub-menu__title) {
margin: 2px var(--space-2);
border-radius: var(--radius-md);
min-height: 44px;
line-height: 44px;
}
.sidebar-menu :deep(.el-menu-item.is-active) {
.sidebar-menu :deep(.el-menu-item.is-active),
.sidebar-menu :deep(.el-sub-menu.is-active > .el-sub-menu__title) {
color: var(--color-primary);
background: var(--color-primary-light);
}
.sidebar-menu :deep(.el-sub-menu .el-menu-item) {
margin-left: var(--space-4);
min-height: 38px;
line-height: 38px;
color: var(--text-secondary);
font-size: var(--text-sm);
}
.sidebar-menu :deep(.el-sub-menu .el-menu-item.is-active) {
color: var(--color-primary);
font-weight: 700;
}
.logout-btn {
margin: var(--space-3) var(--space-4) 0;
flex-shrink: 0;
@@ -263,13 +340,15 @@ async function submitLogout() {
margin-bottom: var(--space-5);
}
.is-sidebar-collapsed .sidebar-menu :deep(.el-menu-item) {
.is-sidebar-collapsed .sidebar-menu :deep(.el-menu-item),
.is-sidebar-collapsed .sidebar-menu :deep(.el-sub-menu__title) {
justify-content: center;
margin: 4px 10px;
padding: 0;
}
.is-sidebar-collapsed .sidebar-menu :deep(.el-menu-item .el-icon) {
.is-sidebar-collapsed .sidebar-menu :deep(.el-menu-item .el-icon),
.is-sidebar-collapsed .sidebar-menu :deep(.el-sub-menu__title .el-icon) {
margin-right: 0;
}
@@ -313,7 +392,8 @@ async function submitLogout() {
overflow: visible;
}
.is-sidebar-collapsed .sidebar-menu :deep(.el-menu-item) {
.is-sidebar-collapsed .sidebar-menu :deep(.el-menu-item),
.is-sidebar-collapsed .sidebar-menu :deep(.el-sub-menu__title) {
justify-content: flex-start;
margin: 2px var(--space-2);
padding: 0 var(--space-5);