| | |
| | | package com.xiaopeng.operation.utils; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.xiaopeng.operation.service.XpPricingService; |
| | | import com.xiaopeng.operation.utils.map.GDMapElectricFenceUtil; |
| | | import com.xiaopeng.operation.utils.holiday.HolidayUtil; |
| | | import com.xiaopeng.operation.utils.map.GDMapGeocodingUtil; |
| | | import com.xiaopeng.operation.vo.XpPricingCardVo; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | public class XpPricingUtil { |
| | | |
| | | @Autowired |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | |
| | | @Autowired |
| | | private GDMapElectricFenceUtil gdMapElectricFenceUtil; |
| | | |
| | | @Autowired |
| | | private XpPricingService xpPricingService; |
| | | |
| | | // public void queryServerCarModel(String startLonLat, String endLonLat, Integer type) throws Exception { |
| | | // //查找与起点匹配的企业(经营范围) |
| | | //// Map<String, String> geocode = gdMapGeocodingUtil.geocode(startLonLat.split(",")[0], startLonLat.split(",")[1]); |
| | | // |
| | | // |
| | | // // TODO: 2023/11/4 无法修改 |
| | | // Map<String, String> distance = gdMapElectricFenceUtil.getDistance(startLonLat, endLonLat, 1); |
| | | // if (null == distance) { |
| | | // return; |
| | | // } |
| | | // String distance1 = distance.get("distance");//距离(米) |
| | | // double distance1_ = Double.valueOf(distance1).doubleValue(); |
| | | // String duration = distance.get("duration");//时间(秒) |
| | | // long duration_ = Long.valueOf(duration).longValue(); |
| | | // |
| | | // |
| | | // List<ServerCarModelWarpper> price = this.getPrice(query.getId(), distance1_, duration_, 0, 1); |
| | | // //添加出租车车型和价格 |
| | | // ServerCarModelWarpper serverCarModelWarpper = this.getTextPrice(query.getId(), distance1_, duration_, 0, 2); |
| | | // price.add(serverCarModelWarpper); |
| | | // return ResultUtil.success(price); |
| | | // } |
| | | // |
| | | // |
| | | // /** |
| | | // * |
| | | // * @param distance 米 |
| | | // * @param duration 秒 |
| | | // * @param cityId |
| | | // * @return |
| | | // * @throws Exception |
| | | // */ |
| | | // public ServerCarModelWarpper getPrice(double distance, long duration, Long cityId) throws Exception { |
| | | // XpPricing xpPricing = xpPricingService.getOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, cityId)); |
| | | // if (null == xpPricing) { |
| | | // return null; |
| | | // } |
| | | // BigDecimal money =BigDecimal.ZERO; |
| | | // String basicPricingJson = xpPricing.getBasicPricingJson(); |
| | | // JSONObject jsonObject = JSON.parseObject(basicPricingJson); |
| | | // Double v2 = calculationPrice(jsonObject, distance, duration, 0, 0.0); |
| | | // return v2; |
| | | // } |
| | | private HolidayUtil holidayUtil; |
| | | |
| | | |
| | | public Double calculationPrice(JSONObject rule, double distance, long duration, long wait,Double waitMoney) throws Exception { |
| | | |
| | | /** |
| | | * 计算基础价格 |
| | | * @param rule |
| | | * @param distance |
| | | * @param duration |
| | | * @param wait |
| | | * @param waitMoney |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public XpPricingCardVo calculationPrice(JSONObject rule, JSONArray startingFareJson, double distance, long duration, long wait, Double waitMoney) throws Exception { |
| | | XpPricingCardVo xpPricingCardVo = new XpPricingCardVo(); |
| | | double amount = 0; |
| | | //等待费 |
| | | Date date = new Date(); |
| | | double d = distance / 1000;//实际公里 |
| | | double t = duration / 60;//实际时间 |
| | | double d1 = (d - rule.getDouble("num2")) < 0 ? 0 : d - rule.getDouble("num2");//超出起步里程的公里 |
| | | double t1 = (t - rule.getDouble("num3")) < 0 ? 0 : t - rule.getDouble("num3");//超过起步分钟数的时间 |
| | | double yt1 = 0;//远途1段 |
| | | double yt2 = 0;//远途2段 |
| | | double yt3 = 0;//远途3段 |
| | | // 计算出是在那个时间段内 |
| | | 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("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 s = Calendar.getInstance(); |
| | | s.setTime(date); |
| | | s.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num14").split(" - ")[0].split(":")[0])); |
| | | s.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num14").split(" - ")[0].split(":")[1])); |
| | | 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 e = Calendar.getInstance(); |
| | | e.setTime(date); |
| | | e.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num14").split(" - ")[1].split(":")[0])); |
| | | e.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num14").split(" - ")[1].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])); |
| | | |
| | | if(date.getTime() > s.getTimeInMillis() && date.getTime() < e.getTimeInMillis()){ |
| | | if(d > rule.getDouble("num6")){ |
| | | yt1 = rule.getDouble("num18") * (d - rule.getDouble("num6")); |
| | | // 先判断今日是否节假日 |
| | | boolean holiday = holidayUtil.isHoliday(); |
| | | if (holiday) { |
| | | if (realDistance > rule.getDouble("num6")) { |
| | | longDistanceOne = rule.getDouble("num32") * (realDistance - rule.getDouble("num6")); |
| | | } |
| | | if(d > rule.getDouble("num9")){ |
| | | yt2 = rule.getDouble("num19") * (d - rule.getDouble("num9")); |
| | | if (realDistance > rule.getDouble("num9")) { |
| | | longDistanceTwo = rule.getDouble("num33") * (realDistance - rule.getDouble("num9")); |
| | | } |
| | | if(d > rule.getDouble("num12")){ |
| | | yt3 = rule.getDouble("num20") * (d - rule.getDouble("num12")); |
| | | if (realDistance > rule.getDouble("num12")) { |
| | | longDistanceThree = rule.getDouble("num34") * (realDistance - rule.getDouble("num12")); |
| | | } |
| | | amount = rule.getDouble("num15") + (d1 * rule.getDouble("num16")) + (t1 * rule.getDouble("num17")) + (wait * waitMoney) + yt1 + yt2 + yt3; |
| | | }else{ |
| | | Calendar s1 = Calendar.getInstance(); |
| | | s1.setTime(date); |
| | | s1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num21").split(" - ")[0].split(":")[0])); |
| | | s1.set(Calendar.MINUTE, Integer.valueOf(rule.getString("num21").split(" - ")[0].split(":")[1])); |
| | | amount = rule.getDouble("num29") + (exceedDistance * rule.getDouble("num30")) + (exceedTime * rule.getDouble("num31")) + (wait * waitMoney) + longDistanceOne + longDistanceTwo + longDistanceThree; |
| | | |
| | | Calendar e1 = Calendar.getInstance(); |
| | | e1.setTime(date); |
| | | e1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(rule.getString("num21").split(" - ")[1].split(":")[0])); |
| | | e1.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])); |
| | | // 起步价 |
| | | xpPricingCardVo.setStartPrice(rule.getDouble("num29")); |
| | | // 时间段 |
| | | xpPricingCardVo.setTime("节假日"); |
| | | |
| | | 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() > s1.getTimeInMillis() && date.getTime() < e1.getTimeInMillis()) || (date.getTime() > s2.getTimeInMillis() && date.getTime() < e2.getTimeInMillis())){ |
| | | if(d > rule.getDouble("num6")){ |
| | | yt1 = rule.getDouble("num26") * (d - rule.getDouble("num6")); |
| | | |
| | | // 里程 |
| | | xpPricingCardVo.setDistance(realDistance); |
| | | |
| | | // 里程费 |
| | | double distancePrice = (exceedDistance * rule.getDouble("num30")) + longDistanceOne + longDistanceTwo + longDistanceThree; |
| | | 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")) { |
| | | longDistanceOne = rule.getDouble("num18") * (realDistance - rule.getDouble("num6")); |
| | | } |
| | | if(d > rule.getDouble("num9")){ |
| | | yt2 = rule.getDouble("num27") * (d - rule.getDouble("num9")); |
| | | if (realDistance > rule.getDouble("num9")) { |
| | | longDistanceTwo = rule.getDouble("num19") * (realDistance - rule.getDouble("num9")); |
| | | } |
| | | if(d > rule.getDouble("num12")){ |
| | | yt3 = rule.getDouble("num28") * (d - rule.getDouble("num12")); |
| | | if (realDistance > rule.getDouble("num12")) { |
| | | longDistanceThree = rule.getDouble("num20") * (realDistance - rule.getDouble("num12")); |
| | | } |
| | | amount = rule.getDouble("num23") + (d1 * rule.getDouble("num24")) + (t1 * rule.getDouble("num25")) + (wait * waitMoney) + yt1 + yt2 + yt3; |
| | | }else{ |
| | | //其他时间段的计算 |
| | | if(d > rule.getDouble("num6")){ |
| | | yt1 = rule.getDouble("num8") * (d - rule.getDouble("num6")); |
| | | amount = rule.getDouble("num15") + (exceedDistance * rule.getDouble("num16")) + (exceedTime * rule.getDouble("num17")) + (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; |
| | | 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")) { |
| | | longDistanceOne = rule.getDouble("num26") * (realDistance - rule.getDouble("num6")); |
| | | } |
| | | if (realDistance > rule.getDouble("num9")) { |
| | | longDistanceTwo = rule.getDouble("num27") * (realDistance - rule.getDouble("num9")); |
| | | } |
| | | if (realDistance > rule.getDouble("num12")) { |
| | | longDistanceThree = rule.getDouble("num28") * (realDistance - rule.getDouble("num12")); |
| | | } |
| | | amount = rule.getDouble("num23") + (exceedDistance * rule.getDouble("num24")) + (exceedTime * rule.getDouble("num25")) + (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; |
| | | xpPricingCardVo.setDistancePrice(distancePrice); |
| | | |
| | | // 时长 |
| | | xpPricingCardVo.setDuration(realTime); |
| | | |
| | | // 时长费 |
| | | xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num25"))); |
| | | |
| | | } else { |
| | | //其他时间段的计算 |
| | | if (realDistance > rule.getDouble("num6")) { |
| | | longDistanceOne = rule.getDouble("num8") * (realDistance - rule.getDouble("num6")); |
| | | } |
| | | if (realDistance > rule.getDouble("num9")) { |
| | | longDistanceTwo = rule.getDouble("num11") * (realDistance - rule.getDouble("num9")); |
| | | } |
| | | if (realDistance > rule.getDouble("num12")) { |
| | | longDistanceThree = rule.getDouble("num13") * (realDistance - rule.getDouble("num12")); |
| | | } |
| | | amount = rule.getDouble("num1") + (exceedDistance * rule.getDouble("num4")) + (exceedTime * rule.getDouble("num5")) + (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; |
| | | xpPricingCardVo.setDistancePrice(distancePrice); |
| | | |
| | | // 时长 |
| | | xpPricingCardVo.setDuration(realTime); |
| | | |
| | | // 时长费 |
| | | xpPricingCardVo.setDurationPrice((exceedTime * rule.getDouble("num5"))); |
| | | |
| | | } |
| | | if(d > rule.getDouble("num9")){ |
| | | yt2 = rule.getDouble("num11") * (d - rule.getDouble("num9")); |
| | | } |
| | | if(d > rule.getDouble("num12")){ |
| | | yt3 = rule.getDouble("num13") * (d - rule.getDouble("num12")); |
| | | } |
| | | amount = rule.getDouble("num1") + (d1 * rule.getDouble("num4")) + (t1 * rule.getDouble("num5")) + (wait * waitMoney) + yt1 + yt2 + yt3; |
| | | } |
| | | } |
| | | return amount; |
| | | |
| | | // 订单总额 |
| | | xpPricingCardVo.setTotalPrice(amount); |
| | | |
| | | |
| | | return xpPricingCardVo; |
| | | } |
| | | } |