Electrolux
2024-04-23 f5cd3ad593ded10a9702cf342d788c4b1540944a
src/components/Form/src/hooks/useFormEvents.ts
@@ -2,12 +2,17 @@
import type { FormProps, FormSchemaInner as FormSchema, FormActionType } from '../types/form';
import type { NamePath } from 'ant-design-vue/lib/form/interface';
import { unref, toRaw, nextTick } from 'vue';
import { isArray, isFunction, isObject, isString, isDef, isNil, isEmpty } from '/@/utils/is';
import { deepMerge } from '/@/utils';
import { dateItemType, handleInputNumberValue, defaultValueComponents } from '../helper';
import { dateUtil } from '/@/utils/dateUtil';
import { cloneDeep, set, uniqBy, get } from 'lodash-es';
import { error } from '/@/utils/log';
import { isArray, isFunction, isObject, isString, isDef, isNil } from '@/utils/is';
import { deepMerge } from '@/utils';
import {
  dateItemType,
  handleInputNumberValue,
  defaultValueComponents,
  isIncludeSimpleComponents,
} from '../helper';
import { dateUtil } from '@/utils/dateUtil';
import { cloneDeep, has, uniqBy, get } from 'lodash-es';
import { error } from '@/utils/log';
interface UseFormActionContext {
  emit: EmitType;
@@ -18,46 +23,6 @@
  formElRef: Ref<FormActionType>;
  schemaRef: Ref<FormSchema[]>;
  handleFormValues: Fn;
}
function tryConstructArray(field: string, values: Recordable = {}): any[] | undefined {
  const pattern = /^\[(.+)\]$/;
  if (pattern.test(field)) {
    const match = field.match(pattern);
    if (match && match[1]) {
      const keys = match[1].split(',');
      if (!keys.length) {
        return undefined;
      }
      const result = [];
      keys.forEach((k, index) => {
        set(result, index, values[k.trim()]);
      });
      return result.filter(Boolean).length ? result : undefined;
    }
  }
}
function tryConstructObject(field: string, values: Recordable = {}): Recordable | undefined {
  const pattern = /^\{(.+)\}$/;
  if (pattern.test(field)) {
    const match = field.match(pattern);
    if (match && match[1]) {
      const keys = match[1].split(',');
      if (!keys.length) {
        return;
      }
      const result = {};
      keys.forEach((k) => {
        set(result, k.trim(), values[k.trim()]);
      });
      return Object.values(result).filter(Boolean).length ? result : undefined;
    }
  }
}
export function useFormEvents({
@@ -82,7 +47,7 @@
      const defaultValueObj = schema?.defaultValueObj;
      const fieldKeys = Object.keys(defaultValueObj || {});
      if (fieldKeys.length) {
        fieldKeys.map((field) => {
        fieldKeys.forEach((field) => {
          formModel[field] = defaultValueObj![field];
        });
      }
@@ -109,24 +74,26 @@
    const fields = getAllFields();
    // key 支持 a.b.c 的嵌套写法
    const delimiter = '.';
    const nestKeyArray = fields.filter((item) => String(item).indexOf(delimiter) >= 0);
    const validKeys: string[] = [];
    fields.forEach((key) => {
      const schema = unref(getSchema).find((item) => item.field === key);
      let value = get(values, key);
      const hasKey = Reflect.has(values, key);
      const hasKey = has(values, key);
      value = handleInputNumberValue(schema?.component, value);
      const { componentProps } = schema || {};
      let _props = componentProps as any;
      if (typeof componentProps === 'function') {
        _props = _props({ formModel: unref(formModel) });
        _props = _props({
          formModel: unref(formModel),
          formActionType,
        });
      }
      const constructValue = tryConstructArray(key, values) || tryConstructObject(key, values);
      const constructValue = get(value, key);
      const setDateFieldValue = (v) => {
        return v ? (_props?.valueFormat ? v : dateUtil(v)) : null;
      };
      // 0| '' is allow
      if (hasKey || !!constructValue) {
@@ -136,15 +103,11 @@
          if (Array.isArray(fieldValue)) {
            const arr: any[] = [];
            for (const ele of fieldValue) {
              arr.push(ele ? dateUtil(ele) : null);
              arr.push(setDateFieldValue(ele));
            }
            unref(formModel)[key] = arr;
          } else {
            unref(formModel)[key] = fieldValue
              ? _props?.valueFormat
                ? fieldValue
                : dateUtil(fieldValue)
              : null;
            unref(formModel)[key] = setDateFieldValue(fieldValue);
          }
        } else {
          unref(formModel)[key] = fieldValue;
@@ -154,20 +117,10 @@
        }
        validKeys.push(key);
      } else {
        nestKeyArray.forEach((nestKey: string) => {
          try {
            const value = nestKey.split('.').reduce((out, item) => out[item], values);
            if (isDef(value)) {
              unref(formModel)[nestKey] = unref(value);
              validKeys.push(nestKey);
            }
          } catch (e) {
            // key not exist
            if (isDef(defaultValueRef.value[nestKey])) {
              unref(formModel)[nestKey] = cloneDeep(unref(defaultValueRef.value[nestKey]));
            }
          }
        });
        // key not exist
        if (isDef(get(defaultValueRef.value, key))) {
          unref(formModel)[key] = cloneDeep(unref(get(defaultValueRef.value, key)));
        }
      }
    });
    validateFields(validKeys).catch((_) => {});
@@ -187,7 +140,7 @@
      fieldList = [fields];
    }
    for (const field of fieldList) {
      _removeSchemaByFeild(field, schemaList);
      _removeSchemaByField(field, schemaList);
    }
    schemaRef.value = schemaList;
  }
@@ -195,7 +148,7 @@
  /**
   * @description: Delete based on field name
   */
  function _removeSchemaByFeild(field: string, schemaList: FormSchema[]): void {
  function _removeSchemaByField(field: string, schemaList: FormSchema[]): void {
    if (isString(field)) {
      const index = schemaList.findIndex((schema) => schema.field === field);
      if (index !== -1) {
@@ -242,7 +195,8 @@
    }
    const hasField = updateData.every(
      (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
      (item) =>
        isIncludeSimpleComponents(item.component) || (Reflect.has(item, 'field') && item.field),
    );
    if (!hasField) {
@@ -264,7 +218,8 @@
    }
    const hasField = updateData.every(
      (item) => item.component === 'Divider' || (Reflect.has(item, 'field') && item.field),
      (item) =>
        isIncludeSimpleComponents(item.component) || (Reflect.has(item, 'field') && item.field),
    );
    if (!hasField) {
@@ -274,21 +229,19 @@
      return;
    }
    const schema: FormSchema[] = [];
    const updatedSchema: FormSchema[] = [];
    unref(getSchema).forEach((val) => {
      let _val;
      updateData.forEach((item) => {
        if (val.field === item.field) {
          _val = item;
        }
      });
      if (_val !== undefined && val.field === _val.field) {
        const newSchema = deepMerge(val, _val);
      const updatedItem = updateData.find((item) => val.field === item.field);
      if (updatedItem) {
        const newSchema = deepMerge(val, updatedItem);
        updatedSchema.push(newSchema as FormSchema);
        schema.push(newSchema as FormSchema);
      } else {
        schema.push(val);
      }
    });
    _setDefaultValue(schema);
    _setDefaultValue(updatedSchema);
    schemaRef.value = uniqBy(schema, 'field');
  }
@@ -306,13 +259,11 @@
    const currentFieldsValue = getFieldsValue();
    schemas.forEach((item) => {
      if (
        item.component != 'Divider' &&
        !isIncludeSimpleComponents(item.component) &&
        Reflect.has(item, 'field') &&
        item.field &&
        !isNil(item.defaultValue) &&
        (!(item.field in currentFieldsValue) ||
          isNil(currentFieldsValue[item.field]) ||
          isEmpty(currentFieldsValue[item.field]))
        (!(item.field in currentFieldsValue) || isNil(currentFieldsValue[item.field]))
      ) {
        obj[item.field] = item.defaultValue;
      }
@@ -336,8 +287,12 @@
  }
  async function validateFields(nameList?: NamePath[] | undefined) {
    const values = unref(formElRef)?.validateFields(nameList);
    const values = await unref(formElRef)?.validateFields(nameList);
    return handleFormValues(values);
  }
  async function setProps(formProps: Partial<FormProps>): Promise<void> {
    await unref(formElRef)?.setProps(formProps);
  }
  async function validate(nameList?: NamePath[] | false | undefined) {
@@ -382,6 +337,22 @@
    }
  }
  const formActionType: Partial<FormActionType> = {
    getFieldsValue,
    setFieldsValue,
    resetFields,
    updateSchema,
    resetSchema,
    setProps,
    removeSchemaByField,
    appendSchemaByField,
    clearValidate,
    validateFields,
    validate,
    submit: handleSubmit,
    scrollToField: scrollToField,
  };
  return {
    handleSubmit,
    clearValidate,
@@ -406,7 +377,7 @@
  let defaultValue = cloneDeep(defaultValueRef.value[key]);
  const isInput = checkIsInput(schema);
  if (isInput) {
    return defaultValue || '';
    return defaultValue || undefined;
  }
  if (!defaultValue && schema && checkIsRangeSlider(schema)) {
    defaultValue = [0, 0];