|
@@ -0,0 +1,111 @@
|
|
|
|
|
+'use strict';
|
|
|
|
|
+
|
|
|
|
|
+((factory) => {
|
|
|
|
|
+ if (typeof module !== 'undefined') {
|
|
|
|
|
+ const scMathUtil = require('./scMathUtil').getUtil();
|
|
|
|
|
+ module.exports = factory(scMathUtil);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ window.calculateUtil = factory(scMathUtil);
|
|
|
|
|
+ }
|
|
|
|
|
+})((scMathUtil) => {
|
|
|
|
|
+ function standar(exp) {
|
|
|
|
|
+ //去空格
|
|
|
|
|
+ exp = exp.replace(/\s/g, '');
|
|
|
|
|
+ //( to (
|
|
|
|
|
+ exp = exp.replace(/(/g, '(');
|
|
|
|
|
+ //)to )
|
|
|
|
|
+ exp = exp.replace(/)/g, ')');
|
|
|
|
|
+ //,to ,
|
|
|
|
|
+ exp = exp.replace(/,/g, ',');
|
|
|
|
|
+ //f to F
|
|
|
|
|
+ exp = exp.replace(new RegExp('f', 'g'), 'F');
|
|
|
|
|
+ return exp;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取累进办法计算的金额
|
|
|
|
|
+ * @param {Number} baseFee - 基准金额
|
|
|
|
|
+ * @param {String} name - 使用累进计算的基数名称(需要与累进库中的名称匹配)
|
|
|
|
|
+ * @param {Array} progressiveData - 项目的累进数据(property.progressiveInterval)
|
|
|
|
|
+ * @param {Number} decimal - 精度
|
|
|
|
|
+ * @return {Number}
|
|
|
|
|
+ */
|
|
|
|
|
+ function getProgressiveFee(baseFee, name, progressiveData, decimal) {
|
|
|
|
|
+ if (!progressiveData) {
|
|
|
|
|
+ throw '该项目不存在累进区间数据';
|
|
|
|
|
+ }
|
|
|
|
|
+ //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
|
|
|
|
|
+ const matchProgressiveData = progressiveData.find(item => standar(item.name) === standar(name));
|
|
|
|
|
+ if (!matchProgressiveData) {
|
|
|
|
|
+ throw `计算基数{${name}}不存在累进区间数据`;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 将原始数据转换成方便处理的数据:[{feeRate: xx, min: 0, max: 200, minOpr: '(', maxOpr: ']'}]
|
|
|
|
|
+ const progression = matchProgressiveData.progression.map(item => {
|
|
|
|
|
+ // item.interval内容: eg (0,200]、[300,500) [1000,+)....
|
|
|
|
|
+ const interval = standar(item.interval);
|
|
|
|
|
+ // ( => 大于 [ => 大于等于 ) => 小于 ] => 小于等于
|
|
|
|
|
+ const minReg = /([\(\[])(\d+)/;
|
|
|
|
|
+ const minMatch = minReg.exec(interval);
|
|
|
|
|
+ if (!minMatch || !minMatch[1] || !minMatch[2]) {
|
|
|
|
|
+ throw `计算基数{${name}}累进区间数据错误`;
|
|
|
|
|
+ }
|
|
|
|
|
+ const minOpr = minMatch[1];
|
|
|
|
|
+ // 后台数据单位为万元,这里转为为元
|
|
|
|
|
+ const min = parseFloat(minMatch[2]) * 10000;
|
|
|
|
|
+ const maxReg = /[\,,]([\d\+]+)([\)\]])/;
|
|
|
|
|
+ const maxMatch = maxReg.exec(interval);
|
|
|
|
|
+ if (!maxMatch || !maxMatch[1] || !maxMatch[2]) {
|
|
|
|
|
+ throw `计算基数{${name}}累进区间数据错误`;
|
|
|
|
|
+ }
|
|
|
|
|
+ const max = maxMatch[1] === '+' ? 'infinity' : parseFloat(maxMatch[1]) * 10000;
|
|
|
|
|
+ const maxOpr = maxMatch[2];
|
|
|
|
|
+ return {
|
|
|
|
|
+ feeRate: item.feeRate,
|
|
|
|
|
+ min,
|
|
|
|
|
+ minOpr,
|
|
|
|
|
+ max,
|
|
|
|
|
+ maxOpr
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ progression.sort((a, b) => a.min - b.min);
|
|
|
|
|
+ // 基数所在区间
|
|
|
|
|
+ const withinData = progression.find(item => {
|
|
|
|
|
+ const oprMiddle = item.max === 'infinity' ? '+' : '';
|
|
|
|
|
+ const oprLink = item.minOpr + oprMiddle + item.maxOpr;
|
|
|
|
|
+ switch (oprLink) {
|
|
|
|
|
+ case '()':
|
|
|
|
|
+ return baseFee > item.min && baseFee < item.max;
|
|
|
|
|
+ case '(]':
|
|
|
|
|
+ return baseFee > item.min && baseFee <= item.max;
|
|
|
|
|
+ case '[)':
|
|
|
|
|
+ return baseFee >= item.min && baseFee < item.max;
|
|
|
|
|
+ case '[]':
|
|
|
|
|
+ return baseFee >= item.min && baseFee <= item.max;
|
|
|
|
|
+ case '(+)':
|
|
|
|
|
+ case '(+]':
|
|
|
|
|
+ return baseFee > item.min;
|
|
|
|
|
+ case '[+)':
|
|
|
|
|
+ case '[+]':
|
|
|
|
|
+ return baseFee >= item.min;
|
|
|
|
|
+ default:
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ if (!withinData) {
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 累进计算
|
|
|
|
|
+ let fee = 0;
|
|
|
|
|
+ //累进之前的区间
|
|
|
|
|
+ for (let i = 0; i < progression.indexOf(withinData); i++) {
|
|
|
|
|
+ const perData = progression[i];
|
|
|
|
|
+ fee += (perData.max - perData.min) * perData.feeRate * 0.01;
|
|
|
|
|
+ }
|
|
|
|
|
+ //累进所在区间
|
|
|
|
|
+ fee += (baseFee - withinData.min) * withinData.feeRate * 0.01;
|
|
|
|
|
+ return scMathUtil.roundForObj(fee, decimal);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ getProgressiveFee,
|
|
|
|
|
+ };
|
|
|
|
|
+});
|