'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 - 精度 * @param {Object} deficiency - 不足处理映射 @example: {'路线工程监理费': 20000 } // 不足2万按2万 * @return {Number} */ function getProgressiveFee(baseFee, name, progressiveData, decimal, deficiency) { 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 = scMathUtil.roundForObj(fee + (baseFee - withinData.min) * withinData.feeRate * 0.01, decimal); // 不足处理 const deficiencyFee = deficiency && deficiency[name] || 0; return deficiencyFee ? fee > 0 && fee < deficiencyFee ? deficiencyFee : fee : fee; } /** * 判断该基数是否包含累进基数 * @param {String} calcBase - 计算基数 * @param {Array} progression - 累进基数名称数组 * @return {Boolean} */ function isProgressive(calcBase, progression) { if (typeof calcBase !== 'string' || !progression) { return false; } const reg = /{[^}]+}/g; const matched = calcBase.match(reg); if (!matched) { return false; } return matched.some(mStr => progression.some(pStr => `{${pStr}}` === mStr)); } return { getProgressiveFee, isProgressive, }; });