فهرست منبع

更新优化

oa,下拉选择关联设置,需要添加层级关系
如果表单删除时,会同时删除有所关联的对象
处理中英,去掉英文
关联选项选择多个时样式调整
lex 2 سال پیش
والد
کامیت
3e72eaf1b3

+ 82 - 51
src/components/VueFormMaking/components/WidgetConfig.vue

@@ -400,17 +400,17 @@
             >
               {{ t("fm.actions.addOption") }}
             </el-button>
-            <el-divider
-              v-if="data.type == 'select'"
-              direction="vertical"
-            ></el-divider>
-            <el-button
-              v-if="data.type == 'select'"
-              type="text"
-              @click="selectRelation"
+            <template v-if="data.type == 'select' && !isSubForm">
+              <el-divider direction="vertical"></el-divider>
+              <el-button type="text" @click="selectRelation">
+                选项关联<span
+                  v-if="data.options.relationStatus"
+                  style="color: red"
+                  >(已设置)</span
+                >
+              </el-button></template
             >
-              选项关联
-            </el-button>
+
             <!-- <el-button v-if="data.type == 'select'" type="text" @click="data.options.defaultValue = null">
               重置默认值
             </el-button> -->
@@ -907,10 +907,8 @@
     >
       <div class="select-container" style="margin-top: -20px">
         <p>
-          根据选择的选项显示,隐藏其他控件。当前控件不能被关联显示。<span
-            style="color: red"
-            >选中的选项自动保存</span
-          >
+          根据选择的选项,显示其他控件。当前控件和上级选项不能被关联显示。
+          <span style="color: red">选中的选项自动保存</span>
         </p>
         <el-row class="select-title">
           <el-col :span="8">当选项为</el-col>
@@ -937,9 +935,10 @@
                 v-for="field in fieldList"
                 :key="field.value"
                 :label="field.label"
-                :disabled="field.value == data.model"
                 :value="field.value"
+                :disabled="field.disabled"
               >
+                <!-- :disabled="field.value == data.model" -->
               </el-option>
             </el-select>
           </el-col>
@@ -991,6 +990,26 @@ export default {
       }
       return false;
     },
+    isSubForm() {
+      // 判断是否在子表单里
+      const templates = this.form.list || [];
+      let status = false;
+      templates.forEach((template) => {
+        // 判断是否是子表单
+        const formStructure = template.columns || [];
+        if (formStructure.length > 0) {
+          formStructure.forEach((item) => {
+            let subList = item.list || [];
+            subList.forEach((sub) => {
+              if (sub.model == this.data.model) {
+                status = true;
+              }
+            });
+          });
+        }
+      });
+      return status;
+    },
   },
   watch: {
     "data.options.isRange": function (val) {
@@ -1037,6 +1056,7 @@ export default {
     },
   },
   created() {
+    // console.log(this.data, "created", this.form);
     this.handleInitHeaders();
   },
   methods: {
@@ -1048,18 +1068,6 @@ export default {
       });
       return tempStr;
     },
-    relationChange() {
-      this.$forceUpdate();
-      console.log(this.data);
-      let relationStatus = false;
-      let options = this.data.options.options || [];
-      options.forEach((item) => {
-        if (item.relationOptions && item.relationOptions.length > 0) {
-          relationStatus = true;
-        }
-      });
-      this.data.options.relationStatus = relationStatus;
-    },
     addDisplayVerifiy() {
       this.data.options.displayVerifiy.list.push({
         model: new Date().valueOf(),
@@ -1082,6 +1090,18 @@ export default {
       this.selectTreeData = val;
       this.cascaderDialog = true;
     },
+    relationChange() {
+      this.$forceUpdate();
+      console.log(this.data);
+      let relationStatus = false;
+      let options = this.data.options.options || [];
+      options.forEach((item) => {
+        if (item.relationOptions && item.relationOptions.length > 0) {
+          relationStatus = true;
+        }
+      });
+      this.data.options.relationStatus = relationStatus;
+    },
     async selectRelation() {
       this.fieldList = this.formatTemplateData(this.form);
       const data = this.data;
@@ -1104,24 +1124,27 @@ export default {
           label: template.name,
           value: template.model,
           type: template.type,
+          disabled:
+            template.options.relationStatus ||
+            template.model == this.data.model,
         };
-        if (template.type != "text" && template.type != "subform") {
+        if (template.type != "text") {
           optionList.push(options);
         }
-        const formStructure = template.columns || [];
-        if (formStructure.length > 0) {
-          let tempList = [];
-          formStructure.forEach((item) => {
-            let subList = item.list || [];
-            subList.forEach((sub) => {
-              optionList.push({
-                label: sub.name,
-                value: sub.model,
-                type: sub.type,
-              });
-            });
-          });
-        }
+        // const formStructure = template.columns || [];
+        // if (formStructure.length > 0) {
+        //   let tempList = [];
+        //   formStructure.forEach((item) => {
+        //     let subList = item.list || [];
+        //     subList.forEach((sub) => {
+        //       optionList.push({
+        //         label: sub.name,
+        //         value: sub.model,
+        //         type: sub.type,
+        //       });
+        //     });
+        //   });
+        // }
       });
       return optionList;
     },
@@ -1287,19 +1310,27 @@ export default {
 }
 .select-container :deep(.el-col) {
   padding: 16px 16px;
-  border: 1px solid #f0f0f0;
-}
-.select-container :deep(.el-col-6) {
-  margin-right: -1px;
+  /* border: 1px solid #f0f0f0; */
 }
 .select-title {
   background: #fafafa;
+  border-right: 1px solid #f0f0f0;
 }
 .select-value {
-  margin-top: -1px;
+  border-right: 1px solid #f0f0f0;
+  display: flex;
+  width: 100%;
+}
+.select-value:last-child {
+  border-bottom: 1px solid #f0f0f0;
+}
+.select-value :deep(.el-col-8) {
+  display: flex;
+  align-items: center;
 }
-.select-value :deep(.el-col-6),
-.select-value :deep(.el-col-18) {
-  margin-top: -1px;
+.select-container :deep(.el-col-8),
+.select-container :deep(.el-col-16) {
+  border-top: 1px solid #f0f0f0;
+  border-left: 1px solid #f0f0f0;
 }
-</style>
+</style>

+ 19 - 2
src/components/VueFormMaking/components/WidgetForm.vue

@@ -170,7 +170,7 @@
                     >
                       <i
                         class="iconfont icon-trash"
-                        @click.stop="handleWidgetDelete(index)"
+                        @click.stop="handleWidgetDelete(index, element)"
                       />
                     </div>
 
@@ -350,7 +350,8 @@ export default {
 
       this.selectWidget = row.columns[colIndex].list[newIndex];
     },
-    handleWidgetDelete(index) {
+    handleWidgetDelete(index, element) {
+      console.log(index, element);
       if (this.data.list.length - 1 === index) {
         if (index === 0) {
           this.selectWidget = {};
@@ -362,6 +363,22 @@ export default {
       }
 
       this.$nextTick(() => {
+        // 判断当前组件是否有关联,如果有关联则删除
+        const list = this.data.list || [];
+        list.forEach((item) => {
+          // 判断是否是下拉组件,是否设置了选项关联
+          if (item.type == "select" && item.options.relationStatus) {
+            const options = item.options.options || [];
+            options.forEach((option) => {
+              const relationOptions = option.relationOptions || [];
+              const index =
+                relationOptions.findIndex((r) => r == element.model) || -1;
+              if (index > -1) {
+                option.relationOptions.splice(index, 1);
+              }
+            });
+          }
+        });
         this.data.list.splice(index, 1);
       });
     },

+ 101 - 58
src/components/VueFormMaking/components/WidgetFormItem.vue

@@ -1,21 +1,26 @@
 <template>
   <el-form-item
     v-if="element && element.key"
-    :label-width="isLabel || !element.options.labelWidthStatus?'0px': elementLabelWidth + 'px'"
-    class="widget-view "
-    :class="{active: selectWidget.key === element.key, 'is_req': element.options.required}"
-    :label="isLabel || element.type==='divider' || !element.options.labelWidthStatus?'':element.name"
+    :label-width="
+      isLabel || !element.options.labelWidthStatus
+        ? '0px'
+        : elementLabelWidth + 'px'
+    "
+    class="widget-view"
+    :class="{
+      active: selectWidget.key === element.key,
+      is_req: element.options.required,
+    }"
+    :label="
+      isLabel || element.type === 'divider' || !element.options.labelWidthStatus
+        ? ''
+        : element.name
+    "
     @click.native.stop="handleSelectWidget(index)"
   >
-
     <div v-if="isTable">
-      <el-table
-        :data="[element]"
-        border
-      >
-        <el-table-column
-          :label="element.name"
-        >
+      <el-table :data="[element]" border>
+        <el-table-column :label="element.name">
           <WidgetFormFields :element="element" />
         </el-table-column>
       </el-table>
@@ -25,111 +30,149 @@
     </div>
 
     <div v-if="selectWidget.key == element.key" class="widget-view-action">
-      <i class="iconfont icon-icon_clone" @click.stop="handleWidgetClone(index)" />
-      <i class="iconfont icon-trash" @click.stop="handleWidgetDelete(index)" />
+      <i
+        class="iconfont icon-icon_clone"
+        @click.stop="handleWidgetClone(index)"
+      />
+      <i
+        class="iconfont icon-trash"
+        @click.stop="handleWidgetDelete(index, element)"
+      />
     </div>
 
     <div v-if="selectWidget.key == element.key" class="widget-view-drag">
       <i class="iconfont icon-drag drag-widget" />
     </div>
-
   </el-form-item>
 </template>
 
 <script>
-import WidgetFormFields from './WidgetFormFields'
+import WidgetFormFields from "./WidgetFormFields";
 export default {
   components: {
-    WidgetFormFields
+    WidgetFormFields,
   },
   /* eslint-disable */
-  props: ['element', 'select', 'index', 'data', 'dataConfig', 'isLabel', 'isTable'],
+  props: [
+    "element",
+    "select",
+    "index",
+    "data",
+    "dataConfig",
+    "isLabel",
+    "isTable",
+  ],
   data() {
     return {
-      elementLabelWidth: '',
-      selectWidget: this.select
-    }
+      elementLabelWidth: "",
+      selectWidget: this.select,
+    };
   },
   watch: {
     select(val) {
-      this.selectWidget = val
+      this.selectWidget = val;
     },
     selectWidget: {
       handler(val) {
-        this.$emit('update:select', val)
+        this.$emit("update:select", val);
       },
-      deep: true
+      deep: true,
     },
-    'element.options.labelWidth': function (val) {
-      this.elementLabelWidth = val
+    "element.options.labelWidth": function (val) {
+      this.elementLabelWidth = val;
     },
-    'element.options.labelWidthDisabled': function (val) {
-      this.setLabelWidth(val)
+    "element.options.labelWidthDisabled": function (val) {
+      this.setLabelWidth(val);
     },
-    'dataConfig.config.labelWidth': function (val) {
-      if (!this.element.options.labelWidthDisabled && this.element.type!=='divider') {
-        this.elementLabelWidth = val
+    "dataConfig.config.labelWidth": function (val) {
+      if (
+        !this.element.options.labelWidthDisabled &&
+        this.element.type !== "divider"
+      ) {
+        this.elementLabelWidth = val;
       }
-    }
+    },
   },
   mounted() {
-    this.setLabelWidth()
+    this.setLabelWidth();
   },
   methods: {
     setLabelWidth(status) {
       if (status === undefined) {
-        status = this.element.options.labelWidthDisabled
+        status = this.element.options.labelWidthDisabled;
       }
       if (status) {
-        this.elementLabelWidth = this.element.options.labelWidth
-      } else if (this.element.type==='divider') {
-        this.elementLabelWidth = 0
+        this.elementLabelWidth = this.element.options.labelWidth;
+      } else if (this.element.type === "divider") {
+        this.elementLabelWidth = 0;
       } else {
         // 全局
-        this.elementLabelWidth = this.dataConfig.config.labelWidth
+        this.elementLabelWidth = this.dataConfig.config.labelWidth;
       }
     },
     handleSelectWidget(index) {
-      this.selectWidget = this.data.list[index]
+      this.selectWidget = this.data.list[index];
     },
-    handleWidgetDelete(index) {
+    handleWidgetDelete(index, element) {
+      console.log(index, element, this.data);
       if (this.data.list.length - 1 === index) {
         if (index === 0) {
-          this.selectWidget = {}
+          this.selectWidget = {};
         } else {
-          this.selectWidget = this.data.list[index - 1]
+          this.selectWidget = this.data.list[index - 1];
         }
       } else {
-        this.selectWidget = this.data.list[index + 1]
+        this.selectWidget = this.data.list[index + 1];
       }
 
       this.$nextTick(() => {
-        this.data.list.splice(index, 1)
-      })
+        // 判断当前组件是否有关联,如果有关联则删除
+        const list = this.data.list || [];
+        list.forEach((item) => {
+          // 判断是否是下拉组件,是否设置了选项关联
+          if (item.type == "select" && item.options.relationStatus) {
+            const options = item.options.options || [];
+            options.forEach((option) => {
+              const relationOptions = option.relationOptions || [];
+              const index =
+                relationOptions.findIndex((r) => r == element.model) || -1;
+              if (index > -1) {
+                option.relationOptions.splice(index, 1);
+              }
+            });
+          }
+        });
+        // 删除组件
+        this.data.list.splice(index, 1);
+      });
     },
     handleWidgetClone(index) {
       let cloneData = {
         ...this.data.list[index],
         options: { ...this.data.list[index].options },
-        key: Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
-      }
-      cloneData.model = cloneData.type + '_' + cloneData.key
-      if (this.data.list[index].type === 'radio' || this.data.list[index].type === 'checkbox' || this.data.list[index].type === 'select') {
+        key: Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 99999),
+      };
+      cloneData.model = cloneData.type + "_" + cloneData.key;
+      if (
+        this.data.list[index].type === "radio" ||
+        this.data.list[index].type === "checkbox" ||
+        this.data.list[index].type === "select"
+      ) {
         cloneData = {
           ...cloneData,
           options: {
             ...cloneData.options,
-            options: cloneData.options.options.map(item => ({ ...item }))
-          }
-        }
+            options: cloneData.options.options.map((item) => ({ ...item })),
+          },
+        };
       }
 
-      this.data.list.splice(index, 0, cloneData)
+      this.data.list.splice(index, 0, cloneData);
 
       this.$nextTick(() => {
-        this.selectWidget = this.data.list[index + 1]
-      })
-    }
-  }
-}
+        this.selectWidget = this.data.list[index + 1];
+      });
+    },
+  },
+};
 </script>