feat: 修复菜单管理 菜单配置 菜单初始化问题

This commit is contained in:
jackhoo_98 2023-04-01 18:41:52 +08:00
parent 968c68efba
commit 94e93a53e5
2 changed files with 171 additions and 61 deletions

View File

@ -68,12 +68,16 @@ import {
drop,
select,
getMaxDepth,
mergeArr,
} from './utils';
import BaseMenu from '@/views/init-home/data/baseMenu';
import type { AntTreeNodeDropEvent } from 'ant-design-vue/es/tree';
import { cloneDeep } from 'lodash';
import { onlyMessage } from '@/utils/comm';
import { MESSAGE_SUBSCRIBE_MENU_CODE, USER_CENTER_MENU_CODE } from '@/utils/consts'
import {
MESSAGE_SUBSCRIBE_MENU_CODE,
USER_CENTER_MENU_CODE,
} from '@/utils/consts';
const selectedKeys: any = ref([]);
const treeData = ref<any>([]);
@ -104,54 +108,34 @@ const params = {
],
};
// children
const filterAndClean = (data: any) => {
// data
if (Array.isArray(data)) {
return data
.filter((item) => item !== null) // null
.map((item: any) => filterAndClean(item)); //
}
// data
if (typeof data === 'object') {
let cleanedChildren = filterAndClean(data.children); //
if (Array.isArray(cleanedChildren)) {
cleanedChildren = cleanedChildren.filter((i) => i);
function filterTree(nodes: Array<any>, selectedKeys: Array<any>) {
const filtered = [];
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (!node.code) {
continue;
}
if (cleanedChildren !== undefined) {
data.children = cleanedChildren;
} else {
delete data.children; // children undefined
if (selectedKeys.indexOf(node.code) !== -1) {
filtered.push(node);
if (node.children) {
node.children = filterTree(node.children, selectedKeys);
}
} else if (node.children) {
node.children = filterTree(node.children, selectedKeys);
if (node.children.length > 0) {
filtered.push(node);
}
}
}
return data;
};
return filtered;
}
const handleOk = async () => {
const { arrMap, rootSet } = developArrToMap(
cloneDeep(treeData.value),
false,
true,
);
const dataMap = new Map();
// map
selectedKeys.value.forEach((item: string) => {
if (arrMap.has(item)) {
dataMap.set(item, arrMap.get(item));
}
});
const _saveDataMap = {
arrMap: dataMap,
rootSet,
};
const dataArr = filterAndClean(mergeMapToArr(_saveDataMap, _saveDataMap));
const _dataArr = filterTree(cloneDeep(treeData.value), selectedKeys.value);
loading.value = true;
const res = await updateMenus(dataArr).catch(() => {});
const res = await updateMenus(_dataArr).catch(() => {});
if (res?.status === 200) {
onlyMessage('操作成功', 'success');
}
@ -163,7 +147,7 @@ const handleCancel = () => {
};
const onSelect = (selecteds: Array<string>, e: any) => {
selectedKeys.value = select(selecteds, e);
selectedKeys.value = select(selecteds, e, cloneDeep(treeData.value));
};
const onDrop = (info: AntTreeNodeDropEvent) => {
@ -186,12 +170,20 @@ onMounted(() => {
);
getMenuTree_api(params).then((resp: any) => {
if (resp.status == 200) {
systemMenu.value = resp.result?.filter((item: { code: string }) => ![USER_CENTER_MENU_CODE, MESSAGE_SUBSCRIBE_MENU_CODE].includes(item.code));
systemMenu.value = resp.result?.filter(
(item: { code: string }) =>
![
USER_CENTER_MENU_CODE,
MESSAGE_SUBSCRIBE_MENU_CODE,
].includes(item.code),
);
//
const baseMenuData = developArrToMap(baseMenu.value);
const systemMenuData = developArrToMap(systemMenu.value, true);
selectedKeys.value = systemMenuData.checkedKeys;
AllMenu.value = mergeMapToArr(baseMenuData, systemMenuData);
// AllMenu.value = mergeMapToArr(baseMenuData, systemMenuData);
AllMenu.value = mergeArr(cloneDeep(BaseMenu), systemMenu.value);
treeData.value = cloneDeep(AllMenu.value);
}
});

View File

@ -22,6 +22,71 @@ 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 mergeItem: any = (oldItem: any, newItem: any) => {
if (!oldItem) {
return newItem;
}
if (!oldItem.children && newItem.children) {
oldItem.children = newItem.children;
return oldItem;
}
if (oldItem.children && !newItem.children) {
return oldItem;
}
if (oldItem.children && newItem.children) {
const mergedChildren = [];
const newChildren = [...newItem.children];
for (const oldChild of oldItem.children) {
const index = newChildren.findIndex(
(child) => child.code === oldChild.code,
);
if (index !== -1) {
mergedChildren.push(
mergeItem(oldChild, newChildren[index]),
);
newChildren.splice(index, 1);
} else {
mergedChildren.push(oldChild);
}
}
return {
...oldItem,
children: mergedChildren.concat(newChildren),
};
}
return oldItem;
};
for (const newItem of newData) {
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);
}
}
return mergedData;
};
/**
* Map菜单转成Arr菜单
* @param baseMenuData baseMenu developArrToMap平铺后的数据
@ -89,31 +154,84 @@ export const developArrToMap = (Menu: any, checked = false, save = false) => {
return { arrMap, rootSet, checkedKeys };
};
/**
* code
* @param data
* @param code code
* @returns result = {
parents: [], //当前code的全部父级code
children: [],//当前code的全部子级code
};
*/
function findAllParentsAndChildren(data: any, code: any) {
const result = {
parents: [],
children: [],
};
function findParentsAndChildrenRecursive(node: any) {
if (node.code === code) {
if (node.children) {
result.children = node.children.flatMap((child: any) => {
if (child.children) {
return [
child.code,
...findChildrenRecursive(child.children),
];
}
return [child.code];
});
}
return true;
}
if (node.children) {
for (let child of node.children) {
if (findParentsAndChildrenRecursive(child)) {
result.parents.push(node.code);
return true;
}
}
}
return false;
}
function findChildrenRecursive(children: any) {
return children.flatMap((child: any) => {
if (child.children) {
return [child.code, ...findChildrenRecursive(child.children)];
}
return [child.code];
});
}
for (let node of data) {
if (findParentsAndChildrenRecursive(node)) {
break;
}
}
return result;
}
/**
*
* @param selecteds onSelect事件默认参数
* @param e onSelect事件默认参数
* @returns keys
*/
export const select = (selecteds: Array<string>, e: any) => {
const { node } = e;
const childKeys: Array<string> = [];
const getChildKeys = (data: any) => {
data.forEach((item: any) => {
childKeys.push(item.code);
if (item?.children) {
getChildKeys(item?.children);
}
});
};
if (node?.children) {
getChildKeys(node.children);
}
export const select = (selecteds: Array<string>, e: any, treeData: any) => {
const { node, selected } = e;
const { parents, children } = findAllParentsAndChildren(
treeData,
node.code,
);
const Keys = new Set(selecteds);
const selectedAllKeys = [...[node.key, ...childKeys]];
const selectedAllKeys = selected
? [...[...parents, ...children]]
: [...children];
selectedAllKeys.forEach((item: string) => {
Keys[e.selected ? 'add' : 'delete'](item);
Keys[selected ? 'add' : 'delete'](item);
});
return [...Keys];
};