From 08abfcfea8247c394b2034cad59734846b403dd9 Mon Sep 17 00:00:00 2001
From: Ben Lin <maobin001@msn.com>
Date: 星期一, 28 十月 2024 22:22:58 +0800
Subject: [PATCH] 计划任务优化

---
 src/components/Form/src/BasicForm.vue |  511 +++++++++++++++++++++++++++++++-------------------------
 1 files changed, 279 insertions(+), 232 deletions(-)

diff --git a/src/components/Form/src/BasicForm.vue b/src/components/Form/src/BasicForm.vue
index f561a9a..63e942c 100644
--- a/src/components/Form/src/BasicForm.vue
+++ b/src/components/Form/src/BasicForm.vue
@@ -37,269 +37,311 @@
     </Row>
   </Form>
 </template>
-<script lang="ts">
-  import type { FormActionType, FormProps, FormSchema } from './types/form';
+<script lang="ts" setup>
+  import type { FormActionType, FormProps, FormSchemaInner as FormSchema } from './types/form';
   import type { AdvanceState } from './types/hooks';
   import type { Ref } from 'vue';
 
-  import { defineComponent, reactive, ref, computed, unref, onMounted, watch, nextTick } from 'vue';
-  import { Form, Row } from 'ant-design-vue';
+  import { reactive, ref, computed, unref, onMounted, watch, nextTick, useAttrs } from 'vue';
+  import { Form, Row, type FormProps as AntFormProps } from 'ant-design-vue';
   import FormItem from './components/FormItem.vue';
   import FormAction from './components/FormAction.vue';
 
-  import { dateItemType } from './helper';
-  import { dateUtil } from '/@/utils/dateUtil';
+  import { dateItemType, isIncludeSimpleComponents } from './helper';
+  import { dateUtil } from '@/utils/dateUtil';
 
-  // import { cloneDeep } from 'lodash-es';
-  import { deepMerge } from '/@/utils';
+  import { deepMerge } from '@/utils';
 
   import { useFormValues } from './hooks/useFormValues';
   import useAdvanced from './hooks/useAdvanced';
-  import { useFormEvents } from './hooks/useFormEvents';
+  import { itemIsUploadComponent, useFormEvents } from './hooks/useFormEvents';
   import { createFormContext } from './hooks/useFormContext';
   import { useAutoFocus } from './hooks/useAutoFocus';
-  import { useModalContext } from '/@/components/Modal';
+  import { useModalContext } from '@/components/Modal';
   import { useDebounceFn } from '@vueuse/core';
 
   import { basicProps } from './props';
-  import { useDesign } from '/@/hooks/web/useDesign';
+  import { useDesign } from '@/hooks/web/useDesign';
   import { cloneDeep } from 'lodash-es';
+  import { TableActionType } from '@/components/Table';
+  import { isArray, isFunction } from '@/utils/is';
 
-  export default defineComponent({
-    name: 'BasicForm',
-    components: { FormItem, Form, Row, FormAction },
-    props: basicProps,
-    emits: ['advanced-change', 'reset', 'submit', 'register', 'field-value-change'],
-    setup(props, { emit, attrs }) {
-      const formModel = reactive({});
-      const modalFn = useModalContext();
+  defineOptions({ name: 'BasicForm' });
 
-      const advanceState = reactive<AdvanceState>({
-        isAdvanced: true,
-        hideAdvanceBtn: false,
-        isLoad: false,
-        actionSpan: 6,
-      });
+  const props = defineProps(basicProps);
 
-      const defaultValueRef = ref({});
-      const isInitedDefaultRef = ref(false);
-      const propsRef = ref<Partial<FormProps>>({});
-      const schemaRef = ref<FormSchema[] | null>(null);
-      const formElRef = ref<FormActionType | null>(null);
+  const emit = defineEmits([
+    'advanced-change',
+    'reset',
+    'submit',
+    'register',
+    'field-value-change',
+  ]);
 
-      const { prefixCls } = useDesign('basic-form');
+  const attrs = useAttrs();
 
-      // Get the basic configuration of the form
-      const getProps = computed((): FormProps => {
-        return { ...props, ...unref(propsRef) };
-      });
+  const formModel = reactive({});
+  const modalFn = useModalContext();
 
-      const getFormClass = computed(() => {
-        return [
-          prefixCls,
-          {
-            [`${prefixCls}--compact`]: unref(getProps).compact,
-          },
-        ];
-      });
+  const advanceState = reactive<AdvanceState>({
+    isAdvanced: true,
+    hideAdvanceBtn: false,
+    isLoad: false,
+    actionSpan: 6,
+  });
 
-      // Get uniform row style and Row configuration for the entire form
-      const getRow = computed(() => {
-        const { baseRowStyle = {}, rowProps } = unref(getProps);
-        return {
-          style: baseRowStyle,
-          ...rowProps,
-        };
-      });
+  const defaultValueRef = ref({});
+  const isInitedDefaultRef = ref(false);
+  const propsRef = ref<Partial<FormProps>>();
+  const schemaRef = ref<FormSchema[] | null>(null);
+  const formElRef = ref<FormActionType | null>(null);
 
-      const getBindValue = computed(() => ({ ...attrs, ...props, ...unref(getProps) }));
+  const { prefixCls } = useDesign('basic-form');
 
-      const getSchema = computed((): FormSchema[] => {
-        const schemas: FormSchema[] = unref(schemaRef) || (unref(getProps).schemas as any);
-        for (const schema of schemas) {
-          const { defaultValue, component, isHandleDateDefaultValue = true } = schema;
-          // handle date type
-          if (isHandleDateDefaultValue && defaultValue && dateItemType.includes(component)) {
-            if (!Array.isArray(defaultValue)) {
-              schema.defaultValue = dateUtil(defaultValue);
-            } else {
-              const def: any[] = [];
-              defaultValue.forEach((item) => {
-                def.push(dateUtil(item));
-              });
-              schema.defaultValue = def;
-            }
-          }
-        }
-        if (unref(getProps).showAdvancedButton) {
-          return cloneDeep(
-            schemas.filter((schema) => schema.component !== 'Divider') as FormSchema[],
-          );
-        } else {
-          return cloneDeep(schemas as FormSchema[]);
-        }
-      });
+  // Get the basic configuration of the form
+  const getProps = computed(() => {
+    return { ...props, ...unref(propsRef) } as FormProps;
+  });
 
-      const { handleToggleAdvanced, fieldsIsAdvancedMap } = useAdvanced({
-        advanceState,
-        emit,
-        getProps,
-        getSchema,
-        formModel,
-        defaultValueRef,
-      });
+  const getFormClass = computed(() => {
+    return [
+      prefixCls,
+      {
+        [`${prefixCls}--compact`]: unref(getProps).compact,
+      },
+    ];
+  });
 
-      const { handleFormValues, initDefault } = useFormValues({
-        getProps,
-        defaultValueRef,
-        getSchema,
-        formModel,
-      });
+  // Get uniform row style and Row configuration for the entire form
+  const getRow = computed(() => {
+    const { baseRowStyle = {}, rowProps } = unref(getProps);
+    return {
+      style: baseRowStyle,
+      ...rowProps,
+    };
+  });
 
-      useAutoFocus({
-        getSchema,
-        getProps,
-        isInitedDefault: isInitedDefaultRef,
-        formElRef: formElRef as Ref<FormActionType>,
-      });
+  const getBindValue = computed(() => ({ ...attrs, ...props, ...unref(getProps) }) as AntFormProps);
 
+  const getSchema = computed((): FormSchema[] => {
+    const schemas: FormSchema[] = cloneDeep(unref(schemaRef) || (unref(getProps).schemas as any));
+    for (const schema of schemas) {
       const {
-        handleSubmit,
-        setFieldsValue,
-        clearValidate,
-        validate,
-        validateFields,
-        getFieldsValue,
-        updateSchema,
-        resetSchema,
-        appendSchemaByField,
-        removeSchemaByField,
-        resetFields,
-        scrollToField,
-      } = useFormEvents({
-        emit,
-        getProps,
-        formModel,
-        getSchema,
-        defaultValueRef,
-        formElRef: formElRef as Ref<FormActionType>,
-        schemaRef: schemaRef as Ref<FormSchema[]>,
-        handleFormValues,
-      });
-
-      createFormContext({
-        resetAction: resetFields,
-        submitAction: handleSubmit,
-      });
-
-      watch(
-        () => unref(getProps).model,
-        () => {
-          const { model } = unref(getProps);
-          if (!model) return;
-          setFieldsValue(model);
-        },
-        {
-          immediate: true,
-        },
-      );
-
-      watch(
-        () => unref(getProps).schemas,
-        (schemas) => {
-          resetSchema(schemas ?? []);
-        },
-      );
-
-      watch(
-        () => getSchema.value,
-        (schema) => {
-          nextTick(() => {
-            //  Solve the problem of modal adaptive height calculation when the form is placed in the modal
-            modalFn?.redoModalHeight?.();
+        defaultValue,
+        component,
+        componentProps = {},
+        isHandleDateDefaultValue = true,
+        field,
+        isHandleDefaultValue = true,
+        valueFormat,
+      } = schema;
+      // handle date type
+      if (
+        isHandleDateDefaultValue &&
+        defaultValue &&
+        component &&
+        dateItemType.includes(component)
+      ) {
+        const opt = {
+          schema,
+          tableAction: props.tableAction ?? ({} as TableActionType),
+          formModel,
+          formActionType: {} as FormActionType,
+        };
+        const valueFormat = componentProps
+          ? typeof componentProps === 'function'
+            ? componentProps(opt)['valueFormat']
+            : componentProps['valueFormat']
+          : null;
+        if (!Array.isArray(defaultValue)) {
+          schema.defaultValue = valueFormat
+            ? dateUtil(defaultValue).format(valueFormat)
+            : dateUtil(defaultValue);
+        } else {
+          const def: any[] = [];
+          defaultValue.forEach((item) => {
+            def.push(valueFormat ? dateUtil(item).format(valueFormat) : dateUtil(item));
           });
-          if (unref(isInitedDefaultRef)) {
-            return;
-          }
-          if (schema?.length) {
-            initDefault();
-            isInitedDefaultRef.value = true;
-          }
-        },
-      );
-
-      watch(
-        () => formModel,
-        useDebounceFn(() => {
-          unref(getProps).submitOnChange && handleSubmit();
-        }, 300),
-        { deep: true },
-      );
-
-      async function setProps(formProps: Partial<FormProps>): Promise<void> {
-        propsRef.value = deepMerge(unref(propsRef) || {}, formProps);
+          schema.defaultValue = def;
+        }
       }
-
-      function setFormModel(key: string, value: any, schema: FormSchema) {
-        formModel[key] = value;
-        emit('field-value-change', key, value);
-        // TODO 浼樺寲楠岃瘉锛岃繖閲屽鏋滄槸autoLink=false鎵嬪姩鍏宠仈鐨勬儏鍐典笅鎵嶄細鍐嶆瑙﹀彂姝ゅ嚱鏁�
-        if (schema && schema.itemProps && !schema.itemProps.autoLink) {
-          validateFields([key]).catch((_) => {});
+      // handle upload type
+      if (defaultValue && itemIsUploadComponent(schema?.component)) {
+        if (isArray(defaultValue)) {
+          schema.defaultValue = defaultValue;
+        } else if (typeof defaultValue == 'string') {
+          schema.defaultValue = [defaultValue];
         }
       }
 
-      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();
-          }
-        }
+      // handle schema.valueFormat
+      if (isHandleDefaultValue && defaultValue && component && isFunction(valueFormat)) {
+        schema.defaultValue = valueFormat({
+          value: defaultValue,
+          schema,
+          model: formModel,
+          field,
+        });
       }
+    }
+    if (unref(getProps).showAdvancedButton) {
+      return schemas.filter(
+        (schema) => !isIncludeSimpleComponents(schema.component),
+      ) as FormSchema[];
+    } else {
+      return schemas as FormSchema[];
+    }
+  });
 
-      const formActionType: Partial<FormActionType> = {
-        getFieldsValue,
-        setFieldsValue,
-        resetFields,
-        updateSchema,
-        resetSchema,
-        setProps,
-        removeSchemaByField,
-        appendSchemaByField,
-        clearValidate,
-        validateFields,
-        validate,
-        submit: handleSubmit,
-        scrollToField: scrollToField,
-      };
+  const { handleToggleAdvanced, fieldsIsAdvancedMap } = useAdvanced({
+    advanceState,
+    emit,
+    getProps,
+    getSchema,
+    formModel,
+    defaultValueRef,
+  });
 
-      onMounted(() => {
-        initDefault();
-        emit('register', formActionType);
-      });
+  const { handleFormValues, initDefault } = useFormValues({
+    getProps,
+    defaultValueRef,
+    getSchema,
+    formModel,
+  });
 
-      return {
-        getBindValue,
-        handleToggleAdvanced,
-        handleEnterPress,
-        formModel,
-        defaultValueRef,
-        advanceState,
-        getRow,
-        getProps,
-        formElRef,
-        getSchema,
-        formActionType: formActionType as any,
-        setFormModel,
-        getFormClass,
-        getFormActionBindProps: computed(() => ({ ...getProps.value, ...advanceState })),
-        fieldsIsAdvancedMap,
-        ...formActionType,
-      };
+  useAutoFocus({
+    getSchema,
+    getProps,
+    isInitedDefault: isInitedDefaultRef,
+    formElRef: formElRef as Ref<FormActionType>,
+  });
+
+  const {
+    handleSubmit,
+    setFieldsValue,
+    clearValidate,
+    validate,
+    validateFields,
+    getFieldsValue,
+    updateSchema,
+    resetSchema,
+    appendSchemaByField,
+    removeSchemaByField,
+    resetFields,
+    scrollToField,
+    resetDefaultField,
+  } = useFormEvents({
+    emit,
+    getProps,
+    formModel,
+    getSchema,
+    defaultValueRef,
+    formElRef: formElRef as Ref<FormActionType>,
+    schemaRef: schemaRef as Ref<FormSchema[]>,
+    handleFormValues,
+  });
+
+  createFormContext({
+    resetAction: resetFields,
+    submitAction: handleSubmit,
+  });
+
+  watch(
+    () => unref(getProps).model,
+    () => {
+      const { model } = unref(getProps);
+      if (!model) return;
+      setFieldsValue(model);
     },
+    {
+      immediate: true,
+    },
+  );
+
+  watch(
+    () => props.schemas,
+    (schemas) => {
+      resetSchema(schemas ?? []);
+    },
+  );
+
+  watch(
+    () => getSchema.value,
+    (schema) => {
+      nextTick(() => {
+        //  Solve the problem of modal adaptive height calculation when the form is placed in the modal
+        modalFn?.redoModalHeight?.();
+      });
+      if (unref(isInitedDefaultRef)) {
+        return;
+      }
+      if (schema?.length) {
+        initDefault();
+        isInitedDefaultRef.value = true;
+      }
+    },
+  );
+
+  watch(
+    () => formModel,
+    useDebounceFn(() => {
+      unref(getProps).submitOnChange && handleSubmit();
+    }, 300),
+    { deep: true },
+  );
+
+  async function setProps(formProps: Partial<FormProps>): Promise<void> {
+    propsRef.value = deepMerge(unref(propsRef) || {}, formProps);
+  }
+
+  function setFormModel(key: string, value: any, schema: FormSchema) {
+    formModel[key] = value;
+    emit('field-value-change', key, value);
+    // TODO 浼樺寲楠岃瘉锛岃繖閲屽鏋滄槸autoLink=false鎵嬪姩鍏宠仈鐨勬儏鍐典笅鎵嶄細鍐嶆瑙﹀彂姝ゅ嚱鏁�
+    if (schema && schema.itemProps && !schema.itemProps.autoLink) {
+      validateFields([key]).catch((_) => {});
+    }
+  }
+
+  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 formActionType = {
+    getFieldsValue,
+    setFieldsValue,
+    resetFields,
+    updateSchema,
+    resetSchema,
+    setProps,
+    removeSchemaByField,
+    appendSchemaByField,
+    clearValidate,
+    validateFields,
+    validate,
+    submit: handleSubmit,
+    scrollToField: scrollToField,
+    resetDefaultField,
+  };
+
+  const getFormActionBindProps = computed(
+    () => ({ ...getProps.value, ...advanceState }) as InstanceType<typeof FormAction>['$props'],
+  );
+
+  defineExpose({
+    ...formActionType,
+  });
+
+  onMounted(() => {
+    initDefault();
+    emit('register', formActionType);
   });
 </script>
 <style lang="less">
@@ -311,21 +353,26 @@
         margin: 0 6px 0 2px;
       }
 
-      &-with-help {
-        margin-bottom: 0;
-      }
+      // &-with-help {
+      //   margin-bottom: 0;
+      // }
 
-      &:not(.ant-form-item-with-help) {
-        margin-bottom: 20px;
-      }
+      // &:not(.ant-form-item-with-help) {
+      //   margin-bottom: 20px;
+      // }
 
-      &.suffix-item {
+      &.suffix-item,
+      &.prefix-item {
         .ant-form-item-children {
           display: flex;
         }
 
-        .ant-form-item-control {
-          margin-top: 4px;
+        .prefix {
+          display: inline-flex;
+          align-items: center;
+          margin-top: 1px;
+          padding-right: 6px;
+          line-height: 1;
         }
 
         .suffix {

--
Gitblit v1.9.3