From e65ed967249aa68809fc8205a8dc082ec8025396 Mon Sep 17 00:00:00 2001
From: yanderong <307678080@qq.com>
Date: 星期五, 26 六月 2026 19:50:46 +0800
Subject: [PATCH] feat: 专车价格计算逻辑修改
---
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 177 insertions(+), 1 deletions(-)
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java
index 2ebe385..b6e009e 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/specialTrain/server/impl/OrderPrivateCarServiceImpl.java
+++ b/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;
//等待费
--
Gitblit v1.7.1