134 lines
2.6 KiB
Vue
134 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import type { DataNode } from 'ant-design-vue/es/tree';
|
|
import { SimpleScrollbar } from '@sa/materials';
|
|
|
|
defineOptions({
|
|
name: 'MenuAuthModal'
|
|
});
|
|
|
|
interface Props {
|
|
/** the roleId */
|
|
roleId: number;
|
|
type: 'add' | 'edit';
|
|
drawerVisible: boolean;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
const menuIds = defineModel<number[]>('menuIds', { default: [] });
|
|
|
|
const tree = shallowRef<DataNode[]>([]);
|
|
|
|
watch(
|
|
() => props.drawerVisible,
|
|
val => {
|
|
if (val) {
|
|
init();
|
|
}
|
|
},
|
|
{
|
|
immediate: true
|
|
}
|
|
);
|
|
|
|
async function getTree() {
|
|
const { error, data } = await fetchGetMenuTree();
|
|
|
|
if (!error) {
|
|
tree.value = recursiveTransform(data);
|
|
}
|
|
}
|
|
|
|
function recursiveTransform(data: Api.SystemManage.MenuTree[]): DataNode[] {
|
|
return data.map(item => {
|
|
const { id: key, label } = item;
|
|
|
|
if (item.children) {
|
|
return {
|
|
key,
|
|
title: label,
|
|
children: recursiveTransform(item.children)
|
|
};
|
|
}
|
|
|
|
return {
|
|
key,
|
|
title: label
|
|
};
|
|
});
|
|
}
|
|
|
|
async function getChecks() {
|
|
const { data, error } = await doGetRoleMenuList(props.roleId);
|
|
if (!error) {
|
|
if (props.type === 'edit') {
|
|
tree.value = recursiveTransform(data.menus);
|
|
nextTick(() => {
|
|
menuIds.value = data.checkedKeys;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
async function init() {
|
|
if (props.type === 'edit') {
|
|
await getChecks();
|
|
} else {
|
|
await getTree();
|
|
}
|
|
}
|
|
|
|
function clearChecks() {
|
|
menuIds.value = [];
|
|
}
|
|
const rootIds = ref([]);
|
|
function fnModalTreeChecked(keys: any, info: any ) {
|
|
let ids = Array.isArray(keys) ? keys : keys.checked;
|
|
// ids = ids.concat(info.halfCheckedKeys);
|
|
rootIds.value = info.halfCheckedKeys;
|
|
menuIds.value = ids;
|
|
}
|
|
defineExpose({
|
|
clearChecks,
|
|
checkedKeys: ()=> {
|
|
return menuIds.value.concat(rootIds.value).concat()
|
|
},
|
|
tree
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="border-0.5 border-gray-300 rounded-md p-2 transition-all dark:border-dark-300" hover="border-gray-500">
|
|
<SimpleScrollbar>
|
|
<ATree
|
|
checkable
|
|
block-node
|
|
:selectable="false"
|
|
@check="fnModalTreeChecked"
|
|
v-model:checked-keys="menuIds"
|
|
:check-strictly="false"
|
|
:tree-data="tree"
|
|
>
|
|
</ATree>
|
|
</SimpleScrollbar>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
:deep(.ant-tree .ant-tree-switcher) {
|
|
line-height: normal;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
:deep(.ant-tree .ant-tree-checkbox) {
|
|
margin-block-start: unset;
|
|
}
|
|
|
|
:deep(.ant-tree .ant-tree-title) {
|
|
font-size: 14px;
|
|
padding: 2px;
|
|
font-weight: 500;
|
|
}
|
|
</style>
|