Przeglądaj źródła

累进基数bug

zhongzewei 6 lat temu
rodzic
commit
80e8fe33e0
1 zmienionych plików z 61 dodań i 44 usunięć
  1. 61 44
      web/building_saas/main/js/models/calc_base.js

+ 61 - 44
web/building_saas/main/js/models/calc_base.js

@@ -427,62 +427,79 @@ let cbTools = {
     //@param {Number}baseFee(相关基数金额) {String}name(使用累进计算的基数名称)
     //@param {Number}baseFee(相关基数金额) {String}name(使用累进计算的基数名称)
     //@return {Number}
     //@return {Number}
     getProgressiveFee: function (baseFee, name) {
     getProgressiveFee: function (baseFee, name) {
-        let progressiveData = calcBase.project.property.progressiveInterval;
+        const progressiveData = calcBase.project.property.progressiveInterval;
         if (!progressiveData) {
         if (!progressiveData) {
             throw '该项目不存在累进区间数据';
             throw '该项目不存在累进区间数据';
         }
         }
-        let matchData = _.find(progressiveData, function (data) {
-            //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
-            return cbAnalyzer.standar(data.name) === cbAnalyzer.standar(name);
-        });
-        if (!matchData) {
-            //return 0;
+        //根据基数名称匹配累进库数据,标准化以免(())等不同导致不匹配
+        const matchProgressiveData = progressiveData.find(item => cbAnalyzer.standar(item.name) === cbAnalyzer.standar(name));
+        if (!matchProgressiveData) {
             throw `计算基数{${name}}不存在累进区间数据`;
             throw `计算基数{${name}}不存在累进区间数据`;
         }
         }
-        let progression = matchData.progression;
-        //获取区间中的最小值(0, 10] = 0
-        function getMin(intervalStr) {
-            let str = cbAnalyzer.standar(intervalStr);
-            let match = /\((\d+)?/g.exec(str);
-            return typeof match[1] !== 'undefined' ? parseFloat(match[1]) * 10000 : null; //后台数据单位为万元,这里转为为元
-        }
-        //获取区间中的最大值(0, 10] = 10
-        function getMax(intervalStr) {
-            let str = cbAnalyzer.standar(intervalStr);
-            let match = /[\,,,](\d+)?/g.exec(str);
-            return typeof match[1] !== 'undefined' ? parseFloat(match[1]) * 10000 : null
-        }
-        //将累进区间进行排序
-        progression.sort(function (a, b) {
-           let aV = getMin(a.interval),
-               bV = getMin(b.interval);
-           return aV - bV;
+        // 将原始数据转换成方便处理的数据:[{feeRate: xx, min: 0, max: 200, minOpr: '(', maxOpr: ']'}]
+        const progression = matchProgressiveData.progression.map(item => {
+            // item.interval内容: eg (0,200]、[300,500) [1000,+)....
+            const interval = cbAnalyzer.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
+            }
         });
         });
-        //累进计算
-        let fee = 0;
-        //找到所在区间
-        let within = _.find(progression, function (data) {
-            let min = getMin(data.interval),
-                max = getMax(data.interval);
-            return min !== null && baseFee > min  && (max !== null && baseFee <= max || max === null);
+        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 (!within) {
+        if (!withinData) {
             return 0;
             return 0;
         }
         }
+        // 累进计算
+        let fee = 0;
         //累进之前的区间
         //累进之前的区间
-        for (let i = 0; i < progression.indexOf(within); i++) {
-            let perData = progression[i],
-                min = getMin(perData.interval),
-                max = getMax(perData.interval);
-            if (min !== null && max !== null) {
-                fee += (max - min) * perData.feeRate * 0.01;
-            }
+        for (let i = 0; i < progression.indexOf(withinData); i++) {
+            const perData = progression[i];
+            fee += (perData.max - perData.min) * perData.feeRate * 0.01;
         }
         }
         //累进所在区间
         //累进所在区间
-        let min = getMin(within.interval);
-        if (min !== null) {
-            fee += (baseFee - min) * within.feeRate * 0.01;
-        }
+        fee += (baseFee - withinData.min) * withinData.feeRate * 0.01;
         return fee.toDecimal(decimalObj.bills.totalPrice);
         return fee.toDecimal(decimalObj.bills.totalPrice);
     },
     },
     //获取清单100章下的节点(只需要找最底层的,排除了底层,父项金额即排除了子项)
     //获取清单100章下的节点(只需要找最底层的,排除了底层,父项金额即排除了子项)