From bfb020da5cf8aa89c5eaae9e59e9ea8e04a49448 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期五, 13 二月 2026 17:15:06 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java | 182 ++++++++++++++++++++++++++++++++-------------
1 files changed, 130 insertions(+), 52 deletions(-)
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java
index 1518bde..ebd23ef 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java
@@ -1,5 +1,4 @@
package com.xiaopeng.order.utils;
-
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalTime;
@@ -16,11 +15,11 @@
PricingConfig config = setupMockConfig();
Calendar cal = Calendar.getInstance();
- cal.set(2023, Calendar.OCTOBER, 10, 16, 50, 0);
+ cal.set(2026, Calendar.MARCH, 13, 14, 40, 15);
Date orderTime = cal.getTime();
// 模拟总里程 25.0 km,以触发多级远途加价
- double totalMillige = 25.0;
+ double totalMillige = 7.874;
// 模拟 GPS 轨迹点
List<GpsPoint> points = createMockGpsPoints(orderTime);
@@ -42,7 +41,7 @@
BigDecimal totalMileage = BigDecimal.valueOf(totalMileageKm);
PricingRule baseRule = config.findMatchedRule(orderTime);
- result.put("起步价(" + baseRule.ruleName + ")", baseRule.baseFare);
+ result.put("起步价(" + baseRule.ruleName + ")"+"-"+baseRule.start+"-"+baseRule.end, baseRule.baseFare);
if (totalMileage.compareTo(baseRule.baseKm) <= 0) {
return formatMap(result);
@@ -51,6 +50,15 @@
BigDecimal remainBaseM = baseRule.baseKm.multiply(new BigDecimal("1000"));
BigDecimal remainBaseMs = baseRule.baseMin.multiply(new BigDecimal("60000"));
BigDecimal currentTotalM = BigDecimal.ZERO;
+ BigDecimal currentTotalMs = BigDecimal.ZERO;
+
+ boolean isOverBaseM = false;
+ boolean isOverBaseMs = false;
+
+ // 超出里程和分钟数的集合
+ Map<String, BigDecimal> bill = new LinkedHashMap<>();
+ Map<String, BigDecimal> activeRuleNameRate = new LinkedHashMap<>();
+ Set<String> activeRuleNameList = new HashSet<>();
for (int i = 1; i < points.size(); i++) {
GpsPoint curr = points.get(i);
@@ -59,65 +67,94 @@
BigDecimal segM = BigDecimal.valueOf(curr.getDistance());
BigDecimal segMs = BigDecimal.valueOf(curr.getLocatetime() - prev.getLocatetime());
currentTotalM = currentTotalM.add(segM); // 累计当前已行驶的总里程
+ currentTotalMs = currentTotalMs.add(segMs); // 累计当前已行驶的总时间
PricingRule activeRule = config.findMatchedRule(new Date(curr.getLocatetime()));
// 扣除起步额度逻辑
BigDecimal billM = BigDecimal.ZERO;
- if (remainBaseM.compareTo(BigDecimal.ZERO) > 0) {
- if (segM.compareTo(remainBaseM) > 0) {
- billM = segM.subtract(remainBaseM);
- remainBaseM = BigDecimal.ZERO;
- } else {
- remainBaseM = remainBaseM.subtract(segM);
- }
- } else {
- billM = segM;
+ if (currentTotalM.compareTo(remainBaseM) > 0) {
+// billM = currentTotalM.subtract(remainBaseM);
+ isOverBaseM = true;
}
-
BigDecimal billMs = BigDecimal.ZERO;
- if (remainBaseMs.compareTo(BigDecimal.ZERO) > 0) {
- if (segMs.compareTo(remainBaseMs) > 0) {
- billMs = segMs.subtract(remainBaseMs);
- remainBaseMs = BigDecimal.ZERO;
- } else {
- remainBaseMs = remainBaseMs.subtract(segMs);
- }
- } else {
- billMs = segMs;
+ if (currentTotalMs.compareTo(remainBaseMs) > 0) {
+// billMs = currentTotalMs.subtract(remainBaseMs);
+ isOverBaseMs = true;
}
-
// 1. 基础费率计算
- BigDecimal distFee = billM.divide(new BigDecimal(1000), 10, RoundingMode.HALF_UP).multiply(activeRule.perKmRate);
- BigDecimal timeFee = billMs.divide(new BigDecimal(60000), 10, RoundingMode.HALF_UP).multiply(activeRule.perMinRate);
+// BigDecimal distFee = billM.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP).multiply(activeRule.perKmRate);
+// BigDecimal timeFee = billMs.multiply(activeRule.perMinRate);
// 2. 远途加价计算 (基于区间判定)
- BigDecimal longExtra = calculateLongDistExtra(currentTotalM, billM, config.longSteps);
+// BigDecimal longExtra = calculateLongDistExtra(currentTotalM, billM, config.longSteps);
- BigDecimal totalSeg = distFee.add(timeFee).add(longExtra);
- result.put(activeRule.ruleName, result.getOrDefault(activeRule.ruleName, BigDecimal.ZERO).add(totalSeg));
+// 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));
+ }
+ // 超出时间
+ if (isOverBaseMs) {
+ 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); // 超出时间的加价
+
+ 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. 基础费率计算
+ for (String ruleName : activeRuleNameList) {
+ String[] split = ruleName.split("_");
+ if(ruleName.endsWith("_Ml")){
+ BigDecimal exceedValue = bill.get(ruleName);
+ if(Objects.nonNull(exceedValue)){
+ exceedValue = exceedValue.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
+ }else{
+ exceedValue = BigDecimal.ZERO;
+ }
+ BigDecimal exceedRate = activeRuleNameRate.get(ruleName);
+ result.put(split[0], result.getOrDefault(split[0], BigDecimal.ZERO).add(exceedValue.multiply(exceedRate)));
+ }else{
+ BigDecimal exceedValue = bill.get(ruleName);
+ if(Objects.nonNull(exceedValue)){
+ exceedValue = exceedValue.divide(new BigDecimal(60000), 2, RoundingMode.HALF_UP);
+ }else{
+ exceedValue = BigDecimal.ZERO;
+ }
+ BigDecimal exceedRate = activeRuleNameRate.get(ruleName);
+ result.put(split[0], result.getOrDefault(split[0], BigDecimal.ZERO).add(exceedValue.multiply(exceedRate)));
+ }
+ }
+ // 2. 远途加价计算 (基于区间判定)
+ BigDecimal longExtra = calculateLongDistExtra(BigDecimal.valueOf(totalMileageKm), config.longSteps);
+ result.put("远途费", longExtra);
return formatMap(result);
}
/**
* 远途加价核心逻辑:判断当前行驶到的里程处于哪个加价区间
*/
- private BigDecimal calculateLongDistExtra(BigDecimal currentTotalM, BigDecimal billM, List<LongRangeStep> steps) {
+ private BigDecimal calculateLongDistExtra(BigDecimal billM, List<LongRangeStep> steps) {
if (billM.compareTo(BigDecimal.ZERO) <= 0) return BigDecimal.ZERO;
// 当前点所在的公里数
- BigDecimal currentKm = currentTotalM.divide(new BigDecimal(1000), 10, RoundingMode.HALF_UP);
+ BigDecimal extraStart = BigDecimal.ZERO;
BigDecimal extraRate = BigDecimal.ZERO;
// 匹配区间规则
for (LongRangeStep step : steps) {
- if (step.isMatch(currentKm)) {
+ if (step.isMatch(billM)) {
extraRate = step.addPrice;
+ extraStart = step.numStart;
break;
}
}
- return billM.divide(new BigDecimal(1000), 10, RoundingMode.HALF_UP).multiply(extraRate);
+ return billM.subtract(extraStart).multiply(extraRate);
}
private Map<String, BigDecimal> formatMap(Map<String, BigDecimal> map) {
@@ -145,16 +182,15 @@
}
public static class PricingConfig {
- PricingRule holiday;
- PricingRule peak;
- PricingRule night;
- List<PricingRule> normals = new ArrayList<>();
- List<LongRangeStep> longSteps = new ArrayList<>(); // 修改为区间列表
- boolean isHoliday = false;
+ public PricingRule holiday;
+ public PricingRule peak;
+ public PricingRule night;
+ public List<PricingRule> normals = new ArrayList<>();
+ public List<LongRangeStep> longSteps = new ArrayList<>(); // 修改为区间列表
public PricingRule findMatchedRule(Date date) {
LocalTime t = date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
- if (isHoliday) return holiday;
+ if (holiday.isMatch(t)) return holiday;
if (peak.isMatch(t)) return peak;
if (night.isMatch(t)) return night;
for (PricingRule r : normals) if (r.isMatch(t)) return r;
@@ -163,9 +199,9 @@
}
public static class PricingRule {
- String ruleName;
- LocalTime start, end;
- BigDecimal baseFare, baseKm, baseMin, perKmRate, perMinRate;
+ public String ruleName;
+ public LocalTime start, end;
+ public BigDecimal baseFare, baseKm, baseMin, perKmRate, perMinRate;
public PricingRule(String n, String s, String e, double bf, double bk, double bm, double pkr, double pmr) {
this.ruleName = n;
@@ -193,17 +229,19 @@
private static PricingConfig setupMockConfig() {
PricingConfig config = new PricingConfig();
- config.peak = new PricingRule("高峰期", "17:00", "19:00", 15.0, 3.0, 5.0, 3.0, 0.8);
- config.night = new PricingRule("夜间行驶", "22:00", "05:00", 18.0, 3.0, 5.0, 3.5, 1.0);
- config.normals.add(new PricingRule("普通时段", "05:00", "17:00", 12.0, 3.0, 5.0, 2.4, 0.5));
+ config.peak = new PricingRule("高峰期", "14:40", "14: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));
+ config.normals.add(new PricingRule("普通时段", "14:48", "17:59", 10.0, 3.0, 5.0, 2.4, 0.5));
// --- 远途加价区间配置 (关键修改) ---
// 1. 超过 num1(12) 不足 num2(20), 加收 num3(1.2)
- config.longSteps.add(new LongRangeStep(12.0, 20.0, 1.2));
+ config.longSteps.add(new LongRangeStep(5.0, 6.0, 1.2));
// 2. 超过 num4(20) 不足 num5(35), 加收 num6(2.0)
- config.longSteps.add(new LongRangeStep(20.0, 35.0, 2.0));
+ config.longSteps.add(new LongRangeStep(6.0, 7.0, 2.0));
// 3. 超过 num7(35) 以后, 加收 num8(3.5) -> numEnd 传个极大值
- config.longSteps.add(new LongRangeStep(35.0, 999999.0, 3.5));
+ config.longSteps.add(new LongRangeStep(7.0, 8.0, 3.5));
return config;
}
@@ -213,9 +251,49 @@
long startTs = startTime.getTime();
list.add(new GpsPoint(0, startTs));
// 模拟行驶了 20km
- list.add(new GpsPoint(12000, startTs + 15 * 60 * 1000));
- list.add(new GpsPoint(8000, startTs + 25 * 60 * 1000));
- list.add(new GpsPoint(5000, startTs + 35 * 60 * 1000));
+ list.add(new GpsPoint(120, startTs + 2 * 10 * 1000));
+ list.add(new GpsPoint(204, startTs + 2 * 20 * 1000));
+ list.add(new GpsPoint(231, startTs + 2 * 30 * 1000));
+ list.add(new GpsPoint(252, startTs + 2 * 40 * 1000));
+ list.add(new GpsPoint(188, startTs + 2 * 50 * 1000));
+ list.add(new GpsPoint(150, startTs + 2 * 60 * 1000));
+ list.add(new GpsPoint(126, startTs + 2 * 70 * 1000));
+ list.add(new GpsPoint(138, startTs + 2 * 80 * 1000));
+ list.add(new GpsPoint(119, startTs + 2 * 90 * 1000));
+ list.add(new GpsPoint(147, startTs + 2 * 100 * 1000));
+ list.add(new GpsPoint(155, startTs + 2 * 110 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 120 * 1000));
+ list.add(new GpsPoint(172, startTs + 2 * 130 * 1000));
+ list.add(new GpsPoint(202, startTs + 2 * 140 * 1000));
+ list.add(new GpsPoint(162, startTs + 2 * 150 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 160 * 1000));
+ list.add(new GpsPoint(132, startTs + 2 * 170 * 1000));
+ list.add(new GpsPoint(142, startTs + 2 * 180 * 1000));
+ list.add(new GpsPoint(262, startTs + 2 * 190 * 1000));
+ list.add(new GpsPoint(242, startTs + 2 * 200 * 1000));
+ list.add(new GpsPoint(282, startTs + 2 * 210 * 1000));
+ list.add(new GpsPoint(222, startTs + 2 * 220 * 1000));
+ list.add(new GpsPoint(212, startTs + 2 * 230 * 1000));
+ list.add(new GpsPoint(142, startTs + 2 * 240 * 1000));
+ list.add(new GpsPoint(262, startTs + 2 * 250 * 1000));
+ list.add(new GpsPoint(169, startTs + 2 * 260 * 1000));
+ list.add(new GpsPoint(170, startTs + 2 * 270 * 1000));
+ list.add(new GpsPoint(180, startTs + 2 * 280 * 1000));
+ list.add(new GpsPoint(165, startTs + 2 * 290 * 1000));
+ list.add(new GpsPoint(180, startTs + 2 * 300 * 1000));
+ list.add(new GpsPoint(198, startTs + 2 * 310 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 320 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 330 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 340 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 350 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 360 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 370 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 380 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 390 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 400 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 410 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 420 * 1000));
+ list.add(new GpsPoint(182, startTs + 2 * 430 * 1000));
return list;
}
}
\ No newline at end of file
--
Gitblit v1.7.1