This commit is contained in:
aaron 2025-03-09 23:55:00 +08:00
parent 3392409028
commit ef2dc67247

View File

@ -126,32 +126,44 @@
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0">
<div class="header-right">
<a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
{{ userInfo.nickname }}
<down-outlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item @click="handleLogout">
<logout-outlined />
退出登录
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<div class="header-content">
<div class="header-left">
<menu-unfold-outlined
v-if="collapsed"
class="trigger"
@click="() => (collapsed = !collapsed)"
/>
<menu-fold-outlined
v-else
class="trigger"
@click="() => (collapsed = !collapsed)"
/>
<div class="breadcrumb-container">
<div class="page-breadcrumb">
<template v-for="(item, index) in breadcrumbItems" :key="index">
<span class="breadcrumb-item">{{ item.title }}</span>
<span v-if="index < breadcrumbItems.length - 1" class="breadcrumb-separator">&gt;</span>
</template>
</div>
</div>
</div>
<div class="header-right">
<a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
{{ userInfo.nickname }}
<down-outlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item @click="handleLogout">
<logout-outlined />
退出登录
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
</div>
<menu-unfold-outlined
v-if="collapsed"
class="trigger"
@click="() => (collapsed = !collapsed)"
/>
<menu-fold-outlined
v-else
class="trigger"
@click="() => (collapsed = !collapsed)"
/>
</a-layout-header>
<a-layout-content
:style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }"
@ -163,7 +175,7 @@
</template>
<script>
import { ref, defineComponent } from 'vue'
import { ref, defineComponent, onMounted, watch, computed } from 'vue'
import {
UserOutlined,
HomeOutlined,
@ -178,7 +190,7 @@ import {
MoneyCollectOutlined,
GiftOutlined
} from '@ant-design/icons-vue'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
export default defineComponent({
name: 'BasicLayout',
@ -198,6 +210,7 @@ export default defineComponent({
},
setup() {
const router = useRouter()
const route = useRoute()
const collapsed = ref(false)
const selectedKeys = ref(['dashboard'])
const openKeys = ref([])
@ -227,6 +240,7 @@ export default defineComponent({
key: 'user',
icon: () => h(UserOutlined),
title: '用户管理',
path: '/user',
children: [
{
key: 'user-list',
@ -237,19 +251,19 @@ export default defineComponent({
key: 'user-partner',
title: '运营商管理',
path: '/user/partner'
},
{
key: 'deliveryman-list',
title: '配送员列表',
path: '/deliveryman/list'
}
]
},
{
key: 'deliveryman',
icon: () => h(UserOutlined),
title: '配送员管理',
path: '/deliveryman/list'
},
{
key: 'order',
icon: () => h(ShoppingOutlined),
title: '订单管理',
path: '/order',
children: [
{
key: 'order-delivery',
@ -267,6 +281,7 @@ export default defineComponent({
key: 'finance',
icon: () => h(MoneyCollectOutlined),
title: '财务管理',
path: '/finance',
children: [
{
key: 'finance-withdraw',
@ -279,6 +294,7 @@ export default defineComponent({
key: 'community',
icon: () => h(HomeOutlined),
title: '小区管理',
path: '/community',
children: [
{
key: 'community-list',
@ -311,6 +327,7 @@ export default defineComponent({
key: 'coupon',
icon: () => h(GiftOutlined),
title: '优惠券管理',
path: '/coupon',
children: [
{
key: 'coupon-template',
@ -328,6 +345,7 @@ export default defineComponent({
key: 'merchant',
icon: () => h(ShopOutlined),
title: '商家管理',
path: '/merchant',
children: [
{
key: 'merchant-list',
@ -350,6 +368,7 @@ export default defineComponent({
key: 'system',
icon: () => h(SettingOutlined),
title: '系统管理',
path: '/system',
children: [
{
key: 'system-logs',
@ -370,13 +389,97 @@ export default defineComponent({
},
])
//
const updateMenuStatus = () => {
const path = route.path
//
const findMenuItem = (items) => {
for (const item of items) {
if (item.path && path.startsWith(item.path)) {
return item.key
}
if (item.children) {
const childKey = findMenuItem(item.children)
if (childKey) {
openKeys.value = Array.from(new Set([...openKeys.value, item.key]))
return childKey
}
}
}
return null
}
const menuKey = findMenuItem(menuItems.value)
if (menuKey) {
selectedKeys.value = [menuKey]
}
}
//
const breadcrumbItems = computed(() => {
const path = route.path
const result = [{ title: '首页', path: '/dashboard' }]
//
const findBreadcrumbPath = (items, parentPath = null) => {
for (const item of items) {
if (item.path && path.startsWith(item.path)) {
if (parentPath) {
result.push(parentPath)
}
result.push({ title: item.title, path: item.path })
if (item.children) {
findBreadcrumbPath(item.children)
}
//
const pathParts = path.split('/')
const itemPathParts = item.path.split('/')
if (pathParts.length > itemPathParts.length) {
// /community/sets/123
if (pathParts[itemPathParts.length] && !isNaN(pathParts[itemPathParts.length])) {
result.push({ title: '详情', path: '' })
}
}
return true
}
if (item.children) {
const found = findBreadcrumbPath(item.children, { title: item.title, path: item.path })
if (found) return true
}
}
return false
}
findBreadcrumbPath(menuItems.value)
return result
})
//
onMounted(() => {
updateMenuStatus()
})
//
watch(() => route.path, () => {
updateMenuStatus()
})
return {
collapsed,
selectedKeys,
openKeys,
userInfo,
handleLogout,
menuItems
menuItems,
breadcrumbItems
}
},
})
@ -418,10 +521,38 @@ export default defineComponent({
:deep(.ant-layout-sider-collapsed) .logo-text {
display: none;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
}
.header-left {
display: flex;
align-items: center;
}
.breadcrumb-container {
margin-left: 16px;
height: 64px;
display: flex;
align-items: center;
}
.page-breadcrumb {
display: flex;
align-items: center;
font-size: 14px;
}
.breadcrumb-item {
display: inline-block;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
}
.breadcrumb-separator {
margin: 0 8px;
color: #8c8c8c;
}
.header-right {
float: right;
margin-right: 24px;
line-height: 64px;
}
.ant-dropdown-link {
color: rgba(0, 0, 0, 0.85);