Эх сурвалжийг харах

fix: BsUi表单组件修改

lirenjie 4 сар өмнө
parent
commit
6d1ffd14fd
1 өөрчлөгдсөн 142 нэмэгдсэн , 112 устгасан
  1. 142 112
      src/components/BsUi/Form/Form.vue

+ 142 - 112
src/components/BsUi/Form/Form.vue

@@ -1,24 +1,37 @@
 <template>
   <div class="form">
-    <a-form ref="formRef" :model="props.formData" v-bind="props.formExtraProps" layout="vertical" :id="props.formId"  :validateTrigger="['submit']" >
-      <a-row v-for="(key, index) in Object.keys(newFormTemp)" :key="index" :id="key">
+    <a-form ref="formRef" :model="props.formData" v-bind="props.formExtraProps" layout="vertical" :id="props.formId"
+      :validateTrigger="['submit']">
+      <a-row v-for="(key, index) in Object.keys(newFormTemp)" :key="index" :id="key" :gutter="16">
         <a-col :span="24" v-if="formGroups.length > 0">
-          <div class="group-title">{{ formGroups.find((v) => v.id === key)?.name }}</div>
+          <BsCatalog :title="formGroups.find((v) => v.id === key)?.name"
+            v-if="formGroups.findIndex((item) => item.type === 'dot') > -1" />
+          <div class="group-title" v-else>{{formGroups.find((v) => v.id === key)?.name}}</div>
         </a-col>
-        <a-col :span="24" v-for="(item, idx) in newFormTemp[key]">
-          <a-row>
-            <a-col :span="24" v-if="item.visible === DISPLAY_STATE.VISIBLE">
-              <a-form-item :label="item.label" :name="item.field" :required="item.required === REQUIRED_STATE.REQUIRED" v-bind="item.formItemExtraProps">
-                <component
-                  :is="item.component"
-                  v-model:value="props.formData[item.field]"
-                  v-model:checked="props.formData[item.field]"
-                  v-bind="item.componentProps"
-                  @change="handleFieldChange(item, $event)"
-                />
-              </a-form-item>
-            </a-col>
-          </a-row>
+        <a-col :span="item.span ?? 24" v-for="(item, idx) in newFormTemp[key]">
+          <a-form-item v-if="item.visible === DISPLAY_STATE.VISIBLE" :name="item.field"
+            :required="item.required === REQUIRED_STATE.REQUIRED" :label="item.label" v-bind="item.formItemExtraProps">
+
+            <template #label v-if="item.tooltip">
+              {{ item.label }}
+              <a-tooltip class="tooltip">
+                <template #title>
+                  <span>{{ item.tooltip }}</span>
+                </template>
+                <QuestionCircleOutlined />
+              </a-tooltip>
+            </template>
+
+            <template #label v-else>{{ item.label }}</template>
+            <component :is="item.component" v-model:value="props.formData[item.field]"
+              v-model:checked="props.formData[item.field]" v-bind="item.componentProps"
+              @change="handleFieldChange(item, $event)">
+              <slot>{{ item.componentProps?.buttonText || '' }}</slot>
+              <template v-for="slot in item.componentProps.slots" #[slot.slotName]>
+                <component :is="slot.customRender()" v-bind="slot.slotProps"></component>
+              </template>
+            </component>
+          </a-form-item>
         </a-col>
 
         <a-col :span="24" v-if="!footerRender && !slots.footerRender">
@@ -45,111 +58,128 @@
 </template>
 
 <script setup lang="jsx">
-  import { computed, ref, useSlots } from 'vue';
-  import RenderVNode from '/@/components/BsUi/RenderVNode/index.js';
-  import { groupBy, mapValues, sortBy } from 'lodash';
-  import { DISPLAY_STATE, REQUIRED_STATE } from '/@/components/BsUi/constant.js'
-
-  const formRef = ref(null);
-  const confirmLoading = ref(false);
-
-  const props = defineProps({
-    formFields: {
-      required: true,
-      default: [],
-    },
-    formData: {
-      required: true,
-      default: {},
-    },
-    formExtraProps: {
-      required: false,
-      default: null,
-    },
-    footerRender: {
-      required: false,
-      default: null,
-    },
-    formGroups: {
-      required: false,
-      default: [],
-    },
-    formId: {
-      required: false,
-      default: 'AchorContentId',
-    },
-    isShowGroupTitle: {
-      required: false,
-      default: true,
-    },
-  });
-  const emits = defineEmits(['cancel', 'ok', 'change']);
-  const slots = useSlots();
+import { computed, ref, useSlots } from 'vue';
+import RenderVNode from '/@/components/BsUi/RenderVNode/index.js';
+import { groupBy, mapValues, sortBy } from 'lodash';
+import { DISPLAY_STATE, REQUIRED_STATE } from '/@/components/BsUi/constant.js'
+import BsCatalog from '/@/components/BsUi/Catalog/index.vue';
+const formRef = ref(null);
+const confirmLoading = ref(false);
 
-  const handleFieldChange = (field, value) => {
-    formRef.value.validateFields([field.field])
-    field?.onChange && field?.onChange(value)
-    emits('change', value)
-  }
+const props = defineProps({
+  formFields: {
+    required: true,
+    default: [],
+  },
+  formData: {
+    required: true,
+    default: {},
+  },
+  formExtraProps: {
+    required: false,
+    default: null,
+  },
+  footerRender: {
+    required: false,
+    default: null,
+  },
+  formGroups: {
+    required: false,
+    default: [],
+  },
+  formId: {
+    required: false,
+    default: 'AchorContentId',
+  },
+  isShowGroupTitle: {
+    required: false,
+    default: true,
+  },
+});
+const emits = defineEmits(['cancel', 'ok', 'change']);
+const slots = useSlots();
+
+const handleFieldChange = (field, value) => {
+  formRef.value.validateFields([field.field])
+  field?.onChange && field?.onChange(value)
+  emits('change', value)
+}
+
+const ValidatorSingalField =(field)=>{
+  return new Promise((resolve,reject)=>{
+    formRef.value.validateFields([field])
+    .then((res)=>{
+      resolve(res)
+    })
+    .catch((error)=>{
+      reject(error)
+    })
+  })
+}
+
+const handlerFormValidator = () => {
+  return new Promise((resolve, reject) => {
+    formRef.value
+      .validateFields()
+      .then(() => {
+        resolve();
+      })
+      .catch((error) => {
+        reject(error);
+      });
+  });
+};
 
+const cancelHandle = () => {
+  emits('cancel');
+};
+const setLoading = (loading) => {
+  confirmLoading.value = loading;
+};
 
-  const handlerFormValidator = () => {
-    return new Promise((resolve, reject) => {
-      formRef.value
-        .validateFields()
-        .then(() => {
-          resolve();
-        })
-        .catch((error) => {
-          reject(error);
-        });
-    });
-  };
-
-  const cancelHandle = () => {
-    emits('cancel');
-  };
-  const setLoading = (loading) => {
-    confirmLoading.value = loading;
-  };
-
-  const confirmHandle = () => {
-    handlerFormValidator.then((res) => {
-      emits('ok', props.formData, formRef.value, setLoading);
-    });
-  };
-
-  const newFormTemp = computed(() => {
-    const groupByIds = groupBy(props.formFields, 'groupId');
-    return mapValues(groupByIds, (group) => sortBy(group, 'sort'));
+const confirmHandle = () => {
+  handlerFormValidator.then((res) => {
+    emits('ok', props.formData, formRef.value, setLoading);
   });
+};
 
-  defineExpose({ handlerFormValidator })
+const newFormTemp = computed(() => {
+  const groupByIds = groupBy(props.formFields, 'groupId');
+  return mapValues(groupByIds, (group) => sortBy(group, 'sort'));
+});
+
+defineExpose({ handlerFormValidator ,ValidatorSingalField})
 </script>
 
 <style lang="scss" scoped>
-  .form {
+.form {
+  width: 100%;
+
+  :deep(.ant-form-item) {
+    margin: 10px 0;
+  }
+
+  .group-title {
     width: 100%;
-    :deep(.ant-form-item) {
-      margin: 10px 0;
-    }
+    height: 40px;
+    background: #e0e8f5;
+    line-height: 40px;
+    color: #4285f4;
+    font-size: 16px;
+    padding-left: 15px;
 
-    .group-title {
-      width: 100%;
-      height: 40px;
-      background: #e0e8f5;
-      line-height: 40px;
-      color: #4285f4;
-      font-size: 16px;
-      padding-left: 15px;
-      &::before {
-        content: '';
-        width: 2px;
-        height: 100%;
-        position: absolute;
-        left: 0;
-        background: #4285f4;
-      }
+    &::before {
+      content: '';
+      width: 2px;
+      height: 100%;
+      position: absolute;
+      left: 0;
+      background: #4285f4;
     }
   }
+
+  .tooltip {
+    padding-left: 8px;
+  }
+}
 </style>