ソースを参照

计算基数 ID引用

zhongzewei 7 年 前
コミット
2412a8f9f1

+ 130 - 42
web/building_saas/main/js/models/calc_base.js

@@ -40,6 +40,25 @@ let cbTools = {
         }
         return null;
     },
+    //通过ID获取节点行
+    getRowByID: function (items, ID) {
+        for(let i = 0, len = items.length; i < len; i++){
+            if(items[i]['data']['ID'] === ID){
+                return i + 1;
+            }
+        }
+        return null;
+    },
+    //通过ID获取节点
+    getNodeByID: function (items, ID) {
+        ID = parseInt(ID);
+        for(let i = 0, len = items.length; i < len; i++){
+            if(items[i]['data']['ID'] === ID){
+                return items[i];
+            }
+        }
+        return null;
+    },
     //获取该节点所有父节点
     getParents: function (node) {
         let rst = [];
@@ -69,7 +88,7 @@ let cbTools = {
             return rst;
         }
         //获取表达式中的基数和行引用
-        let figureF = cbParser.getFigureF(cbParser.getFigure(exp), cbParser.getRArr(cbParser.getFArr(exp)));
+        let figureF = cbParser.getFigureF(cbParser.getFigure(exp), cbParser.getXNum(cbParser.getFArr(exp)));
         for(let i = 0, len = figureF.length; i < len; i++){
             let figure = figureF[i];
             if(figure.type === 'base' && cbTools.isDef(calcBase.baseFigures[figure.value])){
@@ -156,28 +175,22 @@ let cbTools = {
         let parent = node.parent;
         if(this.isFlag(node.data) && (node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.SUB_ENGINERRING
             || node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_TECH)){
-            //node.data.baseFigureClass = null;
             return null;
         }
         else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CONSTRUCTION_ORGANIZATION){
-            //node.data.baseFigureClass = 'CONSTRUCTION_ORGANIZATION';
             return calcBase.baseFigureClass.CONSTRUCTION_ORGANIZATION;
         }
         else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.OTHER){
-            //node.data.baseFigureClass = 'OTHER';
             return calcBase.baseFigureClass.OTHER;
         }
         else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.CHARGE){
-            //node.data.baseFigureClass = 'CHARGE';
             return calcBase.baseFigureClass.CHARGE;
         }
         else if(this.isFlag(node.data) && node.data.flagsIndex.fixed.flag === calcBase.fixedFlag.TAX){
-            //node.data.baseFigureClass = 'TAX';
             return calcBase.baseFigureClass.TAX;
         }
         else {
             if(!parent){
-                //node.data.baseFigureClass = 'OTHERS';
                 return calcBase.baseFigureClass.OTHERS;
             }
             else {
@@ -229,8 +242,8 @@ let cbTools = {
                 if(bases[i]['type'] === 'base' && cbTools.isDef(calcBase.baseFigures[bases[i]['value']])){
                     block.push(calcBase.baseFigures[bases[i]['value']]['fixedBill']['bill']['ID']);
                 }
-                else if(bases[i]['type'] === 'row'){
-                    let node = cbTools.getBillByRow(calcBase.project.mainTree.items, bases[i]['value'] - 1);
+                else if(bases[i]['type'] === 'id'){
+                    let node = cbTools.getNodeByID(calcBase.project.mainTree.items, bases[i]['value']);
                     if(cbTools.isDef(node)){
                         block.push(node.data.ID);
                     }
@@ -241,7 +254,7 @@ let cbTools = {
         function getBase(node){
             if(node && node.children.length === 0){
                 if(cbTools.isDef(node.data.calcBase) && node.data.calcBase !== ''){
-                    let figureF = cbParser.getFigureF(cbParser.getFigure(node.data.calcBase), cbParser.getRArr(cbParser.getFArr(node.data.calcBase)));
+                    let figureF = cbParser.getFigureF(cbParser.getFigure(node.data.calcBase), cbParser.getXNum(cbParser.getFIDArr(node.data.calcBase)));
                     tempBases = tempBases.concat(figureF);
                 }
             }
@@ -503,15 +516,22 @@ let cbAnalyzer = {
     },
     //行引用合法性、存在性
     fLegal: function (items, exp) {
+        //提取F标记
+        let fmArr = cbParser.getFMArr(exp);
         //提取行引用
         let fArr = cbParser.getFArr(exp);
+        if(fmArr.length !== fArr.length){
+            return false;
+        }
         //提取行数
-        let rArr = cbParser.getRArr(fArr);
+        let rArr = cbParser.getXNum(fArr);
+        if(fArr.length !== rArr.length){
+            return false;
+        }
         //判断合法性和存在性
         for(let i = 0, len = rArr.length; i < len; i++){
             let idx = rArr[i] - 1;
             if(cbTools.isUnDef(cbTools.getBillByRow(items, idx))){
-                calcBase.errMsg = '行引用不合法';
                 return false;
             }
         }
@@ -525,16 +545,16 @@ let cbAnalyzer = {
         }
         //用于判断的起始清单ID
         let sIDs = cbTools.getNodeIDs(Array.from(new Set([cbTools.getBaseBill(node)].concat(cbTools.getParents(node)))));
-        let figureF = cbParser.getFigureF(cbParser.getFigure(exp), cbParser.getRArr(cbParser.getFArr(exp)));
+        let figureF = cbParser.getFigureF(cbParser.getFigure(exp), cbParser.getXNum(cbParser.getFIDArr(exp)));
         for(let i = 0, len = figureF.length; i < len; i++){
             let figure = figureF[i];
             let bill = null;
             if(figure.type === 'base' && cbTools.isDef(baseFigures[figure.value])){
                 bill = baseFigures[figure.value]['fixedBill']['bill'];
             }
-            else if(figure.type === 'row'){
-                let tempBill = cbTools.getBillByRow(calcBase.project.mainTree.items, figure.value - 1);
-                bill = cbTools.isDef(tempBill) ? tempBill.data : null;
+            else if(figure.type === 'id'){
+                let node = cbTools.getNodeByID(calcBase.project.mainTree.items, figure.value);
+                bill = cbTools.isDef(node) ? node.data : null;
             }
             if(cbTools.isDef(bill) && checkStack(getRefStack([bill.ID]), sIDs)){
                 console.log('循环计算');
@@ -576,13 +596,18 @@ let cbAnalyzer = {
     legalExp: function (node) {
         let exp = this.standar(node.data.userCalcBase);
         if(this.inputLegal(exp)){
-            if(this.baseLegal(cbTools.getFigure(node), exp)){
-                if(this.fLegal(calcBase.project.mainTree.items, exp)){
-                    if(!this.cycleCalc(node, cbTools.getFigure(node), exp)){
-                        if(this.arithmeticLegal(exp)){
+            if(this.arithmeticLegal(exp)){
+                if(this.baseLegal(cbTools.getFigure(node), exp)){
+                    if(this.fLegal(calcBase.project.mainTree.items, exp)){
+                        //转换成ID引用
+                        exp = cbParser.toIDExpr(exp);
+                        if(!this.cycleCalc(node, cbTools.getFigure(node), exp)){
                             return exp;
                         }
                     }
+                    else {
+                        calcBase.errMsg = '行引用不合法';
+                    }
                 }
             }
         }
@@ -592,22 +617,34 @@ let cbAnalyzer = {
 
 //输入式转换器
 let cbParser = {
+    //获取标记F
+    getFMArr: function (exp) {
+        let fmRex = /F/g;
+        let fmArr = exp.match(fmRex);
+        return cbTools.isDef(fmArr) ? fmArr : [];
+    },
     //获取行引用 eg: F10
     getFArr: function (exp) {
         let fRex = /F\d+/g;
         let fArr = exp.match(fRex);
         return cbTools.isDef(fArr) ? fArr : [];
     },
-    //获取行 eg: F10  10
-    getRArr: function (fArr) {
+    //获取X+num eg: F10  10 @105 105
+    getXNum: function (arr) {
         let rRex = /\d+/g;
         let tempArr = [];
-        for(let i = 0, len = fArr.length; i < len; i++){
-            tempArr = tempArr.concat(fArr[i].match(rRex));
+        for(let i = 0, len = arr.length; i < len; i++){
+            tempArr = tempArr.concat(arr[i].match(rRex));
         }
         let rArr = Array.from(new Set(tempArr));
         return rArr;
     },
+    //获取ID引用
+    getFIDArr: function (exp) {
+        let fidRex = /@\d+/g;
+        let fidArr = exp.match(fidRex);
+        return cbTools.isDef(fidArr) ? fidArr : [];
+    },
     //获取表达式中的中文式,没有{}需求时
     getCN: function(expr){
         let rst = [];
@@ -632,8 +669,8 @@ let cbParser = {
         }
         return rst;
     },
-    //获取表达式中的基数和
-    getFigureF: function (figures, rArr) {
+    //获取表达式中的基数和ID引用
+    getFigureF: function (figures, fidArr) {
         let rst = [];
         for(let i = 0, len = figures.length; i < len; i++){
             let obj = Object.create(null);
@@ -641,15 +678,60 @@ let cbParser = {
             obj.value = figures[i];
             rst.push(obj);
         }
-        for(let i = 0, len = rArr.length; i < len; i++){
+        for(let i = 0, len = fidArr.length; i < len; i++){
             let obj = Object.create(null);
-            obj.type = 'row';
-            obj.value = rArr[i];
+            obj.type = 'id';
+            obj.value = fidArr[i];
             rst.push(obj);
         }
         return rst;
     },
-
+    //将行引用转换成ID引用
+    toIDExpr: function (exp) {
+        let exps = [];
+        //获得行引用
+        let fArr = this.getFArr(exp);
+        for(let i = 0, len = fArr.length; i < len; i++){
+            let r = this.getXNum([fArr[i]]);
+            if(r.length === 1){
+                let node = cbTools.getBillByRow(calcBase.project.mainTree.items, r[0] - 1);
+                if(cbTools.isUnDef(node)){
+                    //continue;
+                    calcBase.errMsg = '行引用错误';
+                    throw '行引用错误';
+                }
+                exps.push({orgExp: fArr[i], newExp: '@' + node.data.ID});
+            }
+            else {
+                calcBase.errMsg = '行引用错误';
+                throw '行引用错误';
+            }
+        }
+        for(let i = 0, len = exps.length; i < len; i++){
+            exp = exp.replace(new RegExp(exps[i].orgExp, 'g'), exps[i].newExp);
+        }
+        return exp;
+    },
+    //将ID引用转换成行引用
+    toFExpr: function (exp) {
+        let exps = [];
+        //获得ID引用
+        let fidArr = this.getFIDArr(exp);
+        for(let i = 0, len = fidArr.length; i < len; i++){
+            let id = this.getXNum([fidArr[i]]);
+            if(id.length === 1){
+                let row = cbTools.getRowByID(calcBase.project.mainTree.items, id[0]);
+                if(cbTools.isUnDef(row)){
+                    continue;
+                }
+                exps.push({orgExp: fidArr[i], newExp: 'F' + row});
+            }
+        }
+        for(let i = 0, len = exps.length; i < len; i++){
+            exp = exp.replace(new RegExp(exps[i].orgExp, 'g'), exps[i].newExp);
+        }
+        return exp;
+    },
     //将表达式转换为可编译的表达式
     toCompileExpr: function(v){
         if(v === ''){
@@ -670,15 +752,15 @@ let cbParser = {
             v = v.replace(new RegExp(exps[i].orgExp, 'g'), exps[i].compileExp);
         }
         //行引用
-        let fArr = this.getFArr(v);
+        let fidArr = this.getFIDArr(v);
         let fExps = [];
-        for(let i = 0, len = fArr.length; i < len; i++){
+        for(let i = 0, len = fidArr.length; i < len; i++){
             let fExp = Object.create(null);
-            fExp.orgExp = fArr[i];
+            fExp.orgExp = fidArr[i];
             fExps.push(fExp);
         }
         for(let i = 0, len = fExps.length; i < len; i++){
-            fExps[i].compileExp = '$CBC.f(\'' + fExps[i].orgExp + '\')';
+            fExps[i].compileExp = '$CBC.ref(\'' + fExps[i].orgExp + '\')';
             v = v.replace(new RegExp(fExps[i].orgExp, 'g'), fExps[i].compileExp);
         }
         return v;
@@ -693,13 +775,18 @@ let cbCalctor = {
         }
         return baseFigureTemplate[calcBase.baseFigures[figure]['base']]();
     },
-    //行引用
-    f: function (fExp) {
-        let r = cbParser.getRArr([fExp]);
-        return cbTools.isDef(calcBase.project.mainTree.items[r[0] - 1]['data']['feesIndex']) &&
-            cbTools.isDef(calcBase.project.mainTree.items[r[0] - 1]['data']['feesIndex']['common'])&&
-            cbTools.isDef(calcBase.project.mainTree.items[r[0] - 1]['data']['feesIndex']['common']['totalFee']) ?
-            calcBase.project.mainTree.items[r[0] - 1]['data']['feesIndex']['common']['totalFee'] : 0;
+    //ID引用
+    ref: function (fExp) {
+        let ID = cbParser.getXNum([fExp]);
+        if(ID.length === 1){
+            let node = cbTools.getNodeByID(calcBase.project.mainTree.items, parseInt(ID[0]));
+            return cbTools.isDef(node) &&
+                    cbTools.isDef(node.data.feesIndex) &&
+                    cbTools.isDef(node.data.feesIndex.common) &&
+                    cbTools.isDef(node.data.feesIndex.common.totalFee) ?
+                    node.data.feesIndex.common.totalFee : 0;
+        }
+        return 0;
     },
     //计算
     exec: function () {
@@ -738,7 +825,7 @@ let calcBase = {
         return cbTools.getBaseBill(node);
     },
     calculate: function (node, reCalc = null) {
-        let me = calcBase,
+            let me = calcBase,
             $CBA = cbAnalyzer,
             $CBP = cbParser,
             $CBC = cbCalctor;
@@ -754,6 +841,7 @@ let calcBase = {
             if(!cbTools.isDef(exp)){
                 throw '表达式不正确';
             }
+
             //输入式转换表达式
             let compileExp = $CBP.toCompileExpr(exp);
             //计算

+ 3 - 1
web/building_saas/main/js/views/project_view.js

@@ -306,7 +306,9 @@ var projectObj = {
                     treeNodeTools.initFeeField(node, 'common');
                     node.data.feesIndex.common.unitFee = value;
                 }
-                else node.data[fieldName] = value;
+                else if(fieldName !== 'calcBase'){
+                    node.data[fieldName] = value;
+                }
                 project.calcProgram.calcAndSave(node);
                 gljOprObj.showRationGLJSheetData();
             } else if (node.sourceType === project.Bills.getSourceType()&&fieldName === 'unit'){//修改清单单位的时候清单工程量要重新4舍5入