From d6749f95c526c0e71ec946bd3bb777bc42b2c34a Mon Sep 17 00:00:00 2001
From: Ben Lin <maobin001@msn.com>
Date: 星期日, 20 十月 2024 17:59:31 +0800
Subject: [PATCH] 工艺绑定优化

---
 src/components/Form/src/components/FormItem.vue |  135 +++++++++++++++++++++++++++++++++------------
 1 files changed, 99 insertions(+), 36 deletions(-)

diff --git a/src/components/Form/src/components/FormItem.vue b/src/components/Form/src/components/FormItem.vue
index 9e598ca..e48f4e9 100644
--- a/src/components/Form/src/components/FormItem.vue
+++ b/src/components/Form/src/components/FormItem.vue
@@ -2,22 +2,29 @@
   import { type Recordable, type Nullable } from '@vben/types';
   import type { PropType, Ref } from 'vue';
   import { computed, defineComponent, toRefs, unref } from 'vue';
-  import type { FormActionType, FormProps, FormSchema } from '../types/form';
-  import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
-  import type { TableActionType } from '/@/components/Table';
+  import {
+    isComponentFormSchema,
+    type FormActionType,
+    type FormProps,
+    type FormSchemaInner as FormSchema,
+  } from '../types/form';
+  
+  import type { Rule as ValidationRule } from 'ant-design-vue/lib/form/interface';
+  import type { TableActionType } from '@/components/Table';
   import { Col, Divider, Form } from 'ant-design-vue';
   import { componentMap } from '../componentMap';
-  import { BasicHelp } from '/@/components/Basic';
-  import { isBoolean, isFunction, isNull } from '/@/utils/is';
-  import { getSlot } from '/@/utils/helper/tsxHelper';
+  import { BasicHelp, BasicTitle } from '@/components/Basic';
+  import { isBoolean, isFunction, isNull } from '@/utils/is';
+  import { getSlot } from '@/utils/helper/tsxHelper';
   import {
     createPlaceholderMessage,
+    isIncludeSimpleComponents,
     NO_AUTO_LINK_COMPONENTS,
     setComponentRuleType,
   } from '../helper';
   import { cloneDeep, upperFirst } from 'lodash-es';
   import { useItemLabelWidth } from '../hooks/useLabelWidth';
-  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useI18n } from '@/hooks/web/useI18n';
 
   export default defineComponent({
     name: 'BasicFormItem',
@@ -61,6 +68,12 @@
         formProps: Ref<FormProps>;
       };
 
+      // 缁勪欢 CropperAvatar 鐨� size 灞炴�х被鍨嬩负 number
+      // 姝ゅ琛ュ厖涓�涓吋瀹�
+      if (schema.value.component === 'CropperAvatar' && typeof formProps.value.size === 'string') {
+        formProps.value.size = undefined;
+      }
+
       const itemLabelWidthProp = useItemLabelWidth(schema, formProps);
 
       const getValues = computed(() => {
@@ -84,7 +97,7 @@
         if (isFunction(componentProps)) {
           componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
         }
-        if (schema.component === 'Divider') {
+        if (isIncludeSimpleComponents(schema.component)) {
           componentProps = Object.assign(
             { type: 'horizontal' },
             {
@@ -109,6 +122,21 @@
           disabled = dynamicDisabled(unref(getValues));
         }
         return disabled;
+      });
+
+      const getReadonly = computed(() => {
+        const { readonly: globReadonly } = props.formProps;
+        const { dynamicReadonly } = props.schema;
+        const { readonly: itemReadonly = false } = unref(getComponentsProps);
+
+        let readonly = globReadonly || itemReadonly;
+        if (isBoolean(dynamicReadonly)) {
+          readonly = dynamicReadonly;
+        }
+        if (isFunction(dynamicReadonly)) {
+          readonly = dynamicReadonly(unref(getValues));
+        }
+        return readonly;
       });
 
       function getShow(): { isShow: boolean; isIfShow: boolean } {
@@ -138,7 +166,6 @@
         isShow = isShow && itemIsAdvanced;
         return { isShow, isIfShow };
       }
-
       function handleRules(): ValidationRule[] {
         const {
           rules: defRules = [],
@@ -148,7 +175,6 @@
           dynamicRules,
           required,
         } = props.schema;
-
         if (isFunction(dynamicRules)) {
           return dynamicRules(unref(getValues)) as ValidationRule[];
         }
@@ -159,7 +185,10 @@
         const joinLabel = Reflect.has(props.schema, 'rulesMessageJoinLabel')
           ? rulesMessageJoinLabel
           : globalRulesMessageJoinLabel;
-        const defaultMsg = createPlaceholderMessage(component) + `${joinLabel ? label : ''}`;
+        const assertLabel = joinLabel ? (isFunction(label) ? '' : label) : '';
+        const defaultMsg = component
+          ? createPlaceholderMessage(component) + assertLabel
+          : assertLabel;
 
         function validator(rule: any, value: any) {
           const msg = rule.message || defaultMsg;
@@ -186,7 +215,6 @@
           }
           return Promise.resolve();
         }
-
         const getRequired = isFunction(required) ? required(unref(getValues)) : required;
 
         /*
@@ -196,7 +224,10 @@
          */
         if (getRequired) {
           if (!rules || rules.length === 0) {
-            rules = [{ required: getRequired, validator }];
+            const trigger = NO_AUTO_LINK_COMPONENTS.includes(component || 'Input')
+              ? 'blur'
+              : 'change';
+            rules = [{ required: getRequired, validator, trigger }];
           } else {
             const requiredIndex: number = rules.findIndex((rule) => Reflect.has(rule, 'required'));
 
@@ -217,10 +248,6 @@
             rule.required = false;
           }
           if (component) {
-            if (!Reflect.has(rule, 'type')) {
-              rule.type = component === 'InputNumber' ? 'number' : 'string';
-            }
-
             rule.message = rule.message || defaultMsg;
 
             if (component.includes('Input') || component.includes('Textarea')) {
@@ -242,12 +269,16 @@
       }
 
       function renderComponent() {
+        if (!isComponentFormSchema(props.schema)) {
+          return null;
+        }
         const {
           renderComponentContent,
           component,
           field,
           changeEvent = 'change',
           valueField,
+          valueFormat,
         } = props.schema;
 
         const isCheck = component && ['Switch', 'Checkbox'].includes(component);
@@ -257,12 +288,17 @@
         const on = {
           [eventKey]: (...args: Nullable<Recordable<any>>[]) => {
             const [e] = args;
+            
+            const target = e ? e.target : null;
+            let value = target ? (isCheck ? target.checked : target.value) : e;
+            if(isFunction(valueFormat)){
+              value = valueFormat({...unref(getValues),value});
+            }
+            props.setFormModel(field, value, props.schema);
+
             if (propsData[eventKey]) {
               propsData[eventKey](...args);
             }
-            const target = e ? e.target : null;
-            const value = target ? (isCheck ? target.checked : target.value) : e;
-            props.setFormModel(field, value, props.schema);
           },
         };
         const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>;
@@ -270,10 +306,10 @@
         const { autoSetPlaceHolder, size } = props.formProps;
         const propsData: Recordable<any> = {
           allowClear: true,
-          getPopupContainer: (trigger: Element) => trigger.parentNode,
           size,
           ...unref(getComponentsProps),
           disabled: unref(getDisable),
+          readonly: unref(getReadonly),
         };
 
         const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder;
@@ -299,7 +335,12 @@
           return <Comp {...compAttr} />;
         }
         const compSlot = isFunction(renderComponentContent)
-          ? { ...renderComponentContent(unref(getValues)) }
+          ? {
+              ...renderComponentContent(unref(getValues), {
+                disabled: unref(getDisable),
+                readonly: unref(getReadonly),
+              }),
+            }
           : {
               default: () => renderComponentContent,
             };
@@ -308,12 +349,13 @@
 
       function renderLabelHelpMessage() {
         const { label, helpMessage, helpComponentProps, subLabel } = props.schema;
+        const getLabel = isFunction(label) ? label(unref(getValues)) : label;
         const renderLabel = subLabel ? (
           <span>
-            {label} <span class="text-secondary">{subLabel}</span>
+            {getLabel} <span class="text-secondary">{subLabel}</span>
           </span>
         ) : (
-          label
+          getLabel
         );
         const getHelpMessage = isFunction(helpMessage)
           ? helpMessage(unref(getValues))
@@ -330,30 +372,46 @@
       }
 
       function renderItem() {
-        const { itemProps, slot, render, field, suffix, component } = props.schema;
+        const { itemProps, slot, render, field, suffix, component, prefix } = props.schema;
         const { labelCol, wrapperCol } = unref(itemLabelWidthProp);
         const { colon } = props.formProps;
-
+        const opts = { disabled: unref(getDisable), readonly: unref(getReadonly) };
         if (component === 'Divider') {
           return (
             <Col span={24}>
               <Divider {...unref(getComponentsProps)}>{renderLabelHelpMessage()}</Divider>
             </Col>
           );
+        } else if (component === 'BasicTitle') {
+          return (
+            <Form.Item
+              labelCol={labelCol}
+              wrapperCol={wrapperCol}
+              name={field}
+              class={{
+                'suffix-item': !!suffix,
+                'prefix-item': !!prefix,
+              }}
+            >
+              <BasicTitle {...unref(getComponentsProps)}>{renderLabelHelpMessage()}</BasicTitle>
+            </Form.Item>
+          );
         } else {
           const getContent = () => {
             return slot
-              ? getSlot(slots, slot, unref(getValues))
+              ? getSlot(slots, slot, unref(getValues), opts)
               : render
-              ? render(unref(getValues))
-              : renderComponent();
+                ? render(unref(getValues), opts)
+                : renderComponent();
           };
 
           const showSuffix = !!suffix;
           const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;
 
+          const showPrefix = !!prefix;
+          const getPrefix = isFunction(prefix) ? prefix(unref(getValues)) : prefix;
           // TODO 鑷畾涔夌粍浠堕獙璇佷細鍑虹幇闂锛屽洜姝よ繖閲屾鏋堕粯璁ゅ皢鑷畾涔夌粍浠惰缃墜鍔ㄨЕ鍙戦獙璇侊紝濡傛灉鍏朵粬缁勪欢杩樻湁姝ら棶棰樿鎵嬪姩璁剧疆autoLink=false
-          if (NO_AUTO_LINK_COMPONENTS.includes(component)) {
+          if (component && NO_AUTO_LINK_COMPONENTS.includes(component)) {
             props.schema &&
               (props.schema.itemProps! = {
                 autoLink: false,
@@ -365,7 +423,10 @@
             <Form.Item
               name={field}
               colon={colon}
-              class={{ 'suffix-item': showSuffix }}
+              class={{
+                'suffix-item': showSuffix,
+                'prefix-item': showPrefix,
+              }}
               {...(itemProps as Recordable<any>)}
               label={renderLabelHelpMessage()}
               rules={handleRules()}
@@ -373,6 +434,7 @@
               wrapperCol={wrapperCol}
             >
               <div style="display:flex">
+                {showPrefix && <span class="prefix">{getPrefix}</span>}
                 <div style="flex:1;">{getContent()}</div>
                 {showSuffix && <span class="suffix">{getSuffix}</span>}
               </div>
@@ -382,8 +444,8 @@
       }
 
       return () => {
-        const { colProps = {}, colSlot, renderColContent, component } = props.schema;
-        if (!componentMap.has(component)) {
+        const { colProps = {}, colSlot, renderColContent, component, slot } = props.schema;
+        if (!((component && componentMap.has(component)) || slot)) {
           return null;
         }
 
@@ -391,13 +453,14 @@
         const realColProps = { ...baseColProps, ...colProps };
         const { isIfShow, isShow } = getShow();
         const values = unref(getValues);
+        const opts = { disabled: unref(getDisable), readonly: unref(getReadonly) };
 
         const getContent = () => {
           return colSlot
-            ? getSlot(slots, colSlot, values)
+            ? getSlot(slots, colSlot, values, opts)
             : renderColContent
-            ? renderColContent(values)
-            : renderItem();
+              ? renderColContent(values, opts)
+              : renderItem();
         };
 
         return (

--
Gitblit v1.9.3