| | |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | | * 公共费用计算 |
| | |
| | | * @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; |
| | | //等待费 |