修复菜单逻辑

This commit is contained in:
2025-11-04 10:57:32 +08:00
parent 34035fb007
commit 86c4060843
4 changed files with 95 additions and 49 deletions
+31 -40
View File
@@ -24,34 +24,7 @@
</template>
</el-menu-item>
<template v-for="item in sortedMenuList" :key="item.path">
<el-menu-item
v-if="!item.children || item.children.length === 0"
:index="item.path"
>
<i :class="['icons', 'fa', item.icon]"></i>
<template #title>
<span>{{ item.label }}</span>
</template>
</el-menu-item>
<el-sub-menu
v-else
:index="item.path"
>
<template #title>
<i :class="['icons', 'fa', item.icon]"></i>
<span>{{ item.label }}</span>
</template>
<el-menu-item
v-for="subItem in item.children"
:key="subItem.path"
:index="subItem.path"
>
<i :class="['icons', 'fa', subItem.icon && typeof subItem.icon === 'string' ? subItem.icon.trim() : '']"></i>
<template #title>
<span>{{ subItem.label }}</span>
</template>
</el-menu-item>
</el-sub-menu>
<MenuTreeItem :menu="item" />
</template>
</el-menu>
</el-aside>
@@ -62,6 +35,7 @@ import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useAllDataStore } from '@/stores';
import { getAllMenus } from '@/api/menu';
import MenuTreeItem from './MenuTreeItem.vue';
const emit = defineEmits(['menu-click']);
@@ -130,8 +104,26 @@ const activeBgColor = computed(() => {
// 将后端数据转换为前端需要的格式
const transformMenuData = (menus) => {
// 首先映射字段格式
const mappedMenus = menus.map(menu => ({
// 功能页面路径关键词,这些菜单不应该显示在侧边栏
const functionPageKeywords = ['/detail', '/add', '/edit', '/delete', '/create', '/update', '/category', '/tag'];
// 判断是否是功能页面
const isFunctionPage = (path) => {
if (!path) return false;
const lowerPath = path.toLowerCase();
return functionPageKeywords.some(keyword => lowerPath.includes(keyword));
};
// 首先映射字段格式,只保留页面菜单(menu_type=1),并过滤掉功能页面
const allMenus = menus
.filter(menu => {
// 只显示页面菜单,不显示API权限菜单
if (menu.menuType !== 1) return false;
// 过滤掉功能页面(详情、新增、编辑、删除、分类、标签等)
if (isFunctionPage(menu.path)) return false;
return true;
})
.map(menu => ({
id: menu.id,
path: menu.path,
icon: menu.icon || 'fa-circle',
@@ -142,30 +134,29 @@ const transformMenuData = (menus) => {
children: []
}));
// 构建树形结构
// 构建菜单映射表(只包含有效的页面菜单)
const menuMap = new Map();
const rootMenus = [];
// 先创建所有菜单的映射
mappedMenus.forEach(menu => {
allMenus.forEach(menu => {
menuMap.set(menu.id, menu);
});
// 构建树形结构
mappedMenus.forEach(menu => {
// 构建树形结构,只保留那些父菜单也存在的菜单项
const rootMenus = [];
allMenus.forEach(menu => {
if (menu.parentId === 0) {
// 顶级菜单直接加入
rootMenus.push(menu);
} else {
// 检查父菜单是否存在(必须是有效的页面菜单)
const parent = menuMap.get(menu.parentId);
if (parent) {
// 父菜单存在,添加到父菜单的children中
if (!parent.children) {
parent.children = [];
}
parent.children.push(menu);
} else {
// 如果找不到父节点,作为根节点处理
rootMenus.push(menu);
}
// 如果父菜单不存在(被过滤掉了或者是menu_type=2),则忽略该菜单项,不添加到任何地方
}
});
+35
View File
@@ -0,0 +1,35 @@
<template>
<el-menu-item
v-if="!menu.children || menu.children.length === 0"
:index="menu.path"
>
<i :class="['icons', 'fa', menu.icon || 'fa-circle']"></i>
<template #title>
<span>{{ menu.label }}</span>
</template>
</el-menu-item>
<el-sub-menu
v-else
:index="menu.path"
>
<template #title>
<i :class="['icons', 'fa', menu.icon || 'fa-circle']"></i>
<span>{{ menu.label }}</span>
</template>
<MenuTreeItem
v-for="child in menu.children"
:key="child.path"
:menu="child"
/>
</el-sub-menu>
</template>
<script setup>
defineProps({
menu: {
type: Object,
required: true
}
});
</script>
+7
View File
@@ -0,0 +1,7 @@
<template>
<div>员工管理</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>
+13
View File
@@ -0,0 +1,13 @@
<template>
<div>
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>