From c96fbe6b0aeb413a17c429133ee6d81d138144b9 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 09 六月 2026 10:58:52 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.0

---
 xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java |  222 +++++++++++++++++++++++++++++--------------------------
 1 files changed, 117 insertions(+), 105 deletions(-)

diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java
index 9d1e4a8..d94e351 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java
@@ -2,8 +2,11 @@
 
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
+import com.xiaopeng.api.dto.WeatherDTO;
 import com.xiaopeng.api.dto.order.GetOrderNumDto;
+import com.xiaopeng.api.feignClient.map.XpMapClient;
 import com.xiaopeng.api.feignClient.order.XpOrderClient;
+import com.xiaopeng.api.model.operation.XpOpenCity;
 import com.xiaopeng.api.vo.order.XpPricingCardVo;
 import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.redis.service.RedisService;
@@ -15,8 +18,11 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -34,6 +40,9 @@
 
     @Autowired
     private XpOrderClient xpOrderClient;
+
+    @Autowired
+    private XpMapClient xpMapClient;
 
 
     /**
@@ -70,67 +79,77 @@
      */
     public XpPricingCardVo calculationFixedPrice(String uid, JSONObject rule, JSONArray startingFareJson, double distance, double duration, long wait, Double waitMoney, Integer isDynamicPriceStatus, Long openCityId, String dynamicPricingJson) {
         // 默认费率1
-        double priceRate=1;
-        if(isDynamicPriceStatus==1){
+        double priceRate = 100;
+        if (isDynamicPriceStatus == 1) {
             // 先判断是否已经调价过了
             Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid);
-            if(userDynamicPriceObj!=null){
+            if (userDynamicPriceObj != null) {
                 // 是否调价过了
                 priceRate = Double.parseDouble(userDynamicPriceObj.toString());
-            }else {
-                // 没有调过
-                //是否触发动态调价 redis获取
-                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + openCityId);
-                if(dynamicPriceObj!=null){
-                    JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
-                    // 触发动态调价
-                    // value=时间
-                    String timeStr = dynamicPriceObj.toString();
-                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
-                    R<Integer> r = xpOrderClient.getOrderNum(new GetOrderNumDto(timeStr,openCityId));
-                    if(r.getData()==200){
-                        int num = r.getData();
-                        // 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_" + openCityId + "_" + uid, priceRate,time.longValue(), TimeUnit.MINUTES);
-                        }
+            } else {
+                JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
+                Integer num1 = jsonObject.getInteger("num1");
+                String timeStr = LocalDateTime.now().minusMinutes(num1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
+                Integer num = xpOrderClient.getOrderNum(new GetOrderNumDto(timeStr,openCityId)).getData();
+                // 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();
                     }
-
+                    if(priceRate > 1){
+                        // 冷却时间
+                        Integer time = getOrderNum(jsonObject, 6);
+                        // 触发调价了
+                        redisService.setCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
+                    }
                 }
             }
+            log.info("供需后的费率 {}", priceRate);
 
+            JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
+            // 天气预报动态调价
+            JSONArray ws = jsonObject.getJSONArray("weatherRules");
+            if (null != ws) {
+                WeatherDTO data = xpMapClient.wether(openCityId.toString()).getData();
+                List<WeatherDTO.Lives> lives = data.getLives();
+                if (lives != null && !lives.isEmpty()) {
+                    String w = lives.get(0).getWeather();
+                    for (Object o : ws) {
+                        JSONObject ele = JSONObject.parseObject(o.toString());
+                        if (w.contains(ele.getString("weatherType")) || ele.getString("weatherType").contains(w)) {
+                            double floatRate = ele.getDouble("ratio");
+                            priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
+                            break;
+                        }
+                    }
+                }
+            }
         }
+        priceRate = new BigDecimal(priceRate).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
+        log.info("浮动费率 {}", priceRate);
 
         XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
-        double amount = 0;
-
         double realDistance = distance;//实际公里
         double realTime = duration ;//实际时间
         double exceedDistance = (realDistance - rule.getDouble("num2")) < 0 ? 0 : realDistance - rule.getDouble("num2");//超出起步里程的公里
         double exceedTime = (realTime - rule.getDouble("num3")) < 0 ? 0 : realTime - rule.getDouble("num3");//超过起步分钟数的时间
 
         // 起步价
-        Double startPrice = rule.getDouble("num1");
+        Double startPrice = rule.getDouble("num1") * priceRate;
 
         // 超出公里数价格
-        Double distancePrice = new BigDecimal(rule.getDouble("num4") * exceedDistance).setScale(2,RoundingMode.HALF_UP).doubleValue();
+        Double distancePrice = new BigDecimal(rule.getDouble("num4") * exceedDistance).multiply(BigDecimal.valueOf(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue();
 
         // 超出时间价格
-        Double durationPrice = new BigDecimal(rule.getDouble("num5") * exceedTime).setScale(2,RoundingMode.HALF_UP).doubleValue();
+        Double durationPrice = new BigDecimal(rule.getDouble("num5") * exceedTime).multiply(BigDecimal.valueOf(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue();
 
         startPrice = new BigDecimal(startPrice).multiply(BigDecimal.valueOf(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
 
@@ -144,6 +163,8 @@
 
         return xpPricingCardVo;
     }
+
+
 
     /**
      *  计算基础价格
@@ -169,47 +190,55 @@
                 // 是否调价过了
                 priceRate = Double.parseDouble(userDynamicPriceObj.toString());
             }else {
-                // 没有调过
-                //是否触发动态调价 redis获取
-                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + openCityId);
-                if(dynamicPriceObj!=null){
-                    JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
-                    // 触发动态调价
-                    // value=时间
-                    String timeStr = dynamicPriceObj.toString();
-                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
-                    R<Integer> r = xpOrderClient.getOrderNum(new GetOrderNumDto(timeStr,openCityId));
-                    if(r.getData()==200){
-                        int num = r.getData();
-                        // 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_" + openCityId + "_" + uid, priceRate,time.longValue(), TimeUnit.MINUTES);
+                JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
+                Integer num1 = jsonObject.getInteger("num1");
+                String timeStr = LocalDateTime.now().minusMinutes(num1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
+                R<Integer> r = xpOrderClient.getOrderNum(new GetOrderNumDto(timeStr,openCityId));
+                if(r.getCode()==200){
+                    int num = r.getData();
+                    // 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_" + openCityId + "_" + uid, priceRate,time.longValue(), TimeUnit.MINUTES);
+                    }
                 }
             }
-
+            log.info("供需后的费率 {}", priceRate);
+            JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
+            // 天气预报动态调价
+            JSONArray ws = jsonObject.getJSONArray("weatherRules");
+            if (null != ws) {
+                WeatherDTO data = xpMapClient.wether(openCityId.toString()).getData();
+                List<WeatherDTO.Lives> lives = data.getLives();
+                if (lives != null && !lives.isEmpty()) {
+                    String w = lives.get(0).getWeather();
+                    for (Object o : ws) {
+                        JSONObject ele = JSONObject.parseObject(o.toString());
+                        if (w.contains(ele.getString("weatherType")) || ele.getString("weatherType").contains(w)) {
+                            double floatRate = ele.getDouble("ratio");
+                            priceRate = new BigDecimal(priceRate).add(new BigDecimal(floatRate)).doubleValue();
+                            break;
+                        }
+                    }
+                }
+            }
         }
 
-
-
         XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
-        double amount = 0;
         //等待费
         Date date = new Date();
         // 计算出是在那个时间段内
@@ -287,11 +316,10 @@
                 longDistanceThree = rule.getDouble("num34") * (realDistance - rule.getDouble("num12"));
                 longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
             }
-            amount = rule.getDouble("num29") + new BigDecimal(exceedDistance * rule.getDouble("num30")).setScale(2,RoundingMode.HALF_UP).doubleValue() + new BigDecimal(exceedTime * rule.getDouble("num31")).setScale(2,RoundingMode.HALF_UP).doubleValue() + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
 
 
             // 起步价
-            xpPricingCardVo.setStartPrice(rule.getDouble("num29"));
+            xpPricingCardVo.setStartPrice(new BigDecimal(rule.getDouble("num29")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
             // 时间段
             xpPricingCardVo.setTime("节假日");
 
@@ -302,13 +330,13 @@
             // 里程费
             double distancePrice = (exceedDistance * rule.getDouble("num30")) + longDistanceOne + longDistanceTwo + longDistanceThree;
             distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
-            xpPricingCardVo.setDistancePrice(distancePrice);
+            xpPricingCardVo.setDistancePrice(new BigDecimal(distancePrice).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
             // 时长
             xpPricingCardVo.setDuration(realTime);
 
             // 时长费
-            xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num31")));
+            xpPricingCardVo.setDurationPrice(new BigDecimal(exceedTime * rule.getDouble("num31")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
 
         } else {
@@ -338,11 +366,10 @@
                     longDistanceThree = rule.getDouble("num20") * (realDistance - rule.getDouble("num12"));
                     longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
                 }
-                amount = rule.getDouble("num15") + new BigDecimal(exceedDistance * rule.getDouble("num16")).setScale(2,RoundingMode.HALF_UP).doubleValue() + new BigDecimal(exceedTime * rule.getDouble("num17")).setScale(2,RoundingMode.HALF_UP).doubleValue() + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
 
 
                 // 起步价
-                xpPricingCardVo.setStartPrice(rule.getDouble("num15"));
+                xpPricingCardVo.setStartPrice(new BigDecimal(rule.getDouble("num15")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
                 // 时间段
                 xpPricingCardVo.setTime(rule.getString("num14"));
 
@@ -351,14 +378,13 @@
 
                 // 里程费
                 double distancePrice = (exceedDistance * rule.getDouble("num16")) + longDistanceOne + longDistanceTwo + longDistanceThree;
-                distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
-                xpPricingCardVo.setDistancePrice(distancePrice);
+                xpPricingCardVo.setDistancePrice(new BigDecimal(distancePrice).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
                 // 时长
                 xpPricingCardVo.setDuration(realTime);
 
                 // 时长费
-                xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num17")));
+                xpPricingCardVo.setDurationPrice(new BigDecimal(exceedTime * rule.getDouble("num17")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
 
             } else {
@@ -410,11 +436,10 @@
                         longDistanceThree = rule.getDouble("num28") * (realDistance - rule.getDouble("num12"));
                         longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
                     }
-                    amount = rule.getDouble("num23") + new BigDecimal(exceedDistance * rule.getDouble("num24")).setScale(2,RoundingMode.HALF_UP).doubleValue() + new BigDecimal(exceedTime * rule.getDouble("num25")).setScale(2,RoundingMode.HALF_UP).doubleValue() + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
 
 
                     // 起步价
-                    xpPricingCardVo.setStartPrice(rule.getDouble("num23"));
+                    xpPricingCardVo.setStartPrice(new BigDecimal(rule.getDouble("num23")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
                     // 时间段
                     if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) {
                         xpPricingCardVo.setTime(rule.getString("num21"));
@@ -428,14 +453,13 @@
 
                     // 里程费
                     double distancePrice = (exceedDistance * rule.getDouble("num24")) + longDistanceOne + longDistanceTwo + longDistanceThree;
-                    distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
-                    xpPricingCardVo.setDistancePrice(distancePrice);
+                    xpPricingCardVo.setDistancePrice(new BigDecimal(distancePrice).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
                     // 时长
                     xpPricingCardVo.setDuration(realTime);
 
                     // 时长费
-                    xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num25")));
+                    xpPricingCardVo.setDurationPrice(new BigDecimal(exceedTime * rule.getDouble("num25")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
                 } else {
                     //其他时间段的计算
@@ -465,11 +489,9 @@
                         longDistanceThree = rule.getDouble("num13") * (realDistance - rule.getDouble("num12"));
                         longDistanceThree = new BigDecimal(longDistanceThree).setScale(2,RoundingMode.HALF_UP).doubleValue();
                     }
-                    amount = rule.getDouble("num1") + new BigDecimal(exceedDistance * rule.getDouble("num4")).setScale(2,RoundingMode.HALF_UP).doubleValue() + new BigDecimal(exceedTime * rule.getDouble("num5")).setScale(2,RoundingMode.HALF_UP).doubleValue() + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
-
 
                     // 起步价
-                    xpPricingCardVo.setStartPrice(rule.getDouble("num1"));
+                    xpPricingCardVo.setStartPrice(new BigDecimal(rule.getDouble("num1")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
                     // 时间段
                     xpPricingCardVo.setTime(rule.getString("startTime") + " - " + rule.getString("endTime"));
 
@@ -483,31 +505,21 @@
 
                     // 里程费
                     double distancePrice = (exceedDistance * rule.getDouble("num4")) + longDistanceOne + longDistanceTwo + longDistanceThree;
-                    distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
-                    xpPricingCardVo.setDistancePrice(distancePrice);
+                    xpPricingCardVo.setDistancePrice(new BigDecimal(distancePrice).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
                     // 时长
                     xpPricingCardVo.setDuration(realTime);
 
                     // 时长费
-                    xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num5")));
+                    xpPricingCardVo.setDurationPrice(new BigDecimal(exceedTime * rule.getDouble("num5")).multiply(new BigDecimal(priceRate)).setScale(2,RoundingMode.HALF_UP).doubleValue());
 
                 }
             }
         }
 
         // 订单总额
-        Double startPrice = xpPricingCardVo.getStartPrice();
-        amount=new BigDecimal(amount).setScale(2,RoundingMode.HALF_UP).doubleValue();
-        // 先减去起步价重新计算
-        amount = amount - startPrice;
-        // 动态计算费用
-        startPrice= new BigDecimal(startPrice).multiply(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
-        amount = amount+startPrice;
-        xpPricingCardVo.setTotalPrice(amount);
-
-
-
+        double amount = xpPricingCardVo.getStartPrice() + xpPricingCardVo.getDistancePrice() + xpPricingCardVo.getDurationPrice();
+        xpPricingCardVo.setTotalPrice(new BigDecimal(amount).setScale(2,RoundingMode.HALF_UP).doubleValue());
         return xpPricingCardVo;
     }
     /**

--
Gitblit v1.7.1