Переглянути джерело

feat(规则管理): 新增计算公式功能并优化表单交互

yusheng 7 місяців тому
батько
коміт
dd0e115cef

+ 1 - 1
src/api/system/file/index.js

@@ -84,7 +84,7 @@ export async function downLoadTemplateNew(url, fileName) {
       responseType: 'blob'
     }
   );
-  console.log(res.data, '***********');
+  console.log(res, '***********');
   download(res.data, fileName);
 }
 

+ 278 - 20
src/views/rulesManagement/releaseRules/components/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>
@@ -68,7 +70,7 @@
         <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,124 @@
               <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-form-item>
         </el-form>
       </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 +231,8 @@
     },
     props: {
       edit: {
-        default:true,
-        type:Boolean
+        default: true,
+        type: Boolean
       }
     },
     computed: {},
@@ -123,29 +240,165 @@
       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 data = {};
+        let equation = [];
+        this.list.forEach((item) => {
+          if (item.type == 'customText') {
+            data = { ...item.valueObj, ...data };
+          } else {
+            item.valueObj.rows.forEach((row) => {
+              row.cells.forEach((cell) => {
+                data[cell.id] = cell.value;
+              });
+            });
+          }
+          equation.push({
+            id: item.id,
+            equation: item.equation
+          });
+        });
+        equation.forEach((item) => {
+          console.log(item.equation);
+
+          for (const key in item.equation) {
+            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)
+                });
+              }
+            }
+          }
+        });
+      },
+      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;
+        }
+
+        this.list.forEach((item) => {
+          if (item.type == 'customText') {
+            for (let key in item.valueObj) {
+              this.idList.push(key);
+            }
+          } else {
+            item.valueObj.rows.forEach((row) => {
+              row.cells.forEach((cell) => {
+                this.idList.push(cell.id);
+              });
+            });
+          }
+        });
+        this.visible = true;
+      },
+      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
               });
             });
           });
@@ -153,10 +406,17 @@
       },
       editShowFn({ templateDivRef, domObj }) {
         this.templateDivRef = templateDivRef;
+        console.log(domObj, 'domObj');
         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 +433,13 @@
         });
       },
       getValue() {
-        // this.$nextTick(() => {
-        //   // sessionStorage['valueJSON'] = JSON.stringify(this.list);
-        //   // localStorage['valueJSON'] = JSON.stringify(this.list);
-        // });
         this.list.forEach((item, index) => {
-          let { form, valueObj } =
+          console.log(item);
+          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;
       }

+ 26 - 11
src/views/rulesManagement/releaseRules/components/templateDiv/customTable.vue

@@ -19,7 +19,7 @@
               type="text"
               class="templateInput"
               :id="item.id"
-              :readonly="item.readonly == 2||!edit"
+              :readonly="item.readonly == 2 || !edit"
               @click="inputClick(item)"
             />
           </th>
@@ -34,8 +34,9 @@
               type="text"
               class="templateInput"
               :id="item.id"
-               :readonly="item.readonly == 2||!edit"
+              :readonly="item.readonly == 2 || !edit"
               @click="inputClick(item)"
+              @input="calculation"
           /></td>
           <td v-if="edit">
             <i
@@ -62,8 +63,7 @@
       edit: {
         default: true,
         type: Boolean
-      },
-    
+      }
     },
     data() {
       return {
@@ -72,7 +72,8 @@
         domId: '',
         rightClickShow: false,
         columns: [],
-        rows: []
+        rows: [],
+        equation: {}
       };
     },
     methods: {
@@ -128,22 +129,35 @@
           }
         }
       },
-
+      calculation() {
+        this.$emit('calculation');
+      },
+      equationValue({ domId, value }) {
+        this.rows.forEach((item, index) => {
+          let cellIndex = item.cells.findIndex((cell) => cell.id == domId);
+          this.$set(this.rows[index].cells[cellIndex], 'value', value);
+        });
+      },
       getValue() {
         return {
           form: null,
+          equation: this.equation,
           valueObj: {
             columns: this.columns,
             rows: this.rows
           }
         };
       },
-      init({ form, valueObj }) {
+      init({ form, valueObj,equation }) {
         this.form = form;
         this.columns = valueObj.columns;
         this.rows = valueObj.rows;
+        this.equation = equation;
       },
       editInputChange(domObj) {
+        if (domObj.equation) {
+          this.equation[this.domId] = domObj.equation;
+        }
         let columnsIndex = this.columns.findIndex(
           (item) => item.id == this.domId
         );
@@ -155,7 +169,7 @@
           let rowsIndex = item.cells.findIndex(
             (cells) => cells.id == this.domId
           );
-          // console.log(rowsIndex,'rowsIndex')
+
           if (rowsIndex >= 0) {
             this.$set(this.rows[index].cells, rowsIndex, domObj);
           }
@@ -163,8 +177,8 @@
       },
 
       inputClick(item) {
-        if(!this.edit){
-          return
+        if (!this.edit) {
+          return;
         }
         this.domId = item.id;
         this.$emit('editShow', {
@@ -173,7 +187,8 @@
             isNoWidth: true,
             id: item.id,
             readonly: item.readonly,
-            value: item.value
+            value: item.value,
+            equation: this.equation[item.id]
           }
         });
       }

+ 29 - 11
src/views/rulesManagement/releaseRules/components/templateDiv/customText.vue

@@ -16,7 +16,7 @@
       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);
@@ -101,15 +100,30 @@
         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 }) {
+        let dom = document.getElementById(domId);
+        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,6 +144,9 @@
         }
         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) {
@@ -147,6 +164,8 @@
       inputChange(event) {
         if (event.target && event.target.className == 'templateInput') {
           this.valueObj[event.target.id] = event.target.value;
+
+          this.$emit('calculation');
         }
       },
       inputClick(event) {
@@ -155,14 +174,13 @@
         }
         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
+              readonly: event.target.readOnly ? 2 : 1,
+              equation: this.equation[this.domId]
             }
           });
         }