liujie
2026-03-13 49b8de3a8447b1766dec1eeb160044e8e302d8b2
处理结束行程一口价
4个文件已修改
1291 ■■■■■ 已修改文件
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 599 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java 689 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -98,7 +98,7 @@
    @Resource
    private XpCruisePlanClient xpCruisePlanClient;
    @Resource
    @Resource(name = "hutoolSnowflake")
    private Snowflake snowflake;
    @Value("${robotaxi.appId:xp_robotaxi_api}")
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/OrderCancelJob.java
@@ -6,6 +6,7 @@
import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
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
@@ -1014,11 +1016,9 @@
        for (XpHistoryStartPointsVo datum : data) {
            if(datum.getOperationStatus()==2){
            if (datum.getOperationStatus() == 2) {
                datum.setOperationStatus(1);
            }
            // 保留2位数小数
@@ -1382,7 +1382,7 @@
                break;
            case 7:
                // 查询自动结束行程时间
                if(xpOrder.getOpenTrunk() != 1){
                if (xpOrder.getOpenTrunk() != 1) {
                    Integer arriveTime = xpSystemSettingClient.getOrderFinishTime().getData();
                    // 添加自动结束行程定时任务job
                    Map<String, ? extends Object> endTripJobMaps =
@@ -1429,6 +1429,8 @@
        // 远途费价格明细
        List<FareBreakdownDetailVo> longDistance = new ArrayList<>();
        XpOrder order = this.getById(orderId);
        Long orderAppUserId = order.getAppUserId();
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
@@ -1492,266 +1494,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());
@@ -1765,12 +1801,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));
@@ -2057,10 +2097,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) {
@@ -2272,6 +2308,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) {
@@ -2283,27 +2321,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);
@@ -2324,8 +2366,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);
    }
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/utils/XpPricingUtil.java
@@ -1,129 +1,576 @@
//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;
//    }
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.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.time.LocalDate;
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 XpOrderClient xpOrderClient;
    /**
     * 获取起步里程
     * @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;
    }
    /**
     * 计算一口价
     */
    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){
            // 先判断是否已经调价过了
            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(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);
                        }
                    }
                }
            }
        }
        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 distancePrice = new BigDecimal(rule.getDouble("num4") * exceedDistance).setScale(2,RoundingMode.HALF_UP).doubleValue();
        // 超出时间价格
        Double durationPrice = new BigDecimal(rule.getDouble("num5") * exceedTime).setScale(2,RoundingMode.HALF_UP).doubleValue();
        startPrice = new BigDecimal(startPrice).multiply(BigDecimal.valueOf(priceRate)).setScale(2, RoundingMode.HALF_UP).doubleValue();
        xpPricingCardVo.setStartPrice(startPrice);
        xpPricingCardVo.setDistancePrice(distancePrice);
        xpPricingCardVo.setDurationPrice(durationPrice);
        xpPricingCardVo.setTotalPrice(startPrice + distancePrice + durationPrice);
        // 里程
        xpPricingCardVo.setDistance(realDistance);
        xpPricingCardVo.setDuration(realTime);
        return xpPricingCardVo;
    }
    /**
     *  计算基础价格
     * @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();
                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
                    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);
                        }
                    }
                }
            }
        }
        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("num6", startingFare.get("num4"));
                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(LocalDate.now());
        if (holiday) {
            if (realDistance > rule.getDouble("num6") && realDistance < rule.getDouble("num7")) {
                longDistanceOne = rule.getDouble("num32") * (realDistance - rule.getDouble("num6"));
                longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
            }
            if (realDistance > rule.getDouble("num7")) {
                longDistanceOne = rule.getDouble("num32") * (rule.getDouble("num7") - rule.getDouble("num6"));
                longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
            }
            if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
                longDistanceTwo = rule.getDouble("num33") * (realDistance - rule.getDouble("num9"));
                longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
            }
            if (realDistance > rule.getDouble("num10")) {
                longDistanceTwo = rule.getDouble("num33") * (rule.getDouble("num10") - rule.getDouble("num9"));
                longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
            }
            if (realDistance > rule.getDouble("num12")) {
                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.setTime("节假日");
            // 里程
            xpPricingCardVo.setDistance(realDistance);
            // 里程费
            double distancePrice = (exceedDistance * rule.getDouble("num30")) + longDistanceOne + longDistanceTwo + longDistanceThree;
            distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
            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") && realDistance < rule.getDouble("num7")) {
                    longDistanceOne = rule.getDouble("num18") * (realDistance - rule.getDouble("num6"));
                    longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
                }
                if (realDistance > rule.getDouble("num7")) {
                    longDistanceOne = rule.getDouble("num18") * (rule.getDouble("num7") - rule.getDouble("num6"));
                    longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
                }
                if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
                    longDistanceTwo = rule.getDouble("num19") * (realDistance - rule.getDouble("num9"));
                    longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
                }
                if (realDistance > rule.getDouble("num10")) {
                    longDistanceTwo = rule.getDouble("num19") * (rule.getDouble("num10") - rule.getDouble("num9"));
                    longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
                }
                if (realDistance > rule.getDouble("num12")) {
                    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.setTime(rule.getString("num14"));
                // 里程
                xpPricingCardVo.setDistance(realDistance);
                // 里程费
                double distancePrice = (exceedDistance * rule.getDouble("num16")) + longDistanceOne + longDistanceTwo + longDistanceThree;
                distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
                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") && realDistance < rule.getDouble("num7")) {
                        longDistanceOne = rule.getDouble("num26") * (realDistance - rule.getDouble("num6"));
                        longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num7")) {
                        longDistanceOne = rule.getDouble("num26") * (rule.getDouble("num7") - rule.getDouble("num6"));
                        longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
                        longDistanceTwo = rule.getDouble("num27") * (realDistance - rule.getDouble("num9"));
                        longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num10")) {
                        longDistanceTwo = rule.getDouble("num27") * (rule.getDouble("num10") - rule.getDouble("num9"));
                        longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num12")) {
                        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"));
                    // 时间段
                    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;
                    distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    xpPricingCardVo.setDistancePrice(distancePrice);
                    // 时长
                    xpPricingCardVo.setDuration(realTime);
                    // 时长费
                    xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num25")));
                } else {
                    //其他时间段的计算
                    if (realDistance > rule.getDouble("num6") && realDistance < rule.getDouble("num7")) {
                        longDistanceOne = rule.getDouble("num8") * (realDistance - rule.getDouble("num6"));
                        longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num7")) {
                        longDistanceOne = rule.getDouble("num8") * (rule.getDouble("num7") - rule.getDouble("num6"));
                        longDistanceOne = new BigDecimal(longDistanceOne).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num9") && realDistance < rule.getDouble("num10")) {
                        longDistanceTwo = rule.getDouble("num11") * (realDistance - rule.getDouble("num9"));
                        longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num10")) {
                        longDistanceTwo = rule.getDouble("num11") * (rule.getDouble("num10") - rule.getDouble("num9"));
                        longDistanceTwo = new BigDecimal(longDistanceTwo).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    }
                    if (realDistance > rule.getDouble("num12")) {
                        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.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;
                    distancePrice = new BigDecimal(distancePrice).setScale(2,RoundingMode.HALF_UP).doubleValue();
                    xpPricingCardVo.setDistancePrice(distancePrice);
                    // 时长
                    xpPricingCardVo.setDuration(realTime);
                    // 时长费
                    xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num5")));
                }
            }
        }
        // 订单总额
        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);
        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) {
//
//
//    /**
//     * 计算基础价格
//     * @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();
//                    // 判断当前距离这个时间范围的新增订单数(排除取消) / 上浮数量 算出应该增加的价格率
//                    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();
//                    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 time = getOrderNum(jsonObject, 6);
//                        // 触发调价了
//                        redisService.setCacheObject("USER_DYNAMIC_PRICE_" + openCityId + "_" + uid, priceRate, time.longValue(), TimeUnit.MINUTES);
//                    }
//
//                }
//            }
//
//        }
//
//
//
//        XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
@@ -207,6 +654,7 @@
//
//            // 时长
//            xpPricingCardVo.setDuration(realTime);
//
//            // 时长费
//            xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num31")));
//
@@ -349,25 +797,24 @@
//        // 先减去起步价重新计算
//        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;
//    }
//}
    /**
     * 获取配置  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;
    }
}