Răsfoiți Sursa

重构: 优化表格组件结构并添加公式计算功能

yusheng 7 luni în urmă
părinte
comite
6b036fb8bd

+ 277 - 113
src/components/templateDiv/customTable.vue

@@ -1,52 +1,74 @@
 <!-- 搜索表单 -->
 <template>
   <div style="margin-top: 10px">
-    <!-- <el-button type="primary" @click="addColumn" v-if="edit">新增列</el-button>
-    <el-button type="primary" @click="addRow" v-if="edit">新增行</el-button> -->
-
-    <table style="margin-top: 10px" :id="id">
-      <thead>
-        <tr>
-          <th v-for="(item, index) in columns" class="tableTh">
-            <!-- <i
-              class="el-icon-delete delete"
-              style="display: none"
-              @click="removeColumn(index)"
-              v-if="edit"
-            ></i> -->
-            <input
-              v-model="item.value"
-              type="text"
-              class="templateInput"
-              :id="item.id"
-              :readonly="item.readonly == 2||!edit"
-              @click="inputClick(item)"
-            />
-          </th>
-          <!-- <th v-if="edit"></th> -->
-        </tr>
-      </thead>
-      <tbody>
-        <tr v-for="(row, rowIndex) in rows">
-          <td v-for="item in row.cells"
-            ><input
-              v-model="item.value"
-              type="text"
-              class="templateInput"
-              :id="item.id"
-               :readonly="item.readonly == 2||!edit"
-              @click="inputClick(item)"
-          /></td>
-          <!-- <td v-if="edit">
-            <i
-              class="sort-handle el-icon-delete delete"
-              style="color: #f56c6c"
-              @click="removeRow(rowIndex)"
-            ></i
-          ></td> -->
-        </tr>
-      </tbody>
-    </table>
+    <!-- <el-button type="primary" @click="addColumn()" v-if="edit"
+      >新增列</el-button
+    >
+    <el-button type="primary" @click="addRow(columns.length)" v-if="edit"
+      >新增行</el-button
+    > -->
+    <div class="table" style="margin-top: 10px" :id="id">
+      <div class="table-body" style="display: flex">
+        <template v-for="(row, index) in columns">
+          <div class="column" :style="{ width: row[0].width + 'px' }">
+            <div
+              class="table-body-item tableTd"
+              v-for="(item, rowIndex) in row"
+              :style="{
+                height: item.rowspan * 30 + 'px',
+                display: item.rowspan ? 'block' : 'none'
+              }"
+            >
+              <!-- <i
+                class="el-icon-delete delete"
+                style="display: none"
+                @click="removeColumn(index)"
+                v-if="edit && rowIndex == 0"
+              ></i>
+              <i
+                class="el-icon-circle-plus-outline add"
+                style="display: none"
+                @click="addColumn(index)"
+                v-if="edit && rowIndex == 0"
+              ></i>
+              <i
+                class="el-icon-delete deleteRow"
+                @click="removeRow(rowIndex)"
+                v-if="edit && rowIndex != 0"
+              ></i>
+              <i
+                class="el-icon-circle-plus-outline addRow"
+                style="display: none"
+                @click="addRow(rowIndex, index)"
+                v-if="edit && rowIndex != 0 && index != columns.length - 1"
+              ></i> -->
+              <textarea
+                v-if="item.rowspan > 1"
+                v-model="item.value"
+                class="templateInput"
+                :id="item.id"
+                :readonly="item.readonly == 2 || !edit"
+                @click="inputClick(item)"
+                @input="calculation"
+                autocomplete="off"
+                style="resize: none"
+              ></textarea>
+              <input
+                v-else
+                v-model="item.value"
+                class="templateInput"
+                :id="item.id"
+                :readonly="item.readonly == 2 || !edit"
+                @click="inputClick(item, rowIndex == 0 ? 'columns' : null)"
+                @input="calculation"
+                type="text"
+                autocomplete="off"
+              />
+            </div>
+          </div>
+        </template>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -62,8 +84,7 @@
       edit: {
         default: true,
         type: Boolean
-      },
-    
+      }
     },
     data() {
       return {
@@ -72,50 +93,126 @@
         domId: '',
         rightClickShow: false,
         columns: [],
-        rows: []
+        // rows: [],
+        equation: {}
       };
     },
+    created() {},
     methods: {
       // 方法:添加新列
-      addColumn() {
-        this.columns.push({
-          value: `列${this.columns.length + 1}`,
-          id: generateRandomString(5),
-          readonly: 1
-        });
-        this.rows.forEach((row) => {
-          row.cells.push({
-            value: '',
-            readonly: 1,
-            id: generateRandomString(5)
-          });
-        });
+      addColumn(index) {
+        let length = this.columns[0]?.length || 1;
+        if (index === 0 || index) {
+          this.columns.splice(
+            index + 1,
+            0,
+            Array(length)
+              .fill(null)
+              .map(() => ({
+                readonly: 1,
+                value: '',
+                rowspan: 1,
+                id: generateRandomString(5)
+              }))
+          );
+        } else {
+          this.columns.push(
+            Array(length)
+              .fill(null)
+              .map(() => ({
+                readonly: 1,
+                value: '',
+                rowspan: 1,
+                id: generateRandomString(5)
+              }))
+          );
+        }
       },
 
       // 方法:删除指定列
       removeColumn(index) {
         this.columns.splice(index, 1);
-        this.rows.forEach((row) => {
-          row.cells.splice(index, 1);
-        });
       },
 
       // 方法:添加新行
-      addRow() {
-        const newRow = {
-          cells: Array(this.columns.length)
-            .fill(null)
-            .map(() => ({
+      addRow(rowIndex, columnIndex) {
+        if (columnIndex > 0) {
+          this.columns.forEach((item, newColumnIndex) => {
+            let newRow = {
               readonly: 1,
               value: '',
+              rowspan: 1,
               id: generateRandomString(5)
-            }))
-        };
-        this.rows.push(newRow);
+            };
+            if (newColumnIndex < columnIndex) {
+              newRow.rowspan = 0;
+              let _rowIndex = null;
+              if (item[rowIndex].rowspan == 0) {
+                _rowIndex = this.getPreventRowspan(newColumnIndex, rowIndex);
+              }
+              console.log(_rowIndex, '_rowIndex');
+              let rowspan =
+                this.columns[newColumnIndex][_rowIndex || rowIndex].rowspan ||
+                1;
+
+              this.$set(
+                this.columns[newColumnIndex][_rowIndex || rowIndex],
+                'rowspan',
+                (rowspan += 1)
+              );
+            }
+            this.columns[newColumnIndex].splice(rowIndex + 1, 0, newRow);
+          });
+        } else {
+          this.columns.forEach((item, index) => {
+            let _rowIndex = rowIndex;
+            if (item[rowIndex].rowspan > 1) {
+              _rowIndex += Number(item[rowIndex].rowspan);
+            }
+            this.columns[index].splice(_rowIndex + 1, 0, {
+              readonly: 1,
+              value: '',
+              rowspan: 1,
+              id: generateRandomString(5)
+            });
+          });
+          console.log(this.columns, 'this.columns');
+        }
+      },
+      //找到真正需要改变rowspan的行
+      getPreventRowspan(columnIndex, rowIndex) {
+        let preventRowspan = null;
+        this.columns[columnIndex].forEach((item, newRowIndex) => {
+          if (newRowIndex < rowIndex && item.rowspan > 1) {
+            preventRowspan = newRowIndex;
+          }
+        });
+
+        return preventRowspan;
       },
       // 方法:删除指定行
-      removeRow(index) {
-        this.rows.splice(index, 1);
+      removeRow(rowIndex) {
+        this.columns.forEach((item, columnIndex) => {
+          if (item[rowIndex].rowspan == 0) {
+            let preventRowspanIndex = this.getPreventRowspan(
+              columnIndex,
+              rowIndex
+            );
+            if (preventRowspanIndex) {
+              this.$set(
+                this.columns[columnIndex][preventRowspanIndex],
+                'rowspan',
+                this.columns[columnIndex][preventRowspanIndex].rowspan - 1
+              );
+            }
+          } else if (item[rowIndex].rowspan > 1) {
+            let data = item[rowIndex];
+            data.rowspan--;
+            this.$set(this.columns[columnIndex], [rowIndex + 1], data);
+          }
+
+          item.splice(rowIndex, 1);
+        });
       },
 
       objInit() {
@@ -128,52 +225,64 @@
           }
         }
       },
-
+      calculation() {
+        this.$emit('calculation');
+      },
+      equationValue({ domId, value }) {
+        this.columns.forEach((item, index) => {
+          let cellIndex = item.findIndex((cell) => cell.id == domId);
+          if (cellIndex != '-1') {
+            this.$set(this.columns[index][cellIndex], 'value', value);
+          }
+        });
+      },
       getValue() {
         return {
           form: null,
+          equation: this.equation,
           valueObj: {
-            columns: this.columns,
-            rows: this.rows
+            columns: this.columns
           }
         };
       },
-      init({ form, valueObj }) {
+      init({ form, valueObj, equation }) {
         this.form = form;
         this.columns = valueObj.columns;
-        this.rows = valueObj.rows;
+
+        this.equation = equation || {};
       },
       editInputChange(domObj) {
-        let columnsIndex = this.columns.findIndex(
-          (item) => item.id == this.domId
-        );
-        if (columnsIndex >= 0) {
-          this.$set(this.columns, columnsIndex, domObj);
-          return;
+        if (domObj.equation) {
+          this.equation[this.domId] = domObj.equation;
         }
-        this.rows.forEach((item, index) => {
-          let rowsIndex = item.cells.findIndex(
-            (cells) => cells.id == this.domId
-          );
-          // console.log(rowsIndex,'rowsIndex')
+
+        this.columns.forEach((item, index) => {
+          let rowsIndex = item.findIndex((cells) => cells.id == this.domId);
+
           if (rowsIndex >= 0) {
-            this.$set(this.rows[index].cells, rowsIndex, domObj);
+            this.$set(this.columns[index], rowsIndex, domObj);
           }
         });
       },
 
-      inputClick(item) {
-        if(!this.edit){
-          return
+      inputClick(item, type) {
+        return
+        if (!this.edit) {
+          return;
         }
+        let dom = document.getElementById(item.id);
+
         this.domId = item.id;
         this.$emit('editShow', {
           templateDivRef: 'customTextRef' + this.id,
           domObj: {
-            isNoWidth: true,
+            width: dom.parentElement.offsetWidth,
+            isNoWidth: type == 'columns' ? false : true,
             id: item.id,
             readonly: item.readonly,
-            value: item.value
+            value: item.value,
+            rowspan: item.rowspan,
+            equation: this.equation[item.id]
           }
         });
       }
@@ -183,26 +292,57 @@
 <style lang="scss" scoped>
   :deep(.templateInput) {
     width: 100%;
-    border: solid 1px #bfbfbf;
-    padding: 1px;
-    margin: 1px;
-    margin-left: 3px;
+    height: 100%;
+    border: none;
+
     text-align: center;
     background-color: #fff;
   }
-  table {
-    width: 100%;
-    border-collapse: collapse;
-  }
-  th,
-  td {
-    border: 1px solid #ddd;
-    padding: 0;
-    text-align: center;
+
+  .table-header {
+    span {
+      display: inline-block;
+      height: 30px;
+      border: 1px solid #ddd;
+      width: 100px;
+      background-color: #f2f2f2 !important;
+    }
+
+    input {
+      background-color: #f2f2f2 !important;
+    }
   }
-  th {
-    background-color: #f2f2f2;
+  .table-body {
+    white-space: nowrap;
+    .column {
+      display: inline-block;
+      width: 100px;
+      > div {
+        height: 30px;
+        border: 1px solid #ddd;
+        width: 100%;
+      }
+      > div:nth-of-type(1) {
+        background-color: #f2f2f2 !important;
+        > input {
+          background-color: #f2f2f2 !important;
+        }
+      }
+    }
   }
+  // th,
+  // td {
+  //   border: 1px solid #ddd;
+  //   padding: 2px;
+  //   text-align: center;
+  //   height: 30px;
+  // }
+  // th {
+  //   background-color: #f2f2f2;
+  //   > input {
+  //     background-color: #f2f2f2 !important;
+  //   }
+  // }
   tr:nth-child(even) {
     background-color: #f9f9f9;
   }
@@ -210,8 +350,17 @@
     border-color: #66afe9; /* 改变边框颜色 */
     outline: none; /* 移除默认的轮廓线 */
   }
-  .tableTh:hover {
+  .tableTd {
     position: relative;
+  }
+  .deleteRow {
+    display: block !important;
+    position: absolute;
+    bottom: 0px;
+    right: -15px;
+    color: #f56c6c;
+  }
+  .tableTd:hover {
     .delete {
       display: block !important;
       position: absolute;
@@ -219,5 +368,20 @@
       top: 0;
       color: #f56c6c;
     }
+
+    .add {
+      display: block !important;
+      position: absolute;
+      right: 20px;
+      top: 0;
+      color: #409eff;
+    }
+    .addRow {
+      display: block !important;
+      position: absolute;
+      bottom: 0px;
+      right: 10px;
+      color: #409eff;
+    }
   }
 </style>

+ 57 - 33
src/components/templateDiv/customText.vue

@@ -1,7 +1,7 @@
 <!-- 搜索表单 -->
 <template>
   <div>
-    <!-- <el-popover
+    <el-popover
       style="position: fixed; z-index: 2000"
       width="130"
       ref="popoverRef"
@@ -11,12 +11,12 @@
       <div>
         <el-button type="primary" @click="addHtml">插入输入框</el-button>
       </div>
-    </el-popover> -->
+    </el-popover>
     <div
       v-html="form"
       :contenteditable="edit"
       class="contenteditable"
-      :ref="'valueChange'"
+      :ref="id"
       :id="id"
       @contextmenu.prevent="onRightClick($event)"
     >
@@ -42,6 +42,7 @@
       return {
         form: null,
         valueObj: {},
+        equation: {},
         domId: '',
         rightClickShow: false
       };
@@ -49,8 +50,6 @@
     methods: {
       addHtml() {
         this.insertInput();
-
-        this.objInit();
       },
       objInit() {
         if (Object.keys(this.valueObj).length) {
@@ -66,7 +65,7 @@
         const selection = window.getSelection();
         if (selection.rangeCount > 0) {
           const range = selection.getRangeAt(0);
-          console.log(range, 'range');
+
           this.getParentID(range.commonAncestorContainer);
           if (this.getParentID(range.commonAncestorContainer)) {
             range.setStart(selection.anchorNode, selection.anchorOffset);
@@ -97,19 +96,39 @@
         const inputElement = document.createElement('input');
         inputElement.setAttribute('type', 'text');
         inputElement.setAttribute('class', 'templateInput');
+        inputElement.setAttribute('autocomplete', 'off');
         inputElement.setAttribute('id', id);
         return inputElement;
       },
       getValue() {
-        // this.form = this.$refs['valueChange'].innerHTML;
+        let inputs = document.querySelectorAll(
+          '#' + this.id + ' .templateInput'
+        );
+        let data = {};
+        if (inputs.length) {
+          inputs.forEach((item) => {
+            data[item.id] = item.value;
+          });
+        }
         return {
-          form: this.$refs['valueChange'].innerHTML,
-          valueObj: this.valueObj
+          form: this.$refs[this.id].innerHTML,
+          valueObj: data,
+          equation: this.equation
         };
       },
-      init({ form, valueObj }) {
+      equationValue({ domId, value }) {
+        if (domId) {
+          let dom = document.getElementById(domId);
+          if (dom) {
+            this.valueObj[domId] = value;
+            dom.value = value;
+          }
+        }
+      },
+      init({ form, valueObj, equation }) {
         this.form = form;
         this.valueObj = valueObj;
+        this.equation = equation || {};
         this.$nextTick(() => {
           if (!this.edit) {
             let inputs = document.querySelectorAll('.templateInput');
@@ -130,9 +149,13 @@
         }
         delete this.valueObj[dom.id];
         this.valueObj[domObj.id] = dom.value;
+        if (domObj.equation) {
+          this.equation[domObj.id] = domObj.equation;
+        }
         dom.id = domObj.id;
       },
       onRightClick(PointerEvent) {
+        return
         this.rightClickShow = true;
         this.$nextTick(() => {
           let y = PointerEvent.pageY;
@@ -147,38 +170,39 @@
       inputChange(event) {
         if (event.target && event.target.className == 'templateInput') {
           this.valueObj[event.target.id] = event.target.value;
+
+          this.$emit('calculation');
         }
       },
-      // inputClick(event) {
-      //   if (!this.edit) {
-      //     return;
-      //   }
-      //   if (event.target && event.target.className == 'templateInput') {
-      //     this.domId = event.target.id;
-      //     console.log(event, 'event');
-      //     // event.getAttribute('class', 'templateInput');
-      //     this.$emit('editShow', {
-      //       templateDivRef: 'customTextRef' + this.id,
-      //       domObj: {
-      //         width: event.target.offsetWidth,
-      //         id: event.target.id,
-      //         readonly: event.target.readOnly ? 2 : 1
-      //       }
-      //     });
-      //   }
-      // }
+      inputClick(event) {
+        return
+        if (!this.edit) {
+          return;
+        }
+        if (event.target && event.target.className == 'templateInput') {
+          this.domId = event.target.id;
+          this.$emit('editShow', {
+            templateDivRef: 'customTextRef' + this.id,
+            domObj: {
+              width: event.target.offsetWidth,
+              id: event.target.id,
+              readonly: event.target.readOnly ? 2 : 1,
+              equation: this.equation[this.domId]
+            }
+          });
+        }
+      }
     },
 
     mounted() {
       this.$nextTick(() => {
-        console.log(document.getElementById(this.id), 'dsd');
         document
           .getElementById(this.id)
-          .addEventListener('change', this.inputChange);
+          .addEventListener('input', this.inputChange);
 
-        // document
-        //   .getElementById(this.id)
-        //   .addEventListener('click', this.inputClick);
+        document
+          .getElementById(this.id)
+          .addEventListener('click', this.inputClick);
       });
     }
   };

+ 292 - 24
src/components/templateDiv/experimentationProcess.vue

@@ -48,6 +48,7 @@
               :form="item.value"
               :valueObj="item.valueObj"
               @editShow="editShowFn"
+              @calculation="calculation"
               :edit="edit"
             ></customText>
             <customTable
@@ -57,6 +58,7 @@
               :id="item.id"
               :form="item.value"
               :valueObj="item.valueObj"
+              @calculation="calculation"
               @editShow="editShowFn"
               :edit="edit"
             ></customTable>
@@ -64,11 +66,11 @@
         </div>
       </vue-draggable>
 
-      <!-- <el-card class="box-card" v-show="editShow" style="width: 320px">
+      <el-card class="box-card" v-show="editShow" style="width: 320px">
         <div slot="header" class="clearfix">
           <span>配置</span>
         </div>
-        <el-form label-width="100px">
+        <el-form label-width="80px">
           <el-form-item label="字段标识:" prop="id">
             <el-input
               v-model="domObj.id"
@@ -94,9 +96,125 @@
               <el-option :key="2" label="是" :value="2"> </el-option>
             </el-select>
           </el-form-item>
+          <el-form-item label="计算公式:" prop="readonly">
+            <el-input
+              :value="domObj.equation?.map((item) => item.value).join('')"
+              type="textarea"
+              placeholder=""
+              disabled
+            ></el-input>
+            <el-button type="primary" @click="setEquation">配置公式</el-button>
+            <el-button type="primary" @click="delEquation">重置</el-button>
+          </el-form-item>
         </el-form>
-      </el-card> -->
+      </el-card>
     </div>
+    <ele-modal
+      title="配置公式"
+      :visible.sync="visible"
+      :close-on-click-modal="false"
+      append-to-body
+      width="800px"
+      resizable
+      maxable
+    >
+      <div class="formula-builder__selects">
+        <!-- 选择参数:从已填的非计算参数内容里取 -->
+        <el-select
+          v-model="equationUnit.paramSelect"
+          placeholder="选择参数"
+          size="mini"
+          style="width: 100px; margin-right: 8px; flex-shrink: 0"
+          @change="paramSelectChange($event, 'id')"
+        >
+          <el-option
+            v-for="item in idList"
+            :key="item"
+            :label="item"
+            :value="item"
+          />
+        </el-select>
+
+        <!-- 选择运算符 -->
+        <el-select
+          v-model="equationUnit.opSelect"
+          placeholder="选择符号"
+          size="mini"
+          style="width: 100px; flex-shrink: 0; margin-right: 8px"
+          @change="paramSelectChange($event, 'symbol')"
+        >
+          <el-option
+            v-for="op in opSelectOptions"
+            :key="op"
+            :label="op"
+            :value="op"
+          />
+        </el-select>
+        <!-- 选择值 -->
+        <el-input
+          v-model="equationUnit.currentValue"
+          placeholder="输入值"
+          size="mini"
+          style="width: 150px; flex-shrink: 0"
+        >
+          <template slot="append">
+            <span
+              style="cursor: pointer"
+              @click="paramSelectChange(equationUnit.currentValue, 'value')"
+              >确认</span
+            >
+          </template>
+        </el-input>
+        <!-- 替换或者追加 -->
+        <el-select
+          v-if="equationUnit.activeIndex != undefined"
+          v-model="equationUnit.replaceOrAppend"
+          placeholder="选择"
+          size="mini"
+          style="width: 80px; margin-left: 8px; flex-shrink: 0"
+        >
+          <el-option key="append" label="追加" value="append" />
+          <el-option key="replace" label="替换" value="replace" />
+        </el-select>
+      </div>
+
+      <!-- 已组装公式标签展示 -->
+      <div
+        v-if="equationUnit.equation.length"
+        style="
+          display: inline-flex;
+          flex-wrap: wrap;
+          max-width: 100%;
+          margin-top: 5px;
+        "
+      >
+        <el-tag
+          v-for="(p, index) in equationUnit.equation"
+          :key="index"
+          size="mini"
+          closable
+          :type="equationUnit.activeIndex === index ? 'primary' : 'info'"
+          @click="formulaPartsTagClick(index)"
+          @close="tagItemDelete(index)"
+        >
+          {{ p.value }}
+        </el-tag>
+      </div>
+
+      <el-input
+        style="margin-top: 5px"
+        :value="equationUnit.equation?.map((item) => item.value).join('')"
+        type="textarea"
+        placeholder=""
+        disabled
+      ></el-input>
+      <div slot="footer" class="footer">
+        <el-button type="primary" @click="editInputChange('equation')"
+          >确认</el-button
+        >
+        <el-button @click="visible = false">返回</el-button>
+      </div>
+    </ele-modal>
   </div>
 </template>
 
@@ -114,8 +232,8 @@
     },
     props: {
       edit: {
-        default:true,
-        type:Boolean
+        default: true,
+        type: Boolean
       }
     },
     computed: {},
@@ -123,29 +241,176 @@
       return {
         list: [],
         editShow: false,
+        visible: false,
         templateDivRef: '',
-        domObj: {}
+        domObj: {},
+        idList: [],
+        opSelectOptions: ['+', '-', '*', '/', '%', '(', ')'],
+        equationUnit: {
+          equation: [],
+          activeIndex: '',
+          paramSelect: '',
+          opSelect: '',
+          currentValue: '',
+          replaceOrAppend: 'append'
+        }
       };
     },
     mounted() {},
-    created() {
-      // if (sessionStorage['valueJSON']) {
-      //   this.list = JSON.parse(sessionStorage['valueJSON']);
-      // }
-      //  if (localStorage['valueJSON']) {
-      //   this.list = JSON.parse(localStorage['valueJSON']);
-      // }
-    },
+    created() {},
     methods: {
+      // 计算
+      calculation() {
+        this.getValue();
+        let equation = [];
+        this.list.forEach((item) => {
+          equation.push({
+            id: item.id,
+            equation: item.equation
+          });
+        });
+        equation.forEach((item) => {
+          for (const key in item.equation) {
+            let data = this.getObjValue(); //每次计算都获取最新的值
+            let value = '';
+            if (item.equation[key].length) {
+              item.equation[key].forEach((equationItem) => {
+                if (equationItem.type == 'symbol') {
+                  value += equationItem.value;
+                } else if (equationItem.type == 'id') {
+                  value += Number(data[equationItem.value]) || 0;
+                } else {
+                  value += equationItem.value;
+                }
+              });
+              if (this.$refs['customTextRef' + item.id][0]) {
+                this.$refs['customTextRef' + item.id][0].equationValue({
+                  domId: key,
+                  value: eval(value)
+                });
+              }
+            }
+          }
+        });
+      },
+      getObjValue() {
+        this.getValue();
+        let data = {};
+        this.list.forEach((item) => {
+          if (item.type == 'customText') {
+            data = { ...item.valueObj, ...data };
+          } else {
+            item.valueObj.columns.forEach((row) => {
+              row.forEach((cell) => {
+                data[cell.id] = cell.value;
+              });
+            });
+          }
+        });
+        return data || {};
+      },
+
+      setEquation() {
+        this.getValue();
+        this.idList = [];
+        if (this.domObj.equation) {
+          this.equationUnit.equation = JSON.parse(
+            JSON.stringify(this.domObj.equation)
+          );
+          this.equationUnit.activeIndex = this.domObj.equation.length;
+        } else {
+          this.equationUnit.equation = [];
+        }
+        this.list.forEach((item) => {
+          if (item.type == 'customText') {
+            for (let key in item.valueObj) {
+              this.idList.push(key);
+            }
+          } else {
+            item.valueObj.columns.forEach((row) => {
+              row.forEach((cell) => {
+                this.idList.push(cell.id);
+              });
+            });
+          }
+        });
+        this.visible = true;
+      },
+      delEquation() {
+        this.equationUnit.equation = [];
+        this.editInputChange('equation');
+      },
+      tagItemDelete(index) {
+        this.equationUnit.equation.splice(index, 1);
+      },
+      formulaPartsTagClick(index, row) {
+        if (!this.equationUnit.replaceOrAppend) {
+          // 默认追加
+          this.equationUnit_replaceOrAppend = 'append';
+        }
+
+        if (
+          this.equationUnit.activeIndex &&
+          this.equationUnit.activeIndex === index
+        ) {
+          this.$set(this.equationUnit, 'activeIndex', undefined);
+        } else {
+          this.$set(this.equationUnit, 'activeIndex', index);
+        }
+      },
+      paramSelectChange(val, type) {
+        if (!val) {
+          return;
+        }
+        if (type == 'id') {
+          this.setValue({ type: 'id', value: val });
+          this.equationUnit.paramSelect = null;
+        } else if (type == 'symbol') {
+          this.setValue({ type: 'symbol', value: val });
+
+          this.equationUnit.opSelect = null;
+        } else if (type == 'value') {
+          this.setValue({ type: 'value', value: val });
+        }
+      },
+      setValue(val) {
+        if (this.equationUnit.activeIndex != undefined) {
+          if (
+            !this.equationUnit.replaceOrAppend ||
+            this.equationUnit.replaceOrAppend === 'replace'
+          ) {
+            this.equationUnit.equation.splice(
+              this.equationUnit.activeIndex,
+              1,
+              val
+            );
+          } else if (this.equationUnit.replaceOrAppend === 'append') {
+            this.equationUnit.equation.splice(
+              this.equationUnit.activeIndex + 1,
+              0,
+              val
+            );
+            // 追加后activeIndex后移一位
+            this.$set(
+              this.equationUnit,
+              'activeIndex',
+              this.equationUnit.activeIndex + 1
+            );
+          }
+        } else {
+          this.equationUnit.equation.push(val);
+        }
+      },
+
       init(list) {
         this.list = JSON.parse(list);
-        console.log(this.list, ' this.list');
         if (this.list.length) {
           this.$nextTick(() => {
             this.list.forEach((item) => {
               this.$refs['customTextRef' + item.id][0].init({
                 form: item.value,
-                valueObj: item.valueObj
+                valueObj: item.valueObj,
+                equation: item.equation
               });
             });
           });
@@ -156,7 +421,13 @@
         this.$set(this, 'domObj', domObj);
         this.editShow = true;
       },
-      editInputChange() {
+      editInputChange(type) {
+        if (type == 'equation') {
+          this.visible = false;
+          this.domObj.equation = JSON.parse(
+            JSON.stringify(this.equationUnit.equation)
+          );
+        }
         this.$nextTick(() => {
           this.$refs[this.templateDivRef][0].editInputChange(this.domObj);
         });
@@ -173,15 +444,12 @@
         });
       },
       getValue() {
-        // this.$nextTick(() => {
-        //   // sessionStorage['valueJSON'] = JSON.stringify(this.list);
-        //   // localStorage['valueJSON'] = JSON.stringify(this.list);
-        // });
         this.list.forEach((item, index) => {
-          let { form, valueObj } =
+          let { form, valueObj, equation } =
             this.$refs['customTextRef' + item.id][0].getValue();
           this.$set(this.list[index], 'value', form);
           this.$set(this.list[index], 'valueObj', valueObj);
+          this.$set(this.list[index], 'equation', equation);
         });
         return this.list;
       }
@@ -192,8 +460,8 @@
 <style scoped lang="scss">
   .listItem {
     padding: 5px;
-    // padding-top: 15px;
-    // border: solid 1px #f1f1f1;
+    padding-top: 15px;
+    border: solid 1px #f1f1f1;
     display: flex;
     width: 100%;
     align-items: center;