| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- <script lang="ts" setup>
- import type { Recordable } from '@vben/types';
- import type { RelationRequest } from '#/api/model';
- import { onMounted, reactive, ref, unref } from 'vue';
- import { useVbenDrawer } from '@vben/common-ui';
- import { Button, message, Tree, type TreeProps } from 'ant-design-vue';
- import { MenuApi, RoleApi, TenantApi } from '#/api';
- import { Icon } from '#/components/icon';
- import { getLeafNodeIds } from '#/utils';
- defineOptions({
- name: 'MenuGrant',
- });
- const emit = defineEmits(['success']);
- const modelRef = ref<Recordable<any>>({});
- const state = reactive<{
- checkedKeys: number[] | string[];
- expandedKeys: number[] | string[];
- lastLeafKeys: number[] | string[];
- selectedKeys: number[] | string[];
- }>({
- selectedKeys: [],
- expandedKeys: [],
- checkedKeys: [],
- lastLeafKeys: [],
- });
- const treeData = ref<TreeProps['treeData']>([]);
- const isExpand = ref(false);
- // 所有节点key
- const allNodeIds = ref([]);
- // 当前展开的key
- const currentExpandedKeys = ref([]);
- const getRoleDetailData = async () => {
- const data =
- modelRef.value.type === 'tenant'
- ? await TenantApi.getMenuIds(unref(modelRef).id)
- : await RoleApi.getMenuIds(unref(modelRef).id);
- state.checkedKeys = data || [];
- state.expandedKeys = data || [];
- state.selectedKeys = data.filter((item: number | string) => {
- return state.lastLeafKeys.includes(item as never);
- });
- };
- const [Drawer, { close, setState, getData }] = useVbenDrawer({
- onConfirm: async () => {
- try {
- setState({ confirmLoading: true });
- const postData: RelationRequest = {
- id: unref(modelRef).id,
- relationIds: state.checkedKeys,
- };
- modelRef.value.type === 'tenant'
- ? await TenantApi.updateGrant(postData)
- : await RoleApi.updateGrant(postData);
- message.success('操作成功');
- close();
- emit('success');
- } catch {
- message.error('操作失败');
- } finally {
- setState({ confirmLoading: false });
- }
- },
- onOpenChange: async (isOpen: boolean) => {
- if (isOpen) {
- setState({ loading: true });
- const data = getData<Recordable<any>>();
- modelRef.value = { ...data.baseData };
- await getRoleDetailData();
- setState({ loading: false });
- }
- },
- });
- const fetch = async () => {
- treeData.value = (await MenuApi.getList(
- {},
- )) as unknown as TreeProps['treeData'];
- state.lastLeafKeys = getLeafNodeIds(unref(treeData));
- };
- onMounted(async () => {
- await fetch();
- });
- /**
- * 点击复选框触发处理
- * @param mCheckedKeys
- */
- const handleCheck = (mCheckedKeys: any, e: any) => {
- state.selectedKeys = mCheckedKeys;
- state.checkedKeys = [...mCheckedKeys, ...e.halfCheckedKeys];
- };
- const handleExpand = (expandedKeys: any) => {
- state.expandedKeys = expandedKeys;
- };
- // 展开折叠按钮事件
- const handleExpandAndCollapse = () => {
- isExpand.value = !isExpand.value;
- currentExpandedKeys.value = isExpand.value ? allNodeIds.value : [];
- };
- </script>
- <template>
- <Drawer class="w-[1000px]" title="授权菜单">
- <Button type="primary" @click="handleExpandAndCollapse">
- {{ isExpand ? '折叠' : '展开' }}
- </Button>
- <Tree
- v-model:checked-keys="state.selectedKeys"
- :block-node="true"
- :checkable="true"
- :default-expand-all="true"
- :expanded-keys="state.expandedKeys"
- :field-names="{
- title: 'title',
- key: 'id',
- }"
- :tree-data="treeData"
- @check="handleCheck"
- @expand="handleExpand"
- >
- <template #title="{ meta }">
- <div class="flex items-center">
- <Icon v-if="meta.icon" :icon="meta.icon" class="mr-1" />
- <span>{{ meta.title }}</span>
- </div>
- </template>
- </Tree>
- </Drawer>
- </template>
|