无关风月
2026-02-12 67aeb1bc74d582c0f82ae19f4a0b087f9d3a73b3
修改费用明细返回结构
2个文件已修改
853 ■■■■■ 已修改文件
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java 825 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -860,8 +860,34 @@
        if (pricing == null) {
            throw new ServiceException("当前城市未配置定价规则", I18nKeyConstant.ORDER_PRICING_NOT_EXISTS);
        }
        // 查询订单轨迹
        List<OrderTrajectory> trajectories = mongoTemplate.find(
                new Query(Criteria.where("orderId").is(orderId))
                        .with(Sort.by(Sort.Direction.ASC, "locatetime")),
                OrderTrajectory.class
        );
        // 计算等待时间
        LocalDateTime boardingTime = order.getBoardingTime();// 上车时间
        LocalDateTime arrivalTime = order.getArrivalTime();// 车辆到达上车点时间
        // 行程开始时间
        Integer waitTime =Math.abs( (int) Duration.between(boardingTime, arrivalTime).getSeconds());
        // 计算订单总行驶距离,单位米
        Double totalDistance = 0.00D;
        // 行程总时间 秒
        LocalDateTime tripBegin = order.getTripBegin();
        LocalDateTime tripEnd = order.getTripEnd();
        long seconds = Duration.between(tripBegin, tripEnd).getSeconds();
        for (OrderTrajectory trajectory : trajectories) {
        }
//        XpPricingCardVo xpPricingCardVo = xpPricingUtil.calculationPrice(
//
//                order.getAppUserId().toString(),JSON.parseObject(pricing.getBasicPricingJson()),
//                JSON.parseArray(pricing.getStartingFareJson()),
//                pricing.getDynamicPricingJson(),
//                pricing.getIsDynamicPrice(),
//                totalDistance,
//                seconds,
//                order.getCityId()
//        );
//        Long id = pricing.getId();
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java
@@ -1,420 +1,129 @@
package com.xiaopeng.order.utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.vo.order.XpPricingCardVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.order.utils.holiday.HolidayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
 * 计算价格的工具类
 */
@Slf4j
@Component
public class XpPricingUtil {
    @Autowired
    private HolidayUtil holidayUtil;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IXpOrderService orderService;
    /**
     * 获取起步里程
     *
     * @param startingFareJsonStr
     * @return
     */
    public static Integer getStartMileage(String startingFareJsonStr) {
        Date date = new Date();
        JSONArray startingFareJson = JSONObject.parseArray(startingFareJsonStr);
        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()) {
                Integer mileage = startingFare.getInteger("num4");
                return mileage;
            }
        }
        return null;
    }
    /**
     * 计算基础价格
     *
     * @param rule                 基础规则
     * @param distance             里程
     * @param duration             时间
     * @param wait                 时间
     * @param waitMoney            等待费
     * @param openCityId           开通城市id
     * @param isDynamicPriceStatus 是否开启动态调价
     * @return
     * @throws Exception
     */
    public XpPricingCardVo calculationPrice(String uid, JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney, Integer isDynamicPriceStatus, Long openCityId, String dynamicPricingJson) {
        // 默认费率1
        double priceRate = 1;
        if (isDynamicPriceStatus == 1) {
            // 先判断是否已经调价过了
            Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid);
            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();
                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
                    Integer num = orderService.getOrderNum(new GetOrderNumDto(timeStr, openCityId));
                    // 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);
                    }
                }
            }
        }
        XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
        double amount = 0;
        //等待费
        Date date = new Date();
        // 计算出是在那个时间段内
        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 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 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]));
        // 先判断今日是否节假日
        boolean holiday = holidayUtil.isHoliday();
        if (holiday) {
            if (realDistance > rule.getDouble("num6")) {
                longDistanceOne = rule.getDouble("num32") * (realDistance - rule.getDouble("num6"));
            }
            if (realDistance > rule.getDouble("num9")) {
                longDistanceTwo = rule.getDouble("num33") * (realDistance - rule.getDouble("num9"));
            }
            if (realDistance > rule.getDouble("num12")) {
                longDistanceThree = rule.getDouble("num34") * (realDistance - rule.getDouble("num12"));
            }
            amount = rule.getDouble("num29") + (exceedDistance * rule.getDouble("num30")) + (exceedTime * rule.getDouble("num31")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
            // 起步价
            xpPricingCardVo.setStartPrice(rule.getDouble("num29"));
            // 时间段
            xpPricingCardVo.setTime("节假日");
            // 里程
            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 (realDistance > rule.getDouble("num9")) {
                    longDistanceTwo = rule.getDouble("num19") * (realDistance - rule.getDouble("num9"));
                }
                if (realDistance > rule.getDouble("num12")) {
                    longDistanceThree = rule.getDouble("num20") * (realDistance - rule.getDouble("num12"));
                }
                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")));
                }
            }
        }
        // 订单总额
        Double startPrice = xpPricingCardVo.getStartPrice();
        // 先减去起步价重新计算
        amount = amount - startPrice;
        // 动态计算费用
        startPrice = new BigDecimal(startPrice).multiply(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
        amount = amount + startPrice;
        xpPricingCardVo.setTotalPrice(amount);
        return xpPricingCardVo;
    }
    /**
     *  行程结束后计算费用
     * @param rule 基础规则
     * @param distance 里程
     * @param duration  时间
     * @param wait  时间
     * @param waitMoney 等待费
     * @param openCityId 开通城市id
     * @param isDynamicPriceStatus 是否开启动态调价
     * @return
     * @throws Exception
     */
//    public XpPricingCardVo calculationFinalPrice(String uid,JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney,Integer isDynamicPriceStatus,Long openCityId,String dynamicPricingJson) {
//package com.xiaopeng.order.utils;
//
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import com.xiaopeng.api.dto.order.GetOrderNumDto;
//import com.xiaopeng.api.feignClient.order.XpOrderClient;
//import com.xiaopeng.api.vo.order.XpPricingCardVo;
//import com.xiaopeng.common.core.domain.R;
//import com.xiaopeng.common.redis.service.RedisService;
//import com.xiaopeng.order.service.IXpOrderService;
//import com.xiaopeng.order.utils.holiday.HolidayUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.util.Calendar;
//import java.util.Date;
//import java.util.concurrent.TimeUnit;
//
///**
// * 计算价格的工具类
// */
//@Slf4j
//@Component
//public class XpPricingUtil {
//
//    @Autowired
//    private HolidayUtil holidayUtil;
//
//    @Autowired
//    private RedisService redisService;
//    @Autowired
//    private IXpOrderService orderService;
//
//    /**
//     * 获取起步里程
//     *
//     * @param startingFareJsonStr
//     * @return
//     */
//    public static Integer getStartMileage(String startingFareJsonStr) {
//        Date date = new Date();
//        JSONArray startingFareJson = JSONObject.parseArray(startingFareJsonStr);
//        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()) {
//                Integer mileage = startingFare.getInteger("num4");
//                return mileage;
//            }
//        }
//        return null;
//    }
//
//
//    /**
//     * 计算基础价格
//     * @param uid                 用户id
//     * @param rule                 基础规则
//     * @param distance             里程
//     * @param duration             时间
//     * @param isDynamicPriceStatus 是否开启动态调价
//     *
//     * @param openCityId           开通城市id
//     * @return
//     * @throws Exception
//     */
//    public XpPricingCardVo calculationPrice(String uid, JSONObject rule,
//                                            JSONArray startingFareJson,
//                                            String dynamicPricingJson,
//                                            Integer isDynamicPriceStatus,
//                                            double distance,
//                                            long duration,
//                                            Long openCityId) {
//        // 默认费率1
//        double priceRate=1;
//        if(isDynamicPriceStatus==1){
//        double priceRate = 1;
//        if (isDynamicPriceStatus == 1) {
//            // 先判断是否已经调价过了
//            Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid);
//            if(userDynamicPriceObj!=null){
//            if (userDynamicPriceObj != null) {
//                // 是否调价过了
//                priceRate = Double.parseDouble(userDynamicPriceObj.toString());
//            }else {
//            } else {
//                // 没有调过
//                //是否触发动态调价 redis获取
//                Object dynamicPriceObj = redisService.getCacheObject("DYNAMIC_PRICE_" + openCityId);
//                if(dynamicPriceObj!=null){
//                if (dynamicPriceObj != null) {
//                    JSONObject jsonObject = JSONObject.parseObject(dynamicPricingJson);
//                    // 触发动态调价
//                    // value=时间
//                    String timeStr = dynamicPriceObj.toString();
//                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
//                    R<Integer> r = xpOrderClient.getOrderNum(timeStr);
//                    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);
//                    Integer num = orderService.getOrderNum(new GetOrderNumDto(timeStr, openCityId));
//                    // 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);
//                    }
//
//                }
//            }
//
//        }
//
//
//
//        XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
@@ -641,24 +350,318 @@
//        // 先减去起步价重新计算
//        amount = amount - startPrice;
//        // 动态计算费用
//        startPrice= new BigDecimal(startPrice).multiply(new BigDecimal(priceRate)).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);
//
//
//        return xpPricingCardVo;
//    }
    /**
     * 获取配置  4每X单  5上升X%  6冷却
     *
     * @param rule
     * @param num
     * @return
     */
    private Integer getOrderNum(JSONObject rule, int num) {
        Integer param = rule.getInteger("num" + num);
        return param;
    }
}
//    /**
//     *  行程结束后计算费用
//     * @param rule 基础规则
//     * @param distance 里程
//     * @param duration  时间
//     * @param wait  时间
//     * @param waitMoney 等待费
//     * @param openCityId 开通城市id
//     * @param isDynamicPriceStatus 是否开启动态调价
//     * @return
//     * @throws Exception
//     */
////    public XpPricingCardVo calculationFinalPrice(String uid,JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney,Integer isDynamicPriceStatus,Long openCityId,String dynamicPricingJson) {
////
////
////        // 默认费率1
////        double priceRate=1;
////        if(isDynamicPriceStatus==1){
////            // 先判断是否已经调价过了
////            Object userDynamicPriceObj = redisService.getCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid);
////            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(timeStr);
////                    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);
////                        }
////                    }
////
////                }
////            }
////
////        }
////
////
////
////        XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
////        double amount = 0;
////        //等待费
////        Date date = new Date();
////        // 计算出是在那个时间段内
////        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 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 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]));
////
////        // 先判断今日是否节假日
////        boolean holiday = holidayUtil.isHoliday();
////        if (holiday) {
////            if (realDistance > rule.getDouble("num6")) {
////                longDistanceOne = rule.getDouble("num32") * (realDistance - rule.getDouble("num6"));
////            }
////            if (realDistance > rule.getDouble("num9")) {
////                longDistanceTwo = rule.getDouble("num33") * (realDistance - rule.getDouble("num9"));
////            }
////            if (realDistance > rule.getDouble("num12")) {
////                longDistanceThree = rule.getDouble("num34") * (realDistance - rule.getDouble("num12"));
////            }
////            amount = rule.getDouble("num29") + (exceedDistance * rule.getDouble("num30")) + (exceedTime * rule.getDouble("num31")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree;
////
////
////            // 起步价
////            xpPricingCardVo.setStartPrice(rule.getDouble("num29"));
////            // 时间段
////            xpPricingCardVo.setTime("节假日");
////
////
////            // 里程
////            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 (realDistance > rule.getDouble("num9")) {
////                    longDistanceTwo = rule.getDouble("num19") * (realDistance - rule.getDouble("num9"));
////                }
////                if (realDistance > rule.getDouble("num12")) {
////                    longDistanceThree = rule.getDouble("num20") * (realDistance - rule.getDouble("num12"));
////                }
////                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")));
////
////                }
////            }
////        }
////
////        // 订单总额
////        Double startPrice = xpPricingCardVo.getStartPrice();
////        // 先减去起步价重新计算
////        amount = amount - startPrice;
////        // 动态计算费用
////        startPrice= new BigDecimal(startPrice).multiply(new BigDecimal(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
////        amount = amount+startPrice;
////        xpPricingCardVo.setTotalPrice(amount);
////
////
////        return xpPricingCardVo;
////    }
//
//
//    /**
//     * 获取配置  4每X单  5上升X%  6冷却
//     *
//     * @param rule
//     * @param num
//     * @return
//     */
//    private Integer getOrderNum(JSONObject rule, int num) {
//        Integer param = rule.getInteger("num" + num);
//        return param;
//    }
//}