calc_util.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * Created by Tony on 2017/6/21.
  3. */
  4. let calcBaseCodeCollection = ["定额基价材料费", "定额基价机械费", "定额基价人工费"
  5. , "定额基价人工费(调整后)", "定额基价材料费(调整后)", "定额基价机械费(调整后)"
  6. , "市场价格人工费", "市场价格材料费", "市场价格机械费"
  7. , "定额基价机上人工费", "主材费", "设备费"
  8. ];
  9. let executeObj = {
  10. currentTpl : null,
  11. currentRationItem: null,
  12. currentFeeRateFile: null,
  13. at: function(code) {
  14. let me = executeObj,
  15. rst = 0;
  16. rst = me.currentTpl.compileAssistantObj[code].execRst;
  17. return rst;
  18. },
  19. base: function(calcBaseCode) {
  20. let me = executeObj, rst = -1,
  21. idx = 10 + calcBaseCodeCollection.indexOf(calcBaseCode);
  22. if (idx >= 0) {
  23. //
  24. } else {
  25. //
  26. }
  27. rst = idx; //暂时返回值,测试用
  28. return rst;
  29. },
  30. fee: function(feeID) {
  31. let me = executeObj, rst = -1;
  32. //
  33. //rst = parseInt(feeID); //暂时返回值,测试用
  34. rst = 0.89;
  35. return rst;
  36. },
  37. factor: function(factorCode) {
  38. let me = executeObj;
  39. //
  40. }
  41. };
  42. class calculation {
  43. init(calcTpl, calFee){
  44. let me = this;
  45. me.calcTpl = calcTpl;
  46. me.calFee = calFee;
  47. me.hasCompiled = false;
  48. };
  49. compile(){
  50. let me = this;
  51. me.hasCompiled = false;
  52. me.errs = [];
  53. let private_extract_code = function(str, idx){
  54. let rst = '', lBracket = 0, rBracket = 0, firstIdx = idx, lastIdx = 0;
  55. for (let i = idx; i < str.length; i++) {
  56. if (str[i] === '(') {
  57. lBracket++;
  58. if (lBracket == 1) firstIdx = i + 1;
  59. }
  60. if (str[i] === ')') {
  61. rBracket++;
  62. if (lBracket == rBracket) {
  63. lastIdx = i - 1;
  64. if (lastIdx > firstIdx) {
  65. if (str[firstIdx] === "'") firstIdx++;
  66. if (str[lastIdx] !== "'") lastIdx++;
  67. if (lastIdx > firstIdx) {
  68. rst = str.slice(firstIdx, lastIdx);
  69. }
  70. }
  71. break;
  72. }
  73. }
  74. }
  75. return rst;
  76. };
  77. let private_parse_ref = function(item, itemIdx){
  78. let expr = item.expression.split('at(').join('@(');
  79. item.expression = expr;
  80. //console.log('expression: ' + expr);
  81. let idx = expr.indexOf('@(', 0);
  82. while (idx >= 0) {
  83. let code = private_extract_code(expr, idx);
  84. //console.log('提取code: ' + code);
  85. if (code.length > 0) {
  86. let subItem = me.compileAssistantObj[code];
  87. if (subItem) {
  88. if (subItem.code !== item.code) {
  89. private_parse_ref(subItem, me.compileAssistantObj[code + "_idx"]);
  90. } else {
  91. me.errs.push("There exists the self refer code: " + code);
  92. }
  93. } else {
  94. me.errs.push("There exists the invalid code by which could not find the item: " + code);
  95. console.log('invalid code: ' + code);
  96. }
  97. }
  98. idx = expr.indexOf('@(', idx + code.length + 3);
  99. }
  100. if (me.calcTpl.compiledSeq.indexOf(itemIdx) < 0) {
  101. //console.log('the code ready to push: ' + item.code);
  102. me.calcTpl.compiledSeq.push(itemIdx);
  103. }
  104. };
  105. let private_setup_seq = function(item, itemIdx){
  106. if (me.calcTpl.compiledSeq.indexOf(itemIdx) < 0) {
  107. private_parse_ref(item, itemIdx);
  108. }
  109. };
  110. let private_compile_items = function() {
  111. for (let idx of me.calcTpl.compiledSeq) {
  112. let item = me.calcTpl.calcItems[idx];
  113. item.compiledExpr = item.expression.split('@(').join('$CE.at(');
  114. item.compiledExpr = item.compiledExpr.split('base(').join('$CE.base(');
  115. item.compiledExpr = item.compiledExpr.split('fee(').join('$CE.fee(');
  116. item.compiledExpr = item.compiledExpr.split('factor(').join('$CE.factor(');
  117. //console.log(item.compiledExpr);
  118. }
  119. };
  120. if (me.calcTpl && me.calcTpl.calcItems && me.calcTpl.calcItems.length > 0) {
  121. me.calcTpl.compiledSeq = [];
  122. me.compileAssistantObj = {};
  123. //1. first round -> prepare
  124. for (let i = 0; i < me.calcTpl.calcItems.length; i++) {
  125. let item = me.calcTpl.calcItems[i];
  126. me.compileAssistantObj[item.code] = item;
  127. me.compileAssistantObj[item.code + "_idx"] = i;
  128. }
  129. //2. second round -> go!
  130. for (let i = 0; i < me.calcTpl.calcItems.length; i++) {
  131. private_setup_seq(me.calcTpl.calcItems[i], i);
  132. }
  133. if (me.errs.length == 0) {
  134. private_compile_items();
  135. if (me.errs.length == 0) me.hasCompiled = true;
  136. } else {
  137. console.log('errors: ' + me.errs.toString());
  138. }
  139. }
  140. //console.log(me.compileAssistantObj);
  141. //console.log(me.calcTpl.compiledSeq);
  142. };
  143. calculate( $RATION){
  144. let me = this;
  145. if ($RATION && me.hasCompiled) {
  146. let $CE = executeObj;
  147. $CE.currentRationItem = $RATION;
  148. $CE.currentTpl = me;
  149. for (let idx of me.calcTpl.compiledSeq) {
  150. let item = me.calcTpl.calcItems[idx];
  151. item.execRst = eval(item.compiledExpr);
  152. }
  153. for (let idx of me.calcTpl.compiledSeq) {
  154. let item = me.calcTpl.calcItems[idx];
  155. console.log('code: ' + item.code + ' | expression: ' + item.compiledExpr + ' | result: ' + item.execRst);
  156. }
  157. }
  158. }
  159. }
  160. module.exports = new calculation();