liujie
2026-03-11 a1f89d04a360e3d37d1ca20959d05dc3b9c2b285
结束行程计费调整
3个文件已修改
228 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderDetail.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpOrderDetail.java
@@ -34,7 +34,7 @@
    @ApiModelProperty(value = "type=1 普通时段 type=2 夜间行驶时段 3高峰时段 4节假日时段")
    private Integer type;
    @ApiModelProperty(value = "1=起步价 2=里程费")
    @ApiModelProperty(value = "1=起步价 2=里程费 3时长 4远途")
    private Integer detailType;
    @ApiModelProperty(value = "时段")
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -1432,20 +1432,15 @@
        TaxiPricingDemoService.PricingConfig config = new TaxiPricingDemoService.PricingConfig();
        JSONArray startingFareJsonArray = JSONArray.parseArray(pricing.getStartingFareJson());
        if (pricing.getPricingType() == 1) {
            JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson());
            config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num21").split(" - ")[0], basicPricingJson.getString("num21").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")), Double.parseDouble(basicPricingJson.getString("num26")), Double.parseDouble(basicPricingJson.getString("num27")), Double.parseDouble(basicPricingJson.getString("num28"))));
            config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num22").split(" - ")[0], basicPricingJson.getString("num22").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25")), Double.parseDouble(basicPricingJson.getString("num26")), Double.parseDouble(basicPricingJson.getString("num27")), Double.parseDouble(basicPricingJson.getString("num28"))));
            config.night = new TaxiPricingDemoService.PricingRule("夜间行驶", basicPricingJson.getString("num14").split(" - ")[0], basicPricingJson.getString("num14").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num16")), Double.parseDouble(basicPricingJson.getString("num17")), Double.parseDouble(basicPricingJson.getString("num18")), Double.parseDouble(basicPricingJson.getString("num19")), Double.parseDouble(basicPricingJson.getString("num20")));
            config.holiday = new TaxiPricingDemoService.PricingRule("节假日", "00:00", "23:59", Double.parseDouble(basicPricingJson.getString("num30")), Double.parseDouble(basicPricingJson.getString("num31")), Double.parseDouble(basicPricingJson.getString("num32")), Double.parseDouble(basicPricingJson.getString("num33")), Double.parseDouble(basicPricingJson.getString("num34")));
            // --- 远途加价区间配置 (关键修改) ---
            // 1. 超过 num1(12) 不足 num2(20), 加收 num3(1.2)
            config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num6")), Double.parseDouble(basicPricingJson.getString("num7")), Double.parseDouble(basicPricingJson.getString("num8"))));
            // 2. 超过 num4(20) 不足 num5(35), 加收 num6(2.0)
            config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num9")), Double.parseDouble(basicPricingJson.getString("num10")), Double.parseDouble(basicPricingJson.getString("num11"))));
            // 3. 超过 num7(35) 以后, 加收 num8(3.5) -> numEnd 传个极大值
            config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num12")), 999999, Double.parseDouble(basicPricingJson.getString("num13"))));
        }
        LocalDateTime boardingTime = order.getBoardingTime();
        Date date = DateUtils.localDateTimeToDate(boardingTime);
        double paramNum4 =0.0;
        double paramNum5 =0.0;
        for (int i = 0; i < startingFareJsonArray.size(); i++) {
            com.alibaba.fastjson.JSONObject jsonObject = startingFareJsonArray.getJSONObject(i);
            String num1 = jsonObject.getString("num1");
@@ -1456,10 +1451,50 @@
            String num6 = jsonObject.getString("num6");
            String num7 = jsonObject.getString("num7");
            config.normals.add(new TaxiPricingDemoService.PricingRule("普通时段", num1, num2, Double.parseDouble(num3), Double.parseDouble(num4), Double.parseDouble(num5), Double.parseDouble(num6), Double.parseDouble(num7)));
            // 判断当前是那个时段
            Calendar calendarStart = Calendar.getInstance();
            calendarStart.setTime(date);
            calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(jsonObject.getString("num1").split(":")[0]));
            calendarStart.set(Calendar.MINUTE, Integer.valueOf(jsonObject.getString("num1").split(":")[1]));
            Calendar calendarEnd = Calendar.getInstance();
            calendarEnd.setTime(date);
            calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(jsonObject.getString("num2").split(":")[0]));
            calendarEnd.set(Calendar.MINUTE, Integer.valueOf(jsonObject.getString("num2").split(":")[1]));
            // 找到符合条件的直接跳出循环
            if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) {
                paramNum4 = jsonObject.getDouble("num4");
                paramNum5 = jsonObject.getDouble("num5");
                break;
            }
        }
        if (pricing.getPricingType() == 1) {
            JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson());
            config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num21").split(" - ")[0], basicPricingJson.getString("num21").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num23")),paramNum4, paramNum5,  Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25"))));
            config.peaks.add(new TaxiPricingDemoService.PricingRule("高峰期", basicPricingJson.getString("num22").split(" - ")[0], basicPricingJson.getString("num22").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num23")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num24")), Double.parseDouble(basicPricingJson.getString("num25"))));
            config.night = new TaxiPricingDemoService.PricingRule("夜间行驶", basicPricingJson.getString("num14").split(" - ")[0], basicPricingJson.getString("num14").split(" - ")[1], Double.parseDouble(basicPricingJson.getString("num15")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num16")), Double.parseDouble(basicPricingJson.getString("num17")));
            config.holiday = new TaxiPricingDemoService.PricingRule("节假日", "00:00", "23:59", Double.parseDouble(basicPricingJson.getString("num29")), paramNum4, paramNum5, Double.parseDouble(basicPricingJson.getString("num30")), Double.parseDouble(basicPricingJson.getString("num31")));
            // --- 远途加价区间配置 (关键修改) ---
            // 1. 超过 num1(12) 不足 num2(20), 加收 num3(1.2)
            config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num6")), Double.parseDouble(basicPricingJson.getString("num7")), Double.parseDouble(basicPricingJson.getString("num8"))));
            // 2. 超过 num4(20) 不足 num5(35), 加收 num6(2.0)
            config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num9")), Double.parseDouble(basicPricingJson.getString("num10")), Double.parseDouble(basicPricingJson.getString("num11"))));
            // 3. 超过 num7(35) 以后, 加收 num8(3.5) -> numEnd 传个极大值
            config.longSteps.add(new TaxiPricingDemoService.LongRangeStep(Double.parseDouble(basicPricingJson.getString("num12")), 999999, Double.parseDouble(basicPricingJson.getString("num13"))));
        }
        TaxiPricingDemoService.TaxiPricingService service = new TaxiPricingDemoService.TaxiPricingService();
        Map<String, BigDecimal> bill = service.calculateOrderPrice(DateUtils.toDate(order.getBoardingTime()), order.getMileageKilometers(), gpsPoints, config);
        Integer holidayToday = holidayUtil.isHolidayToday();
        Map<String, BigDecimal> bill = service.calculateOrderPrice(DateUtils.toDate(order.getBoardingTime()), order.getMileageKilometers(), gpsPoints, config,holidayToday);
        System.err.println("======= 订单计费账单 =======");
        bill.forEach((detail, price) -> System.err.println(detail + ": " + price + " 元"));
@@ -1611,21 +1646,54 @@
            xpOrderDetails.add(xpOrderDetail);
        }
        order.setMileageMoney(mileageMoney);
        for (FareBreakdownDetailVo fareBreakdownDetailVo : longDistance) {
            XpOrderDetail xpOrderDetail = new XpOrderDetail();
            BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
            xpOrderDetail.setOrderId(orderId);
            xpOrderDetail.setDetailType(4);
            xpOrderDetail.setCreateTime(LocalDateTime.now());
            mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney());
            xpOrderDetails.add(xpOrderDetail);
        }
        for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) {
            XpOrderDetail xpOrderDetail = new XpOrderDetail();
            BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
            xpOrderDetail.setOrderId(orderId);
            xpOrderDetail.setDetailType(3);
            xpOrderDetail.setCreateTime(LocalDateTime.now());
            mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney());
            xpOrderDetails.add(xpOrderDetail);
        }
        for (XpOrderDetail xpOrderDetail : xpOrderDetails) {
            xpOrderDetailMapper.insert(xpOrderDetail);
        }
        for (XpOrderDetail xpOrderDetail : xpOrderDetails) {
            if (xpOrderDetail.getDetailType() == 1) {
                order.setDurationType(xpOrderDetail.getType());
                order.setDurationMoney(xpOrderDetail.getMoney());
                order.setDuration(Double.parseDouble(xpOrderDetail.getDuration() + ""));
            } else {
                order.setLongDistanceType(order.getDurationType());
                order.setLongDistance(xpOrderDetail.getMileage().doubleValue());
                order.setLongDistancemoney(xpOrderDetail.getMoney());
            }
        for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) {
            if(order.getDurationMoney()==null){
                order.setDurationMoney(BigDecimal.ZERO);
            }
            BigDecimal add = order.getDurationMoney().add(fareBreakdownDetailVo.getMoney());
            order.setDurationMoney(add);
        }
//        for (XpOrderDetail xpOrderDetail : xpOrderDetails) {
//            if (xpOrderDetail.getDetailType() == 1) {
//                order.setDurationType(xpOrderDetail.getType());
//                order.setDurationMoney(xpOrderDetail.getMoney());
////                order.setDuration(Double.parseDouble(xpOrderDetail.getDuration() + ""));
//            } else {
//                order.setLongDistanceType(order.getDurationType());
//                order.setLongDistance(xpOrderDetail.getMileage().doubleValue());
//                order.setLongDistancemoney(xpOrderDetail.getMoney());
//            }
//
//        }
        BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO)
                .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO)
@@ -2052,6 +2120,7 @@
            detail.setTime(xpOrderDetail.getTime());
            detail.setMileage(xpOrderDetail.getMileage());
            detail.setDuration(xpOrderDetail.getDuration());
            detail.setMoney(xpOrderDetail.getMoney());
            if (xpOrderDetail.getDetailType() == 1) {
                start.add(detail);
            } else {
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/TaxiPricingDemoService.java
@@ -1,4 +1,6 @@
package com.xiaopeng.order.utils;
import com.xiaopeng.order.utils.holiday.HolidayUtil;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalTime;
@@ -11,21 +13,20 @@
 */
public class TaxiPricingDemoService {
    public static void main(String[] args) {
        PricingConfig config = setupMockConfig();
//
        Calendar cal = Calendar.getInstance();
        cal.set(2026, Calendar.APRIL, 11, 15, 49, 15);
        Date orderTime = cal.getTime();
        Date orderTime = new Date();
//
        // 模拟总里程 25.0 km,以触发多级远途加价
        double totalMillige = 9.148;
        double totalMillige = 2.984;
        // 模拟 GPS 轨迹点
        List<GpsPoint> points = createMockGpsPoints(orderTime);
        TaxiPricingService service = new TaxiPricingService();
        Map<String, BigDecimal> bill = service.calculateOrderPrice(orderTime, totalMillige, points, config);
        Map<String, BigDecimal> bill = service.calculateOrderPrice(orderTime, totalMillige, points, config,0);
        System.err.println("======= 订单计费账单 =======");
        bill.forEach((detail, price) -> System.err.println(detail + ": " + price + " 元"));
@@ -40,12 +41,14 @@
    }
    public static class TaxiPricingService {
        public Map<String, BigDecimal> calculateOrderPrice(Date orderTime, double totalMileageKm, List<GpsPoint> points, PricingConfig config) {
        public Map<String, BigDecimal> calculateOrderPrice(Date orderTime, double totalMileageKm, List<GpsPoint> points, PricingConfig config,Integer holiday) {
            Map<String, BigDecimal> result = new LinkedHashMap<>();
            BigDecimal totalMileage = BigDecimal.valueOf(totalMileageKm);
            PricingRule baseRule = config.findMatchedRule(orderTime);
            PricingRule baseRule = config.findMatchedRule(orderTime,holiday);
            result.put("起步价(" + baseRule.ruleName + ")"+"|"+baseRule.start+"-"+baseRule.end+"|"+baseRule.baseMin+"&"+baseRule.baseKm, baseRule.baseFare);
            if (totalMileage.compareTo(baseRule.baseKm) <= 0) {
@@ -74,7 +77,7 @@
                currentTotalM = currentTotalM.add(segM); // 累计当前已行驶的总里程
                currentTotalMs = currentTotalMs.add(segMs); // 累计当前已行驶的总时间
                PricingRule activeRule = config.findMatchedRule(new Date(curr.getLocatetime()));
                PricingRule activeRule = config.findMatchedRule(new Date(curr.getLocatetime()),holiday);
                // 扣除起步额度逻辑
                BigDecimal billM = BigDecimal.ZERO;
@@ -216,9 +219,11 @@
        public List<PricingRule> normals = new ArrayList<>();
        public List<LongRangeStep> longSteps = new ArrayList<>(); // 修改为区间列表
        public PricingRule findMatchedRule(Date date) {
        public PricingRule findMatchedRule(Date date,Integer isHoliday) {
            LocalTime t = date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
            if (holiday.isMatch(t)) return holiday;
            if (isHoliday==1){
                return holiday;
            }
            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;
@@ -257,19 +262,19 @@
    private static PricingConfig setupMockConfig() {
        PricingConfig config = new PricingConfig();
        config.peaks.add(new PricingRule("高峰期", "04:00", "05:00", 15.0, 3.0, 10.0, 4, 4));
        config.peaks.add(new PricingRule("高峰期", "15:00", "16:00", 15.0, 3.0, 10.0, 4, 4));
        config.night = new PricingRule("夜间行驶", "20:04", "23:00", 15.0, 3.0, 10.0, 3, 3);
        config.holiday = new PricingRule("节假日", "18:47", "18:48", 18.0, 3.0, 5.0, 4, 2.0);
        config.normals.add(new PricingRule("普通时段", "00:00", "23:59", 10.0, 3.0, 10.0, 3, 3));
        config.peaks.add(new PricingRule("高峰期", "04:00", "05:00", 15, 1, 10, 4, 4));
        config.peaks.add(new PricingRule("高峰期", "15:00", "16:00", 15, 1, 10, 4, 4));
        config.night = new PricingRule("夜间行驶", "20:04", "23:00", 15, 1, 10, 3, 3);
        config.holiday = new PricingRule("节假日", "00:00", "23:59", 20, 1, 10, 4, 4);
        config.normals.add(new PricingRule("普通时段", "00:00", "23:59", 10.0, 1, 10.0, 3, 3));
        // --- 远途加价区间配置 (关键修改) ---
        // 1. 超过 num1(12) 不足 num2(20), 加收 num3(1.2)
        config.longSteps.add(new LongRangeStep(5.0, 6.0, 1.2));
        config.longSteps.add(new LongRangeStep(1, 3, 3));
        // 2. 超过 num4(20) 不足 num5(35), 加收 num6(2.0)
        config.longSteps.add(new LongRangeStep(6.0, 7.0, 2.0));
        config.longSteps.add(new LongRangeStep(3, 5, 5));
        // 3. 超过 num7(35) 以后, 加收 num8(3.5) -> numEnd 传个极大值
        config.longSteps.add(new LongRangeStep(7.0, 8.0, 3.5));
        config.longSteps.add(new LongRangeStep(5, 999999, 6));
        return config;
    }
@@ -296,39 +301,39 @@
        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));
        list.add(new GpsPoint(182, startTs + 2 * 440 * 1000));
        list.add(new GpsPoint(182, startTs + 2 * 450 * 1000));
        list.add(new GpsPoint(182, startTs + 2 * 460 * 1000));
        list.add(new GpsPoint(182, startTs + 2 * 470 * 1000));
        list.add(new GpsPoint(182, startTs + 2 * 490 * 1000));
        list.add(new GpsPoint(182, startTs + 2 * 500 * 1000));
        list.add(new GpsPoint(182, startTs + 2 * 510 * 1000));
        list.add(new GpsPoint(122, 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));
//        list.add(new GpsPoint(182, startTs + 2 * 440 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 450 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 460 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 470 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 490 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 500 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 510 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 520 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 530 * 1000));
//        list.add(new GpsPoint(182, startTs + 2 * 540 * 1000));