From 5205d55b6088b579a2ecf08d8aa98e260b9b975c Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期五, 13 二月 2026 18:55:57 +0800
Subject: [PATCH] feat(pricing): 优化地理查询实体服务并更新订单处理流程
---
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java | 5
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java | 30 +++----
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java | 11 --
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java | 9 ++
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java | 37 ++++++++-
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java | 6
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java | 4 +
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpBannerServiceImpl.java | 1
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java | 77 +++++++++++++++---
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java | 4
10 files changed, 131 insertions(+), 53 deletions(-)
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
index 84a349a..ed6bca6 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
@@ -34,10 +34,11 @@
}
@Override
- public R<?> saveXpGeoQueryEntity(XpGeoQueryEntity xpGeoQueryEntity) {
- log.error("保存XpGeoQueryEntity失败", cause);
+ public R<?> updateXpGeoQueryEntity(String orderId) {
+ log.error("更新XpGeoQueryEntity失败", cause);
return R.fail();
}
+
};
}
}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
index 622b285..984d045 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
@@ -27,8 +27,8 @@
/**
* 保存XpGeoQueryEntity
*/
- @PostMapping("/inner/saveXpGeoQueryEntity")
- R<?> saveXpGeoQueryEntity(@RequestBody XpGeoQueryEntity xpGeoQueryEntity);
+ @PostMapping("/inner/updateXpGeoQueryEntity")
+ R<?> updateXpGeoQueryEntity(@RequestParam String orderId);
}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java
index 69081f2..22d2f0f 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java
@@ -30,7 +30,7 @@
* 时间戳
*/
@Field("timestamp")
- private Date timestamp;
+ private Long timestamp;
/**
* 秒数
@@ -81,11 +81,11 @@
this.location = location;
}
- public Date getTimestamp() {
+ public Long getTimestamp() {
return timestamp;
}
- public void setTimestamp(Date timestamp) {
+ public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
diff --git a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java
index b5d21e1..976c890 100644
--- a/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java
+++ b/xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java
@@ -1,5 +1,6 @@
package com.xiaopeng.api.vo.operation;
+import com.xiaopeng.api.vo.order.XpPricingCardVo;
import io.swagger.annotations.ApiModel;
@lombok.Data
@@ -10,4 +11,7 @@
private FareVo fareEstimate;
+
+
+ private XpPricingCardVo xpPricingCard;
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
index 5bd1615..fe3c788 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -23,6 +23,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
+import java.util.Date;
/**
* <p>
@@ -49,29 +50,28 @@
}
-
@PostMapping("/base/v1/mini-program/navigation/route-and-fare")
- @ApiOperation(value = "导航-获取路线和费用",tags = {"小程序-获取路线和费用"},response = RouteAndFareVo.class)
+ @ApiOperation(value = "导航-获取路线和费用", tags = {"小程序-获取路线和费用"}, response = RouteAndFareVo.class)
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R<RouteAndFareVo> getRouteAndFare(@RequestBody @Valid RouteAndFareDto routeAndFareDto, HttpServletRequest request) {
// uid已通过拦截器otp校验,可以直接使用
String uid = request.getHeader("XP-Uid");
- return R.ok(xpPricingService.getRouteAndFare(routeAndFareDto,uid));
+ return R.ok(xpPricingService.getRouteAndFare(routeAndFareDto, uid));
}
// 根据开通城市 获取定价
@GetMapping("/getPricingByCityId/{cityId}")
- public R<XpPricing> getPricingByCityId(@PathVariable("cityId")Long cityId) {
+ public R<XpPricing> getPricingByCityId(@PathVariable("cityId") Long cityId) {
XpPricing pricing = xpPricingService.lambdaQuery().eq(XpPricing::getCityId, cityId).last("limit 1").one();
return R.ok(pricing);
}
@GetMapping("/base/v1/mini-program/pricing/rules/{openCityId}")
- @ApiOperation(value = "获取费用规则",tags = {"小程序-根据开通城市获取费用规则"},response = String.class)
+ @ApiOperation(value = "获取费用规则", tags = {"小程序-根据开通城市获取费用规则"}, response = String.class)
public R<?> getPricingRules(@PathVariable Long openCityId) {
XpPricing xpPricing = xpPricingService.getOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, openCityId).eq(XpPricing::getPricingType, 1).last("limit 1"));
- if(xpPricing!=null){
+ if (xpPricing != null) {
return R.ok(xpPricing.getPriceRule());
}
return R.ok("");
@@ -84,20 +84,20 @@
* @return
*/
@PostMapping("/base/v1/mini-program/pricing/getWaitTime")
- @ApiOperation(value = "获取等待时间",tags = {"小程序-获取等待时间"},response = Integer.class)
- public R<Integer> getWaitTime(@RequestBody LonLatDto dto){
- return R.ok(xpPricingService.getWaitTime(dto.getLongitude(),dto.getLatitude()));
+ @ApiOperation(value = "获取等待时间", tags = {"小程序-获取等待时间"}, response = Integer.class)
+ public R<Integer> getWaitTime(@RequestBody LonLatDto dto) {
+ return R.ok(xpPricingService.getWaitTime(dto.getLongitude(), dto.getLatitude()));
}
/**
* 保存信息
- * @param xpGeoQueryEntity
+ * @param
* @return
*/
- @PostMapping("/inner/saveXpGeoQueryEntity")
- public R<?> saveXpGeoQueryEntity(@RequestBody XpGeoQueryEntity xpGeoQueryEntity){
- xpGeoQueryEntityService.save(xpGeoQueryEntity);
+ @PostMapping("/inner/updateXpGeoQueryEntity")
+ public R<?> updateXpGeoQueryEntity(@RequestParam String orderId) {
+ xpGeoQueryEntityService.updateByOrderId(orderId);
return R.ok();
}
@@ -106,7 +106,7 @@
* 播单
*/
@PostMapping("/base/v1/mini-program/order/save")
- @ApiOperation(value = "保存订单",tags = {"小程序-保存订单"})
+ @ApiOperation(value = "保存订单", tags = {"小程序-保存订单"})
@XpClientCheck(checkToken = false, checkOtpToken = true)
public R<SaveOrderVo> saveOrder(@RequestBody @Validated XpOrderDto dto, HttpServletRequest request) {
String uid = request.getHeader("XP-Uid");
@@ -115,8 +115,6 @@
saveOrderVo.setOrderId(l);
return R.ok(saveOrderVo);
}
-
-
}
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java
index 76772d3..21303f3 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java
@@ -20,6 +20,9 @@
String time
);
+
+
+
/**
* 保存地理查询实体
* @param entity 地理查询实体
@@ -27,6 +30,12 @@
*/
XpGeoQueryEntity save(XpGeoQueryEntity entity);
+
+ /**
+ * 修改
+ */
+ XpGeoQueryEntity updateByOrderId(String orderId);
+
/**
* 根据ID查询实体
* @param id 实体ID
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpBannerServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpBannerServiceImpl.java
index 515f57a..c663f54 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpBannerServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpBannerServiceImpl.java
@@ -27,7 +27,6 @@
@Override
public List<XpBannerListVo> getXpBannerList() {
LambdaQueryWrapper<XpBanner> wrapper = new LambdaQueryWrapper<>();
- // TODO 魔法数字
wrapper.eq(XpBanner::getBannerStatus,1);
// 当前时间在开始和结束时间范围内
wrapper.ge(XpBanner::getStartTime,System.currentTimeMillis());
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java
index e38688c..3740056 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java
@@ -1,17 +1,25 @@
package com.xiaopeng.operation.service.impl;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
+import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.operation.repository.XpGeoQueryEntityRepository;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Distance;
+import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.NearQuery;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.stream.Collectors;
/**
* MongoDB 地理查询服务实现类
@@ -21,6 +29,9 @@
@Autowired
private XpGeoQueryEntityRepository repository;
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
/**
* 通过经纬度查询固定范围500米内、一周内、指定时段的数据
@@ -35,26 +46,43 @@
double latitude,
String time
) {
- // 创建中心点坐标
- Point point = new Point(longitude, latitude);
-
- // 设置距离范围为500米
- Distance distance = new Distance(0.5, Metrics.KILOMETERS); // 0.5公里 = 500米
-
- // 计算一周前的时间
+// // 计算一周前的时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DAY_OF_YEAR, -7);
- Date startTime = calendar.getTime();
+ Long startTime = calendar.getTime().getTime();
- // 执行查询 - 使用新的方法,包含时段过滤
- return repository.findByLocationNearAndTimestampAfterAndTimeAndStatusGreaterThan(
- point,
- 500,
- startTime,
- time, // 时段过滤
- 1 // 状态大于1
+ // 1. 创建查询点
+ Point referencePoint = new Point(longitude, latitude);
+
+ // 2. 构建 NearQuery - 完全使用 NearQuery 的 API
+ NearQuery nearQuery = NearQuery.near(referencePoint, Metrics.KILOMETERS)
+ .maxDistance(0.5) // 转成公里
+ .spherical(true);
+
+
+ // 3.时间>startTime time = time参数
+ // 3. 创建额外的查询条件
+ Query query = new Query();
+ query.addCriteria(Criteria.where("timestamp").gte(startTime));
+ query.addCriteria(Criteria.where("time").is(time));
+
+ // 将 NearQuery 和额外的查询条件合并
+ nearQuery.query(query);
+
+
+ // 4. 执行查询 - 明确指定集合名
+ GeoResults<XpGeoQueryEntity> geoResults = mongoTemplate.geoNear(
+ nearQuery,
+ XpGeoQueryEntity.class,
+ "xp_geo_query_entity" // 明确指定集合名,避免映射错误
);
+
+ // 5. 提取结果
+ return geoResults.getContent().stream()
+ .map(geoResult -> geoResult.getContent())
+ .collect(Collectors.toList());
+
}
/**
@@ -67,6 +95,25 @@
return repository.save(entity);
}
+
+
+ @Override
+ public XpGeoQueryEntity updateByOrderId(String orderId) {
+ Query query = new Query(Criteria.where("orderId").is(orderId));
+
+ XpGeoQueryEntity xpGeoQueryEntity = mongoTemplate.findOne(query, XpGeoQueryEntity.class);
+ Long timestamp = xpGeoQueryEntity.getTimestamp();
+ long time = new Date().getTime();
+ // 计算2个时间的秒数差
+ long seconds = (time- timestamp) / 1000;
+ Update update = new Update().set("seconds", seconds).set("status", 1);
+ if(xpGeoQueryEntity.getStatus()==0){
+ mongoTemplate.findAndModify(query, update, XpGeoQueryEntity.class);
+ }
+ return null;
+
+ }
+
/**
* 根据ID查询实体
* @param id 实体ID
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
index 52c4bab..0ba7ff6 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -20,6 +20,7 @@
import com.xiaopeng.api.vo.operation.FareVo;
import com.xiaopeng.api.vo.operation.RouteAndFareVo;
import com.xiaopeng.api.vo.operation.RouteVo;
+import com.xiaopeng.api.vo.order.XpPricingCardVo;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -35,12 +36,13 @@
import com.xiaopeng.operation.utils.XpPricingUtil;
import com.xiaopeng.operation.utils.holiday.HolidayUtil;
import com.xiaopeng.operation.utils.map.FastDistanceCalculator;
-import com.xiaopeng.operation.vo.XpPricingCardVo;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
+import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;
@@ -89,8 +91,6 @@
@Resource
private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper;
- @Resource
- private XpVehicleClient xpVehicleClient;
@Resource
private XpPointMapper xpPointMapper;
@@ -206,6 +206,8 @@
// );
XpPricingCardVo xpPricingCardVo = new XpPricingCardVo();
+
+
// 3. 并行执行远程服务调用 判断是否同一经营区域
CompletableFuture<R<Boolean>> diagnosisAreaFuture = CompletableFuture.supplyAsync(
() -> xpMapClient.diagnosisArea(routeAndFareDto),
@@ -274,6 +276,9 @@
RouteAndFareVo routeAndFareVo = new RouteAndFareVo();
// routeAndFareVo.setRoute(routeVo);
+
+ routeAndFareVo.setXpPricingCard(xpPricingCardVo);
+
FareVo fareVo = new FareVo();
// fareVo.setEstimatedDistanceKm(routeVo.getDistance().doubleValue() / 1000);
// fareVo.setEstimatedDurationMin(routeVo.getDuration() / 60);
@@ -333,7 +338,7 @@
return 1;
} else {
// 已完成接单的数据
- List<XpGeoQueryEntity> validEntities = entities.stream().filter(e -> e.getStatus() > 1).collect(Collectors.toList());
+ List<XpGeoQueryEntity> validEntities = entities.stream().filter(e -> e.getStatus() == 1).collect(Collectors.toList());
// 计算平均等待时间
OptionalDouble averageOptional = validEntities.stream().mapToDouble(XpGeoQueryEntity::getSeconds).average();
@@ -347,6 +352,8 @@
double waitMinutes = (average * count) / 60;
if (waitMinutes > 3) {
throw new ServiceException("当前区域正在等待中,请耐心等待", I18nKeyConstant.WAITING_TIME);
+ }else if(waitMinutes==0){
+ return 1;
}
return (int) waitMinutes;
}
@@ -517,6 +524,16 @@
xpOrder.setQueueName(s);
xpOrderClient.updateOrder(xpOrder);
+ // 存储mongodb 数据
+ XpGeoQueryEntity xpGeoQueryEntity = new XpGeoQueryEntity();
+ xpGeoQueryEntity.setOrderId(orderId.toString());
+ xpGeoQueryEntity.setLocation(new GeoJsonPoint(xpPoint.getPointLon(),xpPoint.getPointLat()));
+ // 计算2个时间的秒数
+ xpGeoQueryEntity.setTime(currentTimeSlot);
+ xpGeoQueryEntity.setStatus(0);
+ xpGeoQueryEntity.setTimestamp(System.currentTimeMillis());
+ geoQueryEntityService.save(xpGeoQueryEntity);
+
return orderId;
}
}
@@ -525,6 +542,18 @@
redisService.setCacheList(key, Arrays.asList(orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule()));
xpOrder.setQueueName(key);
xpOrderClient.updateOrder(xpOrder);
+
+
+ // 存储mongodb 数据
+ XpGeoQueryEntity xpGeoQueryEntity = new XpGeoQueryEntity();
+ xpGeoQueryEntity.setOrderId(orderId.toString());
+ xpGeoQueryEntity.setLocation(new GeoJsonPoint(xpPoint.getPointLon(),xpPoint.getPointLat()));
+ // 计算2个时间的秒数
+ xpGeoQueryEntity.setTime(currentTimeSlot);
+ xpGeoQueryEntity.setStatus(0);
+
+ geoQueryEntityService.save(xpGeoQueryEntity);
+
return orderId;
//
diff --git a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
index fdfcc32..66a49d4 100644
--- a/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
+++ b/xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -1700,17 +1700,8 @@
XpGeoQueryEntity xpGeoQueryEntity = new XpGeoQueryEntity();
String[] split = popFirstElement.split("_");
xpGeoQueryEntity.setOrderId(split[0]);
- String[] split1 = split[1].split(",");
- xpGeoQueryEntity.setLocation(new GeoJsonPoint(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])));
- xpGeoQueryEntity.setTimestamp(new Date());
- // 计算2个时间的秒数
- LocalDateTime createTime = order.getCreateTime();
- LocalDateTime acceptanceTime = order.getAcceptanceTime();
- xpGeoQueryEntity.setSeconds((int) Duration.between(createTime, acceptanceTime).getSeconds());
- String currentTimeSlot = DateUtils.getCurrentTimeSlot();
- xpGeoQueryEntity.setTime(currentTimeSlot);
// 存mongo数据
- xpPricingClient.saveXpGeoQueryEntity(xpGeoQueryEntity);
+ xpPricingClient.updateXpGeoQueryEntity(split[0]);
this.updateById(order);
}
--
Gitblit v1.7.1