feat: 菜单管理 菜单配置 修复菜单重复问题
This commit is contained in:
parent
bdc4f065ef
commit
25f4ecdbab
|
@ -21,6 +21,7 @@
|
|||
@select="onSelect"
|
||||
:selectedKeys="selectedKeys"
|
||||
@drop="onDrop"
|
||||
@dragend="onDragend"
|
||||
>
|
||||
<template #title="row">
|
||||
<div class="tree-content">
|
||||
|
@ -63,12 +64,12 @@ import {
|
|||
} from '@/api/initHome';
|
||||
import {
|
||||
filterMenu,
|
||||
mergeMapToArr,
|
||||
developArrToMap,
|
||||
initData,
|
||||
drop,
|
||||
select,
|
||||
getMaxDepth,
|
||||
mergeArr,
|
||||
findAllParentsAndChildren,
|
||||
} from './utils';
|
||||
import BaseMenu from '@/views/init-home/data/baseMenu';
|
||||
import type { AntTreeNodeDropEvent } from 'ant-design-vue/es/tree';
|
||||
|
@ -83,9 +84,9 @@ const selectedKeys: any = ref([]);
|
|||
const treeData = ref<any>([]);
|
||||
const systemMenu: any = ref([]);
|
||||
const baseMenu: any = ref([]);
|
||||
const AllMenu = ref([]);
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const treeDataDropChange = ref(false); // 标记treeData拖拽成功
|
||||
|
||||
const params = {
|
||||
paging: false,
|
||||
|
@ -156,12 +157,31 @@ const onDrop = (info: AntTreeNodeDropEvent) => {
|
|||
const maxDepth = getMaxDepth(newTreeData);
|
||||
if (maxDepth > 3) {
|
||||
onlyMessage('仅支持3级菜单', 'error');
|
||||
treeDataDropChange.value = false;
|
||||
treeData.value = TreeData;
|
||||
} else {
|
||||
treeDataDropChange.value = true;
|
||||
treeData.value = newTreeData;
|
||||
}
|
||||
};
|
||||
|
||||
const onDragend = (info: AntTreeNodeDropEvent) => {
|
||||
const { node } = info;
|
||||
const { children } = findAllParentsAndChildren(
|
||||
cloneDeep(treeData.value),
|
||||
node.code,
|
||||
);
|
||||
const cancelKeys = [node.code, ...children];
|
||||
const Keys = new Set(cloneDeep(selectedKeys.value));
|
||||
cancelKeys.forEach((i) => {
|
||||
Keys.has(i) && Keys.delete(i);
|
||||
});
|
||||
//拖拽成功时更新selectedKeys
|
||||
if (treeDataDropChange.value) {
|
||||
selectedKeys.value = [...Keys];
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getSystemPermission_api().then((resp: any) => {
|
||||
baseMenu.value = filterMenu(
|
||||
|
@ -178,13 +198,16 @@ onMounted(() => {
|
|||
].includes(item.code),
|
||||
);
|
||||
//初始化菜单
|
||||
const baseMenuData = developArrToMap(baseMenu.value);
|
||||
const systemMenuData = developArrToMap(systemMenu.value, true);
|
||||
initData(baseMenu.value); // 不要克隆,通过引用 处理key和name
|
||||
const systemMenuData = initData(systemMenu.value);
|
||||
selectedKeys.value = systemMenuData.checkedKeys;
|
||||
// AllMenu.value = mergeMapToArr(baseMenuData, systemMenuData);
|
||||
AllMenu.value = mergeArr(cloneDeep(BaseMenu), systemMenu.value);
|
||||
|
||||
treeData.value = cloneDeep(AllMenu.value);
|
||||
const AllMenu = mergeArr(
|
||||
cloneDeep(BaseMenu),
|
||||
cloneDeep(systemMenu.value),
|
||||
);
|
||||
|
||||
treeData.value = AllMenu;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { cloneDeep } from 'lodash-es';
|
||||
import type {
|
||||
AntTreeNodeDropEvent,
|
||||
TreeProps,
|
||||
|
@ -22,17 +23,17 @@ export const filterMenu = (permissions: string[], menus: any[]) => {
|
|||
});
|
||||
};
|
||||
|
||||
// 拖拽跨级 存在顺序错乱,重复code todo
|
||||
/**
|
||||
* 合并数组(合并菜单)
|
||||
* @param oldData Array 默认菜单
|
||||
* @param newData Array 当前系统菜单
|
||||
* @returns Array 合并后的菜单
|
||||
*/
|
||||
|
||||
export const mergeArr = (oldData: Array<any>, newData: Array<any>) => {
|
||||
const mergedData = [];
|
||||
|
||||
const { checkedKeys } = initData(cloneDeep(newData));
|
||||
const filterCodeSet = new Set(checkedKeys); //记录系统选中
|
||||
const mergeItem: any = (oldItem: any, newItem: any) => {
|
||||
if (!oldItem) {
|
||||
return newItem;
|
||||
|
@ -43,9 +44,9 @@ export const mergeArr = (oldData: Array<any>, newData: Array<any>) => {
|
|||
return oldItem;
|
||||
}
|
||||
|
||||
if (oldItem.children && !newItem.children) {
|
||||
return oldItem;
|
||||
}
|
||||
// if (oldItem.children && !newItem.children) {
|
||||
// return oldItem;
|
||||
// }
|
||||
|
||||
if (oldItem.children && newItem.children) {
|
||||
const mergedChildren = [];
|
||||
|
@ -60,7 +61,10 @@ export const mergeArr = (oldData: Array<any>, newData: Array<any>) => {
|
|||
);
|
||||
newChildren.splice(index, 1);
|
||||
} else {
|
||||
mergedChildren.push(oldChild);
|
||||
//防止重复code,系统已经选中的code不能再从old中添加
|
||||
if (!filterCodeSet.has(oldChild.code)) {
|
||||
mergedChildren.push(oldChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
@ -76,11 +80,21 @@ export const mergeArr = (oldData: Array<any>, newData: Array<any>) => {
|
|||
const oldItem = oldData.find((item) => item.code === newItem.code);
|
||||
mergedData.push(mergeItem(oldItem, newItem));
|
||||
}
|
||||
|
||||
for (const oldItem of oldData) {
|
||||
const newItem = newData.find((item) => item.code === oldItem.code);
|
||||
if (!newItem) {
|
||||
mergedData.push(oldItem);
|
||||
if (!filterCodeSet.has(oldItem.code)) {
|
||||
const newItem = newData.find((item) => item.code === oldItem.code);
|
||||
if (!newItem) {
|
||||
//防止重复code,系统已经选中的code不能再从old中添加
|
||||
if (!filterCodeSet.has(oldItem.code)) {
|
||||
if (oldItem.children) {
|
||||
oldItem.children = oldItem.children.filter(
|
||||
(i: any) => !filterCodeSet.has(i.code),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mergedData.push(oldItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,70 +102,26 @@ export const mergeArr = (oldData: Array<any>, newData: Array<any>) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* 合并Map菜单转成Arr菜单
|
||||
* @param baseMenuData baseMenu developArrToMap平铺后的数据
|
||||
* @param systemMenuData systemMenu developArrToMap平铺后的数据
|
||||
* @returns 合并后的菜单
|
||||
*/
|
||||
export const mergeMapToArr = (baseMenuData: any, systemMenuData: any) => {
|
||||
const updataArr = (r: any) => {
|
||||
for (let i = 0; i < r.length; i++) {
|
||||
let child = r[i].children;
|
||||
if (child) {
|
||||
updataArr(child);
|
||||
}
|
||||
r[i] = newMap.get(r[i].code);
|
||||
r[i]?.parentCode && delete r[i].parentCode;
|
||||
}
|
||||
};
|
||||
const root: any = [];
|
||||
const newMap = new Map([...baseMenuData?.arrMap, ...systemMenuData.arrMap]);
|
||||
const newRootArr = [
|
||||
...new Set([...baseMenuData?.rootSet, ...systemMenuData.rootSet]),
|
||||
];
|
||||
newRootArr.forEach((item: any) => {
|
||||
newMap.has(item) && root.push(newMap.get(item));
|
||||
});
|
||||
updataArr(root);
|
||||
return root;
|
||||
};
|
||||
|
||||
/**
|
||||
* 平铺菜单
|
||||
* 初始化菜单
|
||||
* @param value 默认菜单以及查询系统菜单 baseMenu systemMenu
|
||||
* @param checked 查询系统菜单传true
|
||||
* @param save 保存时传true
|
||||
* @returns 平铺菜单Map、根菜单名、系统选中的keys
|
||||
* @returns 系统选中的keys
|
||||
*/
|
||||
export const developArrToMap = (Menu: any, checked = false, save = false) => {
|
||||
const rootSet = new Set();
|
||||
const arrMap = new Map();
|
||||
export const initData = (Menu: any) => {
|
||||
const checkedKeys: any = [];
|
||||
const getMap = (arr: any, parentCode = 'root') => {
|
||||
const getMap = (arr: any) => {
|
||||
arr.forEach((item: any) => {
|
||||
item.title = item.code;
|
||||
item.key = item.code;
|
||||
if (save) {
|
||||
delete item.checked; //保存时删除 checked 字段
|
||||
checkedKeys.push(item.code);
|
||||
} else {
|
||||
if (checked || item?.checked) {
|
||||
item.checked = item?.checked || checked;
|
||||
checkedKeys.push(item.code);
|
||||
}
|
||||
}
|
||||
item.key = item.code; // treeData需要唯一key
|
||||
|
||||
checkedKeys.push(item.code);
|
||||
|
||||
arrMap.set(item.code, item);
|
||||
if (parentCode === 'root') {
|
||||
rootSet.add(item.code); //处理根菜单
|
||||
}
|
||||
if (item?.children) {
|
||||
getMap(item?.children, item.code);
|
||||
getMap(item?.children);
|
||||
}
|
||||
});
|
||||
};
|
||||
getMap(Menu);
|
||||
return { arrMap, rootSet, checkedKeys };
|
||||
return { checkedKeys };
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -164,7 +134,7 @@ export const developArrToMap = (Menu: any, checked = false, save = false) => {
|
|||
};
|
||||
*/
|
||||
|
||||
function findAllParentsAndChildren(data: any, code: any) {
|
||||
export const findAllParentsAndChildren = (data: any, code: any) => {
|
||||
const result = {
|
||||
parents: [],
|
||||
children: [],
|
||||
|
@ -213,7 +183,7 @@ function findAllParentsAndChildren(data: any, code: any) {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 选择功能
|
||||
* @param selecteds onSelect事件默认参数
|
||||
|
|
Loading…
Reference in New Issue