Procházet zdrojové kódy

编辑公式页面

gangyj před 3 roky
rodič
revize
8aacc50c05

+ 24 - 5
src/views/formula/component/formulaTemplate.vue

@@ -6,15 +6,16 @@
       <div>
         <span>参数{{(index+1)}}({{formulainfo.template.args[index].m}}):</span>
         <span>
-          <template v-if="(typeof item)=='object'">
-            元素
+          <template v-if="(typeof item)=='object' && item.type == 'Element'">
+            <el-tag>{{item.name}}</el-tag>
           </template>
           <template v-else>
             <el-input v-model="formulainfo.arguments[index]" placeholder="请输入内容" style="width:200px"></el-input>
           </template>
         </span>
-        <el-link type="primary" @click="changeType('text')" class="mg-l-10">输入文本</el-link>
-        <el-link type="primary" @click="changeType('ele')" class="mg-l-10">选择元素</el-link>
+        <el-link type="primary" @click="changeType('text',index)" class="mg-l-10">输入文本</el-link>
+        <el-link type="primary" @click="changeType('ele',index)" class="mg-l-10">选择元素</el-link>
+        <el-link type="primary" @click="setCurEle(index)" class="mg-l-10">当前元素</el-link>
       </div>
     </div>
   </div>
@@ -30,6 +31,12 @@ export default {
         return {};
       }
     },
+    curele: {
+      type: Object,
+      default: function () {
+        return {};
+      }
+    },
   },
   data(){
     return{
@@ -47,8 +54,20 @@ export default {
   },
   methods:{
     //切换选择的状态
-    changeType(){
+    changeType(type,index){
+      if(type == 'text'){
+        this.$set(this.formulainfo.arguments,index,'');
+      }else if(type == 'ele'){
+        this.$emit('sele-ele-handle',{
+          arguments:this.formulainfo.arguments,
+          index
+        })
+      }
+    },
 
+    //选择当前元素
+    setCurEle(index){
+      this.$set(this.formulainfo.arguments,index,this.curele);
     }
   }
 }

+ 115 - 4
src/views/formula/edit.vue

@@ -98,7 +98,7 @@
                 <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets(')',true)">)</el-link>
                 <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets('[',false)">【</el-link>
                 <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets(']',true)">】</el-link>
-                <el-link :underline="false" type="primary">输入值</el-link>
+                <el-link :underline="false" type="primary" @click="addText">输入值</el-link>
               </div>
             </div>
             <div class="border-grey sele-ele-box">
@@ -148,19 +148,27 @@
       </div>
       <div class="text-align-c">
         <el-button type="warning">取消</el-button>
-        <el-button type="primary">保存</el-button>
+        <el-button type="primary" @click="saveFormula">保存</el-button>
       </div>
     </div>
     <div v-if="!operationVisible && showFunDetail">
-      <el-tabs v-model="actiFunIndex">
+      <el-tabs v-model="actiFunIndex" closable @tab-remove="removeFun" :before-leave="funLeave">
         <el-tab-pane v-for="(item,index) in equationSelectEle.children" :key="item.name" :label="item.name" :name="index.toString()">
-          <formula-template :formulainfo="item">
+          <formula-template :formulainfo="item" :curele="equationSelectEle" @sele-ele-handle="showChooseEle">
             
           </formula-template>
         </el-tab-pane>
       </el-tabs>
     </div>
 
+    <el-dialog title="输入值" :visible.sync="inputVisible" width="300px" append-to-body :close-on-click-modal="false">
+      <el-input v-model="inputText" placeholder="请输入内容"></el-input>
+      <div class="text-align-c mg-t-10">
+        <el-button size="small" @click="addTextHandle" type="primary">保存</el-button>
+        <el-button size="small" @click="inputVisible = false">取消</el-button>
+      </div>
+    </el-dialog>
+
     <el-dialog title="选择元素" :visible.sync="chooseEleVisible" width="800px" append-to-body :close-on-click-modal="false">
       <div>
         <el-row :gutter="20">
@@ -216,8 +224,11 @@ import { findContractByProjectId } from "@/api/manager/contractinfo";
 import { getDetail as getEleDeatil } from "@/api/manager/wbsformelement";
 import { getTypeMap } from "@/api/formula/formula";
 import {mapGetters} from "vuex";
+
 import formulaItem from "./component/formulaItem"
 import formulaTemplate from "./component/formulaTemplate"
+
+import {formulaArrayToString} from "./formulaArrayToString"
 export default {
   components: {
     formulaItem,
@@ -252,6 +263,8 @@ export default {
       eleList:[],
       selectEleFormula:[],
       curSeleEleIndex:0,//公式文字里面选中的元素索引
+      inputVisible:false,//输入弹窗
+      inputText:"",//输入值
 
       resultFormula:[],//=等号左边的数组
       processFormula:[],//=等号右边的数组
@@ -259,6 +272,7 @@ export default {
       processSelectIndex:0,//选中的索引
       actiFunIndex:0,//元素下挂载的计算式的索引
       chooseEleVisible:false,//选择元素弹窗
+      argumenObj:{},
 
       symbolReg:/(\+|-|\*|\/)(.+)/,
     };
@@ -406,6 +420,13 @@ export default {
           name:ele.name,
           selected:false,
         })
+      }else if(ele.type == 'Text'){
+        //输入值
+        this.selectEleFormula.push({
+          type:'Text',
+          name:ele.name,
+          selected:false,
+        })
       }
     },
 
@@ -425,6 +446,19 @@ export default {
       }
     },
 
+    
+    addText(){
+      this.inputVisible = true;
+    },
+    //添加输入值
+    addTextHandle(){
+      this.eleAddFormulaHandle({
+        type:'Text',
+        name:this.inputText
+      })
+      this.inputVisible = false;
+    },
+
     //勾选元素
     eleCheckHandle(checked,item){
       if(checked){
@@ -491,12 +525,89 @@ export default {
       let obj = Object.assign({}, expression);
       obj.template = JSON.parse(obj.template);
       obj.arguments = new Array(obj.template.args.length);
+      obj.arguments[0] = {
+          id:this.equationSelectEle.id,
+          name:this.equationSelectEle.name,
+          selected:false,
+          tableElementKey:this.equationSelectEle.tableElementKey,
+          type:"Element",
+      };
       this.equationSelectEle.children.push(obj);
     },
 
     //选择元素
     chooseEleHandle(){
+      for (let i = 0; i < this.eleList.length; i++) {
+        if (this.eleList[i].checked) {
+          let ele = this.eleList[i]
+          let obj = {
+            type:'Element',
+            name:ele.eName,
+            id:ele.id,
+            selected:false,
+            tableElementKey:ele.tableElementKey,
+            children:[],
+          }
+          this.$set(this.argumenObj.arguments,this.argumenObj.index,obj);
+          this.chooseEleVisible = false;
+          break;
+        }
+      }
+    },
+
+    //显示选择元素弹窗
+    showChooseEle(argumenObj){
+      this.argumenObj = argumenObj;
+      this.chooseEleVisible = true;
+    },
+
+    //移除挂载的函数
+    removeFun(name){
+      //console.log(name)
+      this.equationSelectEle.children.splice(Number(name), 1);
+    },
+
+    //切换公式tab标签
+    funLeave(activeName, oldActiveName){
+      if(oldActiveName){
+        let formula = this.equationSelectEle.children[Number(oldActiveName)];
+        if(formula){
+          return this.checkFormulaLegal(formula);
+        }
+      }
+      
+    },
+
+    //检测公式合法
+    checkFormulaLegal(formula){
+      if(!formula.arguments){
+        return false;
+      }
+
+      //当前选中的元素
+      let curEle = this.equationSelectEle;
+      let isIn = false;
+      for (let i = 0; i < formula.arguments.length; i++) {
+        if(formula.arguments[i] && formula.arguments[i].id ==curEle.id){
+          isIn = true;
+          break;
+        }
+      }
+      if(!isIn){
+        this.$message({
+          type: "warning",
+          message: "参数必须有一个值是当前元素"
+        });
+        return false;
+      }
+
+      return true;
+    },
 
+    //保存公式
+    saveFormula(){
+      let text = formulaArrayToString(this.processFormula,this.resultFormula);
+      console.log(text);
     },
 
     getNodeDetail(data) {

+ 64 - 0
src/views/formula/formulaArrayToString.js

@@ -0,0 +1,64 @@
+
+
+function transformArguments(children,curEle){
+  let fcReg = /(FC\.\S+\().+(\))/;
+  let fcText = '';
+  for (let i = (children.length-1); i >= 0; i--) {
+    let ele = children[i];
+    //console.log(ele.name)
+    let tmpArr = fcReg.exec(ele.template.ft);
+    fcText = tmpArr[1] + fcText;//fc.XX( 左括号部分
+    //console.log(text)
+    ele.arguments.forEach((arg,index)=>{
+      if(arg.type == 'Element'){
+        if(i != (children.length-1) && curEle.id == arg.id){
+          //不是第一个嵌套的公式,且和当前挂载的是同一个元素
+          //认为这个参数是之前公式计算的结果,不再写入元素
+        }else{
+          fcText += `E[${arg.tableElementKey}]`;
+        }
+      }else{
+        fcText += arg;
+      }
+      if(index != ele.arguments.length-1){
+        fcText += ',';
+      }
+    })
+    fcText += ')';
+  }
+
+  return fcText;
+}
+
+export const formulaArrayToString = (processFormula,resultFormula) => {
+  // processFormula =  [{"type":"Element","name":"faf","id":"1534050101579087874","selected":false,"tableElementKey":"assa_faf","children":[{"name":"平方","template":{"ft":"FC.pow(#1,2)","args":[{"key":"#1","m":"底数"}]},"type":0,"example":"求元素最小值:FC.pow(E[元素码],2)","arguments":[{"id":"1534050101579087874","name":"faf","selected":false,"tableElementKey":"assa_faf","type":"Element"}]},{"name":"根号","template":{"ft":"FC.sqrt(#1,#2)","args":[{"key":"#1","m":"开方数"},{"key":"#2","m":"根指数"}]},"type":0,"example":"对元素开方:FC.sqrt(E[元素码],3)","arguments":[{"id":"1534050101579087874","name":"faf","selected":false,"tableElementKey":"assa_faf","type":"Element"},"2"]}]},{"type":"Operator","name":"+","selected":false,"template":"{\"ft\":\"+\",\"args\":[]}"},{"type":"Brackets","name":"(","selected":false},{"type":"Element","name":"aff","id":"1534054463428755457","selected":false,"tableElementKey":"assa_aff","children":[{"name":"日期偏移","template":{"ft":"FC.date(#1,#2)","args":[{"key":"#1","m":"当期日期"},{"key":"#2","m":"偏移天数"}]},"type":3,"example":"三天后的日期FC.date(E[元素码],3)","arguments":[{"id":"1534054463428755457","name":"aff","selected":false,"tableElementKey":"assa_aff","type":"Element"},"1"]},{"name":"包含","template":{"ft":"FC.contain(#1)","args":[{"key":"#1","m":"元素"}]},"type":2,"example":"是否包含","arguments":[{"id":"1534054463428755457","name":"aff","selected":false,"tableElementKey":"assa_aff","type":"Element"}]}]},{"type":"Operator","name":"-","selected":false,"template":"{\"ft\":\"-\",\"args\":[]}"},{"type":"Text","name":"1","selected":false},{"type":"Brackets","name":")","selected":false}];
+  // resultFormula =  [{"type":"Element","name":"sadas","id":"1531842911529267201","selected":false,"tableElementKey":"assa_sadas","children":[{"name":"最大值","template":{"ft":"FC.max(#1)","args":[{"key":"#1","m":"元素"}]},"type":0,"example":"求元素最大值:FC.max(E[元素码])","arguments":[{"id":"1531842911529267201","name":"sadas","selected":false,"tableElementKey":"assa_sadas","type":"Element"}]},{"name":"最小值","template":{"ft":"FC.min(#1)","args":[{"key":"#1","m":"元素"}]},"type":0,"example":"求元素最小值:FC.min(E[元素码])","arguments":[{"id":"1531842911529267201","name":"sadas","selected":false,"tableElementKey":"assa_sadas","type":"Element"}]}]}];
+  // //console.log(JSON.stringify(processFormula))
+  // //console.log(JSON.stringify(resultFormula))
+  // console.log(processFormula)
+  // console.log(resultFormula)
+  let text = '';
+
+  processFormula.forEach(item => {
+    if(item.type == 'Element'){
+      if(item.children.length <1){
+        text += `E[${item.tableElementKey}]`;
+      }else{
+        text += transformArguments(item.children,item);
+      }
+    }else{
+      text += item.name;
+    }
+  });
+
+  if(resultFormula[0].children.length){
+    //等号左侧部分
+    let resText = transformArguments(resultFormula[0].children,resultFormula[0]);
+  
+    //等号左侧元素不需要,左侧的公式嵌套右侧所有结果
+    text = resText.replace(`E[${resultFormula[0].tableElementKey}]`,text);
+  }
+
+  console.log(text);
+  return text;
+}