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-sider>
<a-layout> <a-layout>
<a-layout-header style="background: #fff; padding: 0"> <a-layout-header style="background: #fff; padding: 0">
<div class="header-right"> <div class="header-content">
<a-dropdown> <div class="header-left">
<a class="ant-dropdown-link" @click.prevent> <menu-unfold-outlined
{{ userInfo.nickname }} v-if="collapsed"
<down-outlined /> class="trigger"
</a> @click="() => (collapsed = !collapsed)"
<template #overlay> />
<a-menu> <menu-fold-outlined
<a-menu-item @click="handleLogout"> v-else
<logout-outlined /> class="trigger"
退出登录 @click="() => (collapsed = !collapsed)"
</a-menu-item> />
</a-menu> <div class="breadcrumb-container">
</template> <div class="page-breadcrumb">
</a-dropdown> <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> </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-header>
<a-layout-content <a-layout-content
:style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }" :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }"
@ -163,7 +175,7 @@
</template> </template>
<script> <script>
import { ref, defineComponent } from 'vue' import { ref, defineComponent, onMounted, watch, computed } from 'vue'
import { import {
UserOutlined, UserOutlined,
HomeOutlined, HomeOutlined,
@ -178,7 +190,7 @@ import {
MoneyCollectOutlined, MoneyCollectOutlined,
GiftOutlined GiftOutlined
} from '@ant-design/icons-vue' } from '@ant-design/icons-vue'
import { useRouter } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
export default defineComponent({ export default defineComponent({
name: 'BasicLayout', name: 'BasicLayout',
@ -198,6 +210,7 @@ export default defineComponent({
}, },
setup() { setup() {
const router = useRouter() const router = useRouter()
const route = useRoute()
const collapsed = ref(false) const collapsed = ref(false)
const selectedKeys = ref(['dashboard']) const selectedKeys = ref(['dashboard'])
const openKeys = ref([]) const openKeys = ref([])
@ -227,6 +240,7 @@ export default defineComponent({
key: 'user', key: 'user',
icon: () => h(UserOutlined), icon: () => h(UserOutlined),
title: '用户管理', title: '用户管理',
path: '/user',
children: [ children: [
{ {
key: 'user-list', key: 'user-list',
@ -237,19 +251,19 @@ export default defineComponent({
key: 'user-partner', key: 'user-partner',
title: '运营商管理', title: '运营商管理',
path: '/user/partner' path: '/user/partner'
},
{
key: 'deliveryman-list',
title: '配送员列表',
path: '/deliveryman/list'
} }
] ]
}, },
{
key: 'deliveryman',
icon: () => h(UserOutlined),
title: '配送员管理',
path: '/deliveryman/list'
},
{ {
key: 'order', key: 'order',
icon: () => h(ShoppingOutlined), icon: () => h(ShoppingOutlined),
title: '订单管理', title: '订单管理',
path: '/order',
children: [ children: [
{ {
key: 'order-delivery', key: 'order-delivery',
@ -267,6 +281,7 @@ export default defineComponent({
key: 'finance', key: 'finance',
icon: () => h(MoneyCollectOutlined), icon: () => h(MoneyCollectOutlined),
title: '财务管理', title: '财务管理',
path: '/finance',
children: [ children: [
{ {
key: 'finance-withdraw', key: 'finance-withdraw',
@ -279,6 +294,7 @@ export default defineComponent({
key: 'community', key: 'community',
icon: () => h(HomeOutlined), icon: () => h(HomeOutlined),
title: '小区管理', title: '小区管理',
path: '/community',
children: [ children: [
{ {
key: 'community-list', key: 'community-list',
@ -311,6 +327,7 @@ export default defineComponent({
key: 'coupon', key: 'coupon',
icon: () => h(GiftOutlined), icon: () => h(GiftOutlined),
title: '优惠券管理', title: '优惠券管理',
path: '/coupon',
children: [ children: [
{ {
key: 'coupon-template', key: 'coupon-template',
@ -328,6 +345,7 @@ export default defineComponent({
key: 'merchant', key: 'merchant',
icon: () => h(ShopOutlined), icon: () => h(ShopOutlined),
title: '商家管理', title: '商家管理',
path: '/merchant',
children: [ children: [
{ {
key: 'merchant-list', key: 'merchant-list',
@ -350,6 +368,7 @@ export default defineComponent({
key: 'system', key: 'system',
icon: () => h(SettingOutlined), icon: () => h(SettingOutlined),
title: '系统管理', title: '系统管理',
path: '/system',
children: [ children: [
{ {
key: 'system-logs', 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 { return {
collapsed, collapsed,
selectedKeys, selectedKeys,
openKeys, openKeys,
userInfo, userInfo,
handleLogout, handleLogout,
menuItems menuItems,
breadcrumbItems
} }
}, },
}) })
@ -418,10 +521,38 @@ export default defineComponent({
:deep(.ant-layout-sider-collapsed) .logo-text { :deep(.ant-layout-sider-collapsed) .logo-text {
display: none; 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 { .header-right {
float: right;
margin-right: 24px; margin-right: 24px;
line-height: 64px;
} }
.ant-dropdown-link { .ant-dropdown-link {
color: rgba(0, 0, 0, 0.85); color: rgba(0, 0, 0, 0.85);