index.vue 5.92 KB
<script lang="ts" setup>
  import { computed } from 'vue';
  import { fetchConfigComponent } from '../../../packages';
  import { DataSourceType, PublicFormInstaceType, SelectedWidgetKeys } from '../../index.type';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { ConfigType, CreateComponentType } from '../../../packages/index.type';
  import { ref } from 'vue';
  import { unref, nextTick } from 'vue';
  import { ModalParamsType } from '/#/utils';
  import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum';
  import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
  import { createImgPreview } from '/@/components/Preview';
  import { upload } from '/@/api/oss/ossFileUploader';

  const props = defineProps<{
    selectWidgetKeys: SelectedWidgetKeys;
    componentConfig: CreateComponentType;
  }>();

  const emit = defineEmits(['register', 'ok']);

  const settingFormEl = ref<Nullable<PublicFormInstaceType>>(null);

  const getSettingComponent = computed(() => {
    try {
      const { componentKey } = props.selectWidgetKeys;
      const component = fetchConfigComponent({ key: componentKey } as ConfigType);
      return component;
    } catch (error) {
      return '';
    }
  });

  const currentEditRecord = ref<DataSourceType>({} as DataSourceType);

  const [register, { closeModal }] = useModalInner((data: ModalParamsType<DataSourceType>) => {
    const { record }: any = data;
    currentEditRecord.value = record;
    if (record.structural?.length) {
      record.structural.forEach((item, index) => {
        nextTick(() => {
          unref(settingFormEl)?.appendSchemaByField?.({
            field: item + 'StructuralIcon',
            label: record.structuralLabel[index] + '图标',
            // labelWidth: '300',
            component: 'IconDrawer',
            changeEvent: 'update:value',
            defaultValue: 'shuiwen',
            ifShow: ({ model }) => model[ComponentConfigFieldEnum.DEFAULT_CUSTOM] !== 'custom',
            componentProps({ formModel }) {
              const color = formModel[item + 'StructuralIconColor'];
              return {
                color,
              };
            },
          });
          unref(settingFormEl)?.appendSchemaByField?.({
            field: item + 'StructuralIconColor',
            label: record.structuralLabel[index] + '图标颜色',
            component: 'ColorPicker',
            changeEvent: 'update:value',
            defaultValue: '#367bff',
            ifShow: ({ model }) => {
              return model[ComponentConfigFieldEnum.DEFAULT_CUSTOM] !== 'custom';
            },
          });
          unref(settingFormEl)?.appendSchemaByField?.({
            field: item + 'StructuralCustomIcon',
            label: record.structuralLabel[index] + '图标',
            component: 'ApiUpload',
            ifShow: ({ model }) => model[ComponentConfigFieldEnum.DEFAULT_CUSTOM] === 'custom',
            changeEvent: 'update:fileList',
            valueField: 'fileList',
            required: true,
            helpMessage: ['支持.svg格式,建议尺寸为32*32px,大小不超过50kb '],
            componentProps: ({ formModel, formActionType }) => {
              const { setFieldsValue } = formActionType;
              return {
                maxSize: 50 * 1024,
                listType: 'picture-card',
                maxFileLimit: 1,
                accept: '.svg',
                api: async (file: File) => {
                  try {
                    const formData = new FormData();
                    const { name } = file;
                    formData.set('file', file);
                    const { fileStaticUri, fileName } = await upload(formData);
                    return {
                      uid: fileStaticUri,
                      name: name || fileName,
                      url: fileStaticUri,
                    } as FileItem;
                  } catch (error) {
                    return {};
                  }
                },
                onDownload() {},
                onPreview: (fileList: FileItem) => {
                  createImgPreview({ imageList: [fileList.url!] });
                },

                onDelete(url: string) {
                  // 去重 取要删除的自定义图标
                  setFieldsValue({
                    structuralDeleteUrl: [
                      ...new Set([
                        ...formModel.structuralDeleteUrl
                          .split(',')
                          ?.filter((item) => Boolean(item)),
                        url!,
                      ]),
                    ].join(','),
                  });
                },
              };
            },
          });
        });
      });
    }
    nextTick(() => {
      setFormValues(record.componentInfo || {});
    });
  });

  const getFormValues = () => {
    return unref(settingFormEl)?.getFormValues();
  };

  const setFormValues = (data: Recordable) => {
    unref(settingFormEl)?.setFormValues(data || {});
  };

  const handleOk = async () => {
    const { uuid } = unref(currentEditRecord);
    await unref(settingFormEl)?.validate?.();
    emit('ok', { uuid, componentInfo: getFormValues() } as DataSourceType);
    handleCancel();
  };

  const handleCancel = () => {
    const { structural } = unref(currentEditRecord) || {};
    if (structural?.length) {
      structural.forEach((item) => {
        unref(settingFormEl)?.removeSchemaByFiled?.([
          item + 'StructuralIcon',
          item + 'StructuralIconColor',
          item + 'StructuralCustomIcon',
          // item + 'StructuralDeleteUrl',
        ]);
      });
    }
    closeModal();
  };

  defineExpose({
    getFormValues,
    setFormValues,
  } as PublicFormInstaceType);
</script>

<template>
  <BasicModal
    @register="register"
    title="组件设置"
    @ok="handleOk"
    :width="700"
    @cancel="handleCancel"
  >
    <!--  -->
    <component ref="settingFormEl" :is="getSettingComponent" />
  </BasicModal>
</template>