RoleDrawer.vue 6.14 KB
<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    :title="getTitle"
    width="500px"
    @ok="handleSubmit"
  >
    <BasicForm @register="registerForm">
      <template #menu>
        <BasicTree
          v-if="treeData.length"
          checkable
          toolbar
          :expandedKeys="treeExpandData"
          ref="treeRef"
          :treeData="treeData"
          :replaceFields="{ title: 'menuName' }"
          :checkedKeys="roleMenus"
          @check="handleCheckClick"
          title="菜单分配"
        />
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
<script lang="ts">
  import { defineComponent, ref, computed, unref, nextTick } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { formSchema } from './role.data';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicTree, TreeItem } from '/@/components/Tree';
  import { useMessage } from '/@/hooks/web/useMessage';
  const { t } = useI18n(); //加载国际化
  // 加载菜单数据
  import { getMenuList, getMenusIdsByRoleId } from '/@/api/sys/menu';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { RouteItem } from '/@/api/sys/model/menuModel';
  import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
  export default defineComponent({
    name: 'RoleDrawer',
    components: { BasicDrawer, BasicForm, BasicTree },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const treeExpandData = ref([]);
      const isUpdate = ref<boolean>(true);
      const treeData = ref<TreeItem[]>([]);
      const roleMenus = ref<string[]>([]);
      const allCheckedKeys = ref<string[]>([]);
      const roleId = ref<string>('');
      const treeRef = ref();
      const checked: any = ref([]); //需要选中的节点
      const pidArr: any = ref([]); //获取父节点

      const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
        labelWidth: 100,
        schemas: formSchema,
        showActionButtonGroup: false,
      });

      // 递归函数,将RouteItem里面的字段换名称
      function processChildren(items: RouteItem[]) {
        items.forEach((item) => {
          item.menuName = t(item.meta.title);
          item.icon = item.meta.icon;
          item.key = item.id;
          if (item.children) {
            processChildren(item.children);
          }
        });
      }
      function lookForAllId(data = [], arr = []) {
        for (const item of data) {
          arr.push(item.id);
        }
        return arr;
      }
      const originMenus = ref();
      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
        allCheckedKeys.value = [];
        originMenus.value = [];
        allCheckedKeys.value.length = 0;
        resetFields();
        roleId.value = '';
        // 在打开弹窗时清除所有选择的菜单
        treeRef.value && treeRef.value.checkAll(false);
        isUpdate.value = data.isUpdate;
        // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
        if (!unref(treeData).length) {
          // 获取全部的菜单
          const menuListModel = await getMenuList();
          processChildren(menuListModel);
          treeData.value = menuListModel;
          //修复角色菜单新增-全部展开问题-只展开第一级即可
          nextTick(() => {
            const getAllIds = lookForAllId(treeData.value, []);
            treeExpandData.value = getAllIds;
          });
        }
        // 更新
        if (unref(isUpdate)) {
          allCheckedKeys.value = [];
          checked.value = [];
          //通过角色id去获取角色对应的菜单的ids
          roleMenus.value = await getMenusIdsByRoleId(data.record.id);
          originMenus.value = [...roleMenus.value];

          const getAllIds = lookForAllId(treeData.value, []);
          treeExpandData.value = getAllIds;
          for (let item of treeData.value) {
            if (item?.children != 0) {
              pidArr.value.push(item.key);
            }
            for (let item1 of item?.children) {
              if (item1?.children != 0) {
                pidArr.value.push(item1.key);
              }
            }
          }
          for (let item of roleMenus.value) {
            let isP = pidArr.value.includes(item);
            if (!isP) {
              checked.value.push(item);
            }
          }
          nextTick(() => {
            treeRef.value.setCheckedKeys(checked.value);
            // const expandTreeIds = lookForAllId(treeData.value);
            // treeRef.value.setExpandedKeys(expandTreeIds);
          });
          roleId.value = data.record.id;
          setFieldsValue(data.record);
        }
      });

      const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));

      async function handleSubmit() {
        setDrawerProps({ confirmLoading: true });
        const { createMessage } = useMessage();
        try {
          const values = await validate();
          const req = {
            id: roleId.value,
            name: values.name,
            remark: values.remark,
            status: values.status,
            menu: allCheckedKeys.value.length ? allCheckedKeys.value : originMenus.value,
          };
          if (req.menu == undefined) return createMessage.error('请勾选权限菜单');
          saveOrUpdateRoleInfoWithMenu(req).then(() => {
            closeDrawer();
            emit('success');
            createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);
          });
        } finally {
          setTimeout(() => {
            setDrawerProps({ confirmLoading: false });
          }, 300);
        }
      }
      // Tree check事件
      const handleCheckClick = (checkedNodes, { halfCheckedKeys }) => {
        allCheckedKeys.value = [...checkedNodes, ...halfCheckedKeys];
      };

      return {
        registerDrawer,
        registerForm,
        getTitle,
        handleSubmit,
        treeData,
        roleMenus,
        treeRef,
        handleCheckClick,
        allCheckedKeys,
        treeExpandData,
      };
    },
  });
</script>