puzhibing
2026-03-04 d9142e583e71cea79dc4074f85712e83d941d88f
修改小程序
29个文件已修改
411 ■■■■■ 已修改文件
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ElectronicFenceUpdateDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPointClientFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPointClient.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpWorkOrder.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpCruiseOrder.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpPointsListVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/resources/bootstrap.yml 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/constant/I18nKeyConstant.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages.properties 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_en_US.properties 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_zh_CN.properties 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/VehicleCollectionScheduleTask.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpSchedulingDetailMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/constant/I18nKeyConstant.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointManagementController.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpPointService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointServiceImpl.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/resources/bootstrap.yml 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/operation/ElectronicFenceUpdateDto.java
@@ -19,8 +19,7 @@
    @ApiModelProperty(value = "id")
    @NotNull(message = "id不能为空")
    private Long id;
    @ApiModelProperty(value = "围栏名称")
    @NotEmpty(message = "所属市区不能为空")
    @ApiModelProperty(value = "城市code")
    private String cityCode;
    @ApiModelProperty(value = "围栏名称")
    @NotEmpty(message = "围栏名称不能为空")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPointClientFallbackFactory.java
@@ -109,6 +109,12 @@
                log.error("获取点位信息失败:{}", cause.getMessage());
                return null;
            }
            @Override
            public R<Boolean> nowInTimePoint(Long pointId) {
                log.error("判断点位是在有效期内失败:{}", cause.getMessage());
                return R.fail("判断点位是在有效期内失败");
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPointClient.java
@@ -78,5 +78,11 @@
    @PostMapping("/base/v1/mini-program/inner/point/getPointsInfo")
    R<List<XpPoint>> getPointsInfo(@RequestBody Set<Long> points);
    /**
     * 判断点位是在有效期内
     * @param pointId
     * @return
     */
    @GetMapping("/base/v1/mini-program/inner/point/nowInTimePoint")
    R<Boolean> nowInTimePoint(@RequestParam Long pointId);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpWorkOrder.java
@@ -1,9 +1,7 @@
package com.xiaopeng.api.model.maintenance;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.*;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.List;
@@ -46,6 +44,7 @@
    private String problemImage;
    @ApiModelProperty(value = "反馈用户手机号")
    @TableField(updateStrategy = FieldStrategy.NEVER)
    private String feedbackUserPhone;
    @ApiModelProperty(value = "问题来源 目前只有1电话客服")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/order/XpCruiseOrder.java
@@ -85,10 +85,6 @@
    @TableField("last_order_id")
    private String lastOrderId;
    @ApiModelProperty(value = "订单号")
    @TableField("order_number")
    private String orderNumber;
    @ApiModelProperty(value = "方向 1正2反")
    @TableField("order_reverse")
    private Integer orderReverse;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/XpPointsListVo.java
@@ -29,6 +29,9 @@
    @ApiModelProperty("电子围栏区域id")
    private Long electronicAreaId;
    @ApiModelProperty(value = "运营类型 1=与运营区同步 2=自定义时间段")
    private Integer operationType;
    private Integer effectivePeriod;
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -29,18 +29,6 @@
import com.xiaopeng.api.vo.SystemEventType;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.automaticPilot.protobuf.*;
import com.xiaopeng.api.vo.automaticPilot.protobuf.AbnormalReason;
import com.xiaopeng.api.vo.automaticPilot.protobuf.GearLevel;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderPhase;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderStatusInfo;
import com.xiaopeng.api.vo.automaticPilot.protobuf.RealtimePose;
import com.xiaopeng.api.vo.automaticPilot.protobuf.ResponseMessage;
import com.xiaopeng.api.vo.automaticPilot.protobuf.RtTripInfo;
import com.xiaopeng.api.vo.automaticPilot.protobuf.StatusCode;
import com.xiaopeng.api.vo.automaticPilot.protobuf.VehicleDynamicStatus;
import com.xiaopeng.api.vo.automaticPilot.protobuf.VehicleStaticInfo;
import com.xiaopeng.api.vo.automaticPilot.protobuf.VehicleStatus;
import com.xiaopeng.api.vo.automaticPilot.protobuf.Wgs;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.vehicleConvoy.CancelTaxiPassengerVo;
import com.xiaopeng.automaticPilot.util.XPUUtil;
xp-robotaxi-automatic-pilot-boot/src/main/resources/bootstrap.yml
@@ -29,7 +29,6 @@
        namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
        username: nacos
        password: nacos
        ip: 192.168.110.85
      config:
        # 配置中心地址
        server-addr: 192.168.110.80:8848
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/constant/I18nKeyConstant.java
@@ -53,4 +53,10 @@
    // 路径不存在
    String PATH_NOT_FOUND = "path.not.found";
    //未找到步行路线
    String WALKING_ROUTE_NOT_FOUND = "walking.route.not.found";
    //城市不存在
    String CITY_NOT_FOUND = "city.not.found";
}
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -14,6 +14,7 @@
import com.xiaopeng.api.feignClient.account.XpAppUserClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.operation.XpPointClient;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.feignClient.pushMessage.XpPushMessageClient;
import com.xiaopeng.api.model.account.XpAppUser;
@@ -37,6 +38,7 @@
import com.xiaopeng.itinerary.utils.XpPricingUtil;
import com.xiaopeng.itinerary.utils.holiday.HolidayUtil;
import com.xiaopeng.itinerary.utils.map.FastDistanceCalculator;
import com.xiaopeng.itinerary.utils.map.GDMapGeocodingUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
@@ -116,6 +118,12 @@
    @Resource
    private XpPushMessageClient xpPushMessageClient;
    @Resource
    private GDMapGeocodingUtil gdMapGeocodingUtil;
    @Resource
    private XpPointClient xpPointClient;
    // 自定义线程池用于并行执行任务
    private final ExecutorService executorService;
@@ -174,8 +182,6 @@
    @Override
    public RouteAndFareVo getRouteAndFare(RouteAndFareDto routeAndFareDto, String userId) {
        // 判断是否5分钟内进行了查询 相同站点的起始点  并且是同时段
        String key = "xp-map-query-" + routeAndFareDto.getOpenCityId()
                + "-" + routeAndFareDto.getOrigin().getLongitude() + "-" + routeAndFareDto.getOrigin().getLatitude()
@@ -188,12 +194,17 @@
        }
        // 1. 基础数据查询
        XpOpenCity xpOpenCity = xpOpenCityMapper.selectById(routeAndFareDto.getOpenCityId());
        if (xpOpenCity == null) {
            throw new ServiceException("未找到步行路线", I18nKeyConstant.CITY_INFORMATION_DOES_NOT_EXIST);
        Map<String, String> geocode = gdMapGeocodingUtil.geocode(routeAndFareDto.getOrigin().getLongitude().toString(), routeAndFareDto.getOrigin().getLatitude().toString());
        if(null == geocode){
            throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
        }
        String cityCode = xpOpenCity.getCityCode();
        String cityCode = geocode.get("cityCode");
        List<XpOpenCity> openCities = xpOpenCityMapper.selectList(new LambdaQueryWrapper<XpOpenCity>().eq(XpOpenCity::getCityCode, cityCode));
        if (openCities == null || openCities.isEmpty()) {
            throw new ServiceException("获取城市信息失败", I18nKeyConstant.CITY_NOT_FOUND);
        }
        XpOpenCity xpOpenCity = openCities.get(0);
        routeAndFareDto.setOpenCityId(xpOpenCity.getId());
        XpRoutePlan xpRoutePlan = xpRoutePlanMapper.selectOne(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getAuditStatus, 2).eq(XpRoutePlan::getCityCode, cityCode));
        if (xpRoutePlan != null) {
            routeAndFareDto.setRoutePlanRule(xpRoutePlan.getRoutePlanRule());
@@ -208,14 +219,13 @@
//        // 算距离
        R<RouteVo> distanceAndDuration = xpMapClient.getDistanceAndDuration(routeAndFareDto);
        if (distanceAndDuration.getCode() != 200) {
            throw new ServiceException("未找到路径", I18nKeyConstant.PATH_NOT_FOUND);
            throw new ServiceException("获取导肮信息失败", I18nKeyConstant.PATH_NOT_FOUND);
        }
        RouteVo routeVo = distanceAndDuration.getData();
        // 2. 计算价格(需要在并行任务前完成,因为优惠券查询需要价格)
        XpPricingCardVo xpPricingCardVo;
        if (xpPricing.getPricingType() == 1) {
            xpPricingCardVo = xpPricingUtil.calculationPrice(userId,
@@ -442,12 +452,11 @@
        XpPoint endXpPoint = xpPointService.getById(dto.getEndPointId());
        // 判断点位是否在运营区域内
        LocalTime now = LocalTime.now();
        boolean inTime = xpPointService.getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod());
        boolean inTime = xpPointClient.nowInTimePoint(dto.getStartPointId()).getData();
        if (!inTime) {
            throw new ServiceException("当前点位未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
        }
        inTime = xpPointService.getInTime(now, endXpPoint.getEffectivePeriod(), endXpPoint.getEffectiveTimePeriod());
        inTime = xpPointClient.nowInTimePoint(dto.getEndPointId()).getData();
        if (!inTime) {
            throw new ServiceException("当前点位未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
        }
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages.properties
@@ -1,4 +1,7 @@
# 中文
path.not.found=路径不存在
city.not.found=获取城市信息失败
no.current.region=当前区域未开通服务
path.not.found=获取导航信息失败
to.work=当前的接送点距离过近。建议步行前往
walking.route.not.found=未找到步行路线
welcome.message=欢迎来到我们的应用程序!
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_en_US.properties
@@ -1,4 +1,7 @@
# English (US)
path.not.found=Path does not exist
city.not.found=city.not.found
no.current.region=no.current.region
path.not.found=Failed to obtain navigation information
to.work=\ The current pick-up and drop-off points are too close to each other. It is recommended to walk there
walking.route.not.found=walking.route.not.found
welcome.message=Welcome to our application!
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -1,4 +1,7 @@
# 中文
path.not.found=路径不存在
city.not.found=获取城市信息失败
no.current.region=当前区域未开通服务
path.not.found=获取导航信息失败
to.work=当前的接送点距离过近。建议步行前往
walking.route.not.found=未找到步行路线
welcome.message=欢迎来到我们的应用程序!
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/VehicleCollectionScheduleTask.java
@@ -196,12 +196,6 @@
    /**
     * 向车辆发送收车指令
     * <p>
     * TODO: 具体发送收车指令的实现
     * 可能需要:
     * 1. 调用车辆控制接口发送收车指令
     * 2. 更新车辆状态为"已收车"
     * </p>
     *
     * @param xpVehicle 车辆信息
     */
xp-robotaxi-maintenance-boot/src/main/resources/mapper/maintenance/XpSchedulingDetailMapper.xml
@@ -6,7 +6,7 @@
    <select id="pageList" resultType="com.xiaopeng.maintenance.dto.SchedulingDetailDto">
        SELECT
            aa.fleet_name as fleetName,
            bb.fleet_id as fleetId,
            aa.id as fleetId,
            bb.days
        FROM
            xp_fleet aa
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -116,10 +116,12 @@
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
    public R edit(@Validated @RequestBody PointUpdateDto pointAddDto) {
        XpPoint xpPoint = new XpPoint();
        XpPoint xpPoint = xpPointService.getById(pointAddDto.getId());
        //先删除原有的数据,因为会存在点位的从属区域变化的情况,所以先删除原有的数据后添加新的数据重新分片到新的库中
        xpPointService.removeById(pointAddDto.getId());
        BeanUtils.copyProperties(pointAddDto, xpPoint);
        xpPoint.setElectronicAreaId(null);
        xpPointService.updateById(xpPoint);
        xpPoint.setId(null);
        xpPointService.save(xpPoint);
        return R.ok();
    }
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceAreaServiceImpl.java
@@ -25,6 +25,7 @@
import com.xiaopeng.map.service.XpElectronicFenceAreaService;
import com.xiaopeng.map.utils.AmapWalkingRouteUtil;
import com.xiaopeng.map.utils.ElectricFenceUtil;
import com.xiaopeng.map.utils.GDMapGeocodingUtil;
import com.xiaopeng.map.utils.GaodeMapService;
import com.xiaopeng.map.utils.holiday.HolidayUtil;
import com.xiaopeng.map.vo.IsInOperationAreaVo;
@@ -37,8 +38,10 @@
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -73,6 +76,9 @@
    @Autowired
    private MongoTemplate mongoTemplate;
    @Resource
    private GDMapGeocodingUtil gdMapGeocodingUtil;
    @Override
@@ -100,11 +106,17 @@
                continue;
            }
            // 是否运营时间内
            Boolean inOperationTime = isInOperationTime(operationStrategy);
            if(!inOperationTime){
                continue;
            if(xpElectronicFence.getFailureType() == 2){
                Boolean inOperationTime = isInOperationTime(operationStrategy);
                if(!inOperationTime){
                    continue;
                }
            }else{
                //永不失效,需要判断开始时间是否到达
                if(LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){
                    continue;
                }
            }
            XpElectronicFenceVo vo = new XpElectronicFenceVo();
            // 设置id(使用siteId作为id)
@@ -195,7 +207,12 @@
    public IsInOperationAreaVo isInOperationArea(LonLatDto dto) {
        IsInOperationAreaVo vo = new IsInOperationAreaVo();
        List<XpGeoFencingPolygon> xpGeoFencingPolygons = xpGeoFencingPolygonService.findAll();
        Map<String, String> geocode = gdMapGeocodingUtil.geocode(dto.getLongitude().toString(), dto.getLatitude().toString());
        if(null == geocode){
            throw new RuntimeException("经纬度转换城市code失败");
        }
        String cityCode = geocode.get("cityCode");
        List<XpGeoFencingPolygon> xpGeoFencingPolygons = mongoTemplate.find(new Query(Criteria.where("cityCode").is(cityCode)), XpGeoFencingPolygon.class);
        for (XpGeoFencingPolygon polygon : xpGeoFencingPolygons) {
            if (polygon.getPoints() != null && polygon.getPoints().getCoordinates() != null) {
                // GeoJsonPolygon的coordinates是一个二维数组,第一个元素是外部环
@@ -209,8 +226,12 @@
                    String fenceId = polygon.getFenceId();
                    R<XpElectronicFence> xpElectronicFence = xpElectronicFenceClient.selectById(fenceId);
                    if(xpElectronicFence!=null && null != xpElectronicFence.getData()){
                        String operationStrategy = xpElectronicFence.getData().getOperationStrategy();
                        Boolean inOperationTime = isInOperationTime(operationStrategy);
                        XpElectronicFence electronicFence = xpElectronicFence.getData();
                        String operationStrategy = electronicFence.getOperationStrategy();
                        Boolean inOperationTime = true;
                        if(electronicFence.getFailureType() == 2){
                            inOperationTime = isInOperationTime(operationStrategy);
                        }
                        if(inOperationTime){
                            vo.setStatus("inside");
                            vo.setElectronicAreaId(Long.valueOf(polygon.getAreaId()));
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -25,6 +25,7 @@
import com.xiaopeng.map.mapper.XpElectronicFenceMapper;
import com.xiaopeng.map.mapper.XpPointMapper;
import com.xiaopeng.map.mapper.XpRegionMapper;
import com.xiaopeng.map.service.XpElectronicFenceAreaService;
import com.xiaopeng.map.service.XpElectronicFenceService;
import com.xiaopeng.map.utils.GDMapGeocodingUtil;
import com.xiaopeng.map.utils.PolygonOverlapService;
@@ -69,6 +70,8 @@
    private XpRegionMapper xpRegionMapper;
    @Autowired
    private GDMapGeocodingUtil gdMapGeocodingUtil;
    @Resource
    private XpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Override
    public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
@@ -389,10 +392,7 @@
            this.updateById(xpElectronicFence);
            // 删除旧的区域数据,然后保存新的区域数据
            xpElectronicFenceAreaMapper.delete(new LambdaQueryWrapper<XpElectronicFenceArea>()
                    .eq(XpElectronicFenceArea::getElectronicId, dto.getId()));
            mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpGeoFencingPolygon.class);
            if (xpElectronicFence.getStatus() == 2) {
                // 设置电子围栏ID并保存区域数据
                for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
@@ -400,7 +400,11 @@
                    area.setAreaStatus(1);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                    if(null != area.getId()){
                        xpElectronicFenceAreaService.updateById(area);
                    }else{
                        xpElectronicFenceAreaService.save(area);
                    }
                }
            }else{
                // 设置电子围栏ID并保存区域数据
@@ -409,7 +413,11 @@
                    area.setAreaStatus(2);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                    if(null != area.getId()){
                        xpElectronicFenceAreaService.updateById(area);
                    }else{
                        xpElectronicFenceAreaService.save(area);
                    }
                }
            }
            if (dto.getStatus() == 1 || dto.getStatus() == 2) {
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/constant/I18nKeyConstant.java
@@ -85,4 +85,6 @@
    String CRUISE_PLAN_ADD_FAIL = "cruise.plan.add.fail";
    // 编辑巡游计划失败
    String CRUISE_PLAN_EDIT_FAIL = "cruise.plan.edit.fail";
    //手机号格式错误
    String ACCOUNT_FORMAT_ERROR = "account.format.error";
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java
@@ -136,7 +136,7 @@
    /**
     * 编辑电子围栏
     */
    @PostMapping("/edit")
    @PostMapping("/edit1")
    @ApiOperation(value = "编辑电子围栏")
//    @Transactional
//    @ShardingSphereTransactionType(TransactionType.BASE)
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointController.java
@@ -98,7 +98,15 @@
    }
    /**
     * 判断点位是在有效期内
     * @param pointId
     * @return
     */
    @GetMapping("/inner/point/nowInTimePoint")
    public R<Boolean> nowInTimePoint(@RequestParam Long pointId){
        return R.ok(xpPointService.nowInTimePoint(pointId));
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPointManagementController.java
@@ -30,6 +30,7 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/XpPointService.java
@@ -84,4 +84,12 @@
    PageInfo<XpPoint> pageList(PointPageListListQuery query);
    /**
     * 判断点位是否在当前时间范围内有效
     * @param pointId
     * @return
     */
    Boolean nowInTimePoint(Long pointId);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
@@ -27,6 +27,7 @@
import com.xiaopeng.operation.mapper.XpElectronicFenceMapper;
import com.xiaopeng.operation.mapper.XpPointMapper;
import com.xiaopeng.operation.mapper.XpRegionMapper;
import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
import com.xiaopeng.operation.service.IXpElectronicFenceService;
import com.xiaopeng.operation.utils.GDMapGeocodingUtil;
import com.xiaopeng.operation.utils.PolygonOverlapService;
@@ -70,6 +71,9 @@
    private XpRegionMapper xpRegionMapper;
    @Autowired
    private GDMapGeocodingUtil gdMapGeocodingUtil;
    @Resource
    private IXpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Override
    public PageInfo<XpElectronicFence> pageList(ElectronicPageListQuery query) {
@@ -389,9 +393,7 @@
            dto.setCityCode(cityCode);
            xpElectronicFence.setCityCode(dto.getCityCode());
            this.updateById(xpElectronicFence);
            // 删除旧的区域数据,然后保存新的区域数据
            xpElectronicFenceAreaMapper.delete(new LambdaQueryWrapper<XpElectronicFenceArea>()
                    .eq(XpElectronicFenceArea::getElectronicId, dto.getId()));
            if (xpElectronicFence.getStatus() == 2) {
                // 设置电子围栏ID并保存区域数据
                for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
@@ -399,7 +401,7 @@
                    area.setAreaStatus(1);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                    xpElectronicFenceAreaService.saveOrUpdate(area);
                }
            }else{
                // 设置电子围栏ID并保存区域数据
@@ -408,7 +410,7 @@
                    area.setAreaStatus(2);
                    area.setArea(area.getArea());
                    area.setCityCode(dto.getCityCode());
                    xpElectronicFenceAreaMapper.insert(area);
                    xpElectronicFenceAreaService.saveOrUpdate(area);
                }
            }
            if (dto.getStatus() == 1 || dto.getStatus() == 2) {
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpOpenCityServiceImpl.java
@@ -97,7 +97,7 @@
                .page(new Page<>(query.getPageNum(), query.getPageSize()));
        PageInfo<XpOpenCity> pageInfo = new PageInfo<>();
        pageInfo.setRecords(page.getRecords());
        page.setTotal(page.getTotal());
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointServiceImpl.java
@@ -1,14 +1,13 @@
package com.xiaopeng.operation.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.dto.operation.PointMapQuery;
import com.xiaopeng.api.dto.order.HistoryEndPointsDto;
import com.xiaopeng.api.dto.order.HistoryStartPointsDto;
import com.xiaopeng.api.model.operation.XpBanner;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.operation.XpSystemSetting;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.query.operation.PointListQuery;
import com.xiaopeng.api.query.operation.PointPageListListQuery;
import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo;
@@ -22,6 +21,8 @@
import com.xiaopeng.operation.mapper.XpPointMapper;
import com.xiaopeng.operation.mapper.XpSystemSettingMapper;
import com.xiaopeng.operation.query.PointByNameQuery;
import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
import com.xiaopeng.operation.service.IXpElectronicFenceService;
import com.xiaopeng.operation.service.XpPointService;
import com.xiaopeng.operation.utils.TimeRangeChecker;
import com.xiaopeng.operation.utils.holiday.HolidayUtil;
@@ -33,6 +34,9 @@
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
@@ -61,6 +65,12 @@
    @Resource
    private HolidayUtil holidayUtil;
    @Resource
    private IXpElectronicFenceAreaService xpElectronicFenceAreaService;
    @Resource
    private IXpElectronicFenceService xpElectronicFenceService;
    @Override
    public NearestVo nearest(NearestDto dto) {
@@ -79,16 +89,52 @@
                .apply("ST_Distance_Sphere(point({0}, {1}), point(point_lon, point_lat)) <= {2}",
                        dto.getLongitude(), dto.getLatitude(), orderDistance));
        NearestVo nearestVo = new NearestVo();
        if(list.isEmpty()){
            nearestVo.setPoints(new ArrayList<>());
            nearestVo.setTotal(0);
            return nearestVo;
        }
        List<NearestNextVo> nearestNextVos = new ArrayList<>();
        LocalTime now = LocalTime.now();
        List<Long> areaIds = list.stream().map(XpPoint::getElectronicAreaId).collect(Collectors.toList());
        List<XpElectronicFenceArea> xpElectronicFenceAreas = xpElectronicFenceAreaService.listByIds(areaIds);
        List<Long> fenceIds = xpElectronicFenceAreas.stream().map(XpElectronicFenceArea::getElectronicId).collect(Collectors.toList());
        List<XpElectronicFence> xpElectronicFences = new ArrayList<>();
        if (CollUtil.isNotEmpty(fenceIds)) {
            xpElectronicFences = xpElectronicFenceService.listByIds(fenceIds);
        }
        //判断当前点位是否在运营时间范围内
        for (XpPoint xpPoint : list) {
            // 判断是否在时间段内
            boolean intime = getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod());
            if (!intime) {
                continue;
            Integer operationType = xpPoint.getOperationType();
            if(1 == operationType){
                //与运营区同步
                XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreas.stream().filter(s -> s.getId().equals(xpPoint.getElectronicAreaId())).findFirst().orElse(null);
                if(null == xpElectronicFenceArea){
                    continue;
                }
                XpElectronicFence xpElectronicFence = xpElectronicFences.stream().filter(s -> s.getId().equals(xpElectronicFenceArea.getElectronicId())).findFirst().orElse(null);
                if(null == xpElectronicFence){
                    continue;
                }
                //失效类型 1=永不失效 2=定时失效
                Integer failureType = xpElectronicFence.getFailureType();
                //永不失效,但是还未到开始时间
                if(1 == failureType && LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){
                    continue;
                }else if(2 == failureType && (LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime()) || LocalDateTime.now().isAfter(xpElectronicFence.getFailureTime()))){
                    //定时失效,但是当前时间不在时间范围内
                    continue;
                }
            }else{
                //自定义时间段
                // 判断是否在时间段内
                boolean intime = getInTime(now, xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod());
                if (!intime) {
                    continue;
                }
            }
            // 计算距离 小于的站点
            double v = FastDistanceCalculator.distanceFast(dto.getLatitude(), dto.getLongitude(), xpPoint.getPointLat(), xpPoint.getPointLon());
            if (v < orderDistance) {
@@ -225,17 +271,51 @@
        }
        LocalTime now = LocalTime.now();
        for (XpPointsListVo xpPointsListVo : list) {
            boolean inTime = getInTime(now, xpPointsListVo.getEffectivePeriod(), xpPointsListVo.getEffectiveTimePeriod());
            if (!inTime) {
                // 不在运营段
                xpPointsListVo.setState(0);
            }
        List<Long> areaIds = list.stream().map(XpPointsListVo::getElectronicAreaId).collect(Collectors.toList());
        List<XpElectronicFenceArea> xpElectronicFenceAreas = xpElectronicFenceAreaService.listByIds(areaIds);
        List<Long> fenceIds = xpElectronicFenceAreas.stream().map(XpElectronicFenceArea::getElectronicId).collect(Collectors.toList());
        List<XpElectronicFence> xpElectronicFences = new ArrayList<>();
        if (CollUtil.isNotEmpty(fenceIds)) {
            xpElectronicFences = xpElectronicFenceService.listByIds(fenceIds);
        }
        for (XpPointsListVo xpPointsListVo : list) {
            Integer operationType = xpPointsListVo.getOperationType();
            if(1 == operationType){
                //与运营区同步
                XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreas.stream().filter(s -> s.getId().equals(xpPointsListVo.getElectronicAreaId())).findFirst().orElse(null);
                if(null == xpElectronicFenceArea){
                    // 不在运营段
                    xpPointsListVo.setState(0);
                }
                XpElectronicFence xpElectronicFence = xpElectronicFences.stream().filter(s -> s.getId().equals(xpElectronicFenceArea.getElectronicId())).findFirst().orElse(null);
                if(null == xpElectronicFence){
                    // 不在运营段
                    xpPointsListVo.setState(0);
                }
                //失效类型 1=永不失效 2=定时失效
                Integer failureType = xpElectronicFence.getFailureType();
                //永不失效,但是还未到开始时间
                if(1 == failureType && LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){
                    xpPointsListVo.setState(0);
                }else if(2 == failureType && (LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime()) || LocalDateTime.now().isAfter(xpElectronicFence.getFailureTime()))){
                    //定时失效,但是当前时间不在时间范围内
                    xpPointsListVo.setState(0);
                }
            }else{
                //自定义时间段
                // 判断是否在时间段内
                boolean intime = getInTime(now, xpPointsListVo.getEffectivePeriod(), xpPointsListVo.getEffectiveTimePeriod());
                if (!intime) {
                    // 不在运营段
                    xpPointsListVo.setState(0);
                }
            }
        }
        // 组装数据 并排序 剔除不在运营段的 数据
        List<XpPointsListVo> resultList = list.stream().peek(vo -> vo.setDistance(FastDistanceCalculator.distanceFast(query.getLat(), query.getLon(), vo.getLatitude(), vo.getLongitude()))).filter(vo -> vo.getState() == 1).collect(Collectors.toList());
        List<XpPointsListVo> resultList = list.stream()
                .peek(vo -> vo.setDistance(BigDecimal.valueOf(FastDistanceCalculator.distanceFast(query.getLat(), query.getLon(), vo.getLatitude(), vo.getLongitude())).setScale(0, RoundingMode.HALF_UP).doubleValue()))
                .filter(vo -> vo.getState() == 1).collect(Collectors.toList());
        // 可用点位
        List<XpPointsListVo> availablePoints = resultList.stream().filter(e -> query.getElectronicAreaId() != null && e.getElectronicAreaId().equals(query.getElectronicAreaId())).sorted(Comparator.comparing(XpPointsListVo::getDistance)).collect(Collectors.toList());//
@@ -269,4 +349,41 @@
        return pageInfo;
    }
    @Override
    public Boolean nowInTimePoint(Long pointId) {
        XpPoint xpPoint = this.getById(pointId);
        if(null == xpPoint){
            return false;
        }
        Integer operationType = xpPoint.getOperationType();
        if(1 == operationType){
            //与运营区同步
            XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaService.getById(xpPoint.getElectronicAreaId());
            if(null == xpElectronicFenceArea){
                return false;
            }
            XpElectronicFence xpElectronicFence = xpElectronicFenceService.getById(xpElectronicFenceArea.getElectronicId());
            if(null == xpElectronicFence){
                return false;
            }
            //失效类型 1=永不失效 2=定时失效
            Integer failureType = xpElectronicFence.getFailureType();
            //永不失效,但是还未到开始时间
            if(1 == failureType && LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime())){
                return false;
            }else if(2 == failureType && (LocalDateTime.now().isBefore(xpElectronicFence.getEffectTime()) || LocalDateTime.now().isAfter(xpElectronicFence.getFailureTime()))){
                //定时失效,但是当前时间不在时间范围内
                return false;
            }
        }else{
            //自定义时间段
            // 判断是否在时间段内
            boolean intime = getInTime(LocalTime.now(), xpPoint.getEffectivePeriod(), xpPoint.getEffectiveTimePeriod());
            if (!intime) {
                return false;
            }
        }
        return true;
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java
@@ -1,12 +1,16 @@
package com.xiaopeng.operation.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PhoneUtil;
import com.xiaopeng.api.model.account.SysUser;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.api.model.operation.XpWhitelistOperlog;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.ip.IpUtils;
import com.xiaopeng.common.core.web.domain.AjaxResult;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.constant.I18nKeyConstant;
import com.xiaopeng.operation.dto.WhitelistAddDto;
import com.xiaopeng.operation.mapper.XpWhitelistMapper;
import com.xiaopeng.operation.mapper.XpWhitelistOperlogMapper;
@@ -59,33 +63,42 @@
        }
        List<XpWhitelist> addList = new ArrayList<>();
        List<String> accounts = Arrays.asList(dto.getAccount().split(","));
        StringBuilder operationContent = new StringBuilder("新增账号:");
        StringBuilder accountBuilder = new StringBuilder();
        for (String account : accounts) {
            XpWhitelist xpWhitelist = new XpWhitelist();
            xpWhitelist.setAccount(account);
            xpWhitelist.setStatus(true);
            xpWhitelist.setIsPriorityDispatch(dto.getIsPriorityDispatch());
            xpWhitelist.setWhitelistSource(1);
            xpWhitelist.setCreateBy(sysUser.getCreateBy());
            addList.add(xpWhitelist);
            accountBuilder.append("\"").append(account).append("\"").append(",");
        if (CollUtil.isNotEmpty(accounts)) {
            String notValidPhoneNumber = accounts.stream().filter(item -> !PhoneUtil.isPhone(item)).collect(Collectors.joining(","));
            if (org.apache.commons.lang3.StringUtils.isNotBlank(notValidPhoneNumber)) {
                throw new ServiceException("以下帐号格式不正确:" + notValidPhoneNumber, I18nKeyConstant.ACCOUNT_FORMAT_ERROR, new Object[]{notValidPhoneNumber});
            }
            StringBuilder operationContent = new StringBuilder("新增账号:");
            StringBuilder accountBuilder = new StringBuilder();
            for (String account : accounts) {
                XpWhitelist xpWhitelist = new XpWhitelist();
                xpWhitelist.setAccount(account);
                xpWhitelist.setStatus(true);
                xpWhitelist.setIsPriorityDispatch(dto.getIsPriorityDispatch());
                xpWhitelist.setWhitelistSource(1);
                xpWhitelist.setCreateBy(sysUser.getCreateBy());
                addList.add(xpWhitelist);
                accountBuilder.append("\"").append(account).append("\"").append(",");
            }
            XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
            xpWhitelistOperlog.setOperationName(sysUser.getNickName());
            xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
            xpWhitelistOperlog.setOperationType(1);
            xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
            xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
            StringBuilder content = operationContent.append(accountBuilder.substring(0, accountBuilder.length() - 1));
            xpWhitelistOperlog.setOperationContent(content.toString());
            xpWhitelistOperlogMapper.insert(xpWhitelistOperlog);
            this.saveBatch(addList);
        }
        XpWhitelistOperlog xpWhitelistOperlog = new XpWhitelistOperlog();
        xpWhitelistOperlog.setOperationName(sysUser.getNickName());
        xpWhitelistOperlog.setOperationAccount(sysUser.getPhoneNumber());
        xpWhitelistOperlog.setOperationType(1);
        xpWhitelistOperlog.setOperationIp(IpUtils.getIpAddr());
        xpWhitelistOperlog.setOperationAccountId(sysUser.getId());
        StringBuilder content = operationContent.append(accountBuilder.substring(0, accountBuilder.length() - 1));
        xpWhitelistOperlog.setOperationContent(content.toString());
        xpWhitelistOperlogMapper.insert(xpWhitelistOperlog);
        this.saveBatch(addList);
        return R.ok();
    }
    @Override
    public R editWhitelist(XpWhitelist dto, SysUser sysUser) {
        if (!PhoneUtil.isPhone(dto.getAccount())) {
            throw new ServiceException("以下帐号格式不正确:", I18nKeyConstant.ACCOUNT_FORMAT_ERROR, new Object[]{dto.getAccount()});
        }
        XpWhitelist whitelist = this.getById(dto.getId());
        StringBuilder operationContent = new StringBuilder("编辑账号:");
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointMapper.xml
@@ -91,7 +91,7 @@
    <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
        select p.id,p.operation_type as operationType ,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
        from xp_electronic_fence_area xefa
        left join xp_point p on p.electronic_area_id = xefa.id
        where p.is_deleted = 0 and p.operation_status =2 and xefa.is_deleted = 0
xp-robotaxi-vehicle-convoy-boot/src/main/resources/bootstrap.yml
@@ -29,7 +29,6 @@
        namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
        username: nacos
        password: nacos
        ip: 192.168.110.85
      config:
        # 配置中心地址
        server-addr: 192.168.110.80:8848