Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
xieyonghong 2023-03-26 22:27:49 +08:00
commit 6919d41b93
2 changed files with 207 additions and 64 deletions

View File

@ -23,12 +23,16 @@
style="margin-bottom: 12px"
/>
<j-tree
v-if="treeData.length !== 0"
show-line
defaultExpandAll
multiple
draggable
:tree-data="treeData"
:height="500"
@select="onSelect"
:selectedKeys="selectedKeys"
@drop="onDrop"
>
<template #title="row">
<div class="tree-content">
@ -38,24 +42,6 @@
{{ row.name }}
</div>
</div>
<div class="tree-content-action">
<span @click="(e) => e.stopPropagation()">
<PermissionButton
type="text"
:tooltip="{
title: '删除',
}"
hasPermission="DataCollect/Collector:delete"
:popConfirm="{
title: `确定删除?`,
onConfirm: () =>
handlDelete(row.id),
}"
>
<AIcon type="CloseOutlined" />
</PermissionButton>
</span>
</div>
</div>
</template>
</j-tree>
@ -69,28 +55,32 @@
<script setup lang="ts" name="MenuSetting">
import { getMenuTree_api } from '@/api/system/menu';
import { getSystemPermission as getSystemPermission_api } from '@/api/initHome';
import { filterMenu, getKeys, loop } from './utils';
import {
filterMenu,
mergeMapToArr,
developArrToMap,
drop,
select,
} from './utils';
import BaseMenu from './baseMenu';
import type {
AntTreeNodeDropEvent,
TreeDataItem,
TreeProps,
} from 'ant-design-vue/es/tree';
import type { AntTreeNodeDropEvent } from 'ant-design-vue/es/tree';
import { treeFilter } from '@/utils/tree';
import { cloneDeep } from 'lodash';
const treeData = ref<any>();
const selectedKeys: any = ref([]);
const treeData = ref<any>([]);
const filterText = ref('');
treeData.value = [...BaseMenu];
let systemMenu: any = reactive([]);
const baseMenu = cloneDeep(BaseMenu);
const systemMenu: any = ref([]);
const baseMenu: any = ref([]);
const AllMenu = ref([]);
const BaseMenuMap = new Map();
BaseMenu.forEach((item) => {
BaseMenuMap.set(item.code, item);
});
const onSelect = (selecteds: Array<string>, e: any) => {
selectedKeys.value = select(selecteds, e);
};
console.log(11, BaseMenuMap);
const onDrop = (info: AntTreeNodeDropEvent) => {
treeData.value = drop(info, treeData.value);
};
const params = {
paging: false,
@ -114,20 +104,25 @@ const params = {
};
const change = (val: any) => {
treeData.value = treeFilter(baseMenu, val.target.value, 'name');
};
const handlDelete = (value) => {
console.log(22, value);
treeData.value = treeFilter(AllMenu.value, val.target.value, 'name');
};
onMounted(() => {
getMenuTree_api(params).then((resp: any) => {
if (resp.status == 200) {
systemMenu = resp.result;
console.log(2, systemMenu);
}
// transfer.data.rightTreeData = resp.result;
getSystemPermission_api().then((resp: any) => {
baseMenu.value = filterMenu(
resp.result.map((item: any) => JSON.parse(item).id),
BaseMenu,
);
getMenuTree_api(params).then((resp: any) => {
if (resp.status == 200) {
systemMenu.value = resp.result;
const baseMenuData = developArrToMap(baseMenu.value);
const systemMenuData = developArrToMap(systemMenu.value, true);
selectedKeys.value = systemMenuData.checkedKeys;
AllMenu.value = mergeMapToArr(baseMenuData, systemMenuData);
treeData.value = cloneDeep(AllMenu.value);
}
});
});
});
</script>
@ -183,15 +178,13 @@ onMounted(() => {
&-content {
display: flex;
justify-content: space-between;
width: 100%;
&-title {
flex: 1;
font-weight: 800;
font-size: 12px;
line-height: 17px;
line-height: 24px;
display: flex;
align-items: center;
color: #333333;
}
&-action {

View File

@ -1,4 +1,8 @@
import { TreeProps } from "ant-design-vue";
import type {
AntTreeNodeDropEvent,
TreeProps,
TreeDataItem,
} from 'ant-design-vue/es/tree';
/**
*
@ -18,21 +22,167 @@ export const filterMenu = (permissions: string[], menus: any[]) => {
});
};
// 在树形结构中对id进行匹配通过callback对匹配id的对象进行操作
export const loop= (data: TreeProps['treeData'], id: string | number, callback: any) => {
data?.forEach((item, index) => {
if (item.id === id) {
return callback(item, index, data);
}
if (item.children) {
return loop(item.children, id, callback);
/**
* 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++) {
const child = r[i].children;
if (child) {
updataArr(child);
}
r[i] = newMap.get(r[i].code);
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) => {
root.push(newMap.get(item));
});
}
//
export const getKeys = (data: any[]): (string | number)[] => {
return data.reduce((pre: (string | number)[], next: any) => {
const childrenKeys = next.children ? getKeys(next.children) : [];
return [...pre, next.code, ...childrenKeys];
}, []);
}
updataArr(root);
return root;
};
/**
*
* @param value baseMenu systemMenu
* @param checked true
* @returns Mapkeys
*/
export const developArrToMap = (Menu: any, checked = false) => {
const rootSet = new Set();
const arrMap = new Map();
const checkedKeys: any = [];
const getMap = (arr: any, parentCode = 'root', preKey = '0') => {
arr.forEach((item: any, index: number) => {
const key = preKey + `-${index}`; //初始化key
item.title = item.code;
item.key = key;
if (checked) {
checkedKeys.push(key);
}
arrMap.set(item.code, item);
if (parentCode === 'root') {
rootSet.add(item.code); //处理根菜单
}
if (item?.children) {
getMap(item?.children, item.code, key);
}
});
};
getMap(Menu);
return { arrMap, rootSet, checkedKeys };
};
/**
*
* @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, preKey = '0') => {
data.forEach((item: any, index: number) => {
const checkedKey = preKey + `-${index}`;
childKeys.push(checkedKey);
if (item?.children) {
getChildKeys(item?.children, checkedKey);
}
});
};
if (node?.children) {
getChildKeys(node.children, node.key);
}
const Keys = new Set(selecteds);
const selectedAllKeys = [...[node.key, ...childKeys]];
selectedAllKeys.forEach((item: string) => {
Keys[e.selected ? 'add' : 'delete'](item);
});
return [...Keys];
};
/**
*
* @param info drop事件默认参数
* @param treeData treeData值
* @returns treeData值
*/
export const drop = (info: AntTreeNodeDropEvent, treeData: any) => {
const dropKey = info.node.key;
const dragKey = info.dragNode.key;
const dropPos = info.node.pos.split('-');
const dropPosition =
info.dropPosition - Number(dropPos[dropPos.length - 1]);
const loop = (
data: TreeProps['treeData'],
key: string | number,
callback: any,
) => {
data.forEach((item, index) => {
if (item.key === key) {
return callback(item, index, data);
}
if (item.children) {
return loop(item.children, key, callback);
}
});
};
const data = [...treeData];
let dragObj: TreeDataItem;
loop(
data,
dragKey,
(item: TreeDataItem, index: number, arr: TreeProps['treeData']) => {
arr.splice(index, 1);
dragObj = item;
},
);
if (!info.dropToGap) {
loop(data, dropKey, (item: TreeDataItem) => {
item.children = item.children || [];
item.children.unshift(dragObj);
});
} else if (
(info.node.children || []).length > 0 && // Has children
info.node.expanded && // Is expanded
dropPosition === 1 // On the bottom gap
) {
loop(data, dropKey, (item: TreeDataItem) => {
item.children = item.children || [];
item.children.unshift(dragObj);
});
} else {
let ar: TreeProps['treeData'] = [];
let i = 0;
loop(
data,
dropKey,
(
_item: TreeDataItem,
index: number,
arr: TreeProps['treeData'],
) => {
ar = arr;
i = index;
},
);
if (dropPosition === -1) {
ar.splice(i, 0, dragObj);
} else {
ar.splice(i + 1, 0, dragObj);
}
}
return data;
};