From 85bafa86f44fbe6646019fd8ecbab79f552ccd0a Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期三, 04 二月 2026 21:44:38 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 xp-service/xp-operation/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java |  335 ++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 220 insertions(+), 115 deletions(-)

diff --git a/xp-service/xp-operation/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java b/xp-service/xp-operation/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java
index 0f5849e..0b79b0b 100644
--- a/xp-service/xp-operation/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java
+++ b/xp-service/xp-operation/src/main/java/com/xiaopeng/operation/utils/XpPricingUtil.java
@@ -1,9 +1,10 @@
 package com.xiaopeng.operation.utils;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.xiaopeng.operation.service.XpPricingService;
-import com.xiaopeng.operation.utils.map.GDMapElectricFenceUtil;
+import com.xiaopeng.operation.utils.holiday.HolidayUtil;
 import com.xiaopeng.operation.utils.map.GDMapGeocodingUtil;
+import com.xiaopeng.operation.vo.XpPricingCardVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -18,140 +19,244 @@
 public class XpPricingUtil {
 
     @Autowired
-    private GDMapGeocodingUtil gdMapGeocodingUtil;
-
-    @Autowired
-    private GDMapElectricFenceUtil gdMapElectricFenceUtil;
-
-    @Autowired
-    private XpPricingService xpPricingService;
-
-//    public void queryServerCarModel(String startLonLat, String endLonLat, Integer type) throws Exception {
-//        //查找与起点匹配的企业(经营范围)
-////        Map<String, String> geocode = gdMapGeocodingUtil.geocode(startLonLat.split(",")[0], startLonLat.split(",")[1]);
-//
-//
-//        // TODO: 2023/11/4 无法修改
-//        Map<String, String> distance = gdMapElectricFenceUtil.getDistance(startLonLat, endLonLat, 1);
-//        if (null == distance) {
-//            return;
-//        }
-//        String distance1 = distance.get("distance");//距离(米)
-//        double distance1_ = Double.valueOf(distance1).doubleValue();
-//        String duration = distance.get("duration");//时间(秒)
-//        long duration_ = Long.valueOf(duration).longValue();
-//
-//
-//        List<ServerCarModelWarpper> price = this.getPrice(query.getId(), distance1_, duration_, 0, 1);
-//        //添加出租车车型和价格
-//        ServerCarModelWarpper serverCarModelWarpper = this.getTextPrice(query.getId(), distance1_, duration_, 0, 2);
-//        price.add(serverCarModelWarpper);
-//        return ResultUtil.success(price);
-//    }
-//
-//
-//    /**
-//     *
-//     * @param distance 米
-//     * @param duration 秒
-//     * @param cityId
-//     * @return
-//     * @throws Exception
-//     */
-//    public ServerCarModelWarpper getPrice(double distance, long duration, Long cityId) throws Exception {
-//        XpPricing xpPricing = xpPricingService.getOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, cityId));
-//        if (null == xpPricing) {
-//            return null;
-//        }
-//        BigDecimal money =BigDecimal.ZERO;
-//        String basicPricingJson = xpPricing.getBasicPricingJson();
-//        JSONObject jsonObject = JSON.parseObject(basicPricingJson);
-//        Double v2 = calculationPrice(jsonObject, distance, duration, 0, 0.0);
-//        return v2;
-//    }
+    private HolidayUtil holidayUtil;
 
 
-    public Double  calculationPrice(JSONObject rule, double distance, long duration, long wait,Double waitMoney) throws Exception {
+
+    /**
+     *  计算基础价格
+     * @param rule
+     * @param distance
+     * @param duration
+     * @param wait
+     * @param waitMoney
+     * @return
+     * @throws Exception
+     */
+    public XpPricingCardVo calculationPrice(JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney) throws Exception {
+        XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
         double amount = 0;
         //等待费
         Date date = new Date();
-        double d = distance / 1000;//实际公里
-        double t = duration / 60;//实际时间
-        double d1 = (d - rule.getDouble("num2")) < 0 ? 0 : d - rule.getDouble("num2");//超出起步里程的公里
-        double t1 = (t - rule.getDouble("num3")) < 0 ? 0 : t - rule.getDouble("num3");//超过起步分钟数的时间
-        double yt1 = 0;//远途1段
-        double yt2 = 0;//远途2段
-        double yt3 = 0;//远途3段
+        // 计算出是在那个时间段内
+        for (Object o : startingFareJson) {
+            JSONObject startingFare = (JSONObject) o;
+            Calendar calendarStart = Calendar.getInstance();
+            calendarStart.setTime(date);
+            calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startingFare.getString("num1").split(":")[0]));
+            calendarStart.set(Calendar.MINUTE, Integer.valueOf(startingFare.getString("num1").split(":")[1]));
+
+            Calendar calendarEnd = Calendar.getInstance();
+            calendarEnd.setTime(date);
+            calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startingFare.getString("num2").split(":")[0]));
+            calendarEnd.set(Calendar.MINUTE, Integer.valueOf(startingFare.getString("num2").split(":")[1]));
+            // 找到符合条件的直接跳出循环
+            if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) {
+                rule.put("num1", startingFare.get("num3"));
+                rule.put("num2", startingFare.get("num4"));
+                rule.put("num3", startingFare.get("num5"));
+                rule.put("num4", startingFare.get("num6"));
+                rule.put("num5", startingFare.get("num7"));
+
+                rule.put("startTime", startingFare.getString("num1"));
+                rule.put("endTime", startingFare.getString("num2"));
+                break;
+            }
+        }
+
+
+        double realDistance = distance / 1000;//实际公里
+        double realTime = duration / 60;//实际时间
+        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 longDistanceOne = 0;//远途1段
+        double longDistanceTwo = 0;//远途2段
+        double longDistanceThree = 0;//远途3段
 
 
         //夜间服务处理逻辑
-        Calendar s = Calendar.getInstance();
-        s.setTime(date);
-        s.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num14").split(" - ")[0].split(":")[0]));
-        s.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num14").split(" - ")[0].split(":")[1]));
+        Calendar calendarNight = Calendar.getInstance();
+        calendarNight.setTime(date);
+        calendarNight.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num14").split(" - ")[0].split(":")[0]));
+        calendarNight.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num14").split(" - ")[0].split(":")[1]));
 
-        Calendar e = Calendar.getInstance();
-        e.setTime(date);
-        e.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num14").split(" - ")[1].split(":")[0]));
-        e.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num14").split(" - ")[1].split(":")[1]));
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num14").split(" - ")[1].split(":")[0]));
+        calendar.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num14").split(" - ")[1].split(":")[1]));
 
-        if(date.getTime() > s.getTimeInMillis() && date.getTime() < e.getTimeInMillis()){
-            if(d > rule.getDouble("num6")){
-                yt1 = rule.getDouble("num18") * (d - rule.getDouble("num6"));
+        // 先判断今日是否节假日
+        boolean holiday = holidayUtil.isHoliday();
+        if (holiday) {
+            if (realDistance > rule.getDouble("num6")) {
+                longDistanceOne = rule.getDouble("num32") * (realDistance - rule.getDouble("num6"));
             }
-            if(d >  rule.getDouble("num9")){
-                yt2 = rule.getDouble("num19") * (d - rule.getDouble("num9"));
+            if (realDistance > rule.getDouble("num9")) {
+                longDistanceTwo = rule.getDouble("num33") * (realDistance - rule.getDouble("num9"));
             }
-            if(d > rule.getDouble("num12")){
-                yt3 = rule.getDouble("num20") * (d - rule.getDouble("num12"));
+            if (realDistance > rule.getDouble("num12")) {
+                longDistanceThree = rule.getDouble("num34") * (realDistance - rule.getDouble("num12"));
             }
-            amount = rule.getDouble("num15") + (d1 * rule.getDouble("num16")) + (t1 * rule.getDouble("num17")) + (wait * waitMoney) + yt1 + yt2 + yt3;
-        }else{
-            Calendar s1 = Calendar.getInstance();
-            s1.setTime(date);
-            s1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num21").split(" - ")[0].split(":")[0]));
-            s1.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num21").split(" - ")[0].split(":")[1]));
+            amount = rule.getDouble("num29") + (exceedDistance * rule.getDouble("num30")) + (exceedTime * rule.getDouble("num31")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
 
-            Calendar e1 = Calendar.getInstance();
-            e1.setTime(date);
-            e1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num21").split(" - ")[1].split(":")[0]));
-            e1.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num21").split(" - ")[1].split(":")[1]));
 
-            Calendar s2 = Calendar.getInstance();
-            s2.setTime(date);
-            s2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num22").split(" - ")[0].split(":")[0]));
-            s2.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num22").split(" - ")[0].split(":")[1]));
+            // 起步价
+            xpPricingCardVo.setStartPrice(rule.getDouble("num29"));
+            // 时间段
+            xpPricingCardVo.setTime("节假日");
 
-            Calendar e2 = Calendar.getInstance();
-            e2.setTime(date);
-            e2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num22").split(" - ")[1].split(":")[0]));
-            e2.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num22").split(" - ")[1].split(":")[1]));
-            //高峰时段处理逻辑
-            if((date.getTime() > s1.getTimeInMillis() && date.getTime() < e1.getTimeInMillis()) || (date.getTime() > s2.getTimeInMillis() && date.getTime() < e2.getTimeInMillis())){
-                if(d > rule.getDouble("num6")){
-                    yt1 = rule.getDouble("num26") * (d - rule.getDouble("num6"));
+
+            // 里程
+            xpPricingCardVo.setDistance(realDistance);
+
+            // 里程费
+            double distancePrice = (exceedDistance * rule.getDouble("num30")) + longDistanceOne + longDistanceTwo + longDistanceThree;
+            xpPricingCardVo.setDistancePrice(distancePrice);
+
+            // 时长
+            xpPricingCardVo.setDuration(realTime);
+
+            // 时长费
+            xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num31")));
+
+
+        } else {
+            if (date.getTime() > calendarNight.getTimeInMillis() && date.getTime() < calendar.getTimeInMillis()) {
+                if (realDistance > rule.getDouble("num6")) {
+                    longDistanceOne = rule.getDouble("num18") * (realDistance - rule.getDouble("num6"));
                 }
-                if(d >  rule.getDouble("num9")){
-                    yt2 = rule.getDouble("num27") * (d - rule.getDouble("num9"));
+                if (realDistance > rule.getDouble("num9")) {
+                    longDistanceTwo = rule.getDouble("num19") * (realDistance - rule.getDouble("num9"));
                 }
-                if(d > rule.getDouble("num12")){
-                    yt3 = rule.getDouble("num28") * (d - rule.getDouble("num12"));
+                if (realDistance > rule.getDouble("num12")) {
+                    longDistanceThree = rule.getDouble("num20") * (realDistance - rule.getDouble("num12"));
                 }
-                amount = rule.getDouble("num23") + (d1 * rule.getDouble("num24")) + (t1 * rule.getDouble("num25")) + (wait * waitMoney) + yt1 + yt2 + yt3;
-            }else{
-                //其他时间段的计算
-                if(d > rule.getDouble("num6")){
-                    yt1 = rule.getDouble("num8") * (d - rule.getDouble("num6"));
+                amount = rule.getDouble("num15") + (exceedDistance * rule.getDouble("num16")) + (exceedTime * rule.getDouble("num17")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
+
+
+                // 起步价
+                xpPricingCardVo.setStartPrice(rule.getDouble("num15"));
+                // 时间段
+                xpPricingCardVo.setTime(rule.getString("num14"));
+
+                // 里程
+                xpPricingCardVo.setDistance(realDistance);
+
+                // 里程费
+                double distancePrice = (exceedDistance * rule.getDouble("num16")) + longDistanceOne + longDistanceTwo + longDistanceThree;
+                xpPricingCardVo.setDistancePrice(distancePrice);
+
+                // 时长
+                xpPricingCardVo.setDuration(realTime);
+
+                // 时长费
+                xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num17")));
+
+
+            } else {
+
+                // 高峰处理
+                Calendar calendarStart = Calendar.getInstance();
+                calendarStart.setTime(date);
+                calendarStart.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num21").split(" - ")[0].split(":")[0]));
+                calendarStart.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num21").split(" - ")[0].split(":")[1]));
+
+                Calendar calendarEnd = Calendar.getInstance();
+                calendarEnd.setTime(date);
+                calendarEnd.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num21").split(" - ")[1].split(":")[0]));
+                calendarEnd.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num21").split(" - ")[1].split(":")[1]));
+
+                Calendar s2 = Calendar.getInstance();
+                s2.setTime(date);
+                s2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num22").split(" - ")[0].split(":")[0]));
+                s2.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num22").split(" - ")[0].split(":")[1]));
+
+                Calendar e2 = Calendar.getInstance();
+                e2.setTime(date);
+                e2.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num22").split(" - ")[1].split(":")[0]));
+                e2.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num22").split(" - ")[1].split(":")[1]));
+                //高峰时段处理逻辑
+                if ((date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) || (date.getTime() > s2.getTimeInMillis() && date.getTime() < e2.getTimeInMillis())) {
+                    if (realDistance > rule.getDouble("num6")) {
+                        longDistanceOne = rule.getDouble("num26") * (realDistance - rule.getDouble("num6"));
+                    }
+                    if (realDistance > rule.getDouble("num9")) {
+                        longDistanceTwo = rule.getDouble("num27") * (realDistance - rule.getDouble("num9"));
+                    }
+                    if (realDistance > rule.getDouble("num12")) {
+                        longDistanceThree = rule.getDouble("num28") * (realDistance - rule.getDouble("num12"));
+                    }
+                    amount = rule.getDouble("num23") + (exceedDistance * rule.getDouble("num24")) + (exceedTime * rule.getDouble("num25")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
+
+
+                    // 起步价
+                    xpPricingCardVo.setStartPrice(rule.getDouble("num23"));
+                    // 时间段
+                    if (date.getTime() > calendarStart.getTimeInMillis() && date.getTime() < calendarEnd.getTimeInMillis()) {
+                        xpPricingCardVo.setTime(rule.getString("num21"));
+                    } else {
+                        xpPricingCardVo.setTime(rule.getString("num22"));
+                    }
+
+
+                    // 里程
+                    xpPricingCardVo.setDistance(realDistance);
+
+                    // 里程费
+                    double distancePrice = (exceedDistance * rule.getDouble("num24")) + longDistanceOne + longDistanceTwo + longDistanceThree;
+                    xpPricingCardVo.setDistancePrice(distancePrice);
+
+                    // 时长
+                    xpPricingCardVo.setDuration(realTime);
+
+                    // 时长费
+                    xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num25")));
+
+                } else {
+                    //其他时间段的计算
+                    if (realDistance > rule.getDouble("num6")) {
+                        longDistanceOne = rule.getDouble("num8") * (realDistance - rule.getDouble("num6"));
+                    }
+                    if (realDistance > rule.getDouble("num9")) {
+                        longDistanceTwo = rule.getDouble("num11") * (realDistance - rule.getDouble("num9"));
+                    }
+                    if (realDistance > rule.getDouble("num12")) {
+                        longDistanceThree = rule.getDouble("num13") * (realDistance - rule.getDouble("num12"));
+                    }
+                    amount = rule.getDouble("num1") + (exceedDistance * rule.getDouble("num4")) + (exceedTime * rule.getDouble("num5")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
+
+
+                    // 起步价
+                    xpPricingCardVo.setStartPrice(rule.getDouble("num1"));
+                    // 时间段
+                    xpPricingCardVo.setTime(rule.getString("startTime") + " - " + rule.getString("endTime"));
+
+                    xpPricingCardVo.setDistancePriceNormal(rule.getDouble("num2"));
+
+                    xpPricingCardVo.setDurationPriceNormal(rule.getDouble("num3"));
+
+
+                    // 里程
+                    xpPricingCardVo.setDistance(realDistance);
+
+                    // 里程费
+                    double distancePrice = (exceedDistance * rule.getDouble("num4")) + longDistanceOne + longDistanceTwo + longDistanceThree;
+                    xpPricingCardVo.setDistancePrice(distancePrice);
+
+                    // 时长
+                    xpPricingCardVo.setDuration(realTime);
+
+                    // 时长费
+                    xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num5")));
+
                 }
-                if(d >  rule.getDouble("num9")){
-                    yt2 = rule.getDouble("num11") * (d - rule.getDouble("num9"));
-                }
-                if(d > rule.getDouble("num12")){
-                    yt3 = rule.getDouble("num13") * (d - rule.getDouble("num12"));
-                }
-                amount = rule.getDouble("num1") + (d1 * rule.getDouble("num4")) + (t1 * rule.getDouble("num5")) + (wait * waitMoney) + yt1 + yt2 + yt3;
             }
         }
-        return amount;
+
+        // 订单总额
+        xpPricingCardVo.setTotalPrice(amount);
+
+
+        return xpPricingCardVo;
     }
 }

--
Gitblit v1.7.1