From ffe5f35c096fe2be0d38ec9abf3a2468caba7a40 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 28 四月 2026 14:52:07 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/YueKeDuo

---
 UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java |  291 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 259 insertions(+), 32 deletions(-)

diff --git a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java b/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
index af0462c..3a60020 100644
--- a/UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
+++ b/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);
+	}
 }

--
Gitblit v1.7.1