chenshilong 7 years ago
parent
commit
d1b392aee8

+ 2 - 2
public/web/common_util.js

@@ -22,8 +22,8 @@ function parseFloatPlus(value){
 // 将arr2合并到arr1,并去重复。
 function mergeArr(arr1, arr2){
     if (arr2.length > 0){
-        for (let cNode of arr2){
-            if (!arr1.includes(cNode)) arr1.push(cNode);
+        for (let e of arr2){
+            if (!arr1.includes(e)) arr1.push(e);
         };
     }
 };

+ 108 - 31
web/building_saas/main/js/models/calc_program.js

@@ -563,6 +563,32 @@ let calcTools = {
         if (quantity)
             return parseFloat(quantity).toDecimal(decimalObj.glj.quantity)
         else return 0;
+    },
+    
+    getRationsByProjectGLJ(PGLJID){
+        let rationIDs = [];
+        let RGs = projectObj.project.ration_glj.datas;
+        for (let rg of RGs){
+            if (rg.projectGLJID == PGLJID){
+                rationIDs.push(rg.rationID);
+            }
+        };
+
+        let rationNodes = [];
+        let nodes = projectObj.project.mainTree.nodes;
+        for (let rID of rationIDs){
+            rationNodes.push(nodes['id_' + rID]);
+        };
+        return rationNodes;
+    },
+    getNodesByProgramID(programID){
+        let discreteNodes = [];
+        let nodes = projectObj.project.mainTree.items;
+        for (let node of nodes){
+            if (node.data.programID == programID)
+                discreteNodes.push(node);
+        };
+        return discreteNodes;
     }
 };
 
@@ -751,6 +777,22 @@ let analyzer = {
         return false;
     },
     isLegal: function (dispExpr, itemID, template) {  // 检测包括:无效字符、基数是否中括号、基数是否定义、行引用、循环计算
+
+        function testValue(expr){
+            try {
+                expr = expr.replace(/\[[\u4E00-\u9FA5]+\]/gi, '0');
+                expr = expr.replace(/@\d+/gi, '0');
+                if (expr.includes('00'))
+                    return false;
+
+                eval(expr);
+                return true;
+            }
+            catch (err) {
+                return false;
+            }
+        };
+
         let me = analyzer;
         let expr = me.standard(dispExpr);
         let invalidChars = /[^0-9\u4e00-\u9fa5\+\-\*\/\(\)\.\[\]FL%]/g;
@@ -803,7 +845,11 @@ let analyzer = {
         if (me.isCycleCalc(expression, itemID, template)){
             hintBox.infoBox('系统提示', '表达式中有循环计算!', 1);
             return false;
-        }
+        };
+        if (!testValue(expression)){
+            hintBox.infoBox('系统提示', '表达式语法错误!', 1);
+            return false;
+        };
 
         return true;  // 表达式合法
     },
@@ -1480,6 +1526,7 @@ class CalcProgram {
                     let calcItem = template.calcItems[idx];
                     $CE.tempCalcItem = calcItem;
                     let feeRate = parseFloatPlus(calcItem.feeRate) ? parseFloatPlus(calcItem.feeRate).toDecimal(decimalObj.feeRate) : 100;  // 100%
+                    // console.log(`[${calcItem.ID}]: ${calcItem.compiledExpr}`);   // for test.
                     calcItem.unitFee = (eval(calcItem.compiledExpr) * feeRate * 0.01).toDecimal(decimalObj.decimal('unitPrice', treeNode));   // 如果eval()对清单树有影响,就换成小麦的Expression对象再试
 
                     let q = calcTools.uiNodeQty(treeNode) ? calcTools.uiNodeQty(treeNode) : 0;
@@ -1545,7 +1592,7 @@ class CalcProgram {
         return changedNodes;
     };
 
-    // 计算全部公式项。 (参数意义:将通过本方法后发生改变的节点存入changedNodesArr中)
+    // 计算全部公式项。 (参数意义:将通过本方法后发生改变的节点存入changedArr中)
     calcFormulaNodes(changedArr){
         let me = this;
         let formulaNodes = cbTools.getFormulaNodes(true);
@@ -1585,40 +1632,71 @@ class CalcProgram {
         };
     };
 
-    // 计算多条零散的定额,并计算他们所属的清单、父级清单,然后打包存储。如:批量替换工料机后受影响的定额。
-    calcRationsAndSave(rationNodes, callback){
-        let me = this, leafBills = [], allChangedNodes = [];
-        for (let node of rationNodes) {
-            me.innerCalc(node, allChangedNodes);
-            let leafBill = node.parent;
-            // 多条定额同属一条叶子清单时,避免叶子清单重复计算
-            if (leafBill && leafBills.indexOf(leafBill) < 0) leafBills.push(leafBill);
+    // 计算并保存指定的一个树节点。修改一个树节点,实际上要计算和保存的是一批树结点:层层父结点、被其它结点(的公式)引用的公式结点。
+    // 这个方法实际上封装了calculate()和saveNodes()两个方法,主要目的是为了外部调用方便,少写一点累赘代码。
+    calcAndSave(treeNode, callback){
+        let changedNodes = this.calculate(treeNode);
+        this.saveNodes(changedNodes, callback);
+    };
+
+    // 计算零散的、混杂的树节点:清单、定额混合等(如:用到某一计算程序的定额和清单)。
+    // 计算多条零散的定额,并计算他们所属的清单、父清单、引用清单。如:批量替换工料机后受影响的定额。
+    // 计算多条零散的清单,并计算他们的父清单、引用清单。如:花选删除树结点(如花选清单、定额等,不区分树结点类型)。
+    calcNodesAndSave(nodes, callback){
+        let me = this, rationNodes = [], billNodes = [], leafBills = [], allChangedNodes = [];
+        for (let node of nodes) {
+            if (node.sourceType == ModuleNames.ration)
+                rationNodes.push(node)
+            else
+                billNodes.push(node);
         };
 
-        for (let node of leafBills){
-            let curChangeds = me.calculate(node);
-            mergeArr(allChangedNodes, curChangeds);
+        // 多条定额同属一条叶子清单时,避免叶子清单重复计算
+        for (let ration of rationNodes) {
+            me.innerCalc(ration, allChangedNodes);
+            let leafBill = ration.parent;
+            if (leafBill && leafBills.indexOf(leafBill) < 0)
+                leafBills.push(leafBill);
         };
-        let endShowTime = +new Date();
-        me.saveNodes(allChangedNodes, callback);
-    };
 
-    // 计算多条零散的清单,并计算他们的父清单、引用清单,然后打包存储。如:花选删除树结点(如花选清单、定额等,不区分树结点类型)。
-    calcBillsAndSave(billNodes,callback){
-        let me = this, allChangedNodes = [];
-        for (let node of billNodes) {
-            let curChangeds = me.calculate(node, true, false);
-            mergeArr(allChangedNodes, curChangeds);
+        mergeArr(billNodes, leafBills);
+
+        for (let bill of billNodes){
+            let changeBills = me.calculate(bill, true, false);
+            mergeArr(allChangedNodes, changeBills);
         };
+
         me.calcFormulaNodes(allChangedNodes);
-        me.saveNodes(allChangedNodes,callback);
+        me.saveNodes(allChangedNodes, callback);
     };
-
-    // 计算并保存指定的一个树节点。修改一个树节点,实际上要计算和保存的是一批树结点:层层父结点、被其它结点(的公式)引用的公式结点。
-    // 这个方法实际上封装了calculate()和saveNodes()两个方法,主要目的是为了外部调用方便,少写一点累赘代码。
-    calcAndSave(treeNode, callback){
-        let changedNodes = this.calculate(treeNode);
-        this.saveNodes(changedNodes, callback);
+    calcRationsAndSave(rationNodes, callback){
+        // let me = this, leafBills = [], allChangedNodes = [];
+        // for (let node of rationNodes) {
+        //     me.innerCalc(node, allChangedNodes);
+        //     let leafBill = node.parent;
+        //     // 多条定额同属一条叶子清单时,避免叶子清单重复计算
+        //     if (leafBill && leafBills.indexOf(leafBill) < 0) leafBills.push(leafBill);
+        // };
+        //
+        // for (let node of leafBills){
+        //     let curChangeds = me.calculate(node);
+        //     mergeArr(allChangedNodes, curChangeds);
+        // };
+        // let endShowTime = +new Date();
+        // me.saveNodes(allChangedNodes, callback);
+
+        this.calcNodesAndSave(rationNodes, callback);
+    };
+    calcBillsAndSave(billNodes,callback){
+        // let me = this, allChangedNodes = [];
+        // for (let node of billNodes) {
+        //     let curChangeds = me.calculate(node, true, false);
+        //     mergeArr(allChangedNodes, curChangeds);
+        // };
+        // me.calcFormulaNodes(allChangedNodes);
+        // me.saveNodes(allChangedNodes,callback);
+
+        this.calcNodesAndSave(billNodes, callback);
     };
 
     calcAllNodesAndSave(calcType = calcAllType.catAll, callback){
@@ -1626,8 +1704,7 @@ class CalcProgram {
         this.saveNodes(changedNodes, callback);
     };
 
-    // 排除指定项的综合合价计算(用于带循环计算的情况)。
-    // 这里的汇总只到清单级别即可(清单单价取费时,汇总到清单和汇总到定额两个值不一样)
+    // 排除指定项的综合合价计算(用于带循环计算的情况。这里的汇总只到清单级别即可:清单单价取费时,汇总到清单和汇总到定额两个值不一样)
     getTotalFee(baseNodes, excludeNodes){
         let rst = 0;
         function calcNodes(nodes) {

+ 2 - 1
web/building_saas/main/js/views/calc_base_view.js

@@ -300,7 +300,8 @@ let calcBaseView = {
                         calcProgramManage.saveCalcItem(data, function (rst) {
                             if (rst){
                                 cp.compileTemplate(template);
-                                cp.calcAllNodesAndSave();
+                                let relationNodes = calcTools.getNodesByProgramID(template.ID);
+                                cp.calcNodesAndSave(relationNodes);
                                 calcProgramManage.refreshDetailSheet();
                                 $('#qd-jsjs').modal('hide');
                                 $.bootstrapLoading.end();

+ 9 - 5
web/building_saas/main/js/views/calc_program_manage.js

@@ -109,13 +109,13 @@ let calcProgramManage = {
             return;
         }
 
+        let template = me.getSelectionInfo().template;
         if (dataCode == 'displayFieldName') {
             if (curCalcItem.displayFieldName == args.newValue) {
                 $.bootstrapLoading.end();
                 return;
             }
 
-            let template = me.getSelectionInfo().template;
             if (analyzer.fieldNameIsUsed(template, args.newValue)){
                 let sheet = me.detailSpread.getActiveSheet();
                 sheet.suspendEvent();
@@ -137,17 +137,19 @@ let calcProgramManage = {
         curCalcItem[dataCode] = args.newValue;
         let data = {
             'projectID': projectObj.project.ID(),
-            'templatesID': editInfo.template.ID,
+            'templatesID': template.ID,
             'calcItem': curCalcItem
         };
         me.saveCalcItem(data, function (rst) {
             if (rst){
-                projectObj.project.calcProgram.calcAllNodesAndSave();
+                let relationNodes = calcTools.getNodesByProgramID(template.ID);
+                projectObj.project.calcProgram.calcNodesAndSave(relationNodes);
             }
         });
         $.bootstrapLoading.end();
     },
     onDetailEnterCell: function (sender, args) {
+        // for test.
         // let t = calcProgramManage.getSelectionInfo().template;
         // let c = calcProgramManage.getSelectionInfo().calcItem;
         // let lc = analyzer.calcItemLabourCoe(c);
@@ -317,7 +319,8 @@ let calcProgramManage = {
                                 projectObj.project.calcProgram.compileTemplate(template);
                                 calcProgramManage.refreshDetailSheet();
                                 calcProgramManage.detailSpread.getActiveSheet().setSelection(idx + 1, 0, 1, 1);
-                                projectObj.project.calcProgram.calcAllNodesAndSave();
+                                let relationNodes = calcTools.getNodesByProgramID(template.ID);
+                                projectObj.project.calcProgram.calcNodesAndSave(relationNodes);
                             }
                         });
                         $.bootstrapLoading.end();
@@ -357,7 +360,8 @@ let calcProgramManage = {
                             if (rst){
                                 projectObj.project.calcProgram.compileTemplate(template);
                                 calcProgramManage.refreshDetailSheet();
-                                projectObj.project.calcProgram.calcAllNodesAndSave();
+                                let relationNodes = calcTools.getNodesByProgramID(template.ID);
+                                projectObj.project.calcProgram.calcNodesAndSave(relationNodes);
                             }
                         });
                         $.bootstrapLoading.end();

+ 8 - 1
web/building_saas/main/js/views/project_glj_view.js

@@ -400,6 +400,13 @@ projectGljObject={
             }
             info.sheet.resumeEvent();
             info.sheet.resumePaint();
+
+            if (dataCode === 'supply' || dataCode === 'supply_quantity'){
+                let rations = calcTools.getRationsByProjectGLJ(recode.id);
+                projectObj.project.calcProgram.calcRationsAndSave(rations, function () {
+                    projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
+                });
+            }
         };
         if(dataCode=='basePrice'||dataCode=='marketPrice'){
             value= scMathUtil.roundForObj(value,getDecimal('glj.unitPrice'));//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。
@@ -425,7 +432,7 @@ projectGljObject={
             extend = Object.keys(extend).length > 0 ?  JSON.stringify(extend) : '';
             let updateData = {id: recode.id, field: dataCode, value: value, extend: extend};
             projectGLJ.pGljUpdate(updateData,callback);
-        }
+        };
     },
     getSupplyQuantity : function(supplyType, quantity) {
         // 自行采购和甲定乙供则把甲供数量设置为0,其余情况则设置为当前总消耗量