puzhibing
2026-04-28 19787c0b4f5f29026c1790bbb043b9186cdd0e11
Merge remote-tracking branch 'origin/1.0' into 1.0
1个文件已添加
31个文件已修改
976 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFence.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpStation.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListListQuery.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpStationQuery.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/MultiRouteAndFareVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteOptionVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/XpStationVo.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpPointsListVo.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpStationManagementController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NearestDto.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/StationDetailQueryDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpPointMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpStationService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/BootCommonService.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java 285 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpStationServiceImpl.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/holiday/HolidayUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/mapper/XpPointMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/mapper/XpStationMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityServiceImpl.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java
@@ -317,7 +317,7 @@
        if (uid == null) {
            return 0;
        }
        Long num = baseMapper.selectCount(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getAppUserId, uid).eq(XpAppUserCoupon::getStatus, 1).lt(XpAppUserCoupon::getExpirationTime, LocalDateTime.now()));
        Long num = baseMapper.selectCount(new LambdaQueryWrapper<XpAppUserCoupon>().eq(XpAppUserCoupon::getAppUserId, Long.valueOf(uid)).eq(XpAppUserCoupon::getStatus, 1).lt(XpAppUserCoupon::getExpirationTime, LocalDateTime.now()));
        return num.intValue();
    }
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFence.java
@@ -57,7 +57,16 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime failureTime;
    //[{"name": "策略组1", "time": ["04:00-10:00", "14:00-23:00"], "type": 0, "typeStr": []}]
    /**
     * 自定义时 选择每天只能有一个运营策略
     * type = 0工作日 1法定节假日 2非工作日  3自定义时间  typeStr 代表周 = [1,2,3,4,5,6,7]   typeStr= 0的时候代表每天
     * [{"name": "策略组1", "time": ["09:00-18:00"], "type": 0, "typeStr": []},
     * {"name": "策略组2", "time": ["08:00-21:00"], "type": 2, "typeStr": []},
     * {"name": "策略组3", "time": ["07:00-22:00"], "type": 1, "typeStr": []},
     * {"name": "策略组4", "time": ["12:00-19:00"], "type": 3, "typeStr": [1, 3, 5, 7]}]
     *
     * [{"name": "策略组1", "time": ["08:00-22:00"], "type": 3, "typeStr": [0]}]
     */
    @ApiModelProperty(value = "运营策略")
    private String operationStrategy;
    @ApiModelProperty(value = "城市code")
@@ -74,6 +83,9 @@
    @ApiModelProperty(value = "点位数量")
    @TableField(exist = false)
    private Long pointCount;
    @ApiModelProperty(value = "点位运营数量")
    @TableField(exist = false)
    private Long fenceAreaPointCount;
    @ApiModelProperty(value = "场站数量")
    @TableField(exist = false)
    private Long stationCount;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
@@ -167,15 +167,25 @@
    @ApiModelProperty(value = "状态描述")
    @TableField(exist = false)
    private String hoverStatusDes;
    @ApiModelProperty(value = "场站的生效时间")
    @ApiModelProperty(value = "围栏的生效时间")
    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime electronicEffectTime;
    //[{"name": "策略组1", "time": ["04:00-10:00", "14:00-23:00"], "type": 0, "typeStr": []}]
    @ApiModelProperty(value = "围栏运营策略")
    @TableField(exist = false)
    private String fenceOperationStrategy;
    @ApiModelProperty(value = "场站运营类型 1=与运营区同步 2=自定义时间段")
    @TableField(exist = false)
    private Integer stationOperationType;
    @ApiModelProperty(value = "生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日")
    @TableField(exist = false)
    private Integer stationEffectivePeriod;
    @ApiModelProperty(value = "场站运营策略")
    @TableField(exist = false)
    private String electronicOperationStrategy;
    private String stationEffectiveTimePeriod;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpStation.java
@@ -105,7 +105,8 @@
    private Integer effectivePeriod;
    /**
     * 数据结构 [{"endTime": "18:00", "startTime": "05:00"}]
     * 数据结构
     * ["06:00-12:00", "13:00-21:00"]
     */
    @ApiModelProperty(value = "生效时间段 json")
    private String effectiveTimePeriod;
@@ -136,4 +137,11 @@
    @ApiModelProperty(value = "运营中点位数")
    @TableField(exist = false)
    private Integer operatingPointCount;
    @ApiModelProperty(value = "围栏运营策略")
    @TableField(exist = false)
    private String fenceOperationStrategy;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/PointPageListListQuery.java
@@ -1,10 +1,12 @@
package com.xiaopeng.api.query.operation;
import com.baomidou.mybatisplus.annotation.TableField;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@@ -46,5 +48,27 @@
    @ApiModelProperty(value = "stationIds")
    private List<String> stationIds;
    @ApiModelProperty(value = "电子围栏id")
    private Long electronicId;
    @ApiModelProperty(value = "所属场站id,为空表示运营区直属点位")
    private Long stationId;
    @ApiModelProperty(value = "点位类型 1=运营点位 2=测试点位")
    private Integer pointType;
    @ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效")
    private Integer operationStatus;
    @ApiModelProperty(value = "电子围栏区域id")
    private Boolean electronicAreaIdNotNull;
    @ApiModelProperty(value = "经度")
    @NotNull(message = "经度不能为空")
    private Double longitude;
    @ApiModelProperty(value = "纬度")
    @NotNull(message = "纬度不能为空")
    private Double latitude;
    @ApiModelProperty(value = "距离")
    private Integer orderDistance;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpStationQuery.java
@@ -9,6 +9,9 @@
@Data
public class XpStationQuery extends BasePage {
    @ApiModelProperty(value = "id")
    private Long id;
    @ApiModelProperty(value = "ids")
    private List<Long> ids;
@@ -42,6 +45,8 @@
    @ApiModelProperty(value = "更新结束时间")
    private String updateEndTime;
    @ApiModelProperty(value = "场站点位数量")
    private String stationPointNum;
    @ApiModelProperty(value = "限停时长")
    private Integer parkingTimeLimitMin;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/MultiRouteAndFareVo.java
@@ -30,4 +30,6 @@
    @ApiModelProperty("价格变动超过该百分比则提示路况变化(如 5 表示 5%)")
    private Double priceWaveThresholdPercent;
    @ApiModelProperty(value = "是否开启试运营(0=否,1=是)")
    private Integer operateFree;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteOptionVo.java
@@ -14,6 +14,8 @@
@ApiModel("合并后的路线选项")
public class RouteOptionVo {
    @ApiModelProperty(value = "是否开启试运营(0=否,1=是)")
    private Integer operateFree;
    @ApiModelProperty("路径唯一标识(高德 routeID)")
    private String pathFingerprint;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/XpStationVo.java
@@ -1,10 +1,12 @@
package com.xiaopeng.api.vo.operation;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.operation.XpStation;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@@ -16,4 +18,19 @@
    private List<XpPoint> xpPointList;
    @ApiModelProperty(value = "生效类型 1=立即生效 2=定时生效")
    private Integer fenceEffectType;
    @ApiModelProperty(value = "生效时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime fenceEffectTime;
    @ApiModelProperty(value = "失效类型 1=永不失效 2=定时失效")
    private Integer fenceFailureType;
    @ApiModelProperty(value = "失效时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime fenceFailureTime;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpPointsListVo.java
@@ -1,5 +1,6 @@
package com.xiaopeng.api.vo.order;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -37,8 +38,6 @@
    @ApiModelProperty("电子围栏区域id")
    private Long electronicAreaId;
    @ApiModelProperty("运营类型 1=与运营区同步 2=自定义时间段")
    private Integer operationType;
    @ApiModelProperty("是否收藏 1=是 2=否")
    private Integer isCollect = 2;
@@ -49,6 +48,8 @@
    @ApiModelProperty("点位在场站内排序")
    private Integer stationSortNo;
    @ApiModelProperty("运营类型 1=与运营区同步 2=自定义时间段")
    private Integer operationType;
    @ApiModelProperty("生效周期")
    private Integer effectivePeriod;
@@ -61,6 +62,22 @@
    @ApiModelProperty(value = "停车时长")
    private  Integer time;
    //[{"name": "策略组1", "time": ["04:00-10:00", "14:00-23:00"], "type": 0, "typeStr": []}]
    @ApiModelProperty(value = "围栏运营策略")
    @TableField(exist = false)
    private String fenceOperationStrategy;
    @ApiModelProperty(value = "场站运营类型 1=与运营区同步 2=自定义时间段")
    @TableField(exist = false)
    private Integer stationOperationType;
    @ApiModelProperty(value = "生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日")
    @TableField(exist = false)
    private Integer stationEffectivePeriod;
    @ApiModelProperty(value = "场站运营策略")
    @TableField(exist = false)
    private String stationEffectiveTimePeriod;
    @ApiModelProperty("场站子点位列表")
    private List<XpPointsListVo> children;
}
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/DateUtils.java
@@ -50,6 +50,12 @@
     * @param endTimeStr 结束时间,格式:"HH:mm" 或 "HH:mm:ss"
     * @return 如果在时间段内返回true,否则返回false
     */
    public static boolean isCurrentTimeInRange(LocalTime localTime,String startTimeStr, String endTimeStr) {
        LocalTime startTime = LocalTime.parse(fixTimeFormat(startTimeStr));
        LocalTime endTime = LocalTime.parse(fixTimeFormat(endTimeStr));
        return !localTime.isBefore(startTime) && localTime.isBefore(endTime);
    }
    public static boolean isCurrentTimeInRange(String startTimeStr, String endTimeStr) {
        LocalTime now = LocalTime.now();
        LocalTime startTime = LocalTime.parse(fixTimeFormat(startTimeStr));
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/ActiveOrderServiceImpl.java
@@ -145,6 +145,17 @@
        if(xpVehicle== null){
            throw new ServiceException("获取行驶中的车辆信息错误");
        }
        //剩余里程xx米,或者 剩余时间xx分钟 禁止修改目的地
        //获取订单的
        Object cacheObject = redisService.getCacheObject(CacheConstants.navigationEnd(uid));
        if(cacheObject != null){
            RouteVo routeRemain = JSON.parseObject(cacheObject.toString(), RouteVo.class);
            Integer xczSyDistance = routeRemain.getDistance();//行程中剩余里程
            Integer xczSyTime = routeRemain.getDuration();//行程中剩余时间
            if(systemSetting.getXczSyDistance()<xczSyDistance || systemSetting.getXczSyTime() < xczSyTime){
                throw new ServiceException("即将达到终点,禁止修改目的地");
            }
        }
        // 是否在运营区域时间内
        XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(order.getXpElectronicFenceAreaId());
@@ -183,6 +194,7 @@
        //获取距离和时间
        this.getDD(uid,dto);
        //将修改信息存入到redis,
        // 获取起点经纬度
        XpPoint xpPoint = xpPointService.getById(order.getStartPointId());
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -1037,6 +1037,13 @@
            throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND);
        }
        XpSystemSetting xpSystemSetting = systemSettingMapper.selectOne(null);
        Integer operateFree = 0 ;
        if(null != xpSystemSetting) {
            operateFree = xpSystemSetting.getOperateFree();
        }
        List<RouteOptionVo> options = new ArrayList<>();
        for (Map.Entry<String, RouteVo> e : routeById.entrySet()) {
            String fid = e.getKey();
@@ -1065,6 +1072,7 @@
            if (part.getFareEstimate() != null && part.getFareEstimate().getCouponId() == null) {
                opt.setCouponMessage("当前路线不满足优惠券使用条件");
            }
            opt.setOperateFree(operateFree);
            options.add(opt);
        }
@@ -1087,6 +1095,7 @@
        XpTradingStrategyDetailVO strategyDetailVO = strategyDetailVOR.getData();
        redisService.setCacheObject(CacheConstants.ORDER_MULTI_ROUTE_SNAPSHOT + userId + ":" + snapshotId, JSON.toJSONString(payload), Long.valueOf(strategyDetailVO.getMaxStandingTiming()), TimeUnit.SECONDS);
        MultiRouteAndFareVo vo = new MultiRouteAndFareVo();
        vo.setSnapshotId(snapshotId);
        vo.setGeneratedAtMillis(now);
@@ -1095,6 +1104,8 @@
        vo.setRoutePreferences(listRoutePreferences(routeAndFareDto.getOpenCityId(), userId));
        vo.setStaleCheckSeconds(navigationStaleSeconds);
        vo.setPriceWaveThresholdPercent(navigationPriceWavePercent);
        vo.setOperateFree(operateFree);
        RouteOptionVo first = options.get(0);
        redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + userId, JSON.toJSONString(first.getRoute()), 24L, TimeUnit.HOURS);
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
@@ -22,6 +22,7 @@
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.map.constant.I18nKeyConstant;
import com.xiaopeng.map.service.*;
import com.xiaopeng.map.service.serviceimpl.BootCommonService;
import com.xiaopeng.map.utils.OperationStrategyIndex;
import com.xiaopeng.api.query.operation.FenceAndStationVo;
import io.swagger.annotations.Api;
@@ -39,6 +40,7 @@
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -79,6 +81,8 @@
    private XpPointService xpPointService;
    @Resource
    private XpStationService xpStationService;
    @Resource
    private BootCommonService bootCommonService;
    /**
     * 查询省市管理
@@ -201,6 +205,8 @@
        ElectronicFenceDetailVo.Numbers stationNumbers = new ElectronicFenceDetailVo.Numbers();
        if(CollUtil.isNotEmpty(stationList)){
            LocalDateTime now = LocalDateTime.now();
            LocalTime localTime = LocalTime.now();
            //status 场站状态 0=草稿 1=待启用 2=启用中 3=已停用 4=失效
            for (XpStation xpStation : stationList) {
                switch (xpStation.getStatus()) {
@@ -212,41 +218,11 @@
                        break;
                    case 2: //启动中 判断 待启动的状态 ,当前时间在 运营时间 内是启动中,否则是 待启动
                        LocalDateTime now = LocalDateTime.now();
                        if(xpStation.getOperationType() ==1){//运营类型 1=与运营区同步 2=自定义时间段
                            LocalDateTime startTime = electronicFence.getEffectTime();//生效时间
                            LocalDateTime endTime = electronicFence.getFailureTime();//失效时间
                            if(electronicFence.getFailureType() ==1) {// 失效类型 1=永不失效 2=定时失效
                                endTime = LocalDateTime.now().plusYears(1);
                            }
                            if(!now.isBefore(startTime) && !now.isAfter(endTime)){
                                stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1);
                            }else{
                                stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1);
                            }
                        }else {
                            //数据结构 [{"endTime": "18:00", "startTime": "05:00"}]
                            JSONArray jsonArray = JSONObject.parseArray(xpStation.getEffectiveTimePeriod());
                            boolean flag = false;
                            for (Object object : jsonArray) {
                                JSONObject jsonObject = (JSONObject) object;
                                String startTimeStr = jsonObject.getString("startTime");
                                String endTimeStr = jsonObject.getString("endTime");
                                startTimeStr = LocalDate.now() +" "+ startTimeStr+":00";
                                endTimeStr = LocalDate.now() + " " + endTimeStr + ":00";
                                LocalDateTime startTime = LocalDateTimeUtil.parse(startTimeStr, DatePattern.NORM_DATETIME_PATTERN);
                                LocalDateTime endTime = LocalDateTimeUtil.parse(endTimeStr, DatePattern.NORM_DATETIME_PATTERN);
                                if(!now.isBefore(startTime) && !now.isAfter(endTime)){
                                    flag = true;
                                }
                            }
                            if (flag){
                                stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1);
                            }else{
                                stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1);
                            }
                        boolean stationOperation = bootCommonService.getStationOperation(localTime, xpStation.getOperationType(), xpStation.getEffectivePeriod(), xpStation.getEffectiveTimePeriod(), xpStation.getFenceOperationStrategy());
                        if (stationOperation) {
                            stationNumbers.setStartingUp(stationNumbers.getStartingUp() + 1);
                        }else{
                            stationNumbers.setPendingLaunch(stationNumbers.getPendingLaunch() + 1);
                        }
                        break;
                    case 3:
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointController.java
@@ -1,8 +1,11 @@
package com.xiaopeng.map.controller;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.map.dto.NearestDto;
import com.xiaopeng.map.dto.StationDetailQueryDto;
import com.xiaopeng.map.service.XpPointService;
import com.xiaopeng.map.vo.NearestVo;
import com.xiaopeng.map.vo.StationDetailVo;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
import io.swagger.annotations.Api;
@@ -16,6 +19,7 @@
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
@Slf4j
@RestController
@@ -37,4 +41,6 @@
        String uid = request.getHeader("XP-Uid");
        return R.ok(xpPointService.queryStationDetail(dto, uid));
    }
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpStationManagementController.java
@@ -3,6 +3,7 @@
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpStation;
import com.xiaopeng.api.query.operation.XpStationQuery;
import com.xiaopeng.api.vo.account.LoginUser;
@@ -13,6 +14,7 @@
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.map.exportExcel.XpStationExportExcel;
import com.xiaopeng.map.service.XpElectronicFenceService;
import com.xiaopeng.map.service.XpPointService;
import com.xiaopeng.map.service.XpStationService;
import io.swagger.annotations.Api;
@@ -50,12 +52,13 @@
    private TokenService tokenService;
    @Resource
    private XpPointService xpPointService;
    @Resource
    private XpElectronicFenceService xpElectronicFenceService;
    @ApiOperation(value = "场站管理已经启动列表", tags = {"管理后台-运营-场站管理"})
    @GetMapping("/findListEnable")
    public R<List<XpStation>> findListByCityCode(@RequestParam String cityCode) {
        XpStationQuery query = new XpStationQuery();
        query.setCityCode(cityCode);
        return R.ok( xpStationService.findList(query));
@@ -86,6 +89,14 @@
        XpStationVo beanVo = new XpStationVo();
        BeanUtils.copyProperties(bean, beanVo);
        beanVo.setXpPointList(xpPointService.listByStationId(bean.getId()));
        XpElectronicFence electronicFence = xpElectronicFenceService.getById(bean.getElectronicId());
        beanVo.setFenceEffectType(electronicFence.getEffectType());
        beanVo.setFenceEffectTime(electronicFence.getEffectTime());
        beanVo.setFenceFailureType(electronicFence.getFailureType());
        beanVo.setFenceFailureTime(electronicFence.getFailureTime());
        return R.ok(beanVo);
    }
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/NearestDto.java
@@ -10,12 +10,13 @@
@ApiModel(value = "NearestDto", description = "附近上车站点")
public class NearestDto {
    @ApiModelProperty(value = "经度")
    @NotNull(message = "经度不能为空")
    private Double longitude;
    @ApiModelProperty(value = "纬度")
    @NotNull(message = "纬度不能为空")
    private Double latitude;
    @ApiModelProperty(value = "经度")
    @NotNull(message = "经度不能为空")
    private Double longitude;
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/dto/StationDetailQueryDto.java
@@ -1,5 +1,7 @@
package com.xiaopeng.map.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -12,6 +14,7 @@
    @ApiModelProperty(value = "场站id")
    @NotNull(message = "场站id不能为空")
    @JsonSerialize(using = ToStringSerializer.class)
    private Long stationId;
    @ApiModelProperty(value = "当前纬度")
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/mapper/XpPointMapper.java
@@ -36,6 +36,9 @@
    List<XpPoint> pageList(@Param("pageInfo") PageInfo<XpPoint> pageInfo, @Param("query") PointPageListListQuery query);
    List<XpPoint> pageList( @Param("query") PointPageListListQuery query);
    @Select("SELECT point_number FROM xp_point WHERE point_number LIKE CONCAT(#{cityPrefix}, '-', #{bizType}, '-%') ORDER BY point_number DESC LIMIT 1")
    String selectMaxPointNumber(@Param("cityPrefix") String cityPrefix, @Param("bizType") String bizType);
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java
@@ -66,12 +66,6 @@
    StationDetailVo queryStationDetail(@Valid StationDetailQueryDto dto, String uid);
    /**
     * 判断点位是否时间段内
     * @param now
     * @return
     */
    boolean getInTime(LocalTime now,  Integer effectivePeriod, String effectiveTimePeriod);
    List<XpPoint> pointMap(PointMapQuery query);
    List<FenceAndStationVo> findListFenceAndStation(String cityCode);
@@ -112,6 +106,8 @@
    OrderDistanceVo getOrderDistance();
    List<XpPoint> pageList(PageInfo<XpPoint> pageInfo, PointPageListListQuery query);
    PageInfo<XpPoint> pageList(PointPageListListQuery query);
    Set<Long> getCollectStationIds(String uid);
@@ -129,4 +125,7 @@
    @Transactional(rollbackFor = Exception.class)
    void pointDeleteByStationId(Long stationId, Boolean pointDelete);
    void setStatusFailure(List<Long> electronicAreaIds);
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpStationService.java
@@ -22,8 +22,11 @@
 */
public interface XpStationService extends IService<XpStation> {
    List<XpStation> findList(XpStationQuery query);
    List<XpStation> findList(PageInfo<XpStation> pageInfo, XpStationQuery query);
    PageInfo<XpStation> pageList(XpStationQuery query);
    void validate(XpStationVo dto);
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/BootCommonService.java
New file
@@ -0,0 +1,206 @@
package com.xiaopeng.map.service.serviceimpl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.vo.order.XpPointsListVo;
import com.xiaopeng.common.core.utils.DateUtils;
import com.xiaopeng.map.service.XpStationService;
import com.xiaopeng.map.utils.TimeRangeChecker;
import com.xiaopeng.map.utils.holiday.HolidayUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalTime;
@Service
public class BootCommonService {
    @Resource
    private HolidayUtil holidayUtil;
    //
    /**
     * 判断围栏运营策略
     * 自定义时 选择每天只能有一个运营策略
     * type = 0工作日 1法定节假日 2非工作日  3自定义时间  typeStr 代表周 = [1,2,3,4,5,6,7]   typeStr= 0的时候代表每天
     * [{"name": "策略组1", "time": ["09:00-18:00"], "type": 0, "typeStr": []},
     * {"name": "策略组2", "time": ["08:00-21:00"], "type": 2, "typeStr": []},
     * {"name": "策略组3", "time": ["07:00-22:00"], "type": 1, "typeStr": []},
     * {"name": "策略组4", "time": ["12:00-19:00"], "type": 3, "typeStr": [1, 3, 5, 7]}]
     *
     * [{"name": "策略组1", "time": ["08:00-22:00"], "type": 3, "typeStr": [0]}]
     * @param electronicOperationStrategy
     * @return
     *
     */
    public Boolean getFenceOperation(String electronicOperationStrategy) {
        return getFenceOperation(LocalTime.now(),electronicOperationStrategy);
    }
    public Boolean getFenceOperation(LocalTime localTime,String electronicOperationStrategy) {
        if(StrUtil.isBlank(electronicOperationStrategy)){
            return true;
        }
        JSONArray jsonArray = JSONArray.parseArray(electronicOperationStrategy);
        Integer holidayToday = holidayUtil.isHolidayToday(); //0工作日 1节假日 2非工作日
        for (Object o : jsonArray) {
            JSONObject jsonObject =JSONObject.parseObject(o.toString());
            String type = jsonObject.getString("type");
            String timeStr = null;
            if(type.equals(holidayToday.toString())){
                timeStr = jsonObject.getString("time");
            }else if("3".equals(type)){
                // 判断是什么类型 0每天  1-7 想起
                String typeStr = jsonObject.getString("typeStr");
                // 查看今天周几
                Integer week = DateUtils.getWeek();
                // 包含每天 或者  包含当天
                if(typeStr.contains("0") || typeStr.contains(week.toString())){
                    timeStr = jsonObject.getString("time");
                }
            }
            if(StrUtil.isNotBlank(timeStr)){
                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(localTime,startTime, endTime);
                    if(currentTimeInRange){
                        return true;
                    }
                }
            }
        }
        return false;
    }
    /**
     * 判断场站运营策略
     * ["06:00-12:00", "13:00-21:00"]
     * @param localTime
     * @param operationType 运营类型 1=与运营区同步 2=自定义时间段
     * @param effectivePeriod 生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日
     * @param effectiveTimePeriod 场站生效时间段 json
     * @param effectiveTimePeriod 围栏运营json
     * @return
     */
    public boolean getStationOperation(LocalTime localTime,Integer operationType,Integer effectivePeriod, String effectiveTimePeriod,String fenceOperationStrategy){
        if(operationType == 1){
            return getFenceOperation(localTime,fenceOperationStrategy);
        }else {
            Integer holidayToday = holidayUtil.isHolidayToday();
            if (effectivePeriod == 1) {
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            } else if (effectivePeriod == 2) {
                if (holidayToday != 0) {
                    return false;
                }
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            } else if (effectivePeriod == 3) {
                if (holidayToday != 2) {
                    return false;
                }
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            } else if (effectivePeriod == 4) {
                if (holidayToday != 1) {
                    return false;
                }
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            }
        }
        return true;
    }
    /**
     *
     * @param localTime 时间
     * @param xpPoint 点位对象
     * @return
     */
    public boolean getPointOperation(LocalTime localTime, XpPoint xpPoint){
        if(xpPoint.getOperationType()==2){//运营类型 1=与运营区同步 2=自定义时间段
            return getPointOperation(localTime,xpPoint.getEffectivePeriod(),xpPoint.getEffectiveTimePeriod());
        }else {
            if(xpPoint.getStationId()==null){//调用围栏运营策略
                return getFenceOperation(localTime,xpPoint.getFenceOperationStrategy());
            }else {
                return this.getStationOperation(localTime,xpPoint.getStationOperationType(),xpPoint.getStationEffectivePeriod(),xpPoint.getStationEffectiveTimePeriod(),xpPoint.getFenceOperationStrategy());
            }
        }
    }
    public boolean getPointOperation_vo(LocalTime localTime, XpPointsListVo xpPoint){
        if(xpPoint.getOperationType()==2){//运营类型 1=与运营区同步 2=自定义时间段
            return getPointOperation(localTime,xpPoint.getEffectivePeriod(),xpPoint.getEffectiveTimePeriod());
        }else {
            if(xpPoint.getStationId()==null){//调用围栏运营策略
                return getFenceOperation(localTime,xpPoint.getFenceOperationStrategy());
            }else {
                return this.getStationOperation(localTime,xpPoint.getStationOperationType(),xpPoint.getStationEffectivePeriod(),xpPoint.getStationEffectiveTimePeriod(),xpPoint.getFenceOperationStrategy());
            }
        }
    }
    /**
     * 判断点位是否运营策略
     * ["06:00-12:00", "13:00-21:00"]
     * @param localTime
     * @param effectivePeriod 生效周期 1=每日 2=仅工作日 3=仅非工作日 4=仅节假日
     * @param effectiveTimePeriod 场站运营json/ 生效时间段 json
     * @return
     */
    private boolean getPointOperation(LocalTime localTime, Integer effectivePeriod, String effectiveTimePeriod){
            //  2非工作日  0工作日  1节假日 3调休日
            Integer holidayToday = holidayUtil.isHolidayToday();
            if (effectivePeriod == 1) {
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            } else if (effectivePeriod == 2) {
                if (holidayToday != 0) {
                    return false;
                }
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            } else if (effectivePeriod == 3) {
                if (holidayToday != 2) {
                    return false;
                }
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            } else if (effectivePeriod == 4) {
                if (holidayToday != 1) {
                    return false;
                }
                boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(localTime, effectiveTimePeriod);
                if (!inTime) {
                    return false;
                }
            }
        return true;
    }
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java
@@ -36,6 +36,7 @@
import com.xiaopeng.map.vo.WalkTimeVo;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
@@ -86,6 +87,9 @@
    private GDMapGeocodingUtil gdMapGeocodingUtil;
    @Autowired
    private XpPointService xpPointService;
    @Lazy
    @Autowired
    private BootCommonService bootCommonService;
@@ -126,7 +130,7 @@
            if(xpElectronicFence.getFailureType() == 2){
                JSONArray jsonArray = JSONArray.parseArray(operationStrategy);
                if(!jsonArray.isEmpty()){
                    Boolean inOperationTime = isInOperationTime(operationStrategy);
                    Boolean inOperationTime = bootCommonService.getFenceOperation(operationStrategy);
                    if(!inOperationTime){
                        continue;
                    }
@@ -180,53 +184,7 @@
    }
    /**
     * 是否在运营内
     * @param operationStrategy 规则json字符串
     * @return
     */
    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;
    }
@@ -260,7 +218,7 @@
                        String operationStrategy = electronicFence.getOperationStrategy();
                        Boolean inOperationTime = true;
                        if(electronicFence.getFailureType() == 2){
                            inOperationTime = isInOperationTime(operationStrategy);
                            inOperationTime = bootCommonService.getFenceOperation(operationStrategy);
                        }
                        XpElectronicFenceArea electronicFenceArea = this.getById(Long.valueOf(polygon.getAreaId()));
                        if(inOperationTime && null != electronicFenceArea && !electronicFenceArea.getDeleted()){
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -12,6 +12,8 @@
import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.query.operation.ElectronicPageListQuery;
import com.xiaopeng.api.query.operation.PointListQuery;
import com.xiaopeng.api.query.operation.PointPageListListQuery;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.DateUtils;
@@ -56,6 +58,7 @@
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
@@ -77,6 +80,9 @@
    private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Lazy
    @Resource
    private BootCommonService bootCommonService;
    @Autowired
    private XpPointMapper xpPointMapper;
@@ -98,6 +104,8 @@
    @Lazy
    protected XpStationService xpStationService;
    @Override
    public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
        if (query == null) {
@@ -111,6 +119,7 @@
        if (total == 0L) {
            return new PageInfo<>();
        }
        LocalTime localTime = LocalTime.now();
        List<XpElectronicFence> list = this.baseMapper.pageList(pageInfo, query);
        List<Long> electronicIds = list.stream().map(XpElectronicFence::getId).collect(Collectors.toList());
        Map<Long, List<XpElectronicFenceArea>> electronicFenceAreaMap = xpElectronicFenceAreaMapper.selectList(new LambdaQueryWrapper<XpElectronicFenceArea>()
@@ -118,13 +127,34 @@
                .collect(Collectors.groupingBy(XpElectronicFenceArea::getElectronicId));
        for (XpElectronicFence xpElectronicFence : list) {
            List<XpElectronicFenceArea> xpElectronicFenceAreas = electronicFenceAreaMap.get(xpElectronicFence.getId());
            xpElectronicFence.setOperatingAreaCount(0L);
            xpElectronicFence.setProhibitedAreaCount(0L);
            xpElectronicFence.setFenceAreaPointCount(0l);
            if (xpElectronicFenceAreas != null) {
                xpElectronicFence.setOperatingAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 1).count());
                xpElectronicFence.setProhibitedAreaCount(xpElectronicFenceAreas.stream().filter(xpElectronicFenceArea -> xpElectronicFenceArea.getAreaType() == 2).count());
            } else {
                xpElectronicFence.setOperatingAreaCount(0L);
                xpElectronicFence.setProhibitedAreaCount(0L);
            }
            try {
                PointPageListListQuery queryPoint = new PointPageListListQuery();
                queryPoint.setElectronicId(xpElectronicFence.getId());
                List<XpPoint> xpPoints = xpPointMapper.pageList( queryPoint);
                if(CollUtil.isNotEmpty(xpPoints)){
                    Long fenceAreaPointCount = 0L;
                    for (XpPoint xpPoint : xpPoints) {
                        boolean intime = bootCommonService.getPointOperation(localTime, xpPoint);
                        if(intime){
                            fenceAreaPointCount++;
                        }
                    }
                    xpElectronicFence.setFenceAreaPointCount(fenceAreaPointCount);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException("查询错误");
            }
        }
        pageInfo.setRecords(list);
        return pageInfo;
@@ -1056,16 +1086,18 @@
        List<XpElectronicFenceArea> electronicFenceAreaList = xpElectronicFenceAreaService.lambdaQuery()
                .eq(XpElectronicFenceArea::getElectronicId, electronicId)
                .list();
        List<Long> electronicAreaIds = new ArrayList<>();
        if (!CollUtil.isEmpty(electronicFenceAreaList)) {
            for (XpElectronicFenceArea electronicFenceArea : electronicFenceAreaList) {
                electronicFenceArea.setAreaStatus(2);
                toDeleteAreaIdStrings.add(String.valueOf(electronicFenceArea.getId()));
                electronicAreaIds.add(electronicFenceArea.getId());
            }
            xpElectronicFenceAreaService.updateBatchById(electronicFenceAreaList);
        }
        //点位失效
        xpPointService.setStatusFailure(electronicAreaIds);
        //场站失效
        xpStationService.setStatusFailure(electronicId);//场站失效
        // 删除旧的区域数据,然后保存新的区域数据
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java
@@ -12,15 +12,12 @@
import com.xiaopeng.api.dto.order.HistoryEndPointsDto;
import com.xiaopeng.api.dto.order.HistoryStartPointsDto;
import com.xiaopeng.api.feignClient.account.XpAppUserCollectAddrClient;
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.operation.XpRegion;
import com.xiaopeng.api.model.operation.XpStation;
import com.xiaopeng.api.model.operation.XpSystemSetting;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.query.operation.FenceAndStationVo;
import com.xiaopeng.api.query.operation.PointListQuery;
import com.xiaopeng.api.query.operation.PointPageListListQuery;
import com.xiaopeng.api.query.operation.XpStationQuery;
import com.xiaopeng.api.vo.account.LoginUser;
import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo;
import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo;
import com.xiaopeng.api.vo.order.XpPointsListVo;
@@ -31,19 +28,19 @@
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.evi.oss.service.AliOssService;
import com.xiaopeng.map.constant.I18nKeyConstant;
import com.xiaopeng.map.dto.NearestDto;
import com.xiaopeng.map.dto.StationDetailQueryDto;
import com.xiaopeng.map.mapper.XpPointMapper;
import com.xiaopeng.map.mapper.XpElectronicFenceMapper;
import com.xiaopeng.map.mapper.XpPointMapper;
import com.xiaopeng.map.mapper.XpRegionMapper;
import com.xiaopeng.map.mapper.XpSystemSettingMapper;
import com.xiaopeng.map.query.PointByNameQuery;
import com.xiaopeng.map.service.XpElectronicFenceAreaService;
import com.xiaopeng.map.service.XpPointService;
import com.xiaopeng.map.service.XpStationService;
import com.xiaopeng.map.utils.TimeRangeChecker;
import com.xiaopeng.map.utils.holiday.HolidayUtil;
import com.xiaopeng.map.utils.map.map.FastDistanceCalculator;
import com.xiaopeng.map.vo.*;
@@ -116,6 +113,9 @@
    @Autowired
    private AliOssService aliOssService;
    @Lazy
    @Autowired
    private BootCommonService bootCommonService;
    @Override
    @Transactional
@@ -228,10 +228,18 @@
            orderDistance = xpSystemSetting.getNearPointDistance();
        }
        // 获取所有的站点信息
        List<XpPoint> list = list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getOperationStatus, 2).eq(XpPoint::getPointType,1).isNotNull(XpPoint::getElectronicAreaId)
                // 添加距离计算字段
                .apply("ST_Distance_Sphere(point({0}, {1}), point(point_lon, point_lat)) <= {2}",
                        dto.getLongitude(), dto.getLatitude(), orderDistance));
        PointPageListListQuery query =  new PointPageListListQuery();
        query.setOperationStatus(2);
        query.setPointType(1);
        query.setElectronicAreaIdNotNull(true);
        query.setLongitude(dto.getLongitude());
        query.setLatitude(dto.getLatitude());
        query.setOrderDistance(orderDistance);
        List<XpPoint> list = baseMapper.pageList(query);
        // 添加距离计算字段
//        List<XpPoint> list = list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getOperationStatus, 2).eq(XpPoint::getPointType,1).isNotNull(XpPoint::getElectronicAreaId)
//                .apply("ST_Distance_Sphere(point({0}, {1}), point(point_lon, point_lat)) <= {2}",
//                        dto.getLongitude(), dto.getLatitude(), orderDistance));
        NearestVo nearestVo = new NearestVo();
        List<NearestNextVo> nearestNextVos = new ArrayList<>();
        LocalTime now = LocalTime.now();
@@ -239,7 +247,7 @@
        for (XpPoint xpPoint : list) {
            // 判断是否在时间段内
            boolean intime = getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod());
            boolean intime = bootCommonService.getPointOperation(now, xpPoint);
            if (!intime) {
                continue;
            }
@@ -325,42 +333,6 @@
    }
    public boolean getInTime(LocalTime now,  Integer effectivePeriod, String effectiveTimePeriod){
        //  2非工作日  0工作日  1节假日 3调休日
        Integer holidayToday = holidayUtil.isHolidayToday();
        if(effectivePeriod==1){
            boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod);
            if (!inTime) {
                return false;
            }
        }else if(effectivePeriod==2){
            if(holidayToday!=0){
                return false;
            }
            boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod);
            if (!inTime) {
                return false;
            }
        }else if(effectivePeriod==3){
            if(holidayToday!=2){
                return false;
            }
            boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod);
            if (!inTime) {
                return false;
            }
        }else if(effectivePeriod==4){
            if(holidayToday!=1){
                return false;
            }
            boolean inTime = TimeRangeChecker.isCurrentTimeInRanges(now,effectiveTimePeriod);
            if (!inTime) {
                return false;
            }
        }
        return true;
    }
    @Override
    public List<XpPoint> pointMap(PointMapQuery query) {
@@ -462,37 +434,47 @@
            return stationDetailVo;
        }
        XpStation station = xpStationService.getById(dto.getStationId());
        if (station == null || !isStationAvailable(station)) {
        XpStationQuery query = new XpStationQuery();
        query.setId(dto.getStationId());
        query.setStatus(2);
        List<XpStation> list = xpStationService.findList(query);
        if(CollUtil.isEmpty(list)){
            return stationDetailVo;
        }
        XpStation station = list.get(0);
        LocalTime localTime = LocalTime.now();
        boolean stationOperation = bootCommonService.getStationOperation(localTime, station.getOperationType(), station.getEffectivePeriod(), station.getEffectiveTimePeriod(), station.getFenceOperationStrategy());
        if(!stationOperation){
            return stationDetailVo;
        }
        // 仅查询场站下运营点位,最终结果还会叠加时段/围栏有效性过滤。
        List<XpPoint> stationPoints = this.lambdaQuery()
                .eq(XpPoint::getStationId, station.getId())
                .eq(XpPoint::getPointType, 1)
                .eq(XpPoint::getOperationStatus, 2)
                .list();
        PointPageListListQuery queryPoint = new PointPageListListQuery();
        queryPoint.setStationId( station.getId());
        queryPoint.setPointType(1);
        queryPoint.setOperationStatus(2);
        List<XpPoint> stationPoints = this.baseMapper.pageList(queryPoint);
        if (CollUtil.isEmpty(stationPoints)) {
            return stationDetailVo;
        }
        Map<Long, XpElectronicFenceArea> areaMap = buildAreaMap(stationPoints.stream()
                .map(XpPoint::getElectronicAreaId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList()));
        Map<Long, XpElectronicFence> fenceMap = buildFenceMap(areaMap.values().stream()
                .map(XpElectronicFenceArea::getElectronicId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList()));
//        Map<Long, XpElectronicFenceArea> areaMap = buildAreaMap(stationPoints.stream()
//                .map(XpPoint::getElectronicAreaId)
//                .filter(Objects::nonNull)
//                .distinct()
//                .collect(Collectors.toList()));
//        Map<Long, XpElectronicFence> fenceMap = buildFenceMap(areaMap.values().stream()
//                .map(XpElectronicFenceArea::getElectronicId)
//                .filter(Objects::nonNull)
//                .distinct()
//                .collect(Collectors.toList()));
        Set<Long> collectStationIds = getCollectStationIds(uid);
        Set<Long> collectPointIds = getCollectPointIds(uid);
        // 默认点位优先置顶,其余点位再按场站内排序和距离排序。
        List<StationPointItemVo> points = stationPoints.stream()
                .filter(point -> isPointAvailable(point, areaMap, fenceMap))
                .filter(point -> isPointAvailable(localTime, point))
                .map(point -> toStationPointItem(point, station.getDefaultPointId(), dto.getLatitude(), dto.getLongitude(), collectPointIds))
                .sorted(buildStationPointComparator())
                .collect(Collectors.toList());
@@ -519,10 +501,10 @@
        if (list.isEmpty()) {
            return searchVo;
        }
        LocalTime now = LocalTime.now();
        for (XpPointsListVo xpPointsListVo : list) {
            boolean inTime = getInTime(now, xpPointsListVo.getEffectivePeriod(), xpPointsListVo.getEffectiveTimePeriod());
            boolean inTime = bootCommonService.getPointOperation_vo(now, xpPointsListVo);
            if (!inTime) {
                // 不在运营段
                xpPointsListVo.setState(0);
@@ -557,35 +539,16 @@
        return orderDistanceVo;
    }
    @Override
    public PageInfo<XpPoint> pageList(PointPageListListQuery query) {
        if(CollUtil.isNotEmpty(query.getFenceAndStationList())){
            List<String> fenceAreaIds = new ArrayList<>();
            List<String> stationIds = new ArrayList<>();
            for (FenceAndStationVo bean : query.getFenceAndStationList()) {
                if(bean.getType()==1){
                    fenceAreaIds.addAll(StrUtil.split(bean.getIds(),",") );
                }else{
                    stationIds.addAll(StrUtil.split(bean.getIds(),",") );
                }
            }
            query.setFenceAreaIds(fenceAreaIds);
            query.setStationIds(stationIds);
    public List<XpPoint> pageList(PageInfo<XpPoint> pageInfo, PointPageListListQuery query) {
        List<XpPoint> list = null;
        if (pageInfo == null) {
            list = this.baseMapper.pageList(query);
        }else{
            list = this.baseMapper.pageList(pageInfo,query);
        }
        PageInfo<XpPoint> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize());
        if (StringUtils.isNotBlank(query.getPointLonAndLat())) {
            List<String> lonAndLat = query.getPointLonAndLat().trim().contains(",") ? Arrays.asList(query.getPointLonAndLat().split(",")) :
                    query.getPointLonAndLat().trim().contains(" ") ? Arrays.asList(query.getPointLonAndLat().split(" ")) :
                            Collections.emptyList();
            if (CollUtil.isNotEmpty(lonAndLat)) {
                query.setPointLon(lonAndLat.get(0));
                query.setPointLat(lonAndLat.get(1));
                query.setPointLonAndLat(null);
            }
        }
        List<XpPoint> list = this.baseMapper.pageList(pageInfo,query);
        if(CollUtil.isNotEmpty(list)){
            /**
             * hover在状态标签时,展示信息
@@ -603,11 +566,11 @@
                }
                if(point.getVerificationStatus()==5 && point.getOperationStatus() == 1){
                    if(point.getOperationType() ==  1){//运营类型 1=与运营区同步 2=自定义时间段
                         ;
                        ;
                        //[{"name": "策略组1", "time": ["06:00-12:00", "13:00-22:59"], "type": 0, "typeStr": []},
                        // {"name": "策略组2", "time": ["05:00-12:00", "12:00-16:00"], "type": 2, "typeStr": ""},
                        // {"name": "策略组3", "time": ["09:00-21:59"], "type": 1, "typeStr": ""}]
                        JSONArray electronicOperationStrategys = JSONArray.parseArray(point.getElectronicOperationStrategy());
                        JSONArray electronicOperationStrategys = JSONArray.parseArray(point.getFenceOperationStrategy());
                        if(!electronicOperationStrategys.isEmpty()){
                            StringJoiner joiner = new StringJoiner(";");
                            for (Object electronicOperationStrategy : electronicOperationStrategys) {
@@ -622,13 +585,43 @@
                        if(StrUtil.isNotBlank(point.getEffectiveTimePeriod()) ){
                            List<String> effectiveTimePeriods = JSONArray.parseArray(point.getEffectiveTimePeriod(), String.class);
                            hoverStatusDes = String.join(";", effectiveTimePeriods);
//                        hoverStatusDes = "待生效:"+point.getElectronicEffectTime().toString()  ;
                        }
                    }
                }
                point.setHoverStatusDes(hoverStatusDes);
            }
        }
        return list;
    }
    @Override
    public PageInfo<XpPoint> pageList(PointPageListListQuery query) {
        if(CollUtil.isNotEmpty(query.getFenceAndStationList())){
            List<String> fenceAreaIds = new ArrayList<>();
            List<String> stationIds = new ArrayList<>();
            for (FenceAndStationVo bean : query.getFenceAndStationList()) {
                if(bean.getType()==1){
                    fenceAreaIds.addAll(StrUtil.split(bean.getIds(),",") );
                }else{
                    stationIds.addAll(StrUtil.split(bean.getIds(),",") );
                }
            }
            query.setFenceAreaIds(fenceAreaIds);
            query.setStationIds(stationIds);
        }
        PageInfo<XpPoint> pageInfo = new PageInfo<>(query.getPageNum(),query.getPageSize());
        if (StringUtils.isNotBlank(query.getPointLonAndLat())) {
            List<String> lonAndLat = query.getPointLonAndLat().trim().contains(",") ? Arrays.asList(query.getPointLonAndLat().split(",")) :
                    query.getPointLonAndLat().trim().contains(" ") ? Arrays.asList(query.getPointLonAndLat().split(" ")) :
                            Collections.emptyList();
            if (CollUtil.isNotEmpty(lonAndLat)) {
                query.setPointLon(lonAndLat.get(0));
                query.setPointLat(lonAndLat.get(1));
                query.setPointLonAndLat(null);
            }
        }
        List<XpPoint> list = this.pageList(pageInfo,query);
        pageInfo.setRecords(list);
        return pageInfo;
    }
@@ -652,75 +645,19 @@
                .collect(Collectors.toMap(XpElectronicFence::getId, fence -> fence, (a, b) -> a));
    }
    /**
     * 场站可展示判断:
     * 1. 状态必须为启用中;
     * 2. 与运营区同步时,依赖运营区和围栏的当前有效性;
     * 3. 自定义时段时,依赖场站自身时段配置。
     */
    private boolean isStationAvailable(XpStation station) {
        if (station == null || !Integer.valueOf(6).equals(station.getStatus())) {
            return false;
        }
        if (Integer.valueOf(1).equals(station.getOperationType())) {
            if (station.getElectronicAreaId() == null) {
                return false;
            }
            XpElectronicFenceArea area = xpElectronicFenceAreaService.getById(station.getElectronicAreaId());
            if (area == null || !Integer.valueOf(1).equals(area.getAreaStatus()) || area.getElectronicId() == null) {
                return false;
            }
            XpElectronicFence fence = xpElectronicFenceMapper.selectById(area.getElectronicId());
            return isFenceAvailable(fence);
        }
        if (Integer.valueOf(2).equals(station.getOperationType())
                && station.getEffectivePeriod() != null
                && StringUtils.isNotBlank(station.getEffectiveTimePeriod())) {
            return getInTime(LocalTime.now(), station.getEffectivePeriod(), station.getEffectiveTimePeriod());
        }
        return false;
    }
    /**
     * 子点位是否可展示与场站卡片中。
     * 规则与现有点位有效性保持一致,避免地图页和其他点位查询出现口径偏差。
     */
    private boolean isPointAvailable(XpPoint point, Map<Long, XpElectronicFenceArea> areaMap, Map<Long, XpElectronicFence> fenceMap) {
        if (point == null || !Integer.valueOf(2).equals(point.getOperationStatus())) {
            return false;
        }
        if (Integer.valueOf(1).equals(point.getOperationType())) {
            if (point.getElectronicAreaId() == null) {
                return false;
            }
            XpElectronicFenceArea area = areaMap.get(point.getElectronicAreaId());
            if (area == null || !Integer.valueOf(1).equals(area.getAreaStatus()) || area.getElectronicId() == null) {
                return false;
            }
            return isFenceAvailable(fenceMap.get(area.getElectronicId()));
        }
        if (Integer.valueOf(2).equals(point.getOperationType())
                && point.getEffectivePeriod() != null
                && StringUtils.isNotBlank(point.getEffectiveTimePeriod())) {
            return getInTime(LocalTime.now(), point.getEffectivePeriod(), point.getEffectiveTimePeriod());
        }
        return false;
    private boolean isPointAvailable(LocalTime localTime,  XpPoint point) {
        return bootCommonService.getPointOperation(localTime, point);
    }
    /**
     * 围栏生效判断:
     * 启用中,且当前时间需要落在生效时间与失效时间窗口内。
     */
    private boolean isFenceAvailable(XpElectronicFence fence) {
        if (fence == null || !Integer.valueOf(2).equals(fence.getStatus())) {
            return false;
        }
        LocalDateTime now = LocalDateTime.now();
        if (fence.getEffectTime() != null && now.isBefore(fence.getEffectTime())) {
            return false;
        }
        return !Integer.valueOf(2).equals(fence.getFailureType()) || fence.getFailureTime() == null || !now.isAfter(fence.getFailureTime());
    }
    /**
     * 组装单个场站子点位返回对象,并在有默认点位配置时打标。
@@ -881,4 +818,32 @@
        }
    }
    @Resource
    private TokenService tokenService;
    /**
     * 场站 失效-围栏失效 场站失效
     * @param electronicAreaIds
     */
    @Override
    public void setStatusFailure(List<Long> electronicAreaIds){
        if(CollUtil.isNotEmpty(electronicAreaIds)){
            LambdaQueryWrapper<XpPoint> query = new LambdaQueryWrapper<>();
            query.in(XpPoint::getElectronicAreaId, electronicAreaIds);
            query.eq(XpPoint::getDeleted, 0);
            List<XpPoint> list = super.list(query);
            if(!list.isEmpty()){
                LoginUser loginUser = tokenService.getLoginUser();
                for (XpPoint bean : list) {
                    bean.setUpdateBy(loginUser.getUsername());
                    bean.setUpdateTime(LocalDateTime.now());
                    bean.setOperationStatus(4);//场站状态 0=草稿 1=待启用 2=启用中 3=已停用 4=失效
                    boolean b = updateById(bean);
                }
            }
        }
    }
}
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpStationServiceImpl.java
@@ -1,11 +1,12 @@
package com.xiaopeng.map.service.serviceimpl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.map.XpGeoFencingPolygon;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.query.operation.PointListQuery;
import com.xiaopeng.api.query.operation.PointPageListListQuery;
import com.xiaopeng.api.query.operation.XpStationQuery;
import com.xiaopeng.api.vo.account.LoginUser;
import com.xiaopeng.api.vo.operation.XpStationVo;
@@ -36,8 +37,11 @@
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * <p>
@@ -58,6 +62,7 @@
    private MongoTemplate mongoTemplate;
    @Resource
    private PolygonOverlapService polygonOverlapService;
    @Lazy
    @Resource
    private XpElectronicFenceService xpElectronicFenceService;
    @Resource
@@ -69,10 +74,58 @@
    @Lazy
    @Resource
    private XpPointService xpPointService;
    @Lazy
    @Resource
    private BootCommonService bootCommonService;
    @Override
    public List<XpStation> findList(XpStationQuery query) {
        return this.baseMapper.pageList( query);
        return this.findList(null, query);
    }
    @Override
    public List<XpStation> findList(PageInfo<XpStation> pageInfo, XpStationQuery query) {
        List<XpStation> list = null;
        if(pageInfo ==null){
            list = this.baseMapper.pageList(query);
        }else{
            list = this.baseMapper.pageList(pageInfo, query);
        }
        if(CollUtil.isNotEmpty(list)){
            LocalTime localTime = LocalTime.now();
            List<String> stationIds = new ArrayList<>();
            for (XpStation xpStation : list) {
                stationIds.add(xpStation.getId().toString());
            }
            PointPageListListQuery queryPoint = new PointPageListListQuery();
            queryPoint.setStationIds(stationIds);
            List<XpPoint> xpPoints = xpPointService.pageList(null, queryPoint);
            // 将点位按场站ID分组,提高后续处理效率
            Map<Long, List<XpPoint>> pointMap = xpPoints.stream()
                    .collect(Collectors.groupingBy(XpPoint::getStationId));
            for (XpStation xpStation : list) {
                xpStation.setPointCount(0);
                xpStation.setOperatingPointCount(0);
                List<XpPoint> stationPoints = pointMap.get(xpStation.getId());
                if (CollUtil.isNotEmpty(stationPoints)) {
                    xpStation.setPointCount(stationPoints.size());
                    int operatingPointCount = 0; // 运营中点位数
                    for (XpPoint xpPoint : stationPoints) {
                        boolean pointOperation = bootCommonService.getPointOperation(localTime, xpPoint);
                        if (pointOperation) {
                            operatingPointCount++;
                        }
                    }
                    xpStation.setOperatingPointCount(operatingPointCount);
                }
            }
        }
        return list;
    }
    @Override
@@ -81,18 +134,10 @@
        if (null == query.getCreateSort() && null == query.getUpdateSort()){
            query.setCreateSort(2);
        }
        List<XpStation> list = this.baseMapper.pageList(pageInfo, query);
        if (list.isEmpty()) {
        List<XpStation> list = this.findList(pageInfo, query);
        if(CollUtil.isEmpty(list)){
            return new PageInfo<>();
        }
        for (XpStation xpStation : list) {
            xpStation.setPointCount(0);
            xpStation.setOperatingPointCount(0);
            List<XpPoint> xpPoints = xpPointService.listByStationId((xpStation.getId()));
            if(CollUtil.isNotEmpty(xpPoints)){
                xpStation.setPointCount(xpPoints.size());
                xpStation.setOperatingPointCount((int) xpPoints.stream().filter(p -> p.getOperationStatus() != null && p.getOperationStatus() == 2).count());
            }
        }
        pageInfo.setRecords(list);
        return pageInfo;
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/utils/holiday/HolidayUtil.java
@@ -48,7 +48,7 @@
    }
    /**
     * 2非工作日  0工作日  1节假日 3调休日
     * 2非工作日  0工作日  1节假日
     * @return
     */
    public  Integer isHolidayToday() {
xp-robotaxi-map-boot/src/main/resources/mapper/XpPointMapper.xml
@@ -137,9 +137,15 @@
    <select id="queryPointByName" resultType="com.xiaopeng.api.vo.order.XpPointsListVo">
        select p.id,p.electronic_area_id as electronicAreaId,p.point_name as name,p.point_address as address,
               p.point_lon as longitude,p.point_lat as latitude,p.effective_period,p.effective_time_period,p.point_on_off,
        from xp_electronic_fence_area xefa
        left join xp_point p on p.electronic_area_id = xefa.id
               p.point_lon as longitude,p.point_lat as latitude,
               p.operation_type,p.effective_period,p.effective_time_period,p.point_on_off,p.station_id,
            xef.operation_strategy fenceOperationStrategy,
            xs.station_name  as stationName,
            xs.operation_type as stationOperationType, xs.effective_period  xs.effective_time_period as stationEffectiveTimePeriod
        from xp_point p
        inner join xp_electronic_fence_area xefa on p.electronic_area_id = xefa.id
        inner join xp_electronic_fence xef on xef.id = xefa.electronic_id
        left join xp_station xs on xs.id = xp.station_id
        where p.is_deleted = 0 and p.operation_status =2 and xefa.is_deleted = 0
        and xefa.area_status = 1 and p.electronic_area_id is not null
        and xefa.city_code = #{query.cityCode}
@@ -151,14 +157,12 @@
        </if>
    </select>
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpPoint">
        select xp.id,xp.point_number as pointNumber,xp.point_name as pointName,xp.point_poi as pointPoi,
               xp.point_address as pointAddress,xp.city_code,xp.point_on_off,xp.operation_type,xp.effective_time_period,
               xp.point_lon as pointLon,xp.point_lat as pointLat,xp.create_time as createTime,xp.create_by as createBy
        ,xp.parking_time_limit as parkingTimeLimit,xp.verification_status as verificationStatus,xp.operation_status as operationStatus
        ,xp.station_id as stationId,xp.station_sort_no as stationSortNo,xp.remarks,
        xef.electronic_name as electronicName,xs.station_name  as stationName,xef.effect_time,
        xef.operation_strategy electronicOperationStrategy
        select xp.*,
        xef.electronic_name as electronicName, xef.effect_time, xef.operation_strategy fenceOperationStrategy,
        xs.station_name  as stationName,
        xs.operation_type as stationOperationType, xs.effective_period as stationEffectivePeriod, xs.effective_time_period as stationEffectiveTimePeriod
        from xp_point xp
        left join xp_electronic_fence_area xefa on xefa.id = xp.electronic_area_id
        left join xp_electronic_fence xef on xef.id = xefa.electronic_id
@@ -185,9 +189,31 @@
            )
        </if>
        <if test="query.electronicId != null ">
            and xef.id  =  #{query.electronicId}
        </if>
        <if test="query.stationId != null ">
            and xp.station_id  =  #{query.stationId}
        </if>
        <if test="query.cityCode != null and query.cityCode != ''">
            and xp.city_code =  #{query.cityCode}
        </if>
        <if test="query.pointType != null">
            and xp.point_type = #{query.pointType}
        </if>
        <if test="query.operationStatus != null">
            and xp.operation_status = #{query.operationStatus}
        </if>
        <if test="query.electronicAreaIdNotNull != null">
            and xp.electronic_area_id is not null
        </if>
        <if test="query.orderDistance != null">
            and ST_Distance_Sphere(point(#{longitude}, #{latitude}), point(point_lon, point_lat)) &lt; = #{orderDistance}
        </if>
        <if test="query.pointName != null and query.pointName != ''">
            and xp.point_name like concat('%',#{query.pointName},'%')
xp-robotaxi-map-boot/src/main/resources/mapper/XpStationMapper.xml
@@ -4,10 +4,13 @@
    <select id="pageList" resultType="com.xiaopeng.api.model.operation.XpStation">
        select a.*
        select a.*,b.operation_strategy as fence_operation_strategy
        from xp_station a
        inner join xp_electronic_fence b on a.electronic_id = b.id and b.is_deleted = 0
        where a.is_deleted = 0
        <if test="query.id != null">
            and a.id = #{query.id}
        </if>
          <if test="query.ids != null">
            and a.id in
            <foreach item="id" collection="query.ids" open="(" separator="," close=")">
@@ -47,6 +50,12 @@
        <if test="query.updateEndTime != null and query.updateEndTime!=''">
            and #{query.updateEndTime} >= a.update_time
        </if>
        <if test="query.stationPointNum != null and query.stationPointNum!=''">
            and (
                FIND_IN_SET( (SELECT COUNT(xp.id) FROM xp_point xp WHERE xp.is_deleted=0 and xp.station_id = a.id ),#{query.stationPointNum})
            )
        </if>
        GROUP BY a.id
        <choose>
            <when test="query.createSort == 1 or query.createSort == 2 or query.updateSort == 1 or query.updateSort == 2">
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpActicityServiceImpl.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.dto.operation.XpActivityDto;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.operation.XpActicityStrategy;
@@ -13,7 +14,6 @@
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.mapper.XpActicityMapper;
import com.xiaopeng.operation.service.IXpActicityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.operation.service.IXpActicityStrategyService;
import com.xiaopeng.operation.service.IXpActicityUserService;
import com.xiaopeng.operation.service.IXpActivityNoticeService;
@@ -21,11 +21,9 @@
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Collectors;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -138,7 +138,7 @@
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void taskOrder() {
        System.out.println("5秒执行一次");
//        System.out.println("5秒执行一次");
        Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.QUEUE_POINT_ID);
        for (String name : quoteMatchName) {
            String firstElement = redisService.getFirstElement(name);
@@ -168,7 +168,7 @@
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void taskOrder_targeted() {
        System.out.println("5秒执行一次");
//        System.out.println("5秒执行一次");
        Set<String> quoteMatchName = redisService.getQuoteMatchName(CacheConstants.QUEUE_POINT_ID);
        for (String name : quoteMatchName) {
            String firstElement = redisService.getFirstElement(name);
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -3853,13 +3853,20 @@
                return true;
            }
        }
        RouteVo routeVo = this.getRouteVo(xpOrder, vehicleVin);
        if(routeVo.getDistance() <sylc){
            isCancel = true;
        try {
            RouteVo routeVo = this.getRouteVo(xpOrder, vehicleVin);
            if(routeVo.getDistance() <sylc){
                isCancel = true;
            }
            if(routeVo.getDuration() < sysj){
                isCancel = true;
            }
        } catch (Exception e) {
            log.error("获取两个点位车的距离错误",e);
            throw new ServiceException("获取两个点位车的距离错误");
        }
        if(routeVo.getDuration() < sysj){
            isCancel = true;
        }
        return isCancel;
    }