yanderong
2026-06-26 5fafb0cc62a59c6258909fa72e7b9d33dac69155
feat: 专车计算价格逻辑修改
1个文件已修改
133 ■■■■■ 已修改文件
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ServerCarModelServiceImpl.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ServerCarModelServiceImpl.java
@@ -421,9 +421,138 @@
        
        return serverCarModelWarpper;
    }
    /**
     * 专车费用计算
     */
    public Map<String, Object> calculationPrice(JSONObject rule, double distance, long duration, long wait, Double waitMoney) throws Exception {
        Map<String, Object> map = new HashMap<>();
        Date date = new Date();
        double d = distance / 1000;          // 实际公里
        double t = duration / 60;            // 实际分钟
        double d1 = Math.max(0, d - rule.getDouble("num2")); // 超出起步里程
        double t1 = Math.max(0, t - rule.getDouble("num3")); // 超出起步时间
        // 从 num14 开始,每 7 个为一组,动态匹配时间区间
        // 每组结构:numI=时间区间, numI+1=起步价, numI+2=里程费, numI+3=时间费,
        //           numI+4=远途1费率, numI+5=远途2费率, numI+6=远途3费率
        int startIndex = 14;
        boolean matched = false;
        while (rule.containsKey("num" + startIndex)) {
            String timeRangeKey = "num" + startIndex;
            String timeRange = rule.getString(timeRangeKey);
            // 确保后续6个参数都存在,否则跳出
            if (!rule.containsKey("num" + (startIndex + 6))) {
                break;
            }
            // 解析时间区间,兼容 "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());
                boolean inRange;
                if (rangeStart.before(rangeEnd)) {
                    // 同日区间,例如 "08:00 - 10:00"
                    inRange = date.getTime() > rangeStart.getTimeInMillis()
                            && date.getTime() < rangeEnd.getTimeInMillis();
                } else {
                    // 跨午夜区间,例如 "20:00 - 02:00"
                    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));
                    buildResult(map, rule, d, d1, t1, wait, waitMoney,
                            qibujia, lchengLv, schangLv, yt1Lv, yt2Lv, yt3Lv);
                    matched = true;
                    break;
                }
            } catch (Exception e) {
                // 时间解析失败时跳过该组,继续下一组
            }
            startIndex += 7;
        }
        // 没有任何时间区间匹配,使用基础时段费率(num1 ~ num13)
        if (!matched) {
            buildResult(map, rule, d, d1, t1, wait, waitMoney,
                    rule.getDouble("num1"),
                    rule.getDouble("num4"),
                    rule.getDouble("num5"),
                    rule.getDouble("num8"),
                    rule.getDouble("num11"),
                    rule.getDouble("num13"));
        }
        return map;
    }
    /**
     * 将 "HH:mm" 字符串解析为当天对应的 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;
    }
    /**
     * 计算远途费和总价并写入 map
     */
    private void buildResult(Map<String, Object> map, JSONObject rule,
                             double d, double d1, double t1,
                             long wait, Double waitMoney,
                             double qibujia, double lchengLv, double schangLv,
                             double yt1Lv, double yt2Lv, double yt3Lv) {
        double yt1 = d > rule.getDouble("num6")  ? yt1Lv * (d - rule.getDouble("num6"))  : 0;
        double yt2 = d > rule.getDouble("num9")  ? yt2Lv * (d - rule.getDouble("num9"))  : 0;
        double yt3 = d > rule.getDouble("num12") ? yt3Lv * (d - rule.getDouble("num12")) : 0;
        double lichengfei = d1 * lchengLv;
        double schangfei  = t1 * schangLv;
        double dengdaifei = wait * waitMoney;
        double yuantufei  = yt1 + yt2 + yt3;
        double total      = qibujia + lichengfei + schangfei + dengdaifei + yuantufei;
        map.put("qibujia",   qibujia);
        map.put("lichengfei", lichengfei);
        map.put("shichangfei", schangfei);
        map.put("dengdaifei", dengdaifei);
        map.put("yuantufei",  yuantufei);
        map.put("zongfeiyong", total);
    }
    /**
     * 专车计算逻辑用上面的新方法(这个方法废弃)
     */
    @Deprecated
    public Map<String, Object> calculationPriceBack(JSONObject rule, double distance, long duration, long wait, Double waitMoney) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //等待费
        Date date = new Date();