修复菜单逻辑
This commit is contained in:
parent
34035fb007
commit
86c4060843
@ -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,42 +104,59 @@ const activeBgColor = computed(() => {
|
||||
|
||||
// 将后端数据转换为前端需要的格式
|
||||
const transformMenuData = (menus) => {
|
||||
// 首先映射字段格式
|
||||
const mappedMenus = menus.map(menu => ({
|
||||
id: menu.id,
|
||||
path: menu.path,
|
||||
icon: menu.icon || 'fa-circle',
|
||||
label: menu.name,
|
||||
route: menu.path,
|
||||
parentId: menu.parentId || 0,
|
||||
order: menu.order || 0,
|
||||
children: []
|
||||
}));
|
||||
// 功能页面路径关键词,这些菜单不应该显示在侧边栏
|
||||
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',
|
||||
label: menu.name,
|
||||
route: menu.path,
|
||||
parentId: menu.parentId || 0,
|
||||
order: menu.order || 0,
|
||||
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
pc/src/components/MenuTreeItem.vue
Normal file
35
pc/src/components/MenuTreeItem.vue
Normal 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
pc/src/views/apps/oa/employees/index.vue
Normal file
7
pc/src/views/apps/oa/employees/index.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div>员工管理</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
13
pc/src/views/apps/oa/index.vue
Normal file
13
pc/src/views/apps/oa/index.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user