yanderong
2026-06-26 e65ed967249aa68809fc8205a8dc082ec8025396
feat: 专车价格计算逻辑修改
1个文件已修改
178 ■■■■■ 已修改文件
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java
@@ -1285,6 +1285,181 @@
        return orderPrivateCar;
    }
    /**
     * sky
     * 公共费用计算
     * @param orderPrivateCar
     * @param rule  计费规则
     * @param wait  规则-等待时长
     * @param waitMoney 规则-等待单价
     * @param parkingFee    停车费
     * @param crossingFee   过路费
     * @return
     * @throws Exception
     */
    public OrderPrivateCar calculationPrice(OrderPrivateCar orderPrivateCar, JSONObject rule,
                                            long wait, Double waitMoney,
                                            Double parkingFee, Double crossingFee) throws Exception {
        orderPrivateCar.setChargeRule(rule.toJSONString());
        Date date = new Date();
        if (orderPrivateCar.getEndServiceTime() == null) {
            orderPrivateCar.setEndServiceTime(date);
        }
        double d  = (orderPrivateCar.getMileage() == null ? 0D : orderPrivateCar.getMileage()) / 1000;
        double t  = ((orderPrivateCar.getEndServiceTime().getTime()
                - orderPrivateCar.getStartServiceTime().getTime()) / 60000) + 1;
        double d1 = Math.max(0, d - rule.getDouble("num2"));
        double t1 = Math.max(0, t - rule.getDouble("num3"));
        double w  = ((orderPrivateCar.getStartServiceTime().getTime()
                - orderPrivateCar.getArriveTime().getTime()) / 60000) + 1;
        double w1 = (w - wait) < 0 ? 0
                : new BigDecimal(w - wait).setScale(0, BigDecimal.ROUND_UP).doubleValue();
        // 从 num14 开始,每 7 个为一组:numI=时间区间, +1=起步价, +2=里程费率,
        //   +3=时长费率, +4=远途1费率, +5=远途2费率, +6=远途3费率
        int startIndex = 14;
        boolean matched = false;
        while (rule.containsKey("num" + startIndex)) {
            // 必须保证后续 6 个参数都存在
            if (!rule.containsKey("num" + (startIndex + 6))) {
                break;
            }
            String timeRange = rule.getString("num" + startIndex);
            // 兼容 "HH:mm - HH:mm" 和 "HH:mm-HH:mm" 两种格式
            String[] parts = timeRange.split("\\s*-\\s*");
            if (parts.length != 2) {
                startIndex += 7;
                continue;
            }
            try {
                Calendar rangeStart = parseTimeToCalendar(date, parts[0].trim());
                Calendar rangeEnd   = parseTimeToCalendar(date, parts[1].trim());
                // 跨天处理(如 "20:00 - 02:00")
                if (rangeStart.getTimeInMillis() > rangeEnd.getTimeInMillis()) {
                    rangeEnd.add(Calendar.DAY_OF_YEAR, 1);
                }
                boolean inRange = date.getTime() > rangeStart.getTimeInMillis()
                        && date.getTime() < rangeEnd.getTimeInMillis();
                if (inRange) {
                    double qibujia  = rule.getDouble("num" + (startIndex + 1));
                    double lchengLv = rule.getDouble("num" + (startIndex + 2));
                    double schangLv = rule.getDouble("num" + (startIndex + 3));
                    double yt1Lv    = rule.getDouble("num" + (startIndex + 4));
                    double yt2Lv    = rule.getDouble("num" + (startIndex + 5));
                    double yt3Lv    = rule.getDouble("num" + (startIndex + 6));
                    applyPricing(orderPrivateCar, rule, d, d1, t1, w1,
                            waitMoney, parkingFee, crossingFee,
                            qibujia, lchengLv, schangLv, yt1Lv, yt2Lv, yt3Lv);
                    matched = true;
                    break;
                }
            } catch (Exception e) {
                // 时间解析异常时跳过该组,继续匹配下一组
            }
            startIndex += 7;
        }
        // 无任何时间组匹配,使用基础费率(num1 ~ num13)
        if (!matched) {
            applyPricing(orderPrivateCar, rule, d, d1, t1, w1,
                    waitMoney, parkingFee, crossingFee,
                    rule.getDouble("num1"),
                    rule.getDouble("num4"),
                    rule.getDouble("num5"),
                    rule.getDouble("num8"),
                    rule.getDouble("num11"),
                    rule.getDouble("num13"));
        }
        return orderPrivateCar;
    }
    /**
     * sky
     * 将 "HH:mm" 解析为基于 baseDate 当天的 Calendar
     */
    private Calendar parseTimeToCalendar(Date baseDate, String hhmm) {
        String[] hm = hhmm.split(":");
        Calendar cal = Calendar.getInstance();
        cal.setTime(baseDate);
        cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hm[0]));
        cal.set(Calendar.MINUTE,      Integer.parseInt(hm[1]));
        cal.set(Calendar.SECOND,      0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal;
    }
    /**
     * sky
     * 按指定费率计算远途费、各项费用,并写入 orderPrivateCar
     *
     * 远途分段逻辑(与原代码保持一致):
     *   段1:num6 < d < num7  → yt1 = yt1Lv * d
     *   段2:num9 < d < num10 → yt1 = yt1Lv * num7,  yt2 = yt2Lv * (d - num9)
     *   段3:d > num12        → yt1 = yt1Lv * num7,  yt2 = yt2Lv * (num10 - num9),  yt3 = yt3Lv * (d - num12)
     */
    private void applyPricing(OrderPrivateCar orderPrivateCar, JSONObject rule,
                              double d, double d1, double t1, double w1,
                              Double waitMoney, Double parkingFee, Double crossingFee,
                              double qibujia, double lchengLv, double schangLv,
                              double yt1Lv, double yt2Lv, double yt3Lv) {
        double num6  = rule.getDouble("num6");
        double num7  = rule.getDouble("num7");
        double num9  = rule.getDouble("num9");
        double num10 = rule.getDouble("num10");
        double num12 = rule.getDouble("num12");
        double yt1 = 0, yt2 = 0, yt3 = 0;
        if (d > num6 && d < num7) {
            yt1 = yt1Lv * d;
        }
        if (d > num9 && d < num10) {
            yt1 = yt1Lv * num7;
            yt2 = yt2Lv * (d - num9);
        }
        if (d > num12) {
            yt1 = yt1Lv * num7;
            yt2 = yt2Lv * (num10 - num9);
            yt3 = yt3Lv * (d - num12);
        }
        double mileageMoney  = new BigDecimal(d1 * lchengLv).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        double durationMoney = new BigDecimal(t1 * schangLv).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        double waitMoneyAmt  = new BigDecimal(w1 * waitMoney).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        double longDistMoney = new BigDecimal(yt1 + yt2 + yt3).setScale(2, BigDecimal.ROUND_DOWN).doubleValue();
        orderPrivateCar.setStartMileage(rule.getDouble("num2"));
        orderPrivateCar.setStartMoney(qibujia);
        orderPrivateCar.setMileageKilometers(new BigDecimal(d1).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        orderPrivateCar.setMileageMoney(mileageMoney);
        orderPrivateCar.setDuration(new BigDecimal(t1).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        orderPrivateCar.setDurationMoney(durationMoney);
        orderPrivateCar.setWait(new BigDecimal(w1).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        orderPrivateCar.setWaitMoney(waitMoneyAmt);
        orderPrivateCar.setLongDistance(new BigDecimal(d > num6 ? d - num6 : 0).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        orderPrivateCar.setLongDistanceMoney(longDistMoney);
        orderPrivateCar.setParkMoney(parkingFee);
        orderPrivateCar.setRoadTollMoney(crossingFee);
        orderPrivateCar.setRedPacketMoney(0D);
        orderPrivateCar.setCouponMoney(0D);
        orderPrivateCar.setDiscount(0D);
        orderPrivateCar.setPayMoney(0D);
        double amount = qibujia + mileageMoney + durationMoney + waitMoneyAmt + longDistMoney;
        orderPrivateCar.setOrderMoney(amount + parkingFee + crossingFee);
    }
    /**
     * 公共费用计算
@@ -1297,7 +1472,8 @@
     * @return
     * @throws Exception
     */
    public OrderPrivateCar  calculationPrice(OrderPrivateCar orderPrivateCar,JSONObject rule, long wait,Double waitMoney, Double parkingFee, Double crossingFee) throws Exception {
    @Deprecated
    public OrderPrivateCar  calculationPriceBack(OrderPrivateCar orderPrivateCar,JSONObject rule, long wait,Double waitMoney, Double parkingFee, Double crossingFee) throws Exception {
        orderPrivateCar.setChargeRule(rule.toJSONString());
        double amount = 0.0;
        //等待费