瀏覽代碼

公式文本和数组相互转换

gangyj 3 年之前
父節點
當前提交
cf43b42d73
共有 3 個文件被更改,包括 135 次插入85 次删除
  1. 4 1
      src/views/formula/edit.vue
  2. 1 7
      src/views/formula/formulaArrayToString.js
  3. 130 77
      src/views/formula/formulaStringToArray.js

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

@@ -654,7 +654,10 @@ export default {
         this.formulaid = detail.id;
         let formula = formulaStringToArray(detail.formula,detail.map,this.formulaMap);
         this.processFormula = formula.processFormula;
-        this.resultFormula[0].children = formula.resultFormulaChildren;
+        formula.resultFormula[0].id = this.resultFormula[0].id;
+        formula.resultFormula[0].name = this.resultFormula[0].name;
+        formula.resultFormula[0].tableElementKey = this.resultFormula[0].tableElementKey;
+        this.resultFormula[0].children = formula.resultFormula[0].children;
       }
     },
 

+ 1 - 7
src/views/formula/formulaArrayToString.js

@@ -56,12 +56,6 @@ function transformArguments(children,curEle,eleMap){
 }
 
 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 = '';
   let eleMap = {};//元素字典,为了回显的时候查询信息
 
@@ -94,7 +88,7 @@ export const formulaArrayToString = (processFormula,resultFormula) => {
     text = resText.replace(`E[${resultFormula[0].tableElementKey}]`,text);
   }
 
-  //console.log(text);
+  console.log(text);
   //console.log(eleMap)
   return {text,eleMap};
 }

+ 130 - 77
src/views/formula/formulaStringToArray.js

@@ -1,6 +1,39 @@
 
-//解析公式的参数
-function parseFormulaArguments(ele,funObj,resArr){
+
+function parseFormula(arr,resultFormula,processFormula,isAllFun){
+  let tmpArr = [];//放置这一层的数组
+  for (let i = 0; i < arr.length; i++) {
+    tmpArr.push(arr[i]);
+    if(arr[i].type != "Function"){
+      isAllFun = false;
+    }
+  }
+  if(isAllFun){
+    for (let i = 0; i < tmpArr.length; i++) {
+      parseArguments(resultFormula[0],tmpArr[i]);
+      parseFormula(arr[i].children,resultFormula,processFormula,isAllFun);
+    }
+  }else{
+    for (let i = 0; i < tmpArr.length; i++) {
+      if(tmpArr[i].type == 'Function'){
+        let obj = {
+          children:[],
+          name:"临时占位",
+          selected:false,
+          type:"Element",
+        }
+        parseProcessFormula(arr[i],obj);
+        processFormula.push(Object.assign({},obj))
+        delete obj.children;
+      }else if(tmpArr[i].name){
+        processFormula.push(tmpArr[i]);
+      }
+    }
+  }
+}
+
+//解析方法里面的参数
+function parseArguments(ele,funObj){
   let fcReg = /(FC\.\S+\()(.+)\)/;
   let fun = {
     example:funObj.example,
@@ -8,50 +41,67 @@ function parseFormulaArguments(ele,funObj,resArr){
     template:funObj.template,
   };
   let argTextArr = funObj.children;//放参数文本的数组
+
+  //根据逗号位置分割参数
+  let index = 0;
+  let argSpliceArr = [[]];
+  while (index < argTextArr.length) {
+    if(argTextArr[index].type =='Comma'){
+      argSpliceArr.push([]);
+    }else{
+      argSpliceArr[argSpliceArr.length-1].push(argTextArr[index])
+    }
+    index++
+  }
+
   fun.arguments = [];
 
   let tmpArr = fcReg.exec(funObj.template.ft);
   let argList = tmpArr[2].split(",");//括号里面参数部分#1,#2..
 
   argList.forEach((argText,index)=>{
-    //只用动态的
-    if(argText.indexOf('#')>-1){
-      if(argTextArr[index].type == 'Element'){
-        fun.arguments.push(argTextArr[index])
-      }else if(argTextArr[index].type == 'Function'){
-        fun.arguments.push(ele)
-      }else{
-        fun.arguments.push(argTextArr[index].tag)
+      //只用动态的
+      if(argText.indexOf('#')>-1){
+        if(argSpliceArr[index].length>1){
+          //是前面的计算结果
+          fun.arguments.push(ele)
+        }else{
+          let arg = argSpliceArr[index][0];
+          if(arg.type == 'Element'){
+            fun.arguments.push(arg)
+          }else if(arg.type == 'Function'){
+            fun.arguments.push(ele)
+          }else if(arg.type == 'Text'){
+            fun.arguments.push(arg.tag)
+          }else{
+            fun.arguments.push(undefined)
+          }
+        }
       }
-    }
-  })
+    })
 
   ele.children.push(fun);
-  if(funObj.parent){
-    let isTop = false;
-    for (let i = 0; i < funObj.parent.children.length; i++) {
-      if(funObj.parent.children[i].type == "Operator" ||
-        funObj.parent.children[i].type == "Brackets"
-      ){
-        //有这些认为就最顶层,外面的方法是放到结果那里的
-        isTop = true;
-        break;
-      }
-    }
-    if(!isTop){
-      parseFormulaArguments(ele,funObj.parent,resArr)
-    }
-  }else{
-    //结束之后把parent删掉
-    delete ele.parent;
-    for (let i = 0; i < resArr.length; i++) {
-      if(resArr[i] == funObj){
-        //用元素替换最顶层的方法
-        resArr[i] = ele;
-        break;
-      }
+}
+
+function parseProcessFormula(funObj,ele){
+  parseArguments(ele,funObj);
+  let inFun = false;//是不是有Function
+  let endEle = null;//认为最下面一层第一个元素是显示的元素
+  for (let i = 0; i < funObj.children.length; i++) {
+    if(funObj.children[i].type == 'Function'){
+      parseProcessFormula(funObj.children[i],ele);
+      inFun = true;
+    }else if(funObj.children[i].type == "Element" && !endEle){
+      endEle = funObj.children[i];
     }
   }
+  if(!inFun){
+    //把临时的属性改为最终找到的
+    ele.id = endEle.id;
+    ele.name = endEle.name;
+    ele.tableElementKey = endEle.tableElementKey;
+  }
+
 }
 
 export const formulaStringToArray = (text,elemap,formulaMap) => {
@@ -62,8 +112,8 @@ export const formulaStringToArray = (text,elemap,formulaMap) => {
   const endBracketsReg = /^\)/;//右括号
   const elementReg = /^E\[(.[^\]]+_.[^\]]+)\]/;//元素
   const commaReg = /^,/;//逗号
-  const operatorReg = /^\+|-|\*|%/;//加减乘除
-  const wordReg = /^[\u4e00-\u9fa5\w'"-]+/;//文本
+  const operatorReg = /^(\+|-|\*|%)/;//加减乘除
+  const wordReg = /^[\u4e00-\u9fa5\w0-9'"-]+/;//文本
 
   let elementMap = JSON.parse(elemap);//元素字典
   //console.log(formulaMap)
@@ -73,7 +123,6 @@ export const formulaStringToArray = (text,elemap,formulaMap) => {
   let nuText = text;//未处理的字符串
   //let startStack = [];//方法体开始部分和左括号 放进来的栈
   let contentStack = [];//内容放进来的栈
-  let elementArr = [];//存放元素的数组
 
   while (strIndex < text.length) {
     nuText = text.substring(strIndex);
@@ -108,25 +157,46 @@ export const formulaStringToArray = (text,elemap,formulaMap) => {
       let endBrackets = nuText.match(endBracketsReg)[0];
 
       let popObj = contentStack.pop();
+      let arrType = [];
+      
       if(contentStack.length > 0){
         let content =contentStack[contentStack.length - 1];
-        popObj.parent = content;
         content.children.push(popObj);
+        arrType = content.children;
       }else{
         //匹配完成最顶层的一整个方法体,或括号
         resArr.push(popObj);
+        arrType = resArr;
+      }
+
+      if(popObj.type =='Brackets'){
+        let brackArr = [];
+        //如果是括号,把括号里面的提出一层
+        popObj.children.forEach((ele)=>{
+          brackArr.push(ele);
+        })
+        //补个右括号
+        brackArr.push({
+          type:'Brackets',
+          selected:false,
+          name:')',
+        });
+        arrType.push(...brackArr);
+        delete popObj.children
       }
+      //console.log(popObj,'pop')
 
       strIndex += endBrackets.length;//索引移动
     }else if(startBracketsReg.test(nuText)){
       //console.log('匹配左括号')
       //匹配左括号
       let startBrackets = nuText.match(startBracketsReg)[0];
-
+      
       contentStack.push({
         type:'Brackets',
         children:[],
         selected:false,
+        name:startBrackets,
         tag:startBrackets
       });
 
@@ -155,22 +225,18 @@ export const formulaStringToArray = (text,elemap,formulaMap) => {
       }
       
       let content =contentStack[contentStack.length - 1];
-      obj.parent = content;
       content.children.push(obj);
 
-      elementArr.push(obj)
-
       strIndex += eleArr[0].length;//索引移动
     }else if(commaReg.test(nuText)){
       //console.log('匹配逗号')
       //匹配逗号
       let comma = nuText.match(commaReg)[0];
 
-      // 方法体里面的逗号忽略
-      // contentStack[contentStack.length - 1].children.push({
-      //   type:'Comma',
-      //   tag:comma
-      // });
+      contentStack[contentStack.length - 1].children.push({
+        type:'Comma',
+        tag:comma
+      });
 
       strIndex += comma.length;//索引移动
     }else if(operatorReg.test(nuText)){
@@ -216,39 +282,26 @@ export const formulaStringToArray = (text,elemap,formulaMap) => {
     }
   }
 
-  //数组清理到最后能显示的元素
-  for (let i = elementArr.length-1; i >0; i--) {
-    //判断当前元素是不是最底层
-    let isBottom = true;
-    let childrenEles = [];
-    let chs = elementArr[i].parent.children;
-    for (let j = 0; j < chs.length; j++) {
-      if(chs[j].type == "Function"){
-        isBottom = false;
-      }else if(chs[j].type == "Element"){
-        childrenEles.push(chs[j]);
-      }
-    }
-    if(isBottom){
-      //认为最底层的参数第一个元素就是显示在页面的那个元素
-      if(childrenEles[0] != elementArr[i]){
-        elementArr.splice(i,1);
-      }
-    }else{
-      elementArr.splice(i,1);
-    }
-  }
+  let resultFormula = [{
+    children:[],
+    name:"临时占位",
+    selected:false,
+    type:"Element",
+  }]
+
+  let processFormula = []
+  let isAllFun = true;//一层全是方法,有其他说明到了显示层
 
-  elementArr.forEach((ele)=>{
-    parseFormulaArguments(ele,ele.parent,resArr);
-  })
+  //从顶层开始
+  parseFormula(resArr,resultFormula,processFormula,isAllFun);
 
-  console.log(contentStack)
+  //console.log(contentStack)
   console.log(resArr);
-  console.log(elementArr);
+  console.log(resultFormula);
+  console.log(processFormula);
 
   return {
-    processFormula:resArr,
-    resultFormulaChildren:[],
+    processFormula:processFormula,
+    resultFormula:resultFormula,
   };
 }