From e6364fb72bf036d3af583b334626b3aee48697eb Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期四, 12 二月 2026 16:31:25 +0800
Subject: [PATCH] 小程序接口  动态价格修改

---
 xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java |  142 +++++++++++++++++++++++++++++++++++------------
 1 files changed, 105 insertions(+), 37 deletions(-)

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 21f7c33..18937d2 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
@@ -1,6 +1,7 @@
 package com.xiaopeng.operation.service.impl;
 
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -33,6 +34,7 @@
 import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
 import com.xiaopeng.operation.service.XpPricingService;
 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;
@@ -100,14 +102,19 @@
     @Resource
     private XpAppUserClient xpAppUserClient;
 
+    @Resource
+    private HolidayUtil holidayUtil;
 
     @Autowired
     private IXpGeoQueryEntityService geoQueryEntityService;
 
+    @Autowired
+    private XpElectronicFenceMapper xpElectronicFenceMapper;
 
 
     // 自定义线程池用于并行执行任务
     private final ExecutorService executorService;
+
 
     // 初始化自定义线程池
     public XpPricingServiceImpl() {
@@ -170,7 +177,7 @@
                 + "-" + routeAndFareDto.getDestination().getLongitude() + "-" + routeAndFareDto.getDestination().getLatitude() + "-" + getCurrentTimeSlot() + "-" + userId;
 
         if (redisService.hasKey(key)) {
-            String jsonStr = Objects.requireNonNull(redisService.getCacheObject( key)).toString();
+            String jsonStr = Objects.requireNonNull(redisService.getCacheObject(key)).toString();
             RouteAndFareVo RouteAndFareVo = JSONObject.parseObject(jsonStr, RouteAndFareVo.class);
             return (RouteAndFareVo);
         }
@@ -215,11 +222,11 @@
         // 优惠券
         CompletableFuture<R<UserCouponVo>> couponFuture = CompletableFuture.supplyAsync(
                 () -> {
-                        // 优惠券
-                        return xpAppUserCouponClient.getUserCoupon(
+                    // 优惠券
+                    return xpAppUserCouponClient.getUserCoupon(
 //                                new GetUserCouponDto(Long.valueOf(userId), xpPricingCardVo.getTotalPrice(),routeAndFareDto.getOpenCityId())
-                                new GetUserCouponDto(Long.valueOf(userId), 1d,routeAndFareDto.getOpenCityId())
-                        );
+                            new GetUserCouponDto(Long.valueOf(userId), 1d, routeAndFareDto.getOpenCityId())
+                    );
                 },
                 executorService
         );
@@ -285,7 +292,7 @@
 
         // 10. 检查等待时间
         Integer waitTime = getWaitTime(routeAndFareDto.getOrigin().getLongitude(), routeAndFareDto.getOrigin().getLatitude());
-        if(waitTime>3){
+        if (waitTime > 3) {
             throw new ServiceException("当前区域正在等待中,请耐心等待", I18nKeyConstant.WAITING_TIME);
         }
         fareVo.setWaitingTime(waitTime);
@@ -315,7 +322,7 @@
      * @return
      */
     @Override
-    public Integer getWaitTime(double lon,double lat) {
+    public Integer getWaitTime(double lon, double lat) {
         List<XpGeoQueryEntity> entities = geoQueryEntityService.findByLocationWithin500MetersAndLastWeekAndStatusGreater(
                 lon,
                 lat,
@@ -324,7 +331,7 @@
 
 
         if (entities.isEmpty()) {
-           return 1;
+            return 1;
         } else {
             // 已完成接单的数据
             List<XpGeoQueryEntity> validEntities = entities.stream().filter(e -> e.getStatus() > 1).collect(Collectors.toList());
@@ -336,7 +343,7 @@
                 // 未完成接单的数量
                 int count = entities.size() - validEntities.size();
                 if (count == 0) {
-                   return 1;
+                    return 1;
                 } else {
                     double waitMinutes = (average * count) / 60;
                     if (waitMinutes > 3) {
@@ -345,19 +352,28 @@
                     return (int) waitMinutes;
                 }
             } else {
-                return  1;
+                return 1;
             }
         }
     }
 
 
-
     @Override
     public Long saveOrder(XpOrderDto dto, String uid) {
+        // 是否在运营区域时间内
+        XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(dto.getXpElectronicFenceAreaId());
+        XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId());
+        String operationStrategy = xpElectronicFence.getOperationStrategy();
+        Boolean inOperationTime = isInOperationTime(operationStrategy);
+        if (!inOperationTime) {
+            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
+        }
+
+
         Integer cancelCount = xpTradingStrategyMapper.selectOne(null).getCancleCount();
         // 判断是否有进行的订单
         R<Long> r = xpOrderClient.hasUnPaodOrder(uid);
-        if(r.getData()>0){
+        if (r.getData() > 0) {
             throw new RuntimeException("有正在进行的订单");
         }
 
@@ -369,30 +385,40 @@
 
         // 判断当天取消的次数 后台配置 redis 查询
         Object cancelOrder = redisService.getCacheObject("CANCEL_ORDER_" + uid);
-        if(cancelOrder!=null){
+        if (cancelOrder != null) {
             Integer num = Integer.valueOf(cancelOrder.toString());
-            if(num>=cancelCount){
+            if (num >= cancelCount) {
                 return 0l;
             }
         }
 
 
+        // 获取起步里程
+        XpPricing xpPricing = this.baseMapper.selectOne(new LambdaQueryWrapper<XpPricing>().eq(XpPricing::getCityId, dto.getOpenCityId()));
+        Integer startMileage = XpPricingUtil.getStartMileage(xpPricing.getStartingFareJson());
+        if (startMileage == null) {
+            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
+        }
+
 
         // 根据id获取手机号
 
-        Boolean isPriorityDispatch=false;
+        Boolean isPriorityDispatch = false;
         R<XpAppUser> xpAppUserR = xpAppUserClient.queryOperationsUserById(Long.valueOf(uid));
-        if(xpAppUserR.getCode()==R.SUCCESS){
+        if (xpAppUserR.getCode() == R.SUCCESS) {
             Long count = xpWhitelistMapper.selectCount(new LambdaQueryWrapper<XpWhitelist>().eq(XpWhitelist::getAccount, xpAppUserR.getData().getPhoneNumber()).eq(XpWhitelist::getIsPriorityDispatch, 1));
-            if(count>0){
-                isPriorityDispatch=true;
+            if (count > 0) {
+                isPriorityDispatch = true;
             }
         }
 
         // 生成订单数据
         XpOrder xpOrder = new XpOrder();
+
+        xpOrder.setStartMileage(Double.valueOf(startMileage));
+
         xpOrder.setAppUserId(Long.valueOf(uid));
-        xpOrder.setOrderNumber("XP"+System.currentTimeMillis());
+        xpOrder.setOrderNumber("XP" + System.currentTimeMillis());
         xpOrder.setPlacementLon(dto.getPlacementLon());
         xpOrder.setPlacementLat(dto.getPlacementLat());
         xpOrder.setPlacementAddress(dto.getPlacementAddress());
@@ -444,27 +470,27 @@
         R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
         Integer distance = 0;
         Integer duration = 0;
-        if(distanceAndDuration.getCode()!=200){
+        if (distanceAndDuration.getCode() != 200) {
             //静默处理
             return 0l;
         }
-        distance=distanceAndDuration.getData().getDistance();
-        duration=distanceAndDuration.getData().getDuration();
+        distance = distanceAndDuration.getData().getDistance();
+        duration = distanceAndDuration.getData().getDuration();
 
 
         // 产生订单
         R<Long> addOrderR = xpOrderClient.addOrder(xpOrder);
-        if(addOrderR.getCode()!=R.SUCCESS){
+        if (addOrderR.getCode() != R.SUCCESS) {
             throw new ServiceException("订单生成失败", I18nKeyConstant.ORDER_CREATE_FAIL);
         }
         Long orderId = addOrderR.getData();
         // 最大距离
         Object maxPushDistanceObj = redisService.getCacheObject(CacheConstants.MAX_PUSH_DISTANCE);
-        Double maxPushDistance= 0.0;
-        if(maxPushDistanceObj!=null){
-             maxPushDistance = Double.valueOf(maxPushDistanceObj.toString());
-        }else {
-             maxPushDistance = xpTradingStrategyMapper.selectOne(null).getThreePushDistance();
+        Double maxPushDistance = 0.0;
+        if (maxPushDistanceObj != null) {
+            maxPushDistance = Double.valueOf(maxPushDistanceObj.toString());
+        } else {
+            maxPushDistance = xpTradingStrategyMapper.selectOne(null).getThreePushDistance();
         }
 
         // 找出现在所有的队列 通过计算距离 算出目前应该放在那个队列  如果没有符合的新增一个队列  符合后看是否白名单账号 是则直接放在队列前端
@@ -474,20 +500,20 @@
             String lonLat = s.split("-")[2];
             // 和上车点进行判断是否<maxPushDistance
             double v = FastDistanceCalculator.distanceFast(Double.parseDouble(lonLat.split(",")[1]), Double.parseDouble(lonLat.split(",")[0]), xpPoint.getPointLat(), xpPoint.getPointLon());
-            if(v<maxPushDistance){
-                if(isPriorityDispatch){
+            if (v < maxPushDistance) {
+                if (isPriorityDispatch) {
                     // 头部  value 订单_经纬度_状态_用户id_订单编号_距离_时间
-                    redisService.addToTail(s,orderId+"_"+xpPoint.getPointLon()+","+xpPoint.getPointLat()+"_0"+"_"+uid+"_"+xpOrder.getOrderNumber()+"_"+distance+"_"+duration+"_"+routeAndFareDto.getRoutePlanRule());
-                }else {
+                    redisService.addToTail(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule());
+                } else {
                     // 尾部
-                    redisService.addToTail(s,orderId+"_"+xpPoint.getPointLon()+","+xpPoint.getPointLat()+"_0"+"_"+uid+"_"+xpOrder.getOrderNumber()+"_"+distance+"_"+duration+"_"+routeAndFareDto.getRoutePlanRule());
+                    redisService.addToTail(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule());
                 }
                 return orderId;
             }
         }
 
-        String key = CacheConstants.QUEUE_POINT_ID+"-"+ xpPoint.getId()+"-"+xpPoint.getPointLon()+","+xpPoint.getPointLat();
-        redisService.setCacheList(key,Arrays.asList(orderId+"_"+xpPoint.getPointLon()+","+xpPoint.getPointLat()+"_0"+"_"+uid+"_"+xpOrder.getOrderNumber()+"_"+distance+"_"+duration+"_"+routeAndFareDto.getRoutePlanRule()));
+        String key = CacheConstants.QUEUE_POINT_ID + "-" + xpPoint.getId() + "-" + xpPoint.getPointLon() + "," + xpPoint.getPointLat();
+        redisService.setCacheList(key, Arrays.asList(orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule()));
         return orderId;
 
 //
@@ -497,12 +523,54 @@
 //
 
 
-
-
         // 产生订单  存订单数据  // 下发指令  消息推送用户端
 //        return null;
 
     }
 
 
+    private Boolean isInOperationTime(String operationStrategy) {
+        JSONArray jsonArray = JSONArray.parseArray(operationStrategy);
+        Integer holidayToday = holidayUtil.isHolidayToday();
+        for (Object o : jsonArray) {
+            JSONObject jsonObject = JSONObject.parseObject(o.toString());
+            String type = jsonObject.getString("type");
+            if (type.equals(holidayToday.toString())) {
+                JSONArray time = jsonObject.getJSONArray("time");
+                // 判断当前时间 是否在time时间段中
+                for (Object object : time) {
+                    String[] timeArray = object.toString().split("-");
+                    String startTime = timeArray[0];
+                    String endTime = timeArray[1];
+                    boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime);
+                    if (currentTimeInRange) {
+                        return true;
+                    }
+                }
+            } else if (type.equals("3")) {
+                // 判断是什么类型 0每天  1-7 想起
+                String typeStr = jsonObject.getString("typeStr");
+                // 查看今天周几
+                Integer week = DateUtils.getWeek();
+                // 包含每天 或者  包含当天
+                if (typeStr.contains("0") || typeStr.contains(week.toString())) {
+                    JSONArray time = jsonObject.getJSONArray("time");
+                    // 判断当前时间 是否在time时间段中
+                    for (Object object : time) {
+                        String[] timeArray = object.toString().split("-");
+                        String startTime = timeArray[0];
+                        String endTime = timeArray[1];
+                        boolean currentTimeInRange = DateUtils.isCurrentTimeInRange(startTime, endTime);
+                        if (currentTimeInRange) {
+                            return true;
+                        }
+                    }
+                }
+
+            }
+        }
+        return false;
+    }
+
+
 }

--
Gitblit v1.7.1