From 07f26b29ec4532349f8d05001d339d909422e401 Mon Sep 17 00:00:00 2001
From: 曾富康 <1067864236@qq.com>
Date: 星期四, 25 六月 2026 16:03:54 +0800
Subject: [PATCH] 新增需求
---
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 166 insertions(+), 0 deletions(-)
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java
index a548e9b..019b0d4 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java
@@ -22,6 +22,7 @@
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.modular.system.model.vo.*;
import com.stylefeng.guns.modular.system.service.*;
+import com.stylefeng.guns.modular.system.util.GeodesyUtil;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.util.WeChatUtil;
import com.stylefeng.guns.modular.system.warpper.*;
@@ -131,6 +132,9 @@
@Autowired
private WeChatUtil weChatUtil;
+
+ @Autowired
+ private GeodesyUtil geodesyUtil;
/**
* 获取短信验证码
@@ -469,9 +473,171 @@
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
}
+// addMockNearbyDrivers(collect);
return ResultUtil.success(collect);
}
+ /**
+ * 司机端首页订单热力图。
+ * 热力图统计的是订单起点位置,不统计司机位置;订单坐标统一取 startLon/startLat。
+ * radius 为前端传入的查询半径,单位公里;不传时默认查询 5 公里范围内的可接订单。
+ * 返回结果只包含热力图必要字段,不返回订单ID、乘客信息、地址等敏感数据。
+ */
+ @ResponseBody
+ @PostMapping("/base/driver/queryNearbyOrderHeatMap")
+ @ApiOperation(value = "司机端首页订单热力图", tags = {"司机端-首页"}, notes = "热力图统计订单位置,不统计司机位置")
+ @ApiImplicitParams({
+ @ApiImplicitParam(value = "司机当前位置经度", name = "lon", required = true, dataType = "String"),
+ @ApiImplicitParam(value = "司机当前位置纬度", name = "lat", required = true, dataType = "String"),
+ @ApiImplicitParam(value = "查询半径,单位公里,不传默认5公里", name = "radius", required = false, dataType = "String"),
+ @ApiImplicitParam(value = "订单业务类型:1=专车,2=出租车,3=跨城,4/5=小件物流,不传查询全部", name = "type", required = false, dataType = "int")
+ })
+ public ResultUtil<Map<String, Object>> queryNearbyOrderHeatMap(String lon, String lat, String radius, Integer type) {
+ try {
+ if (ToolUtil.isEmpty(lon) || ToolUtil.isEmpty(lat)) {
+ return ResultUtil.paranErr();
+ }
+ Double centerLon = Double.valueOf(lon);
+ Double centerLat = Double.valueOf(lat);
+ Double radiusKm = ToolUtil.isEmpty(radius) ? 5D : Double.valueOf(radius);
+ if (radiusKm <= 0) {
+ return ResultUtil.paranErr();
+ }
+
+ List<Map<String, Object>> points = new ArrayList<>();
+ String centerLonLat = centerLon + "," + centerLat;
+
+ if (type == null || type == 1) {
+ List<OrderPrivateCar> privateCars = orderPrivateCarService.selectList(new EntityWrapper<OrderPrivateCar>()
+ .eq("state", 1).isNotNull("startLon").isNotNull("startLat"));
+ addOrderHeatMapPoints(points, privateCars, centerLonLat, radiusKm, 1);
+ }
+ if (type == null || type == 2) {
+ List<OrderTaxi> taxis = orderTaxiService.selectList(new EntityWrapper<OrderTaxi>()
+ .eq("state", 1).isNotNull("startLon").isNotNull("startLat"));
+ addOrderHeatMapPoints(points, taxis, centerLonLat, radiusKm, 2);
+ }
+ if (type == null || type == 3) {
+ List<OrderCrossCity> crossCities = orderCrossCityService.selectList(new EntityWrapper<OrderCrossCity>()
+ .eq("state", 1).isNotNull("startLon").isNotNull("startLat"));
+ addOrderHeatMapPoints(points, crossCities, centerLonLat, radiusKm, 3);
+ }
+ if (type == null || type == 4 || type == 5) {
+ Wrapper<OrderLogistics> wrapper = new EntityWrapper<OrderLogistics>()
+ .eq("state", 1).isNotNull("startLon").isNotNull("startLat");
+ if (type != null) {
+ wrapper.eq("type", type);
+ }
+ List<OrderLogistics> logistics = orderLogisticsService.selectList(wrapper);
+ addOrderHeatMapPoints(points, logistics, centerLonLat, radiusKm, null);
+ }
+
+ Map<String, Object> data = new HashMap<>();
+// addMockOrderHeatMapPoints(points);
+ data.put("centerLon", centerLon);
+ data.put("centerLat", centerLat);
+ data.put("radius", radiusKm);
+ data.put("total", points.size());
+ data.put("points", points);
+ return ResultUtil.success(data);
+ } catch (NumberFormatException e) {
+ return ResultUtil.paranErr();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return ResultUtil.runErr();
+ }
+ }
+
+ /**
+ * 将指定业务的订单转换为热力点,并按半径过滤。
+ * 每个订单默认生成一个热力点,count=1;小件物流使用订单自身 type 区分 4/5。
+ */
+ private void addOrderHeatMapPoints(List<Map<String, Object>> points, List<?> orders, String centerLonLat, Double radiusKm, Integer fixedType) {
+ if (ToolUtil.isEmpty(orders)) {
+ return;
+ }
+ for (Object order : orders) {
+ Double startLon = null;
+ Double startLat = null;
+ Integer orderType = fixedType;
+ if (order instanceof OrderPrivateCar) {
+ OrderPrivateCar orderPrivateCar = (OrderPrivateCar) order;
+ startLon = orderPrivateCar.getStartLon();
+ startLat = orderPrivateCar.getStartLat();
+ } else if (order instanceof OrderTaxi) {
+ OrderTaxi orderTaxi = (OrderTaxi) order;
+ startLon = orderTaxi.getStartLon();
+ startLat = orderTaxi.getStartLat();
+ } else if (order instanceof OrderCrossCity) {
+ OrderCrossCity orderCrossCity = (OrderCrossCity) order;
+ startLon = orderCrossCity.getStartLon();
+ startLat = orderCrossCity.getStartLat();
+ } else if (order instanceof OrderLogistics) {
+ OrderLogistics orderLogistics = (OrderLogistics) order;
+ startLon = orderLogistics.getStartLon();
+ startLat = orderLogistics.getStartLat();
+ orderType = orderLogistics.getType();
+ }
+ if (startLon == null || startLat == null) {
+ continue;
+ }
+
+ Map<String, Double> distance = geodesyUtil.getDistance(centerLonLat, startLon + "," + startLat);
+ if (distance == null || distance.get("WGS84") == null || distance.get("WGS84") > radiusKm * 1000) {
+ continue;
+ }
+
+ Map<String, Object> point = new HashMap<>();
+ point.put("lon", startLon);
+ point.put("lat", startLat);
+ point.put("count", 1);
+ point.put("type", orderType);
+ points.add(point);
+ }
+ }
+
+ /**
+ * 测试用司机假数据:在 104.05,30.59 附近补充 5 个司机位置,便于前端联调地图展示。
+ */
+ private void addMockNearbyDrivers(List<Map<String, Object>> collect) {
+ double[][] mockPositions = {
+ {104.0500, 30.5900},
+ {104.0512, 30.5908},
+ {104.0489, 30.5894},
+ {104.0520, 30.5886},
+ {104.0495, 30.5915}
+ };
+ for (int i = 0; i < mockPositions.length; i++) {
+ Map<String, Object> map = new HashMap<>();
+ map.put("driverId", -1001 - i);
+ map.put("name", "测试司机" + (i + 1));
+ map.put("lot", mockPositions[i][0]);
+ map.put("lat", mockPositions[i][1]);
+ collect.add(map);
+ }
+ }
+
+ /**
+ * 测试用订单热力图假数据:在 104.05,30.59 附近补充 5 个订单热力点,便于前端联调热力图展示。
+ */
+ private void addMockOrderHeatMapPoints(List<Map<String, Object>> points) {
+ double[][] mockPositions = {
+ {104.0500, 30.5900},
+ {104.0510, 30.5906},
+ {104.0490, 30.5892},
+ {104.0522, 30.5888},
+ {104.0487, 30.5913}
+ };
+ for (int i = 0; i < mockPositions.length; i++) {
+ Map<String, Object> point = new HashMap<>();
+ point.put("lon", mockPositions[i][0]);
+ point.put("lat", mockPositions[i][1]);
+ point.put("count", 1);
+ point.put("type", i + 1);
+ points.add(point);
+ }
+ }
+
@ResponseBody
@PostMapping("/api/driver/queryOrderDataFromDriver")
--
Gitblit v1.7.1