From 789b6001c78884c80c5250a3388bb52981069339 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期五, 13 三月 2026 22:27:48 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java |  599 ++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 320 insertions(+), 279 deletions(-)

diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
index dbc37fa..c053d7a 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -89,6 +89,7 @@
 import com.xiaopeng.order.service.IXpOrderService;
 import com.xiaopeng.order.utils.TaxiPricingDemoService;
 import com.xiaopeng.order.utils.RegionCodeFilterUtil;
+import com.xiaopeng.order.utils.XpPricingUtil;
 import com.xiaopeng.order.utils.holiday.HolidayUtil;
 import com.xiaopeng.order.vo.OrderDetailVo;
 import lombok.RequiredArgsConstructor;
@@ -149,6 +150,7 @@
     private final XpCruiseOrderMapper xpCruiseOrderMapper;
     private final XpTaskRuleClient xpTaskRuleClient;
     private final XpCruisePlanClient xpCruisePlanClient;
+    private final XpPricingUtil xpPricingUtil;
 
 
     @Autowired
@@ -1016,11 +1018,9 @@
 
         for (XpHistoryStartPointsVo datum : data) {
 
-            if(datum.getOperationStatus()==2){
+            if (datum.getOperationStatus() == 2) {
                 datum.setOperationStatus(1);
             }
-
-
 
 
             // 保留2位数小数
@@ -1385,7 +1385,7 @@
                 break;
             case 7:
                 // 查询自动结束行程时间
-                if(xpOrder.getOpenTrunk() != 1){
+                if (xpOrder.getOpenTrunk() != 1) {
                     Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData();
                     // 添加自动结束行程定时任务job
                     Map<String, ? extends Object> endTripJobMaps =
@@ -1432,6 +1432,8 @@
         // 远途费价格明细
         List<FareBreakdownDetailVo> longDistance = new ArrayList<>();
         XpOrder order = this.getById(orderId);
+
+        Long orderAppUserId = order.getAppUserId();
         if (order == null) {
             throw new RuntimeException("订单不存在");
         }
@@ -1495,266 +1497,300 @@
         Date date = DateUtils.localDateTimeToDate(boardingTime);
 
 
-        double paramNum4 =0.0;
-        double paramNum5 =0.0;
-
-
+        double paramNum4 = 0.0;
+        double paramNum5 = 0.0;
 
 
         //一口价
-        if(pricing.getPricingType() == 2){
-            JSONObject basicPricingJson = JSONObject.parseObject(pricing.getBasicPricingJson());
-            String num1 = "00:00";
-            String num2 = "23:59";
-            String num3 = basicPricingJson.getString("num1");
-            String num4 = basicPricingJson.getString("num2");
-            String num5 = basicPricingJson.getString("num3");
-            String num6 = basicPricingJson.getString("num4");
-            String num7 = basicPricingJson.getString("num5");
-            config.normals.add(new TaxiPricingDemoService.PricingRule("普通时段", num1, num2, Double.parseDouble(num3), Double.parseDouble(num4), Double.parseDouble(num5), Double.parseDouble(num6), Double.parseDouble(num7)));
-            paramNum4 = basicPricingJson.getDouble("num2");
-            paramNum5 = basicPricingJson.getDouble("num3");
-        }
+        if (pricing.getPricingType() == 2) {
+            Double mileageKilometers = order.getMileageKilometers();
+            Double duration1 = order.getDuration();
 
-
-        //动态计费
-        if (pricing.getPricingType() == 1) {
-
-            for (int i = 0; i < startingFareJsonArray.size(); i++) {
-                com.alibaba.fastjson.JSONObject jsonObject = startingFareJsonArray.getJSONObject(i);
-                String num1 = jsonObject.getString("num1");
-                String num2 = jsonObject.getString("num2");
-                String num3 = jsonObject.getString("num3");
-                String num4 = jsonObject.getString("num4");
-                String num5 = jsonObject.getString("num5");
-                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;
-                }
-            }
-
-
-            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();
-        Integer holidayToday = holidayUtil.isHolidayToday();
-        Map<String, BigDecimal> bill = service.calculateOrderPrice(DateUtils.toDate(order.getBoardingTime()), order.getMileageKilometers(), gpsPoints, config,holidayToday);
-        log.info("======= 订单计费账单 =======");
-        bill.forEach((detail, price) -> log.info(detail + ": " + price + " 元"));
-
-        BigDecimal totalAmount = bill.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
-        log.info("--------------------------");
-        log.info("应付总额: " + totalAmount + " 元");
-        BigDecimal startMoney = BigDecimal.ZERO;
-        // 默认费率1
-        double priceRate = 1;
-        if (pricing.getIsDynamicPrice() == 1) {
-            // 先判断是否已经调价过了
-            Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid);
-            if (userDynamicPriceObj != null) {
-                // 是否调价过了
-                priceRate = Double.parseDouble(userDynamicPriceObj.toString());
-            } else {
-                // 没有调过
-                //是否触发动态调价 redis获取
-                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId());
-                if (dynamicPriceObj != null) {
-                    JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
-                    // 触发动态调价
-                    // value=时间
-                    String timeStr = dynamicPriceObj.toString();
-                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
-                    Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId()));
-                    // X单上升一次调价
-                    Integer orderNum = getOrderNum(jsonObject, 4);
-                    // 需要调价的次数
-                    int count = num / orderNum;
-                    if (count > 0) {
-                        // 计算每次上升的费率
-                        Integer upRate = getOrderNum(jsonObject, 5);
-                        BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
-                        for (int i = count; i > 0; i--) {
-                            // 当前费率+(费率*上升百分比)
-                            priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
-                        }
-                        // 冷却时间
-                        Integer time = getOrderNum(jsonObject, 6);
-                        // 触发调价了
-                        redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
-                    }
-
-                }
-            }
-
-        }
-        // 封装费用明细数据
-        for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) {
-            // 封装起步价
-            FareBreakdownDetailVo startDetail = new FareBreakdownDetailVo();
-            String key = stringBigDecimalEntry.getKey();
-            if (key.contains("起步价")) {
-                startDetail.setTime(key.split("\\|")[1]);
-                startDetail.setMoney(stringBigDecimalEntry.getValue());
-                startMoney = startMoney.add(stringBigDecimalEntry.getValue());
-                if (key.contains("普通时段")) {
-                    startDetail.setType(1);
-                } else if (key.contains("夜间")) {
-                    startDetail.setType(2);
-                } else if (key.contains("高峰")) {
-                    startDetail.setType(3);
-                } else if (key.contains("节假")) {
-                    startDetail.setType(4);
-                }
-                String durationAndMileage = key.split("\\|")[2];
-                startDetail.setDuration(Double.valueOf(durationAndMileage.split("&")[0]));
-                startDetail.setMileage(new BigDecimal(durationAndMileage.split("&")[1]));
-                start.add(startDetail);
-            }
-            // 封装里程费
-            if (!key.contains("起步") && !key.contains("时长") && !key.contains("远途") && !key.contains("distance")) {
-                FareBreakdownDetailVo mileageDetail = new FareBreakdownDetailVo();
-                if (key.contains("普通时段")) {
-                    mileageDetail.setType(1);
-                    String key1 = "distance普通时段|" + key.split("\\|")[1];
-                    String key2 = "普通时段|" + key.split("\\|")[1];
-                    BigDecimal distance = bill.get(key1);
-                    BigDecimal money = bill.get(key2);
-                    mileageDetail.setMileage(distance);
-                    order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-                    mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-                } else if (key.contains("夜间行驶")) {
-                    mileageDetail.setType(2);
-                    String key1 = "distance夜间行驶|" + key.split("\\|")[1];
-                    String key2 = "夜间行驶|" + key.split("\\|")[1];
-                    BigDecimal distance = bill.get(key1);
-                    BigDecimal money = bill.get(key2);
-                    mileageDetail.setMileage(distance);
-                    order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-
-                    mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-                } else if (key.contains("高峰期")) {
-                    mileageDetail.setType(3);
-                    String key1 = "distance高峰期|" + key.split("\\|")[1];
-                    String key2 = "高峰期|" + key.split("\\|")[1];
-                    BigDecimal distance = bill.get(key1);
-                    BigDecimal money = bill.get(key2);
-                    mileageDetail.setMileage(distance);
-                    order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-
-                    mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-                } else if (key.contains("节假")) {
-                    mileageDetail.setType(4);
-                    String key1 = "distance节假日|" + key.split("\\|")[1];
-                    String key2 = "节假日|" + key.split("\\|")[1];
-                    BigDecimal distance = bill.get(key1);
-                    BigDecimal money = bill.get(key2);
-                    mileageDetail.setMileage(distance);
-                    order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-                    mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
-                }
-                mileage.add(mileageDetail);
-            }
-            // 封装时长费
-            FareBreakdownDetailVo timeDetail = new FareBreakdownDetailVo();
-            if (key.contains("时长费")) {
-                timeDetail.setType(startDetail.getType());
-                timeDetail.setMoney(stringBigDecimalEntry.getValue());
-                timeDetail.setDuration(Double.valueOf(key.split("&")[1]));
-                duration.add(timeDetail);
-            }
-            // 封装远途费
-            FareBreakdownDetailVo longDetail = new FareBreakdownDetailVo();
-            if (key.contains("远途费")) {
-                longDetail.setType(startDetail.getType());
-                longDetail.setMoney(stringBigDecimalEntry.getValue());
-                longDetail.setMileage(new BigDecimal(key.split("&")[1]));
-                longDistance.add(longDetail);
-            }
-        }
-        for (FareBreakdownDetailVo fareBreakdownDetailVo : start) {
+            com.alibaba.fastjson.JSONObject basicPricingJson = com.alibaba.fastjson.JSONObject.parseObject(pricing.getBasicPricingJson());
+//            String num1 = "00:00";
+//            String num2 = "23:59";
+//            String num3 = basicPricingJson.getString("num1");
+//            String num4 = basicPricingJson.getString("num2");
+//            String num5 = basicPricingJson.getString("num3");
+//            String num6 = basicPricingJson.getString("num4");
+//            String num7 = basicPricingJson.getString("num5");
+//            config.normals.add(new TaxiPricingDemoService.PricingRule("普通时段", num1, num2, Double.parseDouble(num3), Double.parseDouble(num4), Double.parseDouble(num5), Double.parseDouble(num6), Double.parseDouble(num7)));
+//            paramNum4 = basicPricingJson.getDouble("num2");
+//            paramNum5 = basicPricingJson.getDouble("num3");
+            XpPricingCardVo xpPricingCardVo = xpPricingUtil.calculationFixedPrice(orderAppUserId.toString(), basicPricingJson, null, mileageKilometers, duration1, 0, 0.0, pricing.getIsDynamicPrice(), order.getCityId(), pricing.getDynamicPricingJson());
             XpOrderDetail xpOrderDetail = new XpOrderDetail();
-            BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
-            xpOrderDetail.setOrderId(orderId);
             xpOrderDetail.setDetailType(1);
-            xpOrderDetail.setCreateTime(LocalDateTime.now());
-            xpOrderDetails.add(xpOrderDetail);
-        }
-        BigDecimal mileageMoney = BigDecimal.ZERO;
-        for (FareBreakdownDetailVo fareBreakdownDetailVo : mileage) {
-            XpOrderDetail xpOrderDetail = new XpOrderDetail();
-            BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
             xpOrderDetail.setOrderId(orderId);
+            xpOrderDetail.setType(1);
+            xpOrderDetail.setMileage(new BigDecimal(mileageKilometers).setScale(2, RoundingMode.HALF_UP));
+            xpOrderDetail.setDuration(duration1);
+            xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getStartPrice()).setScale(2, RoundingMode.HALF_UP));
+            xpOrderDetails.add(xpOrderDetail);
+            xpOrderDetail = new XpOrderDetail();
             xpOrderDetail.setDetailType(2);
-            xpOrderDetail.setCreateTime(LocalDateTime.now());
-            mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney());
-            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());
+            xpOrderDetail.setType(1);
+            xpOrderDetail.setMileage(new BigDecimal(mileageKilometers).setScale(2, RoundingMode.HALF_UP));
+            xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getDistancePrice()).setScale(2,RoundingMode.HALF_UP));
             xpOrderDetails.add(xpOrderDetail);
-        }
-
-
-        for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) {
-            XpOrderDetail xpOrderDetail = new XpOrderDetail();
-            BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
-            xpOrderDetail.setOrderId(orderId);
+            xpOrderDetail = new XpOrderDetail();
             xpOrderDetail.setDetailType(3);
-            xpOrderDetail.setCreateTime(LocalDateTime.now());
-            mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney());
+            xpOrderDetail.setOrderId(orderId);
+            xpOrderDetail.setType(1);
+            xpOrderDetail.setMoney(new BigDecimal(xpPricingCardVo.getDurationPrice()).setScale(2, RoundingMode.HALF_UP));
+            xpOrderDetail.setDuration(duration1);
             xpOrderDetails.add(xpOrderDetail);
-        }
 
-
-
-        for (XpOrderDetail xpOrderDetail : xpOrderDetails) {
-            xpOrderDetailMapper.insert(xpOrderDetail);
-        }
-
-        for (FareBreakdownDetailVo fareBreakdownDetailVo : duration) {
-            if(order.getDurationMoney()==null){
-                order.setDurationMoney(BigDecimal.ZERO);
+            BigDecimal totalPrice =BigDecimal.ZERO;
+            for (XpOrderDetail xpOrderDetail1 : xpOrderDetails) {
+                totalPrice = totalPrice.add(xpOrderDetail1.getMoney());
+                xpOrderDetailMapper.insert(xpOrderDetail1);
             }
-            BigDecimal add = order.getDurationMoney().add(fareBreakdownDetailVo.getMoney());
-            order.setDurationMoney(add);
-        }
+            order.setOrderMoney(totalPrice);
+            order.setAppUserId(null);
+            baseMapper.updateById(order);
+
+
+        } else {
+
+
+            //动态计费
+            if (pricing.getPricingType() == 1) {
+
+                for (int i = 0; i < startingFareJsonArray.size(); i++) {
+                    com.alibaba.fastjson.JSONObject jsonObject = startingFareJsonArray.getJSONObject(i);
+                    String num1 = jsonObject.getString("num1");
+                    String num2 = jsonObject.getString("num2");
+                    String num3 = jsonObject.getString("num3");
+                    String num4 = jsonObject.getString("num4");
+                    String num5 = jsonObject.getString("num5");
+                    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;
+                    }
+                }
+
+
+                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();
+            Integer holidayToday = holidayUtil.isHolidayToday();
+            Map<String, BigDecimal> bill = service.calculateOrderPrice(DateUtils.toDate(order.getBoardingTime()), order.getMileageKilometers(), gpsPoints, config, holidayToday);
+            log.info("======= 订单计费账单 =======");
+            bill.forEach((detail, price) -> log.info(detail + ": " + price + " 元"));
+
+            BigDecimal totalAmount = bill.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
+            log.info("--------------------------");
+            log.info("应付总额: " + totalAmount + " 元");
+            BigDecimal startMoney = BigDecimal.ZERO;
+            // 默认费率1
+            double priceRate = 1;
+            if (pricing.getIsDynamicPrice() == 1) {
+                // 先判断是否已经调价过了
+                Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid);
+                if (userDynamicPriceObj != null) {
+                    // 是否调价过了
+                    priceRate = Double.parseDouble(userDynamicPriceObj.toString());
+                } else {
+                    // 没有调过
+                    //是否触发动态调价 redis获取
+                    Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + order.getCityId());
+                    if (dynamicPriceObj != null) {
+                        JSONObject jsonObject = JSONObject.parseObject(pricing.getDynamicPricingJson());
+                        // 触发动态调价
+                        // value=时间
+                        String timeStr = dynamicPriceObj.toString();
+                        // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
+                        Integer num = this.getOrderNum(new GetOrderNumDto(timeStr, order.getCityId()));
+                        // X单上升一次调价
+                        Integer orderNum = getOrderNum(jsonObject, 4);
+                        // 需要调价的次数
+                        int count = num / orderNum;
+                        if (count > 0) {
+                            // 计算每次上升的费率
+                            Integer upRate = getOrderNum(jsonObject, 5);
+                            BigDecimal divide = new BigDecimal(upRate).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
+                            for (int i = count; i > 0; i--) {
+                                // 当前费率+(费率*上升百分比)
+                                priceRate = new BigDecimal(priceRate).multiply(divide).add(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
+                            }
+                            // 冷却时间
+                            Integer time = getOrderNum(jsonObject, 6);
+                            // 触发调价了
+                            redisService.setCacheObject("USER_DYNAMIC_PRICE_" + order.getCityId() + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
+                        }
+
+                    }
+                }
+
+            }
+            // 封装费用明细数据
+            for (Map.Entry<String, BigDecimal> stringBigDecimalEntry : bill.entrySet()) {
+                // 封装起步价
+                FareBreakdownDetailVo startDetail = new FareBreakdownDetailVo();
+                String key = stringBigDecimalEntry.getKey();
+                if (key.contains("起步价")) {
+                    startDetail.setTime(key.split("\\|")[1]);
+                    startDetail.setMoney(stringBigDecimalEntry.getValue());
+                    startMoney = startMoney.add(stringBigDecimalEntry.getValue());
+                    if (key.contains("普通时段")) {
+                        startDetail.setType(1);
+                    } else if (key.contains("夜间")) {
+                        startDetail.setType(2);
+                    } else if (key.contains("高峰")) {
+                        startDetail.setType(3);
+                    } else if (key.contains("节假")) {
+                        startDetail.setType(4);
+                    }
+                    String durationAndMileage = key.split("\\|")[2];
+                    startDetail.setDuration(Double.valueOf(durationAndMileage.split("&")[0]));
+                    startDetail.setMileage(new BigDecimal(durationAndMileage.split("&")[1]));
+                    start.add(startDetail);
+                }
+                // 封装里程费
+                if (!key.contains("起步") && !key.contains("时长") && !key.contains("远途") && !key.contains("distance")) {
+                    FareBreakdownDetailVo mileageDetail = new FareBreakdownDetailVo();
+                    if (key.contains("普通时段")) {
+                        mileageDetail.setType(1);
+                        String key1 = "distance普通时段|" + key.split("\\|")[1];
+                        String key2 = "普通时段|" + key.split("\\|")[1];
+                        BigDecimal distance = bill.get(key1);
+                        BigDecimal money = bill.get(key2);
+                        mileageDetail.setMileage(distance);
+                        order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+                        mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+                    } else if (key.contains("夜间行驶")) {
+                        mileageDetail.setType(2);
+                        String key1 = "distance夜间行驶|" + key.split("\\|")[1];
+                        String key2 = "夜间行驶|" + key.split("\\|")[1];
+                        BigDecimal distance = bill.get(key1);
+                        BigDecimal money = bill.get(key2);
+                        mileageDetail.setMileage(distance);
+                        order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+
+                        mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+                    } else if (key.contains("高峰期")) {
+                        mileageDetail.setType(3);
+                        String key1 = "distance高峰期|" + key.split("\\|")[1];
+                        String key2 = "高峰期|" + key.split("\\|")[1];
+                        BigDecimal distance = bill.get(key1);
+                        BigDecimal money = bill.get(key2);
+                        mileageDetail.setMileage(distance);
+                        order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+
+                        mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+                    } else if (key.contains("节假")) {
+                        mileageDetail.setType(4);
+                        String key1 = "distance节假日|" + key.split("\\|")[1];
+                        String key2 = "节假日|" + key.split("\\|")[1];
+                        BigDecimal distance = bill.get(key1);
+                        BigDecimal money = bill.get(key2);
+                        mileageDetail.setMileage(distance);
+                        order.setStartMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+                        mileageDetail.setMoney(money.multiply(BigDecimal.valueOf(priceRate)));
+                    }
+                    mileage.add(mileageDetail);
+                }
+                // 封装时长费
+                FareBreakdownDetailVo timeDetail = new FareBreakdownDetailVo();
+                if (key.contains("时长费")) {
+                    timeDetail.setType(startDetail.getType());
+                    timeDetail.setMoney(stringBigDecimalEntry.getValue());
+                    timeDetail.setDuration(Double.valueOf(key.split("&")[1]));
+                    duration.add(timeDetail);
+                }
+                // 封装远途费
+                FareBreakdownDetailVo longDetail = new FareBreakdownDetailVo();
+                if (key.contains("远途费")) {
+                    longDetail.setType(startDetail.getType());
+                    longDetail.setMoney(stringBigDecimalEntry.getValue());
+                    longDetail.setMileage(new BigDecimal(key.split("&")[1]));
+                    longDistance.add(longDetail);
+                }
+            }
+            for (FareBreakdownDetailVo fareBreakdownDetailVo : start) {
+                XpOrderDetail xpOrderDetail = new XpOrderDetail();
+                BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
+                xpOrderDetail.setOrderId(orderId);
+                xpOrderDetail.setDetailType(1);
+                xpOrderDetail.setCreateTime(LocalDateTime.now());
+                xpOrderDetails.add(xpOrderDetail);
+            }
+            BigDecimal mileageMoney = BigDecimal.ZERO;
+            for (FareBreakdownDetailVo fareBreakdownDetailVo : mileage) {
+                XpOrderDetail xpOrderDetail = new XpOrderDetail();
+                BeanUtils.copyProperties(fareBreakdownDetailVo, xpOrderDetail);
+                xpOrderDetail.setOrderId(orderId);
+                xpOrderDetail.setDetailType(2);
+                xpOrderDetail.setCreateTime(LocalDateTime.now());
+                mileageMoney = mileageMoney.add(fareBreakdownDetailVo.getMoney());
+                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 (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());
@@ -1768,12 +1804,16 @@
 //
 //        }
 
-        BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO)
-                .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO)
-                .add(order.getWaitMoney() != null ? order.getWaitMoney() : BigDecimal.ZERO);
-        order.setOrderMoney(orderMoney);
-        order.setAppUserId(null);
-        baseMapper.updateById(order);
+            BigDecimal orderMoney = startMoney.add(mileageMoney).add(order.getDurationMoney() != null ? order.getDurationMoney() : BigDecimal.ZERO)
+                    .add(order.getLongDistancemoney() != null ? order.getLongDistancemoney() : BigDecimal.ZERO)
+                    .add(order.getWaitMoney() != null ? order.getWaitMoney() : BigDecimal.ZERO);
+            order.setOrderMoney(orderMoney);
+            order.setAppUserId(null);
+            baseMapper.updateById(order);
+
+        }
+
+
         if (order.getCouponId() != null) {
             UseUserCouponDto useUserCouponDto = new UseUserCouponDto();
             useUserCouponDto.setUserId(Long.valueOf(uid));
@@ -2065,10 +2105,6 @@
     }
 
 
-
-
-
-
     private MileageDto mileageType(MileageDto param, JSONArray startingFareJsonArray, Date mileageDate, LocalDateTime begin, String num14, String num16, String num17, String num21, String num22, String num24, String num25, String num30, String num31) {
         // 计算出是在哪个普通时间段内
         for (Object o : startingFareJsonArray) {
@@ -2280,6 +2316,8 @@
 
         List<FareBreakdownDetailVo> start = new ArrayList<>();
         List<FareBreakdownDetailVo> mileage = new ArrayList<>();
+        List<FareBreakdownDetailVo> duration = new ArrayList<>();
+        List<FareBreakdownDetailVo> longDistance = new ArrayList<>();
 
         List<XpOrderDetail> xpOrderDetails = xpOrderDetailMapper.selectList(new LambdaQueryWrapper<XpOrderDetail>().eq(XpOrderDetail::getOrderId, orderId));
         for (XpOrderDetail xpOrderDetail : xpOrderDetails) {
@@ -2291,27 +2329,31 @@
             detail.setMoney(xpOrderDetail.getMoney());
             if (xpOrderDetail.getDetailType() == 1) {
                 start.add(detail);
-            } else {
+            } else if(xpOrderDetail.getDetailType()==2){
                 mileage.add(detail);
+            }else if(xpOrderDetail.getDetailType()==3){
+                duration.add(detail);
+            }else if(xpOrderDetail.getDetailType()==4){
+                longDistance.add(detail);
             }
         }
-        List<FareBreakdownDetailVo> duration = new ArrayList<>();
-        if (order.getDuration() != null && order.getDuration() > 0) {
-            FareBreakdownDetailVo durationDetail = new FareBreakdownDetailVo();
-            durationDetail.setType(order.getDurationType());
-            durationDetail.setDuration(order.getDuration());
-            durationDetail.setMoney(order.getDurationMoney());
-            duration.add(durationDetail);
-        }
-        List<FareBreakdownDetailVo> longDistance = new ArrayList<>();
 
-        if (order.getLongDistance() != null && order.getLongDistance() > 0) {
-            FareBreakdownDetailVo longDistanceDetail = new FareBreakdownDetailVo();
-            longDistanceDetail.setType(order.getLongDistanceType());
-            longDistanceDetail.setMileage(BigDecimal.valueOf(order.getLongDistance()));
-            longDistanceDetail.setMoney(order.getLongDistancemoney());
-            longDistance.add(longDistanceDetail);
-        }
+//        if (order.getDuration() != null && order.getDuration() > 0) {
+//            FareBreakdownDetailVo durationDetail = new FareBreakdownDetailVo();
+//            durationDetail.setType(order.getDurationType());
+//            durationDetail.setDuration(order.getDuration());
+//            durationDetail.setMoney(order.getDurationMoney());
+//            duration.add(durationDetail);
+//        }
+
+//
+//        if (order.getLongDistance() != null && order.getLongDistance() > 0) {
+//            FareBreakdownDetailVo longDistanceDetail = new FareBreakdownDetailVo();
+//            longDistanceDetail.setType(order.getLongDistanceType());
+//            longDistanceDetail.setMileage(BigDecimal.valueOf(order.getLongDistance()));
+//            longDistanceDetail.setMoney(order.getLongDistancemoney());
+//            longDistance.add(longDistanceDetail);
+//        }
         res.setStart(start);
         res.setMileage(mileage);
         res.setDuration(duration);
@@ -2332,8 +2374,7 @@
         Duration durationBetween = Duration.between(createTime, tripEnd);
 
         // 转换为秒并保留一位小数
-        BigDecimal minutes = BigDecimal.valueOf(durationBetween.getSeconds())
-                ;
+        BigDecimal minutes = BigDecimal.valueOf(durationBetween.getSeconds());
         res.setTime(minutes);
         return R.ok(res);
     }

--
Gitblit v1.7.1