| | |
| | | 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; |
| | |
| | | |
| | | @Resource |
| | | private OrderTaxiMapper orderTaxiMapper; |
| | | |
| | | @Resource |
| | | private DriverSelfTripMapper driverSelfTripMapper; |
| | | |
| | | |
| | | @Resource |
| | |
| | | |
| | | @Autowired |
| | | private GDMapGeocodingUtil gdMapGeocodingUtil; |
| | | |
| | | @Autowired |
| | | private GeodesyUtil geodesyUtil; |
| | | |
| | | @Autowired |
| | | private ChinaMobileUtil chinaMobileUtil; |
| | |
| | | @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; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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); |
| | |
| | | } |
| | | 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("线路信息不存在"); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 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()); |
| | |
| | | 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; |
| | |
| | | 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); |
| | | } |
| | | } |