common_util.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Zhong
  6. * @date 2019/11/12
  7. * @version
  8. */
  9. ((factory) => {
  10. if (typeof module !== 'undefined') {
  11. module.exports = factory();
  12. } else {
  13. window.commonUtil = factory();
  14. }
  15. })(() => {
  16. function isDef(val) {
  17. return typeof val !== 'undefined' && val !== null;
  18. }
  19. function isEmptyVal(val) {
  20. return val === null || val === undefined || val === '';
  21. }
  22. // 将树数据排序好
  23. function getSortedTreeData(rootID, items) {
  24. return sortSameDedth(rootID, items).reverse();
  25. function sortSameDedth(parentID, items) {
  26. const sameDepthItems = items.filter(item => item.ParentID === parentID);
  27. if (!sameDepthItems.length) {
  28. return [];
  29. }
  30. const NextIDMapping = {};
  31. sameDepthItems.forEach(item => NextIDMapping[item.NextSiblingID] = item);
  32. let curItem = sameDepthItems.length > 1 ? sameDepthItems.find(item => item.NextSiblingID === -1) : sameDepthItems[0];
  33. const sorted = [];
  34. while (curItem) {
  35. sorted.push(...sortSameDedth(curItem.ID, items));
  36. sorted.push(curItem);
  37. curItem = NextIDMapping[curItem.ID] || null;
  38. }
  39. return sorted;
  40. }
  41. }
  42. function standar(exp) {
  43. //去空格
  44. exp = exp.replace(/\s/g, '');
  45. //( to (
  46. exp = exp.replace(/(/g, '(');
  47. //)to )
  48. exp = exp.replace(/)/g, ')');
  49. //,to ,
  50. exp = exp.replace(/,/g, ',');
  51. //f to F
  52. exp = exp.replace(new RegExp('f', 'g'), 'F');
  53. return exp;
  54. }
  55. /**
  56. * 获取累进办法计算的金额
  57. * @param {Number} baseFee - 基准金额
  58. * @param {String} name - 使用累进计算的基数名称(需要与累进库中的名称匹配)
  59. * @param {Array} progressiveData - 项目的累进数据(property.progressiveInterval)
  60. * @param {Function} decimalFunc - scMath中的精度方法
  61. * @param {Number} decimal - 精度
  62. * @return {Number}
  63. */
  64. function getProgressiveFee(baseFee, name, progressiveData, decimalFunc, decimal) {
  65. if (!progressiveData) {
  66. throw '该项目不存在累进区间数据';
  67. }
  68. //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
  69. const matchProgressiveData = progressiveData.find(item => standar(item.name) === standar(name));
  70. if (!matchProgressiveData) {
  71. throw `计算基数{${name}}不存在累进区间数据`;
  72. }
  73. // 将原始数据转换成方便处理的数据:[{feeRate: xx, min: 0, max: 200, minOpr: '(', maxOpr: ']'}]
  74. const progression = matchProgressiveData.progression.map(item => {
  75. // item.interval内容: eg (0,200]、[300,500) [1000,+)....
  76. const interval = standar(item.interval);
  77. // ( => 大于 [ => 大于等于 ) => 小于 ] => 小于等于
  78. const minReg = /([\(\[])(\d+)/;
  79. const minMatch = minReg.exec(interval);
  80. if (!minMatch || !minMatch[1] || !minMatch[2]) {
  81. throw `计算基数{${name}}累进区间数据错误`;
  82. }
  83. const minOpr = minMatch[1];
  84. // 后台数据单位为万元,这里转为为元
  85. const min = parseFloat(minMatch[2]) * 10000;
  86. const maxReg = /[\,,]([\d\+]+)([\)\]])/;
  87. const maxMatch = maxReg.exec(interval);
  88. if (!maxMatch || !maxMatch[1] || !maxMatch[2]) {
  89. throw `计算基数{${name}}累进区间数据错误`;
  90. }
  91. const max = maxMatch[1] === '+' ? 'infinity' : parseFloat(maxMatch[1]) * 10000;
  92. const maxOpr = maxMatch[2];
  93. return {
  94. feeRate: item.feeRate,
  95. min,
  96. minOpr,
  97. max,
  98. maxOpr
  99. }
  100. });
  101. progression.sort((a, b) => a.min - b.min);
  102. // 基数所在区间
  103. const withinData = progression.find(item => {
  104. const oprMiddle = item.max === 'infinity' ? '+' : '';
  105. const oprLink = item.minOpr + oprMiddle + item.maxOpr;
  106. switch (oprLink) {
  107. case '()':
  108. return baseFee > item.min && baseFee < item.max;
  109. case '(]':
  110. return baseFee > item.min && baseFee <= item.max;
  111. case '[)':
  112. return baseFee >= item.min && baseFee < item.max;
  113. case '[]':
  114. return baseFee >= item.min && baseFee <= item.max;
  115. case '(+)':
  116. case '(+]':
  117. return baseFee > item.min;
  118. case '[+)':
  119. case '[+]':
  120. return baseFee >= item.min;
  121. default:
  122. return false;
  123. }
  124. });
  125. if (!withinData) {
  126. return 0;
  127. }
  128. // 累进计算
  129. let fee = 0;
  130. //累进之前的区间
  131. for (let i = 0; i < progression.indexOf(withinData); i++) {
  132. const perData = progression[i];
  133. fee += (perData.max - perData.min) * perData.feeRate * 0.01;
  134. }
  135. //累进所在区间
  136. fee += (baseFee - withinData.min) * withinData.feeRate * 0.01;
  137. return decimalFunc(fee, decimal);
  138. //return fee.toDecimal(decimalObj.bills.totalPrice);
  139. }
  140. return {
  141. isDef,
  142. isEmptyVal,
  143. getSortedTreeData
  144. };
  145. });