|
@@ -6,7 +6,8 @@
|
|
|
* 用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
|
|
|
*/
|
|
|
|
|
|
-/*let defaultBillTemplate = {
|
|
|
+/* 新版GLD 取消了默认清单模板,所以这里废弃。先留着,预防不时之需。
|
|
|
+let defaultBillTemplate = {
|
|
|
ID: 15,
|
|
|
name: "清单公式",
|
|
|
calcItems: [
|
|
@@ -430,26 +431,74 @@ let treeNodeTools = {
|
|
|
return nodes;
|
|
|
},
|
|
|
|
|
|
- isRation: function(treeNode){
|
|
|
- return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
|
|
|
+ isBill: function(treeNode){
|
|
|
+ return treeNode.sourceType === ModuleNames.bills;
|
|
|
},
|
|
|
-
|
|
|
isLeafBill: function(treeNode){
|
|
|
- return treeNode.sourceType === projectObj.project.Bills.getSourceType() &&
|
|
|
+ return treeNode.sourceType === ModuleNames.bills &&
|
|
|
treeNode.source.children &&
|
|
|
treeNode.source.children.length === 0;
|
|
|
},
|
|
|
-
|
|
|
isNullBill: function (treeNode) {
|
|
|
return this.isLeafBill(treeNode) && (treeNode.children.length === 0) && (!treeNode.data.calcBase);
|
|
|
},
|
|
|
|
|
|
+ isRationCategory: function(treeNode){
|
|
|
+ return treeNode.sourceType === ModuleNames.ration;
|
|
|
+ },
|
|
|
+ isRation: function(treeNode){
|
|
|
+ return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.ration;
|
|
|
+ },
|
|
|
isVolumePrice: function (treeNode) {
|
|
|
return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.volumePrice;
|
|
|
},
|
|
|
-
|
|
|
isGljRation: function (treeNode) {
|
|
|
return treeNode.sourceType === ModuleNames.ration && treeNode.data.type === rationType.gljRation;
|
|
|
+ },
|
|
|
+
|
|
|
+ initFeeField(treeNode, fieldName){
|
|
|
+ if (!treeNode.data.fees) {
|
|
|
+ treeNode.data.fees = [];
|
|
|
+ treeNode.data.feesIndex = {};
|
|
|
+ };
|
|
|
+ if (!treeNode.data.feesIndex[fieldName]) {
|
|
|
+ let fee = {
|
|
|
+ 'fieldName': fieldName,
|
|
|
+ 'unitFee': 0,
|
|
|
+ 'totalFee': 0,
|
|
|
+ 'tenderUnitFee': 0,
|
|
|
+ 'tenderTotalFee': 0
|
|
|
+ };
|
|
|
+ treeNode.data.fees.push(fee);
|
|
|
+ treeNode.data.feesIndex[fieldName] = fee;
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ getCalcType(treeNode) {
|
|
|
+ if (this.isRationCategory(treeNode)){
|
|
|
+ return treeNodeCalcType.ctRationCalcProgram;
|
|
|
+ }
|
|
|
+ else if (this.isNullBill(treeNode)){
|
|
|
+ return treeNodeCalcType.ctCommonUnitFee;
|
|
|
+ }
|
|
|
+ else if (this.isLeafBill(treeNode)) {
|
|
|
+ if (treeNode.children && treeNode.children.length > 0){
|
|
|
+ // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
|
|
|
+ if (projectObj.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
|
|
|
+ return treeNodeCalcType.ctBillCalcProgram;
|
|
|
+ else // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
|
|
|
+ return treeNodeCalcType.ctGatherRationsFees;
|
|
|
+ }
|
|
|
+ else{ // 公式计算
|
|
|
+ return treeNodeCalcType.ctCalcBaseValue;
|
|
|
+ };
|
|
|
+ }
|
|
|
+ else if (this.isBill(treeNode)) { // 父清单:汇总子清单的费用类别
|
|
|
+ return treeNodeCalcType.ctGatherBillsFees;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ return treeNodeCalcType.ctRationCalcProgram;
|
|
|
+ };
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -461,15 +510,18 @@ class CalcProgram {
|
|
|
project.registerModule(ModuleNames.calc_program, me);
|
|
|
};
|
|
|
|
|
|
+ // 兼容Project框架方法
|
|
|
getSourceType () {
|
|
|
return ModuleNames.calc_program;
|
|
|
};
|
|
|
|
|
|
+ // 兼容Project框架方法
|
|
|
loadData (datas) {
|
|
|
this.datas = datas;
|
|
|
this.compileAllTemps();
|
|
|
};
|
|
|
|
|
|
+ // 兼容Project框架方法
|
|
|
doAfterUpdate (err, data) {
|
|
|
if(!err){
|
|
|
$.bootstrapLoading.end();
|
|
@@ -648,28 +700,62 @@ class CalcProgram {
|
|
|
};
|
|
|
};
|
|
|
|
|
|
- initFeeField(treeNode, fieldName){
|
|
|
- if (!treeNode.data.fees) {
|
|
|
- treeNode.data.fees = [];
|
|
|
- treeNode.data.feesIndex = {};
|
|
|
+ // 存储、刷新零散的多个结点。
|
|
|
+ saveNodes(treeNodes){
|
|
|
+ if (treeNodes.length < 1) return;
|
|
|
+
|
|
|
+ let me = this;
|
|
|
+
|
|
|
+ me.project.beginUpdate('');
|
|
|
+ for (let node of treeNodes){
|
|
|
+ if (node.changed){
|
|
|
+ let data = {
|
|
|
+ ID: node.data.ID,
|
|
|
+ projectID: me.project.ID(),
|
|
|
+ /* subType、quantity、calcBase、programID、marketUnitFee等等字段较为特殊,它们的改变一定会触发计算并导致计算
|
|
|
+ 结果的变化,从而引发保存动作。将这些字段放在该位置跟计算结果一起保存,可减少前端跟后端的通讯频率。 */
|
|
|
+ subType: node.data.subType,
|
|
|
+ quantity: node.data.quantity,
|
|
|
+ calcBase: node.data.calcBase,
|
|
|
+ calcBaseValue: node.data.calcBaseValue,
|
|
|
+ programID: node.data.programID,
|
|
|
+ marketUnitFee: node.data.marketUnitFee,
|
|
|
+ marketTotalFee: node.data.marketTotalFee,
|
|
|
+ fees: node.data.fees,
|
|
|
+ isFromDetail:node.data.isFromDetail,
|
|
|
+ feeRate: node.data.feeRate,
|
|
|
+ feeRateID: node.data.feeRateID,
|
|
|
+ contain:node.data.contain,
|
|
|
+ quantityEXP:node.data.quantityEXP
|
|
|
+ };
|
|
|
+ if(node.sourceType==ModuleNames.ration && node.data.type==rationType.gljRation){//定额类型的工料机做特殊处理
|
|
|
+ data.code=node.data.code;
|
|
|
+ data.projectGLJID = node.data.projectGLJID;
|
|
|
+ delete data.marketUnitFee;
|
|
|
+ }
|
|
|
+
|
|
|
+ let newData = {'updateType': 'ut_update', 'updateData': data};
|
|
|
+ me.project.push(node.sourceType, [newData]);
|
|
|
+ }
|
|
|
};
|
|
|
- if (!treeNode.data.feesIndex[fieldName]) {
|
|
|
- let fee = {
|
|
|
- 'fieldName': fieldName,
|
|
|
- 'unitFee': 0,
|
|
|
- 'totalFee': 0,
|
|
|
- 'tenderUnitFee': 0,
|
|
|
- 'tenderTotalFee': 0
|
|
|
- };
|
|
|
- treeNode.data.fees.push(fee);
|
|
|
- treeNode.data.feesIndex[fieldName] = fee;
|
|
|
+ me.project.endUpdate();
|
|
|
+
|
|
|
+ for (let node of treeNodes){delete node.changed};
|
|
|
+ projectObj.mainController.refreshTreeNode(treeNodes);
|
|
|
+
|
|
|
+ if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
|
|
|
+ calcProgramObj.showData(me.project.mainTree.selected, false);
|
|
|
};
|
|
|
};
|
|
|
|
|
|
- // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
|
|
|
- InnerCalc(treeNode){
|
|
|
+ // 只计算treeNode自身。changedArr: 外部传来的一个数组,专门存储发生变动的节点。
|
|
|
+ innerCalc(treeNode, changedArr){
|
|
|
let me = this;
|
|
|
- let project = me.project;
|
|
|
+ // 仅用作树节点显示的工料机不能参与计算。
|
|
|
+ if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return;
|
|
|
+
|
|
|
+ treeNode.calcType = treeNodeTools.getCalcType(treeNode);
|
|
|
+ // if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue) return;
|
|
|
|
|
|
function initFees(treeNode){
|
|
|
if (!treeNode.data.fees) {
|
|
@@ -711,12 +797,13 @@ class CalcProgram {
|
|
|
return ['labour', 'material', 'machine', 'mainMaterial', 'equipment'].indexOf(type) > -1;
|
|
|
};
|
|
|
|
|
|
- // 汇总定额或子清单的费用类别
|
|
|
- if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees || treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
|
|
|
+ // 父清单汇总子项(定额或子清单)的费用类别
|
|
|
+ if (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees ||
|
|
|
+ treeNode.calcType == treeNodeCalcType.ctGatherBillsFees){
|
|
|
treeNode.data.programID = null;
|
|
|
initFees(treeNode);
|
|
|
|
|
|
- let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? project.Ration.getRationsByNode(treeNode) : treeNode.children;
|
|
|
+ let objsArr = (treeNode.calcType == treeNodeCalcType.ctGatherRationsFees) ? me.project.Ration.getRationsByNode(treeNode) : treeNode.children;
|
|
|
let rst = [];
|
|
|
for (let ft of cpFeeTypes) {
|
|
|
let ftObj = {};
|
|
@@ -798,7 +885,7 @@ class CalcProgram {
|
|
|
|
|
|
delete treeNode.data.fees; // 直接删掉再新增,不用一个个费判断更新,效率更高。
|
|
|
delete treeNode.data.feesIndex;
|
|
|
- me.initFeeField(treeNode, 'common');
|
|
|
+ treeNodeTools.initFeeField(treeNode, 'common');
|
|
|
treeNode.data.feesIndex.common.unitFee = uf.toDecimal(decimalObj.bills.unitPrice);
|
|
|
treeNode.data.feesIndex.common.totalFee = tf.toDecimal(decimalObj.bills.totalPrice);
|
|
|
treeNode.data.feesIndex.common.tenderUnitFee = tuf.toDecimal(decimalObj.bills.unitPrice);
|
|
@@ -806,13 +893,12 @@ class CalcProgram {
|
|
|
treeNode.changed = true;
|
|
|
treeNode.data.calcTemplate = {"calcItems": []};
|
|
|
}
|
|
|
- // 叶子清单的计算基数计算
|
|
|
+ // 叶子清单公式计算
|
|
|
else if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
|
|
|
delete treeNode.data.gljList;
|
|
|
if (treeNode.data.programID) treeNode.data.programID = null;
|
|
|
|
|
|
let f = treeNode.data.feeRate ? treeNode.data.feeRate : 100;
|
|
|
- // let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
|
|
|
if (!treeNode.data.quantity) treeNode.data.quantity = 1;
|
|
|
let q = treeNode.data.quantity;
|
|
|
let b = treeNode.data.calcBaseValue ? treeNode.data.calcBaseValue : 0;
|
|
@@ -823,7 +909,7 @@ class CalcProgram {
|
|
|
|
|
|
delete treeNode.data.fees; // 直接删掉再新增,不用一个个费判断更新,效率更高。
|
|
|
delete treeNode.data.feesIndex;
|
|
|
- me.initFeeField(treeNode, 'common');
|
|
|
+ treeNodeTools.initFeeField(treeNode, 'common');
|
|
|
treeNode.data.feesIndex.common.unitFee = uf;
|
|
|
treeNode.data.feesIndex.common.totalFee = tf;
|
|
|
treeNode.data.feesIndex.common.tenderUnitFee = tuf;
|
|
@@ -831,7 +917,7 @@ class CalcProgram {
|
|
|
treeNode.changed = true;
|
|
|
treeNode.data.calcTemplate = {"calcItems": []};
|
|
|
}
|
|
|
- // 定额或清单自己的计算程序计算
|
|
|
+ // 定额或叶子清单自己的计算程序计算
|
|
|
else{
|
|
|
if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
|
|
|
if (treeNode.data.type == rationType.volumePrice){
|
|
@@ -852,10 +938,9 @@ class CalcProgram {
|
|
|
};
|
|
|
}
|
|
|
else if (treeNode.calcType == treeNodeCalcType.ctBillCalcProgram) {
|
|
|
- let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
|
|
|
- treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
|
|
|
+ let rations = me.project.Ration.getBillsSortRation(treeNode.source.getID());
|
|
|
+ treeNode.data.gljList = me.project.ration_glj.getGatherGljArrByRations(rations);
|
|
|
|
|
|
- // if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
|
|
|
if (treeNode.data.programID == undefined){
|
|
|
treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
|
|
|
}
|
|
@@ -889,104 +974,32 @@ class CalcProgram {
|
|
|
};
|
|
|
}
|
|
|
};
|
|
|
- };
|
|
|
-
|
|
|
- // 计算本节点(默认同时递归计算所有父节点,可选)
|
|
|
- calculate(treeNode, calcParents = true){
|
|
|
- let me = this;
|
|
|
- if (treeNode.sourceType === me.project.ration_glj.getSourceType()) return; // 仅用作树节点显示的工料机不能参与计算。
|
|
|
- let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
|
|
|
- let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
|
|
|
|
|
|
- if (isRation){
|
|
|
- treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
|
|
|
- }
|
|
|
- else if (treeNodeTools.isNullBill(treeNode)){
|
|
|
- treeNode.calcType = treeNodeCalcType.ctCommonUnitFee;
|
|
|
- }
|
|
|
- else if (treeNodeTools.isLeafBill(treeNode)) {
|
|
|
- if (treeNode.children && treeNode.children.length > 0){
|
|
|
- // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
|
|
|
- if (me.project.property.billsCalcMode === leafBillGetFeeType.billsPrice)
|
|
|
- treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
|
|
|
- else // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
|
|
|
- treeNode.calcType = treeNodeCalcType.ctGatherRationsFees;
|
|
|
- }
|
|
|
- else{ // 公式计算
|
|
|
- treeNode.calcType = treeNodeCalcType.ctCalcBaseValue;
|
|
|
- };
|
|
|
- }
|
|
|
- else if (isBill) // 父清单:汇总子清单的费用类别
|
|
|
- treeNode.calcType = treeNodeCalcType.ctGatherBillsFees;
|
|
|
-
|
|
|
- me.InnerCalc(treeNode);
|
|
|
-
|
|
|
- // 计算所有父结点
|
|
|
- if (treeNode.changed && calcParents && treeNode.parent) {
|
|
|
- me.calculate(treeNode.parent);
|
|
|
- };
|
|
|
+ if (treeNode.changed && !changedArr.includes(treeNode)) changedArr.push(treeNode);
|
|
|
};
|
|
|
|
|
|
- // 存储、刷新本节点(默认存储刷新所有父节点,可选)
|
|
|
- saveNode(treeNode, saveParents = true) {
|
|
|
- if (!treeNode.changed) return;
|
|
|
+ // 计算本节点、所有父节点(默认,可选)、公式引用节点。
|
|
|
+ calculate(treeNode, calcParents = true){
|
|
|
let me = this;
|
|
|
- let nodesArr = [];
|
|
|
- let curNode = treeNode;
|
|
|
- while (curNode) {
|
|
|
- if (curNode.changed){nodesArr.push(curNode)};
|
|
|
- if (saveParents) curNode = curNode.parent
|
|
|
- else break;
|
|
|
- };
|
|
|
- me.saveNodes(nodesArr);
|
|
|
- };
|
|
|
-
|
|
|
- // 存储、刷新零散的多个树结点
|
|
|
- saveNodes(treeNodes){
|
|
|
- if (treeNodes.length < 1) return;
|
|
|
+ let changedNodes = [];
|
|
|
|
|
|
- let me = this;
|
|
|
+ me.innerCalc(treeNode, changedNodes);
|
|
|
|
|
|
- me.project.beginUpdate('');
|
|
|
- for (let node of treeNodes){
|
|
|
- if (node.changed){
|
|
|
- let data = {
|
|
|
- ID: node.data.ID,
|
|
|
- projectID: me.project.ID(),
|
|
|
- /* subType、quantity、calcBase、programID、marketUnitFee等等字段较为特殊,它们的改变一定会触发计算并导致计算
|
|
|
- 结果的变化,从而引发保存动作。将这些字段放在该位置跟计算结果一起保存,可减少前端跟后端的通讯频率。 */
|
|
|
- subType: node.data.subType,
|
|
|
- quantity: node.data.quantity,
|
|
|
- calcBase: node.data.calcBase,
|
|
|
- calcBaseValue: node.data.calcBaseValue,
|
|
|
- programID: node.data.programID,
|
|
|
- marketUnitFee: node.data.marketUnitFee,
|
|
|
- marketTotalFee: node.data.marketTotalFee,
|
|
|
- fees: node.data.fees,
|
|
|
- isFromDetail:node.data.isFromDetail,
|
|
|
- feeRate: node.data.feeRate,
|
|
|
- feeRateID: node.data.feeRateID,
|
|
|
- contain:node.data.contain,
|
|
|
- quantityEXP:node.data.quantityEXP
|
|
|
+ if (treeNode.changed) {
|
|
|
+ // 计算父结点
|
|
|
+ if (calcParents){
|
|
|
+ let curNode = treeNode.parent;
|
|
|
+ while (curNode){
|
|
|
+ me.innerCalc(curNode, changedNodes);
|
|
|
+ curNode = curNode.parent;
|
|
|
};
|
|
|
- if(node.sourceType==ModuleNames.ration && node.data.type==rationType.gljRation){//定额类型的工料机做特殊处理
|
|
|
- data.code=node.data.code;
|
|
|
- data.projectGLJID = node.data.projectGLJID;
|
|
|
- delete data.marketUnitFee;
|
|
|
- }
|
|
|
+ };
|
|
|
|
|
|
- let newData = {'updateType': 'ut_update', 'updateData': data};
|
|
|
- me.project.push(node.sourceType, [newData]);
|
|
|
- }
|
|
|
+ // 父结点算完,再计算所有的公式结点(必须先算完父结点,再算公式结点)
|
|
|
+ me.calcFormulaNodes(changedNodes);
|
|
|
};
|
|
|
- me.project.endUpdate();
|
|
|
-
|
|
|
- for (let node of treeNodes){delete node.changed};
|
|
|
- projectObj.mainController.refreshTreeNode(treeNodes);
|
|
|
|
|
|
- if (activeSubSheetIs(subSheetIndex.ssiCalcProgram)) {
|
|
|
- calcProgramObj.showData(me.project.mainTree.selected, false);
|
|
|
- };
|
|
|
+ return changedNodes;
|
|
|
};
|
|
|
|
|
|
/* 计算所有树结点(分3种情况),并返回发生变动的零散的多个树结点。
|
|
@@ -1016,20 +1029,30 @@ class CalcProgram {
|
|
|
return changedNodes;
|
|
|
};
|
|
|
|
|
|
- // 计算全部公式项
|
|
|
- calcFormulaNodes(){
|
|
|
- let nodes = treeNodeTools.getFormulaNodes();
|
|
|
- if (nodes.length == 0) return;
|
|
|
- for (let node of nodes){
|
|
|
- this.calcFormulaNode(node);
|
|
|
+ // 计算全部公式项。 (参数意义:将通过本方法后发生改变的节点存入changedNodesArr中)
|
|
|
+ calcFormulaNodes(changedArr){
|
|
|
+ let me = this;
|
|
|
+ let formulaNodes = treeNodeTools.getFormulaNodes();
|
|
|
+ if (formulaNodes.length == 0) return;
|
|
|
+ for (let formulaNode of formulaNodes){
|
|
|
+ formulaNode.data.userCalcBase = formulaNode.data.calcBase; // 这句不该出现,projectObj.project.calcBase中要改进。
|
|
|
+ projectObj.project.calcBase.calculate(formulaNode, true);
|
|
|
+ if (projectObj.project.calcBase.success){
|
|
|
+ // 计算公式结点
|
|
|
+ me.innerCalc(formulaNode, changedArr);
|
|
|
+
|
|
|
+ // 计算父结点
|
|
|
+ if (formulaNode.changed){
|
|
|
+ let curNode = formulaNode.parent;
|
|
|
+ while (curNode){
|
|
|
+ me.innerCalc(curNode, changedArr);
|
|
|
+ curNode = curNode.parent;
|
|
|
+ };
|
|
|
+ };
|
|
|
+ };
|
|
|
};
|
|
|
};
|
|
|
|
|
|
- // 计算公式项。(它一定是叶子结点,它的父结点一定没有公式)
|
|
|
- calcFormulaNode(treeNode){
|
|
|
- // do
|
|
|
- };
|
|
|
-
|
|
|
// 计算叶子清单下的所有子结点(如定额、量价、工料机定额等), 并计算自身和所有父结点。最后打包存储。
|
|
|
calcLeafAndSave(treeNode){
|
|
|
let me = this;
|
|
@@ -1056,22 +1079,24 @@ class CalcProgram {
|
|
|
calcRationsAndSave(rationNodes){
|
|
|
let me = this, leafBills = [], changedNodes = [];
|
|
|
for (let node of rationNodes) {
|
|
|
- me.calculate(node, false);
|
|
|
- if (node.changed) changedNodes.push(node);
|
|
|
+ me.innerCalc(node, changedNodes);
|
|
|
let leafBill = node.parent;
|
|
|
- if (leafBill && leafBills.indexOf(leafBill) < 0) leafBills.push(leafBill); // 多条定额同属一条叶子清单时,避免叶子清单重复计算
|
|
|
+ // 多条定额同属一条叶子清单时,避免叶子清单重复计算
|
|
|
+ if (leafBill && leafBills.indexOf(leafBill) < 0) leafBills.push(leafBill);
|
|
|
};
|
|
|
|
|
|
for (let node of leafBills){
|
|
|
me.calculate(node);
|
|
|
- let cur = node;
|
|
|
- while (cur) {
|
|
|
- if (cur.changed && changedNodes.indexOf(cur) < 0) changedNodes.push(cur);
|
|
|
- cur = cur.parent;
|
|
|
- };
|
|
|
};
|
|
|
|
|
|
me.saveNodes(changedNodes);
|
|
|
};
|
|
|
|
|
|
+ // 计算并保存指定的一个树节点。修改一个树节点,实际上要计算和保存的是一批树结点:层层父结点、被其它结点(的公式)引用的公式结点。
|
|
|
+ // 这个方法实际上封装了calculate()和saveNodes()两个方法,主要目的是为了外部调用方便,少写一点累赘代码。
|
|
|
+ calcAndSave(treeNode){
|
|
|
+ let changedNodes = this.calculate(treeNode);
|
|
|
+ this.saveNodes(changedNodes);
|
|
|
+ };
|
|
|
+
|
|
|
}
|