AccountModal.vue 11.5 KB
<template>
  <BasicModal
    width="650px"
    v-bind="$attrs"
    @register="registerModal"
    :title="getTitle"
    @ok="handleSubmit"
  >
    <div style="height: 50vh">
      <BasicForm @register="registerForm">
        <template #organizationId="{ model, field }">
          <Button
            type="link"
            @click="handleOpenCreate"
            class="ml-1"
            style="padding: 0; z-index: 9999"
            >{{ t('common.createText') + t('business.organizationText') }}
          </Button>
          <BasicTree
            v-if="organizationTreeData.length"
            v-model:value="model[field]"
            :treeData="organizationTreeData"
            :checked-keys="checkGroup"
            :expandedKeys="treeExpandData"
            ref="basicTreeRef"
            @check="handleCheckClick"
            @unSelectAll="handleUnSelectAll"
            @strictlyStatus="handleStrictlyStatus"
            checkable
            toolbar
            @change="handleTreeSelect"
          />
        </template>
        <template #roleSlot="{ model, field }">
          <a-select
            mode="multiple"
            allowClear
            :placeholder="t('common.chooseText') + t('system.account.role')"
            v-model:value="model[field]"
            @change="handleRoleSelect"
            :options="roleOptions.map((item) => ({ value: item.value, label: item.label }))"
          >
            <template #dropdownRender="{ menuNode: menu }">
              <v-nodes :vnodes="menu" />
              <a-divider style="margin: 4px 0" />
              <div @click="handleOpenRole" style="padding: 4px 0; cursor: pointer">
                <plus-outlined />
                {{ t('system.account.createRole') }}
              </div>
            </template>
          </a-select>
        </template>
      </BasicForm>

      <OrganizationDrawer @register="registerDrawer" @success="handleReload" />
    </div>
  </BasicModal>
  <RoleDrawer @register="registerRoleDrawer" @success="handleSuccess" />
</template>
<script lang="ts">
  import { defineComponent, ref, computed, unref, reactive, onMounted } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { accountFormSchema } from './account.data';
  import { Button } from 'ant-design-vue';
  import {
    findCurrentUserRelation,
    SaveOrUpdateUserInfo,
    filterRoleList,
  } from '/@/api/system/system';
  import { BasicTree, TreeItem, CheckKeys, CheckEvent } from '/@/components/Tree';
  import { findCurrentUserGroups } from '/@/api/system/group';
  import { RoleOrOrganizationParam } from '/@/api/system/model/systemModel';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { copyTransTreeFun } from '/@/utils/fnUtils';
  import { TOption } from '/@/views/rule/linkedge/config/config.data';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import { useDrawer } from '/@/components/Drawer';
  import RoleDrawer from '../role/RoleDrawer.vue';
  import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
  import { useI18n } from '/@/hooks/web/useI18n';

  export default defineComponent({
    name: 'AccountModal',
    components: {
      BasicModal,
      BasicForm,
      Button,
      BasicTree,
      OrganizationDrawer,
      PlusOutlined,
      RoleDrawer,
      VNodes: (_, { attrs }) => {
        return attrs.vnodes;
      },
    },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const { t } = useI18n();
      const roleOptions = ref<TOption[]>([]);
      const isUpdate = ref(true);
      const rowId = ref('');
      const organizationTreeData = ref<TreeItem[]>([]);
      const basicTreeRef = ref();
      const checkGroup = ref<string[]>([]);
      const treeExpandData = ref([]);
      const olderPhoneNumber = ref();
      const postData = reactive({});
      const singleEditPostPhoneNumber = reactive({
        phoneNumber: '',
      });
      const checkedKeysWithHalfChecked = ref<(string | number)[]>([]);
      const getRoleList = async () => {
        const res = await filterRoleList();
        roleOptions.value = res.map((m) => {
          return {
            label: m.name,
            value: m.id,
          };
        });
      };
      onMounted(async () => {
        await getRoleList();
      });
      const [registerRoleDrawer, { openDrawer }] = useDrawer();

      const handleOpenRole = () => {
        openDrawer(true, {
          isUpdate: false,
        });
      };
      const clearValidateByField = (field: string) => {
        clearValidate(field);
      };
      const handleRoleSelect = (e) => {
        if (e?.length > 0) clearValidateByField('roleIds');
        else validateFields(['roleIds']);
      };
      const handleTreeSelect = (e) => {
        if (e) clearValidateByField('organizationIds');
      };
      const handleSuccess = async () => {
        await getRoleList();
      };
      const [
        registerForm,
        {
          setFieldsValue,
          updateSchema,
          resetFields,
          validate,
          getFieldsValue,
          clearValidate,
          validateFields,
        },
      ] = useForm({
        labelWidth: 100,
        schemas: accountFormSchema,
        showActionButtonGroup: false,
        actionColOptions: {
          span: 18,
        },
      });
      //获取所有父级id
      function findForAllId(data = [], arr = []) {
        for (const item of data) {
          arr.push(item.id);
        }
        return arr;
      }

      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        await resetFields();
        setModalProps({ confirmLoading: false });
        isUpdate.value = !!data?.isUpdate;
        const groupListModel = await findCurrentUserGroups();
        if (!unref(organizationTreeData).length) {
          copyTransTreeFun(groupListModel);
          organizationTreeData.value = groupListModel;
          const getAllIds = findForAllId(organizationTreeData.value as any, []);
          //设置要展开的id
          treeExpandData.value = getAllIds;
        }
        if (unref(isUpdate)) {
          rowId.value = data.record.id;
          const roleParams = new RoleOrOrganizationParam(rowId.value, true, false);
          olderPhoneNumber.value = data.record.phoneNumber;
          singleEditPostPhoneNumber.phoneNumber = data.record.phoneNumber;
          findCurrentUserRelation(roleParams).then((result) => {
            Reflect.set(data.record, 'roleIds', result);
            Reflect.set(data.record, 'password', '******');
            setFieldsValue(data.record);
          });
          const organizationParams = new RoleOrOrganizationParam(rowId.value, false, true);
          checkGroup.value = await findCurrentUserRelation(organizationParams);
        }
        await updateSchema([
          {
            field: 'username',
            dynamicDisabled: unref(isUpdate),
          },
          {
            field: 'password',
            ifShow: !unref(isUpdate),
          },
        ]);
      });
      const getTitle = computed(() =>
        !unref(isUpdate) ? t('system.account.createButton') : t('system.account.editButton')
      );

      async function handleSubmit() {
        setModalProps({ confirmLoading: true });
        try {
          const { createMessage } = useMessage();
          if (unref(isUpdate)) {
            Object.assign(postData, singleEditPostPhoneNumber);
          }
          const values = await validate([
            'id',
            'username',
            'realName',
            'password',
            'roleIds',
            'email',
            'accountExpireTime',
            'enabled',
            'remark',
            'organizationIds',
            olderPhoneNumber.value === getFieldsValue().phoneNumber ? '' : 'phoneNumber',
          ]);
          let treeCheckedKeys: string[] | CheckKeys =
            (unref(basicTreeRef)?.getCheckedKeys() as string[] | CheckKeys) || [];
          //fix 取消层级独立后(unref(treeRef)?.getCheckedKeys() as string[])的数据不是数组,是{checked:[],halfChecked:[]}对象,迭代报错
          if (!Array.isArray(treeCheckedKeys)) {
            treeCheckedKeys = treeCheckedKeys?.checked;
          }
          const organizationIds = [
            ...new Set([...unref(checkedKeysWithHalfChecked), ...treeCheckedKeys]),
          ];
          values.accountExpireTime =
            typeof values.accountExpireTime != 'undefined' && values.accountExpireTime != null
              ? values.accountExpireTime.format('YYYY-MM-DD HH:mm:ss')
              : null;
          values.organizationIds = organizationIds;
          Object.assign(postData, values);
          if (unref(isUpdate)) {
            if (values.email == '') {
              delete postData.email;
            }
          } else {
            if (values.email == '') {
              delete postData.email;
            }
          }
          await SaveOrUpdateUserInfo(
            { ...postData, roleType: 'PLATFORM_ADMIN' } as any,
            unref(isUpdate)
          );
          closeModal();
          emit('success');
          // t('common.editText') : t('common.createText')) + t('common.successText')
          createMessage.success(
            (unref(isUpdate) ? t('common.editText') : t('common.createText')) +
              t('common.successText')
          );
        } finally {
          setTimeout(() => {
            setModalProps({ confirmLoading: false });
          }, 300);
        }
      }
      // 取消全部的时候清除回显时获取的
      const handleUnSelectAll = () => {
        checkedKeysWithHalfChecked.value = [];
      };

      const strictlyStatus = ref(false); //层级关联或独立的状态 false为层级关联 true为层级独立

      const handleStrictlyStatus = (status) => (strictlyStatus.value = status);

      const handleCheckClick = (selectedKeys: CheckKeys, event: CheckEvent) => {
        //fix 取消层级独立后selectedKeys不是数组,是{checked:[],halfChecked:[]}对象 迭代报错
        // 层级独立
        if (strictlyStatus.value) {
          if (!Array.isArray(selectedKeys)) {
            selectedKeys = selectedKeys?.checked;
            event.halfCheckedKeys = [];
          }
        } else {
          // 层级关联
          event.halfCheckedKeys = [];
        }
        checkedKeysWithHalfChecked.value = [
          ...selectedKeys,
          ...(event.halfCheckedKeys as string[]),
        ];
      };

      const [registerDrawer, { openDrawer: addOpenDrawer }] = useDrawer();

      const handleOpenCreate = () => {
        addOpenDrawer(true, { isUpdate: false });
      };
      const handleReload = async () => {
        const groupListModel = await findCurrentUserGroups();
        copyTransTreeFun(groupListModel);
        organizationTreeData.value = groupListModel;
      };

      return {
        registerModal,
        registerForm,
        handleSubmit,
        getTitle,
        organizationTreeData,
        checkGroup,
        basicTreeRef,
        treeExpandData,
        roleOptions,
        registerRoleDrawer,
        handleOpenRole,
        handleSuccess,
        handleRoleSelect,
        handleTreeSelect,
        handleCheckClick,
        handleUnSelectAll,
        handleStrictlyStatus,
        handleOpenCreate,
        registerDrawer,
        handleReload,
        t,
      };
    },
  });
</script>
<style scoped lang="less">
  :deep(.vben-basic-tree) {
    width: 100% !important;
    margin-top: -28px !important;
    padding: 0;
  }

  :deep(.is-unflod) {
    display: none !important;
  }

  :deep(.is-flod) {
    display: none !important;
  }
</style>