/** * Created by Tony on 2017/6/21. */ let calcBaseCodeCollection = ["定额基价人工费", "定额基价材料费", "定额基价机械费" , "定额基价人工费(调整后)", "定额基价材料费(调整后)", "定额基价机械费(调整后)" , "市场价格人工费", "市场价格材料费", "市场价格机械费" , "定额基价机上人工费", "主材费", "设备费" ]; let dummyCalcBaseCodeTypeCollection = [[2], [6], [64] , [], [], [] , [], [], [] , [], [], [] ]; let executeObj = { currentTpl : null, currentRationItem: null, currentFeeRateFile: null, at: function(code) { let me = executeObj, rst = 0; rst = me.currentTpl.compileAssistantObj[code].execRst; return rst; }, base: function(calcBaseCode) { let me = executeObj, rst = 0, idx = calcBaseCodeCollection.indexOf(calcBaseCode); if (idx >= 0) { if (dummyCalcBaseCodeTypeCollection[idx].length > 0) { let tmpSum = 0; for (let glj of me.currentRationItem.rationGljList) { if (dummyCalcBaseCodeTypeCollection[idx].indexOf(glj["glj"]["gljType"]) >= 0) { tmpSum += glj["glj"]["basePrice"] * glj["consumeAmt"]; } } rst = tmpSum; } else { //rst = 10 + idx; //随便给个数 } } //rst = idx; //暂时返回值,测试用 return rst; }, fee: function(feeID) { let me = executeObj, rst = 0; /* for (let fee of me.currentFeeRateFile) { if (fee.ID == feeID) { rst = fee.rate; break; } } /*/ if (me.compiledFeeRateFile["fee_" + feeID]) rst = me.compiledFeeRateFile["fee_" + feeID].rate; //*/ return rst; }, factor: function(factorCode) { let me = executeObj; let rst = 0.89; //暂时固定输出,测试用 return rst; } }; class calculation { init(calcTpl, calFee){ let me = this; me.calcTpl = calcTpl; me.calFee = calFee; me.hasCompiled = false; }; compile(){ let me = this; me.hasCompiled = false; me.errs = []; let private_extract_code = function(str, idx){ let rst = '', lBracket = 0, rBracket = 0, firstIdx = idx, lastIdx = 0; for (let i = idx; i < str.length; i++) { if (str[i] === '(') { lBracket++; if (lBracket == 1) firstIdx = i + 1; } if (str[i] === ')') { rBracket++; if (lBracket == rBracket) { lastIdx = i - 1; if (lastIdx > firstIdx) { if (str[firstIdx] === "'") firstIdx++; if (str[lastIdx] !== "'") lastIdx++; if (lastIdx > firstIdx) { rst = str.slice(firstIdx, lastIdx); } } break; } } } return rst; }; let private_parse_ref = function(item, itemIdx){ let expr = item.expression.split('at(').join('@('); item.expression = expr; //console.log('expression: ' + expr); let idx = expr.indexOf('@(', 0); while (idx >= 0) { let code = private_extract_code(expr, idx); //console.log('提取code: ' + code); if (code.length > 0) { let subItem = me.compileAssistantObj[code]; if (subItem) { if (subItem.code !== item.code) { private_parse_ref(subItem, me.compileAssistantObj[code + "_idx"]); } else { me.errs.push("There exists the self refer code: " + code); } } else { me.errs.push("There exists the invalid code by which could not find the item: " + code); console.log('invalid code: ' + code); } } idx = expr.indexOf('@(', idx + code.length + 3); } if (me.calcTpl.compiledSeq.indexOf(itemIdx) < 0) { //console.log('the code ready to push: ' + item.code); me.calcTpl.compiledSeq.push(itemIdx); } }; let private_setup_seq = function(item, itemIdx){ if (me.calcTpl.compiledSeq.indexOf(itemIdx) < 0) { private_parse_ref(item, itemIdx); } }; let private_compile_items = function() { for (let idx of me.calcTpl.compiledSeq) { let item = me.calcTpl.calcItems[idx]; item.compiledExpr = item.expression.split('@(').join('$CE.at('); item.compiledExpr = item.compiledExpr.split('base(').join('$CE.base('); item.compiledExpr = item.compiledExpr.split('fee(').join('$CE.fee('); item.compiledExpr = item.compiledExpr.split('factor(').join('$CE.factor('); //console.log(item.compiledExpr); } }; let private_comile_feeFile = function() { if (me.calFee) { me.compiledFee = {}; for (let fee of me.calFee) { me.compiledFee["fee_" + fee.ID] = fee; } } }; if (me.calcTpl && me.calcTpl.calcItems && me.calcTpl.calcItems.length > 0) { me.calcTpl.compiledSeq = []; me.compileAssistantObj = {}; //1. first round -> prepare private_comile_feeFile(); for (let i = 0; i < me.calcTpl.calcItems.length; i++) { let item = me.calcTpl.calcItems[i]; me.compileAssistantObj[item.code] = item; me.compileAssistantObj[item.code + "_idx"] = i; } //2. second round -> go! for (let i = 0; i < me.calcTpl.calcItems.length; i++) { private_setup_seq(me.calcTpl.calcItems[i], i); } if (me.errs.length == 0) { private_compile_items(); if (me.errs.length == 0) me.hasCompiled = true; } else { console.log('errors: ' + me.errs.toString()); } } //console.log(me.compileAssistantObj); //console.log(me.calcTpl.compiledSeq); }; calculate( $RATION){ let me = this; if ($RATION && me.hasCompiled) { let $CE = executeObj; $CE.currentRationItem = $RATION; $CE.currentTpl = me; $CE.currentFeeRateFile = me.calFee; $CE.compiledFeeRateFile = me.compiledFee; for (let idx of me.calcTpl.compiledSeq) { let item = me.calcTpl.calcItems[idx]; item.execRst = eval(item.compiledExpr); } } } } module.exports = new calculation();