<template>
  <div>
    <Form
      ref="formRef"
      :model="formModel"
      :layout="getProps?.layout"
      :label-col="getProps?.labelCol"
      :wrapper-col="getProps?.wrapperCol"
      :labelAlign="getProps?.labelAlign"
      @keypress.enter="handleEnterPress"
    >
      <Row v-bind="getRow">
        <template v-for="schema in getSchemas" :key="schema.field">
          <Col
            :span="schema.colProps?.span"
            v-show="getIsShow(schema, formModel[schema.field!])"
            v-if="getIfShow(schema, formModel[schema.field!])"
            style="padding-left: 16px; padding-right: 16px"
            :style="schema.colProps?.style"
          >
            <template v-if="showComponent(schema)">
              <SimpleFormItem
                :refreshFieldObj="refreshFieldObj"
                :schema="schema"
                :form-api="formApi"
                :isWorkFlow="isWorkFlow"
                v-model:value="formModel[schema.field!]"
                :slots="$slots"
                ref="SimpleFormItemRefs"
              />
            </template>
          </Col>
        </template>
      </Row>

      <div :style="{ textAlign: getProps.buttonLocation }">
        <slot name="buttonBefore"></slot>

        <a-button type="primary" v-if="getProps.showSubmitButton" @click="handleSubmit">
          {{ t('提交') }}
        </a-button>
        <a-button style="margin-left: 10px" v-if="getProps.showResetButton" @click="handleReset">
          {{ t('重置') }}
        </a-button>
        <slot name="buttonAfter"></slot>
      </div>
    </Form>
  </div>
</template>
<script lang="ts" setup>
  import { Form, FormInstance, Row, Col, Modal, message } from 'ant-design-vue';
  import {
    cloneDeep,
    isArray,
    isBoolean,
    isFunction,
    isObject,
    isString,
    uniqBy,
    isNil,
    isNumber,
    upperFirst,
  } from 'lodash-es';
  import {
    computed,
    reactive,
    ref,
    provide,
    unref,
    nextTick,
    toRaw,
    createVNode,
    inject,
    watch,
  } from 'vue';
  import {
    CardComponentProps,
    FormActionType,
    FormProps,
    FormSchema,
    GridComponentProps,
    TabComponentProps,
    regTestProps,
    requestProps,
  } from '../../Form/src/types/form';
  import SimpleFormItem from './components/SimpleFormItem.vue';
  import { NamePath, ValidateOptions } from 'ant-design-vue/lib/form/interface';
  import {
    arrayValueComponents,
    defaultValueComponents,
    staticDataComponents,
    noFieldComponent,
    noDefaultValueComponents,
    noShowWorkFlowComponents,
    noShowGenerateComponents,
  } from '../../Form/src/helper';
  import { deepMerge } from '/@/utils';
  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
  import type { ModalFuncProps } from 'ant-design-vue/lib/modal/Modal';
  import { defHttp } from '/@/utils/http/axios';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { needDicDefaultValue } from '../../Designer/src/types';
  import { camelCaseString } from '/@/utils/event/design';
  import { useUserStore } from '/@/store/modules/user';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useGo } from '/@/hooks/web/usePage';
  import { useRouter } from 'vue-router';
  const { currentRoute } = useRouter();
  const { query } = unref(currentRoute);
  const { notification } = useMessage();
  const userStore = useUserStore();
  const go = useGo();

  const { t } = useI18n();
  const formRef = ref<FormInstance>();

  const propsRef = ref<Partial<FormProps>>({});

  const schemaRef = ref<Nullable<FormSchema[]>>(null);

  let SimpleFormItemRefs = ref() as any;

  const emit = defineEmits(['submit', 'modelChange']);

  const props = defineProps({
    // 表单配置规则
    formProps: {
      type: Object as PropType<FormProps>,
    },
    //表单数据
    formModel: {
      type: Object as PropType<Recordable>,
      default: () => {},
    },
    //是否是工作流
    isWorkFlow: {
      type: Boolean,
      default: false,
    },
    //是否系统表单需要转驼峰，兼容旧系统表单
    isCamelCase: {
      type: Boolean,
      default: false,
    },
  });

  const getSchemas = computed<FormSchema[]>(() => {
    return (unref(getProps).schemas as any) || unref(schemaRef);
  });

  // Get the basic configuration of the form
  const getProps = computed((): FormProps => {
    return { ...(props.formProps as FormProps), ...unref(propsRef) } as FormProps;
  });

  // Get uniform row style and Row configuration for the entire form
  const getRow = computed((): Recordable => {
    const { baseRowStyle = {}, rowProps } = props.formProps!;

    return {
      style: baseRowStyle,
      ...rowProps,
    };
  });

  function showComponent(schema) {
    return props.isWorkFlow
      ? !noShowWorkFlowComponents.includes(schema.type)
      : !noShowGenerateComponents.includes(schema.type);
  }

  function getIsShow(schema: FormSchema, itemValue: any): boolean {
    const { show } = schema;
    const { showAdvancedButton } = getProps.value;
    const itemIsAdvanced = showAdvancedButton
      ? isBoolean(schema.isAdvanced)
        ? schema.isAdvanced
        : true
      : true;

    let isShow = true;

    if (isBoolean(show)) {
      isShow = show;
    }
    if (isFunction(show)) {
      isShow = show({
        values: itemValue,
        model: formModel!,
        schema: schema,
        field: schema.field!,
      });
    }

    isShow = isShow && itemIsAdvanced;
    return isShow;
  }

  function getIfShow(schema: FormSchema, itemValue: any): boolean {
    const { ifShow } = schema;

    let isIfShow = true;

    if (isBoolean(ifShow)) {
      isIfShow = ifShow;
    }
    if (isFunction(ifShow)) {
      isIfShow = ifShow({
        values: itemValue,
        model: formModel!,
        schema: schema,
        field: schema.field!,
      });
    }
    return isIfShow;
  }

  const formModel = reactive<Recordable>(props.formModel);
  const isCustom = inject<boolean>('isCustomForm', false);
  provide('formModel', formModel);
  provide('formProps', getProps);
  provide('isCustomForm', isCustom || props.isWorkFlow);
  provide('isCamelCase', props.isCamelCase);

  watch(
    () => formModel,
    () => {
      emit('modelChange', formModel);
    },
    { deep: true },
  );
  const handleSubmit = async () => {
    try {
      const { submitFunc } = unref(getProps);
      if (submitFunc && isFunction(submitFunc)) {
        await submitFunc();
        return;
      }
      const res = await formRef.value!.validate();
      emit('submit', res);
    } catch (error) {}
  };

  const handleReset = () => {
    resetFields();
  };

  const refreshFieldObj = ref<object>({});

  function getComponent(component) {
    if (unref(getProps)?.hiddenComponent?.length) {
      unref(getProps)?.hiddenComponent?.forEach((component) => {
        formModel[component.bindField] = component.value;
      });
    }
    const layoutComponents = ['tab', 'grid', 'card'];
    component?.map((info) => {
      if (layoutComponents.includes(info.type!)) {
        info.children?.map((childInfo) => {
          childInfo.list.map((com) => {
            if (layoutComponents.includes(com.type) || com.type === 'table-layout') {
              getComponent(childInfo.list);
            } else {
              setComponentDefault(com);
            }
          });
        });
      } else if (info.type === 'table-layout') {
        info.children?.map((childInfo) => {
          childInfo.list.map((com) => {
            com.children.map((item) => {
              if (layoutComponents.includes(item.type) || item.type === 'table-layout') {
                getComponent(com.children);
              } else {
                setComponentDefault(item);
              }
            });
          });
        });
      } else {
        setComponentDefault(info);
      }
    });
  }

  function setComponentDefault(item) {
    let componentPropsInfo = item.componentProps;
    if (item.componentProps && isFunction(item.componentProps)) {
      componentPropsInfo = item.componentProps({
        schema: item,
        formModel,
        formActionType: formApi,
      });
    }
    if (
      (staticDataComponents.includes(item.component) &&
        (componentPropsInfo as any)?.datasourceType === 'staticData') ||
      (needDicDefaultValue.includes(item.type) &&
        (componentPropsInfo as any)?.datasourceType === 'dic')
    ) {
      let { defaultSelect } = componentPropsInfo as any;
      formModel[item.field] = defaultSelect;
      return;
    }
    let { defaultValue } = item;

    if (item.component === 'Signature' && defaultValue) {
      let val = {};
      const userIds = defaultValue.split(',');
      userIds.forEach((item) => {
        val[item] = '';
      });
      formModel[item.field] = JSON.stringify(val);
      return;
    }
    if (!!item.field && !noDefaultValueComponents.includes(item.component)) {
      if (item.component === 'OneForOne') {
        if (componentPropsInfo.childSchemas?.length) {
          const singleFormObj = {};
          componentPropsInfo.childSchemas.map((singleCom) => {
            let singleComponentProps = singleCom.componentProps;
            if (singleCom.componentProps && isFunction(singleCom.componentProps)) {
              singleComponentProps = singleCom.componentProps({
                schema: item,
                formModel,
                formActionType: formApi,
              });
            }
            if (
              (staticDataComponents.includes(singleCom.component) &&
                (singleComponentProps as any)?.datasourceType === 'staticData') ||
              (needDicDefaultValue.includes(singleCom.type) &&
                (singleComponentProps as any)?.datasourceType === 'dic')
            ) {
              let { defaultSelect } = singleComponentProps as any;
              singleFormObj[singleCom.field] = defaultSelect;
            } else {
              singleFormObj[singleCom.field] = singleCom.defaultValue;
            }
          });
          formModel[item.field] = [singleFormObj];
        }
        return;
      } else {
        if (item.component == 'Input') {
          if (
            componentPropsInfo?.addressKey &&
            query[componentPropsInfo.addressKey] !== undefined
          ) {
            defaultValue = query[componentPropsInfo.addressKey];
          }
        }
        formModel[item.field] = item.component === 'SubForm' ? [] : defaultValue;
        return;
      }
    }
  }

  /**
   * 回车提交表单
   */
  function handleEnterPress(e: KeyboardEvent) {
    const { autoSubmitOnEnter } = unref(getProps);
    if (!autoSubmitOnEnter) return;
    if (e.key === 'Enter' && e.target && e.target instanceof HTMLElement) {
      const target: HTMLElement = e.target as HTMLElement;
      if (target && target.tagName && target.tagName.toUpperCase() == 'INPUT') {
        handleSubmit();
      }
    }
  }

  //调用表单验证
  const validate = async (nameList?: NamePath[]): Promise<any> => formRef.value?.validate(nameList);

  //清除表单验证
  const clearValidate = async (name?: string | string[]): Promise<any> =>
    formRef.value?.clearValidate(name);

  //跳到某个字段
  const scrollToField = async (name: NamePath, options?: ScrollOptions): Promise<any> =>
    formRef.value?.scrollToField(name, options);

  //验证某个字段
  const validateFields = async (
    nameList?: NamePath[] | string,
    options?: ValidateOptions,
  ): Promise<any> => formRef.value?.validateFields(nameList, options);

  const findSchema = (schemaArr, key) => {
    let schema;
    const formListComponent = ['tab', 'grid', 'card'];
    schemaArr?.some((info) => {
      if (formListComponent.includes(info.type!)) {
        const hasComponent = info.children.some((childInfo) => {
          schema = childInfo.list.find((com) => {
            let field = props.isCamelCase ? camelCaseString(com.field) : com.field;
            return field === key;
          });
          if (!!schema) return true;
          schema = findSchema(childInfo.list, key);
          return !!schema;
        });
        return !!hasComponent;
      } else if (info.type === 'table-layout') {
        const hasComponent = info.children.some((childInfo) => {
          return childInfo.list.some((chil) => {
            schema = chil.children.find((com) => {
              let field = props.isCamelCase ? camelCaseString(com.field) : com.field;
              return field === key;
            });
            if (!!schema) return true;
            schema = findSchema(chil.children, key);
            return !!schema;
          });
        });
        return !!hasComponent;
      } else {
        schema =
          (props.isCamelCase ? camelCaseString(info.field) : info.field) === key ? info : null;
        return !!schema;
      }
    });
    return schema;
  };

  const setDefaultValue = async (): Promise<void> => {
    getComponent(getSchemas.value);
  };

  /* 重置表单只读数据，比如编码组件在上下布局模式中新增须记住之前填写的数据，导致编码组件在新增保存之后再新增不自动递增了，
     所以需要在点新增的时候清空数据才能赋新的值
     */
  const resetReadonlyFields = async (): Promise<void> => {
    Object.keys(formModel).forEach((key) => {
      if (!key) return;
      const schema = findSchema(unref(getSchemas), key);
      if (schema?.component == 'AutoCodeRule') {
        formModel[key] = '';
      }
    });
    nextTick(() => clearValidate());
  };

  // 重置表单所有数据
  const resetFields = async (): Promise<void> => {
    Object.keys(formModel).forEach((key) => {
      //没有绑定字段的组件不处理
      if (!key) return;
      let schema = findSchema(unref(getSchemas), key);
      let componentPropsInfo = schema?.componentProps;
      if (schema?.componentProps && isFunction(schema?.componentProps)) {
        componentPropsInfo = schema?.componentProps({
          schema,
          formModel,
          formActionType: formApi,
        });
      }
      if (!schema && unref(getProps)?.hiddenComponent?.length) {
        schema = unref(getProps)?.hiddenComponent?.find((item) => item.bindField === key);
        schema.defaultValue = schema.value;
      }
      const isInput = schema?.component && defaultValueComponents.includes(schema.component);
      const isSubForm = schema?.component && arrayValueComponents.includes(schema.component);
      const isRange = schema?.component && schema?.component.includes('Range');
      const isStatic =
        schema?.component &&
        staticDataComponents.includes(schema.component) &&
        componentPropsInfo.datasourceType === 'staticData';
      const isDic =
        schema?.type &&
        needDicDefaultValue.includes(schema.type) &&
        componentPropsInfo.datasourceType === 'dic';

      if (isSubForm) {
        if (schema.component === 'OneForOne') {
          if (componentPropsInfo.childSchemas?.length) {
            const singleFormObj = {};
            componentPropsInfo.childSchemas.map((singleCom) => {
              let singleComponentProps = singleCom?.componentProps;
              if (singleCom?.componentProps && isFunction(singleCom?.componentProps)) {
                singleComponentProps = singleCom?.componentProps({
                  schema,
                  formModel,
                  formActionType: formApi,
                });
              }
              if (
                (staticDataComponents.includes(singleCom.component) &&
                  singleComponentProps.datasourceType === 'staticData') ||
                (needDicDefaultValue.includes(singleCom.type) &&
                  singleComponentProps.datasourceType === 'dic')
              ) {
                singleFormObj[singleCom.field] = singleComponentProps.defaultSelect;
              } else {
                singleFormObj[singleCom.field] = singleCom.defaultValue;
              }
            });
            formModel[key] = [singleFormObj];
          }
        } else {
          formModel[key] = [];
        }
      } else if (isInput) {
        formModel[key] = schema?.defaultValue || '';
        if (schema.component == 'Input') {
          if (
            componentPropsInfo?.addressKey &&
            query[componentPropsInfo.addressKey] !== undefined
          ) {
            formModel[key] = query[componentPropsInfo.addressKey];
          }
        }
      } else if (isRange) {
        const startTimeKey = key.split(',')[0];
        const endTimeKey = key.split(',')[1];
        formModel[key] = schema?.defaultValue || [];
        formModel[startTimeKey] =
          schema?.defaultValue && schema?.defaultValue.length > 0 && schema?.defaultValue[0];
        formModel[endTimeKey] =
          schema?.defaultValue && schema?.defaultValue.length > 0 && schema?.defaultValue[1];
      } else if (isStatic || isDic) {
        formModel[key] = componentPropsInfo.defaultSelect;
      } else if (schema?.component === 'Signature' && componentPropsInfo.defaultValue) {
        let val = {};
        const userIds = componentPropsInfo.defaultValue.split(',');
        userIds.forEach((item) => {
          val[item] = '';
        });
        formModel[key] = JSON.stringify(val);
      } else {
        if (schema?.component == 'LabelComponent') {
          formModel[key] = null;
        } else {
          formModel[key] =
            schema?.defaultValue || schema?.defaultValue === 0 ? schema?.defaultValue : '';
        }
      }
    });
    nextTick(() => clearValidate());
  };

  // 更改formProps
  const setProps = async (formProps: Partial<FormProps>): Promise<void> => {
    propsRef.value = deepMerge(unref(propsRef) || {}, formProps);
  };

  //设定某个字段值  慎用  建议直接页面直接操作formModel数据
  const setFieldsValue = async (values: Recordable): Promise<void> => {
    Object.keys(values).forEach((key) => {
      if (!isNil(key)) {
        formModel[key] = values[key];
      }
    });

    executeEvent(unref(getSchemas));
  };

  /**
   * 执行schema中 所有change事件
   * 修改bug #5090
   * 为了保证表单赋值触发所有组件的change事件
   */
  const executeEvent = (allSchemas: FormSchema[]) => {
    for (const schema of allSchemas) {
      //如果是这几个组件 需要查询子级
      if (['Card', 'Tab', 'Grid'].includes(schema.component)) {
        if (schema.component === 'Tab') {
          for (const child of schema.children as TabComponentProps[]) {
            executeEvent(child.list);
          }
        }

        if (schema.component === 'Card') {
          for (const child of schema.children as CardComponentProps[]) {
            executeEvent(child.list);
          }
        }

        if (schema.component === 'Grid') {
          for (const child of schema.children as GridComponentProps[]) {
            executeEvent(child.list);
          }
        }
      } else {
        if (schema.componentProps?.['events']) {
          for (const eventKey in schema.componentProps['events']) {
            if (eventKey !== 'change') return;
            try {
              const event = new Function(
                'schema',
                'formModel',
                'formActionType',
                'eventData',
                'options',
                `${schema.componentProps['events'][eventKey]}`,
              );
              schema.componentProps['on' + upperFirst(eventKey)] = function (e, opt) {
                event(schema, formModel, formApi, e, opt);
              };
            } catch (error) {
              console.log('error', error);
              notification.error({
                message: 'Tip',
                description: '触发事件填写有误！',
              });
            }
          }
        }
      }
    }

    // if (componentProps['events']) {
    //   for (const eventKey in componentProps['events']) {
    //     try {
    //       const event = new Function(
    //         'schema',
    //         'formModel',
    //         'formActionType',
    //         `${componentProps['events'][eventKey]}`,
    //       );
    //       componentProps['on' + upperFirst(eventKey)] = function () {
    //         event(props.schema, formModel, props.formApi);
    //       };
    //     } catch (error) {
    //       console.log('error', error);
    //       notification.error({
    //         message: 'Tip',
    //         description: '触发事件填写有误！',
    //       });
    //     }
    //   }
    // }
  };

  // if (componentProps['events']) {
  //   for (const eventKey in componentProps['events']) {
  //     try {
  //       const event = new Function(
  //         'schema',
  //         'formModel',
  //         'formActionType',
  //         `${componentProps['events'][eventKey]}`,
  //       );
  //       componentProps['on' + upperFirst(eventKey)] = function () {
  //         event(props.schema, formModel, props.formApi);
  //       };
  //     } catch (error) {
  //       console.log('error', error);
  //       notification.error({
  //         message: 'Tip',
  //         description: '触发事件填写有误！',
  //       });
  //     }
  //   }
  // }

  //获取表单值  慎用  建议直接页面直接操作formModel数据
  const getFieldsValue = (): Recordable => {
    return toRaw(unref(formModel));
  };

  //更新schema
  const updateSchema = async (data: Partial<FormSchema> | Partial<FormSchema>[]): Promise<void> => {
    let updateData: Partial<FormSchema>[] = [];
    if (isObject(data)) {
      updateData.push(data as FormSchema);
    }
    if (isArray(data)) {
      updateData = [...data];
    }
    // const hasField = updateData.every(
    //   (item) =>
    //     noFieldComponent.includes(item.component!) || (Reflect.has(item, 'field') && item.field),
    // );
    // if (!hasField) {
    //   throw new Error(
    //     'All children of the form Schema array that need to be updated must contain the `field` field',
    //   );
    // }
    const schema: FormSchema[] = [];
    updateData.forEach((item: FormSchema) => {
      unref(getSchemas).forEach((val: FormSchema) => {
        //如果当前组件是布局组件 需要去child 里面更新
        if (['Card', 'Tab', 'Grid', 'TableLayout'].includes(val.component)) {
          deepEachChild(val.children!, item, val.component === 'TableLayout');
        } else {
          if (val.key && item.key && val.key === item.key) {
            const newSchema = deepMerge(val, item);
            schema.push(newSchema as FormSchema);
          } else if (val.type === 'form' && item.form === val.field) {
            if (item.subFormColumns) {
              item.subFormColumns[item.field][item.index] = deepMerge(
                cloneDeep(item.subFormColumns[item.field].default),
                item,
              );
            }

            val.componentProps.columns.forEach((col) => {
              if (col.dataIndex === item.field) {
                col = deepMerge(col, item);
              } else if (col.componentType == 'SunForm') {
                //次级表格
                col.componentProps.columns.forEach((chilcol) => {
                  let sunItem = item.sunForm?.find((o) => o.field == chilcol.dataIndex);
                  if (sunItem) {
                    chilcol = deepMerge(chilcol, sunItem);
                  }
                });
              }
            });
            schema.push(val);
          } else if (val.field === item.field) {
            const newSchema = deepMerge(val, item);
            schema.push(newSchema as FormSchema);
          } else {
            schema.push(val);
          }
        }
      });
    });

    schemaRef.value = uniqBy(schema, 'field');
  };
  const deepEachChild = (
    childs: GridComponentProps[] | TabComponentProps[] | CardComponentProps[],
    thisItem: FormSchema,
    isTableLayout: boolean,
  ) => {
    childs?.forEach((child: GridComponentProps | CardComponentProps | TabComponentProps) => {
      child.list.forEach((it: FormSchema) => {
        changeChild(it, thisItem);
        if (isTableLayout) {
          it.children?.forEach((layout: FormSchema) => {
            changeChild(layout, thisItem);
          });
        }
      });
    });
  };

  const changeChild = (com, thisItem) => {
    if (['Card', 'Tab', 'Grid', 'TableLayout'].includes(com.component)) {
      deepEachChild(com.children!, thisItem, com.component === 'TableLayout');
    }
    if (thisItem.key && com.key && thisItem.key === com.key) {
      com = deepMerge(com, thisItem);
    } else if (thisItem.field === com.field) {
      com = deepMerge(com, thisItem);
    }
  };

  //重置schema
  const resetSchema = async (data: Partial<FormSchema> | Partial<FormSchema>[]): Promise<void> => {
    let updateData: Partial<FormSchema>[] = [];
    if (isObject(data)) {
      updateData.push(data as FormSchema);
    }
    if (isArray(data)) {
      updateData = [...data];
    }

    const hasField = updateData.every(
      (item) =>
        noFieldComponent.includes(item.component!) || (Reflect.has(item, 'field') && item.field),
    );
    if (!hasField) {
      throw new Error(
        'All children of the form Schema array that need to be updated must contain the `field` field',
      );
      return;
    }

    schemaRef.value = updateData as FormSchema[];
  };
  //移除schema
  const removeSchemaByFiled = async (fields: string | string[]): Promise<void> => {
    const schemaList: FormSchema[] = cloneDeep(unref(getSchemas));
    if (!fields) {
      return;
    }

    let fieldList: string[] = isString(fields) ? [fields] : fields;
    if (isString(fields)) {
      fieldList = [fields];
    }
    for (const field of fieldList) {
      if (isString(field)) {
        const index = schemaList.findIndex((schema) => schema.field === field);
        if (index !== -1) {
          delete formModel[field];
          schemaList.splice(index, 1);
        }
      }
    }
    schemaRef.value = schemaList;
  };
  //追加schema
  const appendSchemaByField = async (
    schema: FormSchema,
    prefixField: string | undefined,
    first?: boolean | undefined,
  ): Promise<void> => {
    const schemaList: FormSchema[] = cloneDeep(unref(getSchemas));

    const index = schemaList.findIndex((schema) => schema.field === prefixField);
    if (!prefixField || index === -1 || first) {
      first ? schemaList.unshift(schema) : schemaList.push(schema);
      schemaRef.value = schemaList;
      return;
    }
    if (index !== -1) {
      schemaList.splice(index + 1, 0, schema);
    }

    schemaRef.value = schemaList;
  };

  // 提交
  const submit = async (e?: Event): Promise<void> => {
    e && e.preventDefault();
    const { submitFunc } = unref(getProps);
    if (submitFunc && isFunction(submitFunc)) {
      await submitFunc();
      return;
    }
    const formEl = unref(formRef);
    if (!formEl) return;
    try {
      const values = await validate();
      emit('submit', values);
    } catch (error: any) {
      throw new Error(error);
    }
  };

  const showModal = async (modal: ModalFuncProps) => {
    Modal.confirm({
      title: modal.title,
      icon: createVNode(ExclamationCircleOutlined),
      content: createVNode('div', { style: 'color:red;' }, modal.content),
      onOk: modal.onOk,
      onCancel: modal.onCancel,
      ...modal,
    });
  };

  const showMessage = (content: string) => {
    message.info(content);
  };

  const getUserInfo = (info: string) => {
    if (info === 'roleId') {
      return userStore.getUserInfo.roles.length && userStore.getUserInfo.roles[0].id;
    }
    return userStore.getUserInfo[info];
  };

  const regTest = async (regular: regTestProps) => {
    const regExpression = regular.regExpression;
    const testRes = regExpression.test(regular.testValue);
    testRes ? message.success(regular.successMessage) : message.error(regular.errorMessage);
  };

  const httpRequest = async (request: requestProps) => {
    if (request.requestType.toLowerCase() === 'get') {
      return defHttp[request.requestType](
        {
          url: request.requestUrl,
          params: request.params,
          ...request,
        },
        {
          errorMessageMode: request.errorMessageMode || 'none',
          ...request,
        },
      );
    } else {
      return defHttp[request.requestType](
        {
          url: request.requestUrl,
          data: request.params,
          ...request,
        },
        {
          errorMessageMode: request.errorMessageMode || 'none',
          ...request,
        },
      );
    }
  };

  const refreshAPI = (field: string, index) => {
    if (!field) return;
    const fieldArr = field.split('.');
    if (fieldArr.length > 1) {
      if (isNumber(index)) {
        const fieldName = fieldArr[1] + 'List';
        if (unref(refreshFieldObj)[fieldArr[0]]) {
          if (Object.keys(unref(refreshFieldObj)[fieldArr[0]]).includes(fieldName)) {
            if (!isNil(unref(refreshFieldObj)[fieldArr[0]][fieldName][index])) {
              unref(refreshFieldObj)[fieldArr[0]][fieldName][index]++;
            } else {
              unref(refreshFieldObj)[fieldArr[0]][fieldName][index] = 1;
            }
          } else {
            unref(refreshFieldObj)[fieldArr[0]][fieldName] = {
              [index]: 1,
            };
          }
        } else {
          unref(refreshFieldObj)[fieldArr[0]] = {
            [fieldName]: {
              [index]: 1,
            },
          };
        }
      } else {
        if (unref(refreshFieldObj)[fieldArr[0]]) {
          if (!Object.keys(unref(refreshFieldObj)[fieldArr[0]]).includes(fieldArr[1])) {
            unref(refreshFieldObj)[fieldArr[0]][fieldArr[1]] = 0;
          } else {
            unref(refreshFieldObj)[fieldArr[0]][fieldArr[1]]++;
          }
        } else {
          unref(refreshFieldObj)[fieldArr[0]] = {
            [fieldArr[1]]: 0,
          };
        }
      }
    } else {
      if (!Object.keys(unref(refreshFieldObj)).includes(field)) {
        unref(refreshFieldObj)[field] = 0;
      }
      unref(refreshFieldObj)[field]++;
    }
  };

  const changeStyle = (schema, style, field?) => {
    if (field) {
      schema = findSchema(unref(getSchemas), field);
    }
    schema.componentProps.style = { ...schema.componentProps.style, ...style };
  };
  const changeCompShow = (schema, value, field?) => {
    if (field) {
      field.forEach((o) => {
        schema = findSchema(unref(getSchemas), o);
        schema.show = value;
      });
    }
    schema.show = value;
  };
  async function sendMessageForAllIframe() {
    for (let index = 0; index < SimpleFormItemRefs.value.length; index++) {
      if (SimpleFormItemRefs.value[index]) {
        if (SimpleFormItemRefs.value[index].componentType == 'XjrIframe') {
          if (
            SimpleFormItemRefs.value[index] &&
            SimpleFormItemRefs.value[index].sendMessageForIframe
          ) {
            SimpleFormItemRefs.value[index].sendMessageForIframe();
          }
        }
      }
    }
  }
  function getTableSelectedRows(key) {
    let rows = null;
    for (let index = 0; index < SimpleFormItemRefs.value.length; index++) {
      if (SimpleFormItemRefs.value[index]) {
        if (SimpleFormItemRefs.value[index].key == key) {
          if (SimpleFormItemRefs.value[index]) {
            rows = SimpleFormItemRefs.value[index].getTableSelectedRows();
            if (rows) return rows;
          }
        } else if (
          ['Grid', 'Tab', 'Card', 'TableLayout'].includes(
            SimpleFormItemRefs.value[index].componentType,
          )
        ) {
          rows = SimpleFormItemRefs.value[index].gridFormApi(key, 'getTableSelectedRows');
          if (rows) return rows;
        }
      }
    }
    return rows;
  }
  function customOpenModal(key) {
    let rows = [];
    for (let index = 0; index < SimpleFormItemRefs.value.length; index++) {
      if (SimpleFormItemRefs.value[index]) {
        if (SimpleFormItemRefs.value[index].key == key) {
          if (SimpleFormItemRefs.value[index]) {
            rows = SimpleFormItemRefs.value[index].customOpenModal();
            if (rows) return rows;
          }
        } else if (
          ['Grid', 'Tab', 'Card', 'TableLayout'].includes(
            SimpleFormItemRefs.value[index].componentType,
          )
        ) {
          rows = SimpleFormItemRefs.value[index].gridFormApi(key, 'customOpenModal');
          if (rows) return rows;
        }
      }
    }
    return rows;
  }
  const openTab = (path) => {
    go(path);
  };

  const formApi: FormActionType = {
    submit,
    validate,
    clearValidate,
    scrollToField,
    validateFields,
    resetFields,
    resetReadonlyFields,
    setProps,
    updateSchema,
    setFieldsValue,
    getFieldsValue,
    removeSchemaByFiled,
    appendSchemaByField,
    resetSchema,
    showModal,
    regTest,
    httpRequest,
    refreshAPI,
    changeStyle,
    setDefaultValue,
    showMessage,
    getUserInfo,
    changeCompShow,
    sendMessageForAllIframe,
    openTab,
    getTableSelectedRows,
    customOpenModal,
  };

  getComponent(getSchemas.value);

  //将表单方法  导出 给父组件使用。
  defineExpose<FormActionType>(formApi);
</script>
<style lang="less" scoped>
  :deep(.ant-input[disabled]),
  :deep(.ant-picker-input > input[disabled]),
  :deep(.ant-checkbox-disabled + span),
  :deep(.ant-radio-disabled + span) {
    color: #000;
  }

  :deep(.ant-select-selection-item) {
    color: #000;
  }

  :deep(.ant-input-number-input-wrap) {
    color: inherit;
    text-align: inherit;
    font-size: inherit;
    font-style: inherit;
  }

  :deep(.ant-input-number-input) {
    text-align: inherit;
    font-style: inherit;
  }

  :deep(.ant-form-item) {
    margin-bottom: 16px;
  }
</style>
