puzhibing
2026-02-13 40c97867e634b0c4949dfd964bf06da35fc4bd88
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java
@@ -41,7 +41,7 @@
            BigDecimal totalMileage = BigDecimal.valueOf(totalMileageKm);
            PricingRule baseRule = config.findMatchedRule(orderTime);
            result.put("起步价(" + baseRule.ruleName + ")"+"-"+baseRule.start+"-"+baseRule.end, baseRule.baseFare);
            result.put("起步价(" + baseRule.ruleName + ")"+"|"+baseRule.start+"-"+baseRule.end+"="+baseRule.baseMin+"&"+baseRule.baseKm, baseRule.baseFare);
            if (totalMileage.compareTo(baseRule.baseKm) <= 0) {
                return formatMap(result);
@@ -92,19 +92,19 @@
//                BigDecimal totalSeg = distFee.add(timeFee).add(longExtra);
                // 超出里程
                if (isOverBaseM) {
                    bill.put(activeRule.ruleName + "-"+activeRule.start + "-" + activeRule.end + "_Ml", bill.getOrDefault(activeRule.ruleName + activeRule.start + "-" + activeRule.end + "_Ml", BigDecimal.ZERO).add(segM));
                    bill.put(activeRule.ruleName + "|"+activeRule.start + "-" + activeRule.end + "_Ml", bill.getOrDefault(activeRule.ruleName + activeRule.start + "-" + activeRule.end + "_Ml", BigDecimal.ZERO).add(segM));
                }
                // 超出时间
                if (isOverBaseMs) {
                    bill.put(activeRule.ruleName + "-"+activeRule.start + "-" + activeRule.end + "_Ms", bill.getOrDefault(activeRule.ruleName + activeRule.start + "-" + activeRule.end + "_Ms", BigDecimal.ZERO).add(segMs));
                    bill.put(activeRule.ruleName + "|"+activeRule.start + "-" + activeRule.end + "_Ms", bill.getOrDefault(activeRule.ruleName + activeRule.start + "-" + activeRule.end + "_Ms", BigDecimal.ZERO).add(segMs));
                }
                // 若不存在规则名称,则添加
                activeRuleNameRate.computeIfAbsent(activeRule.ruleName + "-"+activeRule.start + "-" + activeRule.end + "_Ml", k -> activeRule.perKmRate); // 超出里程的加价
                activeRuleNameRate.computeIfAbsent(activeRule.ruleName + "-"+activeRule.start + "-" + activeRule.end + "_Ms",k ->activeRule.perMinRate); // 超出时间的加价
                activeRuleNameRate.computeIfAbsent(activeRule.ruleName + "|"+activeRule.start + "-" + activeRule.end + "_Ml", k -> activeRule.perKmRate); // 超出里程的加价
                activeRuleNameRate.computeIfAbsent(activeRule.ruleName + "|"+activeRule.start + "-" + activeRule.end + "_Ms",k ->activeRule.perMinRate); // 超出时间的加价
                activeRuleNameList.add(activeRule.ruleName + "-"+activeRule.start + "-" + activeRule.end + "_Ml");
                activeRuleNameList.add(activeRule.ruleName + "-"+activeRule.start + "-" + activeRule.end + "_Ms");
                activeRuleNameList.add(activeRule.ruleName + "|"+activeRule.start + "-" + activeRule.end + "_Ml");
                activeRuleNameList.add(activeRule.ruleName + "|"+activeRule.start + "-" + activeRule.end + "_Ms");
//                result.put(activeRule.ruleName, result.getOrDefault(activeRule.ruleName, BigDecimal.ZERO).add(totalSeg));
            }
            // 1. 基础费率计算
@@ -113,6 +113,7 @@
                if(ruleName.endsWith("_Ml")){
                    BigDecimal exceedValue = bill.get(ruleName);
                    if(Objects.nonNull(exceedValue)){
                        result.put("distance"+split[0], result.getOrDefault(split[0], BigDecimal.ZERO).add(exceedValue));
                        exceedValue = exceedValue.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
                    }else{
                        exceedValue = BigDecimal.ZERO;
@@ -127,12 +128,14 @@
                        exceedValue = BigDecimal.ZERO;
                    }
                    BigDecimal exceedRate = activeRuleNameRate.get(ruleName);
                    result.put(split[0], result.getOrDefault(split[0], BigDecimal.ZERO).add(exceedValue.multiply(exceedRate)));
                    result.put("时长费"+split[0]+"&"+exceedValue, result.getOrDefault(split[0], BigDecimal.ZERO).add(exceedValue.multiply(exceedRate)));
                }
            }
            // 2. 远途加价计算 (基于区间判定)
            BigDecimal longExtra = calculateLongDistExtra(BigDecimal.valueOf(totalMileageKm), config.longSteps);
            result.put("远途费", longExtra);
            // 计算远途里程
            BigDecimal longExtraValue = calculateLongDistExtra(BigDecimal.valueOf(totalMileageKm), config.longSteps);
            result.put("远途费&"+longExtraValue, longExtra);
            return formatMap(result);
        }
@@ -155,6 +158,26 @@
                }
            }
            return billM.subtract(extraStart).multiply(extraRate);
        }
        /**
         * 计算远途费的里程
         */
        private BigDecimal calculateLongDistExtraValue(BigDecimal billM, List<LongRangeStep> steps) {
            if (billM.compareTo(BigDecimal.ZERO) <= 0) return BigDecimal.ZERO;
            // 当前点所在的公里数
            BigDecimal extraStart = BigDecimal.ZERO;
            BigDecimal extraRate = BigDecimal.ZERO;
            // 匹配区间规则
            for (LongRangeStep step : steps) {
                if (step.isMatch(billM)) {
                    extraRate = step.addPrice;
                    extraStart = step.numStart;
                    break;
                }
            }
            return billM.subtract(extraStart);
        }
        private Map<String, BigDecimal> formatMap(Map<String, BigDecimal> map) {
@@ -183,7 +206,7 @@
    public static class PricingConfig {
        public PricingRule holiday;
        public PricingRule peak;
        public List<PricingRule> peaks = new ArrayList<>();
        public PricingRule night;
        public List<PricingRule> normals = new ArrayList<>();
        public List<LongRangeStep> longSteps = new ArrayList<>(); // 修改为区间列表
@@ -191,7 +214,7 @@
        public PricingRule findMatchedRule(Date date) {
            LocalTime t = date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
            if (holiday.isMatch(t)) return holiday;
            if (peak.isMatch(t)) return peak;
            for (PricingRule r : peaks) if (r.isMatch(t)) return r;
            if (night.isMatch(t)) return night;
            for (PricingRule r : normals) if (r.isMatch(t)) return r;
            return normals.get(0);
@@ -229,7 +252,8 @@
    private static PricingConfig setupMockConfig() {
        PricingConfig config = new PricingConfig();
        config.peak = new PricingRule("高峰期", "14:40", "14:46", 15.0, 3.0, 5.0, 3.0, 0.8);
        config.peaks.add(new PricingRule("高峰期", "14:40", "14:46", 15.0, 3.0, 5.0, 3.0, 0.8));
        config.peaks.add(new PricingRule("高峰期", "19:40", "20:46", 15.0, 3.0, 5.0, 3.0, 0.8));
        config.night = new PricingRule("夜间行驶", "14:47", "14:48", 18.0, 3.0, 5.0, 3.5, 1.0);
        config.holiday = new PricingRule("节假日", "18:47", "18:48", 18.0, 3.0, 5.0, 4, 2.0);
        config.normals.add(new PricingRule("普通时段", "14:46", "14:47", 10.0, 3.0, 5.0, 2.4, 0.5));