liujie
2026-04-28 ffe5f35c096fe2be0d38ec9abf3a2468caba7a40
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
@@ -7,10 +7,12 @@
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.account.controller.AppOrderController;
import com.stylefeng.guns.modular.crossCity.dao.DriverSelfTripMapper;
import com.stylefeng.guns.modular.crossCity.dao.LinePriceMapper;
import com.stylefeng.guns.modular.crossCity.dao.LineMapper;
import com.stylefeng.guns.modular.crossCity.dao.LineShiftDriverMapper;
import com.stylefeng.guns.modular.crossCity.dao.OrderCrossCityMapper;
import com.stylefeng.guns.modular.crossCity.model.DriverSelfTrip;
import com.stylefeng.guns.modular.crossCity.model.Line;
import com.stylefeng.guns.modular.crossCity.model.LineShiftDriver;
import com.stylefeng.guns.modular.crossCity.model.LineSite;
@@ -89,6 +91,9 @@
   
   @Resource
   private OrderTaxiMapper orderTaxiMapper;
   @Resource
   private DriverSelfTripMapper driverSelfTripMapper;
   
   @Resource
@@ -132,6 +137,9 @@
   
   @Autowired
   private GDMapGeocodingUtil gdMapGeocodingUtil;
   @Autowired
   private GeodesyUtil geodesyUtil;
   
   @Autowired
   private ChinaMobileUtil chinaMobileUtil;
@@ -239,28 +247,24 @@
   @Override
   public ResultUtil queryOrderMoney(String startLonLat, String endLonLat, Integer peopleNumber, Integer travelMode, Integer lineId,
                                     Integer lineDestinationId, Integer serverCarModelId, Integer totalSeat, String seatNumber) throws Exception {
      if (lineDestinationId != null) {
         Map<String, Object> destination = lineMapper.queryLineDestinationById(lineDestinationId, lineId);
         if (destination == null) {
            return ResultUtil.error("目的地不存在");
      Double endLon = null;
      Double endLat = null;
      if (ToolUtil.isNotEmpty(endLonLat) && endLonLat.contains(",")) {
         String[] endArr = endLonLat.split(",");
         if (endArr.length == 2) {
            endLon = Double.valueOf(endArr[0]);
            endLat = Double.valueOf(endArr[1]);
         }
         Object priceObj = (totalSeat != null && totalSeat <= 5) ? destination.get("price5") : destination.get("price7");
         if (priceObj == null) {
            return ResultUtil.error("目的地价格未配置");
         }
         double unitPrice = Double.valueOf(String.valueOf(priceObj));
         double totalPrice = new BigDecimal(unitPrice).multiply(new BigDecimal(peopleNumber)).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
         Map<String, Object> map = new HashMap<>();
         map.put("distance", 0);
         map.put("price", totalPrice);
         return ResultUtil.success(map);
      }
      // TODO: 2023/11/4 无法修改
      Map<String, String> distance = gdMapElectricFenceUtil.getDistance(startLonLat, endLonLat, 1);//调用高德计算距离
      if (null != distance) {
         return this.getPrice(Double.valueOf(distance.get("distance")), peopleNumber, travelMode, lineId, serverCarModelId, totalSeat, seatNumber);
      ResultUtil<Map<String, Object>> result = this.getPriceV2(lineId, lineDestinationId, totalSeat, peopleNumber, endLon, endLat, null);
      if (result.getCode() != 200) {
         return result;
      }
      Double price = Double.valueOf(String.valueOf(result.getData().get("price")));
      if (price < 0) {
         return ResultUtil.error("获取距离计算出错");
      }
      return result;
   }
   
   /**
@@ -1316,9 +1320,16 @@
      endAddress = endAddress.replaceAll("& #41;", ")");
      orderCrossCity.setEndAddress(endAddress);
      orderCrossCity.setMileage(0D);
      ResultUtil<Map<String, Object>> price = this.getPrice(orderCrossCityWarpper.getDistance(), orderCrossCityWarpper.getPeopleNumber(), orderCrossCityWarpper.getTravelMode(), orderCrossCityWarpper.getLineId(),
            orderCrossCityWarpper.getServerCarModelId(), orderCrossCityWarpper.getTotalSeat(), orderCrossCityWarpper.getSeatNumber());
      ResultUtil<Map<String, Object>> price = this.getPriceV2(orderCrossCityWarpper.getLineId(), orderCrossCityWarpper.getLineDestinationId(),
            orderCrossCityWarpper.getTotalSeat(), orderCrossCityWarpper.getPeopleNumber(), orderCrossCityWarpper.getEndLon(),
            orderCrossCityWarpper.getEndLat(), orderCrossCityWarpper.getLineShiftDriverId());
      if (price.getCode() != 200) {
         return ResultUtil.error("计算价格失败");
      }
      Double money = Double.valueOf(price.getData().get("price").toString());
      if (money < 0) {
         return ResultUtil.error("计算价格失败");
      }
      orderCrossCity.setOrderMoney(money);
      Integer companyId = driver.getCompanyId();
      orderCrossCity.setCompanyId(companyId);
@@ -2993,12 +3004,29 @@
      }
      String seatNumber = seatNumberBuilder.toString();
      // 6. 获取线路班次信息
      LineSite lineSite = lineSiteService.selectById(lineShiftDriver.getLineShiftId());
      LineSite lineSite;
      if (lineShiftDriver.getLineShiftId() != null && lineShiftDriver.getLineShiftId() == -1) {
         lineSite = new LineSite();
         lineSite.setId(-1);
         lineSite.setLineId(-1);
         Integer customerId = lineShiftDriverMapper.queryCustomerIdByLineShiftDriverId(lineShiftDriver.getId());
         if (customerId != null) {
            DriverSelfTrip selfTrip = driverSelfTripMapper.selectById(customerId);
            if (selfTrip != null) {
               lineSite.setStartTime(selfTrip.getStartTime());
            }
         }
      } else {
         lineSite = lineSiteService.selectById(lineShiftDriver.getLineShiftId());
      }
      if (lineSite == null) {
         return ResultUtil.error("线路班次信息不存在");
      }
      Line line = lineService.selectById(lineSite.getLineId());
      if (line == null) {
      Line line = null;
      if (lineSite.getLineId() != null && lineSite.getLineId() != -1) {
         line = lineService.selectById(lineSite.getLineId());
      }
      if (lineSite.getLineId() != null && lineSite.getLineId() != -1 && line == null) {
         return ResultUtil.error("线路信息不存在");
      }
@@ -3026,13 +3054,13 @@
      }
      // 10. 计算价格
      Map<String, String> distanceMap = gdMapElectricFenceUtil.getDistance(
            warpper.getStartLon() + "," + warpper.getStartLat(),
            warpper.getEndLon() + "," + warpper.getEndLat(), 1);
      if (distanceMap == null) {
         return ResultUtil.error("计算行程距离出错");
      }
      Double distance = Double.valueOf(distanceMap.get("distance"));
//      Map<String, String> distanceMap = gdMapElectricFenceUtil.getDistance(
//            warpper.getStartLon() + "," + warpper.getStartLat(),
//            warpper.getEndLon() + "," + warpper.getEndLat(), 1);
//      if (distanceMap == null) {
//         return ResultUtil.error("计算行程距离出错");
//      }
//      Double distance = Double.valueOf(distanceMap.get("distance"));
      // 获取车辆信息
      Car car = carMapper.selectById(driver.getCarId());
@@ -3047,12 +3075,14 @@
      if(null == carService){
         return ResultUtil.error("车辆未开通该服务");
      }
      ResultUtil<Map<String, Object>> priceResult = this.getPrice(distance, warpper.getPeopleNumber(), 1,
            lineSite.getLineId(), carService.getServerCarModelId(), lineShiftDriver.getTotalSeat(), seatNumber);
      ResultUtil<Map<String, Object>> priceResult = this.getPriceV2(lineSite.getLineId(), lineShiftDriver, warpper);
      if (priceResult.getCode() != 200) {
         return ResultUtil.error("计算价格失败");
      }
      Double ticketPrice = Double.valueOf(priceResult.getData().get("price").toString());
      if (ticketPrice < 0) {
         return ResultUtil.error("计算价格失败");
      }
      // 计算合计费用
      Double otherFee = warpper.getOtherFee() != null ? warpper.getOtherFee().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() : 0D;
@@ -3204,4 +3234,201 @@
      baseWarpper.setId(orderCrossCity.getId());
      return ResultUtil.success(baseWarpper);
   }
   public ResultUtil<Map<String, Object>> getPriceV2(Integer lineId, LineShiftDriver lineShiftDriver, OrderCrossCityScanWarpper warpper) {
      Map<String, Object> map = new HashMap<>();
      map.put("distance", 0);
      if (lineShiftDriver == null || warpper == null || warpper.getEndLon() == null || warpper.getEndLat() == null
            || warpper.getPeopleNumber() == null || warpper.getPeopleNumber() <= 0) {
         map.put("price", -1);
         return ResultUtil.success(map);
      }
      if (lineId != null && lineId == -1) {
         BigDecimal price = querySelfTripNearestPrice(lineShiftDriver, warpper);
         map.put("price", price == null ? -1 : multiplyPeopleNumber(price, warpper.getPeopleNumber()).doubleValue());
         return ResultUtil.success(map);
      }
      BigDecimal price = queryLineDestinationPrice(lineId, lineShiftDriver, warpper);
      map.put("price", price == null ? -1 : multiplyPeopleNumber(price, warpper.getPeopleNumber()).doubleValue());
      return ResultUtil.success(map);
   }
   public ResultUtil<Map<String, Object>> getPriceV2(Integer lineId, Integer lineDestinationId, Integer totalSeat,
                                                     Integer peopleNumber, Double endLon, Double endLat, Integer lineShiftDriverId) {
      Map<String, Object> map = new HashMap<>();
      map.put("distance", 0);
      if (peopleNumber == null || peopleNumber <= 0 || endLon == null || endLat == null) {
         map.put("price", -1);
         return ResultUtil.success(map);
      }
      if (lineDestinationId != null) {
         Map<String, Object> destination = lineMapper.queryLineDestinationById(lineDestinationId, lineId);
         BigDecimal unitPrice = null;
         if (destination != null) {
            unitPrice = totalSeat != null && totalSeat == 6 ? getBigDecimal(destination.get("price7")) : getBigDecimal(destination.get("price5"));
            if (unitPrice == null) {
               unitPrice = getBigDecimal(destination.get("price5"));
            }
         }
         map.put("price", unitPrice == null ? -1 : multiplyPeopleNumber(unitPrice, peopleNumber).doubleValue());
         return ResultUtil.success(map);
      }
      if (lineId != null && lineId == -1) {
         if (lineShiftDriverId == null) {
            map.put("price", -1);
            return ResultUtil.success(map);
         }
         LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(lineShiftDriverId);
         if (lineShiftDriver == null) {
            map.put("price", -1);
            return ResultUtil.success(map);
         }
         OrderCrossCityScanWarpper warpper = new OrderCrossCityScanWarpper();
         warpper.setEndLon(endLon);
         warpper.setEndLat(endLat);
         warpper.setPeopleNumber(peopleNumber);
         return getPriceV2(lineId, lineShiftDriver, warpper);
      }
      List<Map<String, Object>> destinations = lineMapper.queryLineDestinations(lineId);
      if (destinations == null || destinations.size() == 0) {
         map.put("price", -1);
         return ResultUtil.success(map);
      }
      BigDecimal defaultPrice5 = getBigDecimal(destinations.get(0).get("price5"));
      BigDecimal matchedPrice = null;
      for (Map<String, Object> destination : destinations) {
         if (isPointInDestinationFence(destination, endLon, endLat)) {
            matchedPrice = totalSeat != null && totalSeat == 6 ? getBigDecimal(destination.get("price7")) : getBigDecimal(destination.get("price5"));
            if (matchedPrice == null) {
               matchedPrice = getBigDecimal(destination.get("price5"));
            }
            break;
         }
      }
      BigDecimal finalPrice = matchedPrice == null ? defaultPrice5 : matchedPrice;
      map.put("price", finalPrice == null ? -1 : multiplyPeopleNumber(finalPrice, peopleNumber).doubleValue());
      return ResultUtil.success(map);
   }
   private BigDecimal querySelfTripNearestPrice(LineShiftDriver lineShiftDriver, OrderCrossCityScanWarpper warpper) {
      Integer customerId = lineShiftDriverMapper.queryCustomerIdByLineShiftDriverId(lineShiftDriver.getId());
      if (customerId == null) {
         return null;
      }
      DriverSelfTrip selfTrip = driverSelfTripMapper.selectById(customerId);
      if (selfTrip == null || ToolUtil.isEmpty(selfTrip.getDestJson())) {
         return null;
      }
      JSONArray destArray = JSON.parseArray(selfTrip.getDestJson());
      if (destArray == null || destArray.size() == 0) {
         return null;
      }
      BigDecimal bestPrice = null;
      Double minDistance = null;
      String target = warpper.getEndLon() + "," + warpper.getEndLat();
      for (int i = 0; i < destArray.size(); i++) {
         JSONObject dest = destArray.getJSONObject(i);
         if (dest == null || dest.getDouble("endLon") == null || dest.getDouble("endLat") == null || dest.getBigDecimal("price") == null) {
            continue;
         }
         String source = dest.getDouble("endLon") + "," + dest.getDouble("endLat");
         Double distance = geodesyUtil.getDistance(source, target).get("WGS84");
         if (distance == null) {
            continue;
         }
         if (minDistance == null || distance < minDistance) {
            minDistance = distance;
            bestPrice = dest.getBigDecimal("price");
         }
      }
      return bestPrice;
   }
   private BigDecimal queryLineDestinationPrice(Integer lineId, LineShiftDriver lineShiftDriver, OrderCrossCityScanWarpper warpper) {
      List<Map<String, Object>> destinations = lineMapper.queryLineDestinations(lineId);
      if (destinations == null || destinations.size() == 0) {
         return null;
      }
      BigDecimal defaultPrice5 = getBigDecimal(destinations.get(0).get("price5"));
      for (Map<String, Object> destination : destinations) {
         if (isPointInDestinationFence(destination, warpper.getEndLon(), warpper.getEndLat())) {
            if (lineShiftDriver.getTotalSeat() != null && lineShiftDriver.getTotalSeat() == 6) {
               BigDecimal price7 = getBigDecimal(destination.get("price7"));
               return price7 == null ? defaultPrice5 : price7;
            }
            BigDecimal price5 = getBigDecimal(destination.get("price5"));
            return price5 == null ? defaultPrice5 : price5;
         }
      }
      return defaultPrice5;
   }
   private boolean isPointInDestinationFence(Map<String, Object> destination, Double lon, Double lat) {
      if (destination == null || lon == null || lat == null) {
         return false;
      }
      Integer fenceType = destination.get("fenceType") == null ? null : Integer.valueOf(String.valueOf(destination.get("fenceType")));
      String coordinate = destination.get("coordinate") == null ? null : String.valueOf(destination.get("coordinate"));
      if (fenceType == null || ToolUtil.isEmpty(coordinate)) {
         return false;
      }
      if (fenceType == 1) {
         String[] arr = coordinate.split(";");
         if (arr.length != 2) {
            return false;
         }
         String[] center = arr[0].split(",");
         if (center.length != 2) {
            return false;
         }
         String source = center[0] + "," + center[1];
         String target = lon + "," + lat;
         Double distance = geodesyUtil.getDistance(source, target).get("WGS84");
         return distance != null && distance <= Double.valueOf(arr[1]);
      }
      return isPointInPolygon(coordinate, lon, lat);
   }
   private boolean isPointInPolygon(String coordinate, Double lon, Double lat) {
      String[] points = coordinate.split(";");
      if (points.length < 3) {
         return false;
      }
      boolean inside = false;
      for (int i = 0, j = points.length - 1; i < points.length; j = i++) {
         String[] current = points[i].split(",");
         String[] previous = points[j].split(",");
         if (current.length != 2 || previous.length != 2) {
            continue;
         }
         double xi = Double.parseDouble(current[0]);
         double yi = Double.parseDouble(current[1]);
         double xj = Double.parseDouble(previous[0]);
         double yj = Double.parseDouble(previous[1]);
         boolean intersect = ((yi > lat) != (yj > lat))
               && (lon < (xj - xi) * (lat - yi) / ((yj - yi) == 0 ? 0.0000001D : (yj - yi)) + xi);
         if (intersect) {
            inside = !inside;
         }
      }
      return inside;
   }
   private BigDecimal getBigDecimal(Object value) {
      if (value == null || ToolUtil.isEmpty(String.valueOf(value))) {
         return null;
      }
      try {
         return new BigDecimal(String.valueOf(value));
      } catch (Exception e) {
         return null;
      }
   }
   private BigDecimal multiplyPeopleNumber(BigDecimal price, Integer peopleNumber) {
      if (price == null || peopleNumber == null || peopleNumber <= 0) {
         return null;
      }
      return price.multiply(new BigDecimal(peopleNumber)).setScale(2, BigDecimal.ROUND_HALF_UP);
   }
}