“mitao”
2026-04-17 246c72b8e1cba97de66efd8112ed166210ebc686
fix:围栏点位重名校验、围栏禁行区禁用
9个文件已修改
67 ■■■■■ 已修改文件
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/constant/I18nKeyConstant.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/i18n/messages.properties 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/i18n/messages_en_US.properties 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/resources/i18n/messages_zh_CN.properties 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/constant/I18nKeyConstant.java
@@ -31,6 +31,8 @@
    String FENCE_STRUCTURE_NOT_EXIST = "fence.structure.not.exist";
    // 围栏不存在
    String FENCE_NOT_EXIST = "fence.not.exist";
    // 围栏名称已存在
    String FENCE_NAME_EXISTS = "fence.name.exists";
    // 围栏启用状态不可复制
    String FENCE_STATUS_CANNOT_COPIED = "fence.status.cannot.copied";
@@ -97,6 +99,8 @@
    String POINT_NUMBER_LOCK_FAIL = "point.number.lock.fail";
    // 点位-编号解析失败
    String POINT_NUMBER_PARSE_FAIL = "point.number.parse.fail";
    // 点位-名称已存在
    String POINT_NAME_EXISTS = "point.name.exists";
    // 点位删除-存在关联巡游点位
    String POINT_DELETE_HAS_CRUISE_PLAN_POINT = "point.delete.has.cruise.plan.point";
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpPointManagementController.java
@@ -204,6 +204,7 @@
        if (xpPoint == null) {
            throw new ServiceException("系统异常", I18nKeyConstant.SYSTEM_EXCEPTION);
        }
        xpPointService.validatePointNameUnique(pointAddDto.getPointName(), pointAddDto.getId());
        BeanUtils.copyProperties(pointAddDto, xpPoint);
        if (Integer.valueOf(2).equals(pointAddDto.getOperationStatus()) && Integer.valueOf(5).equals(pointAddDto.getVerificationStatus())) {
            Long electronicAreaId = xpPoint.getElectronicAreaId();
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpElectronicFenceService.java
@@ -27,6 +27,11 @@
    R editElectronic(ElectronicFenceUpdateDto dto);
    /**
     * 校验围栏名称唯一
     */
    void validateElectronicNameUnique(String electronicName, Long excludeId);
    /**
     * 查询启用的电子围栏列表
     * @return
     */
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/XpPointService.java
@@ -39,6 +39,11 @@
    XpPoint addPointWithGeneratedNumber(@Valid PointAddDto pointAddDto);
    /**
     * 校验点位名称唯一
     */
    void validatePointNameUnique(String pointName, Long excludeId);
    /**
     * 获取附近上车站点
     */
    NearestVo nearest(@Valid NearestDto dto);
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -211,6 +211,7 @@
    @Transactional
    @ShardingSphereTransactionType(TransactionType.BASE)
    public R addElectronic(ElectronicFenceAddDto dto) {
        validateElectronicNameUnique(dto.getElectronicName(), null);
        // 获取现有的运营区域(areaType=1)
        LambdaQueryWrapper<XpElectronicFenceArea> xpElectronicFenceAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xpElectronicFenceAreaLambdaQueryWrapper.eq(XpElectronicFenceArea::getAreaType, 1);
@@ -343,6 +344,7 @@
    @Transactional
    @ShardingSphereTransactionType(TransactionType.BASE)
    public R editElectronic(ElectronicFenceUpdateDto dto) {
        validateElectronicNameUnique(dto.getElectronicName(), dto.getId());
        // 获取现有的运营区域(areaType=1),排除当前正在编辑的电子围栏
        LambdaQueryWrapper<XpElectronicFenceArea> xpElectronicFenceAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xpElectronicFenceAreaLambdaQueryWrapper.eq(XpElectronicFenceArea::getAreaType, 1);
@@ -448,7 +450,9 @@
            // 设置电子围栏ID并保存区域数据
            for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
                area.setElectronicId(xpElectronicFence.getId());
                area.setAreaStatus(1);
                if (area.getAreaType() == null || area.getAreaType() == 1) {
                    area.setAreaStatus(1);
                }
                area.setArea(area.getArea());
                area.setCityCode(dto.getCityCode());
                if (null != area.getId()) {
@@ -461,7 +465,9 @@
            // 设置电子围栏ID并保存区域数据
            for (XpElectronicFenceArea area : updatedElectronicFenceAreas) {
                area.setElectronicId(xpElectronicFence.getId());
                area.setAreaStatus(2);
                if (area.getAreaType() == null || area.getAreaType() == 1) {
                    area.setAreaStatus(2);
                }
                area.setArea(area.getArea());
                area.setCityCode(dto.getCityCode());
                if (null != area.getId()) {
@@ -531,6 +537,12 @@
                        old.setPoints(geoJsonPolygon);
                        mongoTemplate.save(old);
                    }
                } else if (newElectronicFenceArea.getAreaType() == 2
                        && newElectronicFenceArea.getId() != null) {
                    Query query = new Query();
                    query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId())));
                    query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId())));
                    mongoTemplate.remove(query, XpGeoFencingProhibitedPolygon.class);
                }
            }
        }
@@ -749,6 +761,21 @@
        return R.ok();
    }
    @Override
    public void validateElectronicNameUnique(String electronicName, Long excludeId) {
        if (!StringUtils.hasText(electronicName)) {
            return;
        }
        long count = this.lambdaQuery()
                .eq(XpElectronicFence::getElectronicName, electronicName)
                .ne(excludeId != null, XpElectronicFence::getId, excludeId)
                .count();
        if (count > 0) {
            throw new ServiceException("围栏名称已存在", I18nKeyConstant.FENCE_NAME_EXISTS);
        }
    }
    private static List<Long> normalizePointIds(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java
@@ -107,6 +107,7 @@
        if (pointAddDto.getElectronicAreaId() == null) {
            throw new ServiceException("运营区域ID不能为空", I18nKeyConstant.POINT_ELECTRONIC_AREA_ID_EMPTY);
        }
        validatePointNameUnique(pointAddDto.getPointName(), null);
        String cityPrefix = buildCityPrefix(pointAddDto.getElectronicAreaId());
        String lockKey = buildPointNumberLockKey(cityPrefix, POINT_BIZ_TYPE);
@@ -147,6 +148,20 @@
    }
    @Override
    public void validatePointNameUnique(String pointName, Long excludeId) {
        if (!StringUtils.hasText(pointName)) {
            return;
        }
        long count = this.lambdaQuery()
                .eq(XpPoint::getPointName, pointName)
                .ne(excludeId != null, XpPoint::getId, excludeId)
                .count();
        if (count > 0) {
            throw new ServiceException("点位名称已存在", I18nKeyConstant.POINT_NAME_EXISTS);
        }
    }
    @Override
    public NearestVo nearest(NearestDto dto) {
        // 走缓存
        Object orderDistanceObj = redisService.getCacheObject(CacheConstants.NEAR_POINT_DISTANCE);
xp-robotaxi-map-boot/src/main/resources/i18n/messages.properties
@@ -10,6 +10,7 @@
area.overlap.error=运营区域{0}与现有运营区域{1}发生重叠,请编辑已有的运营区域;
fence.structure.not.exist=围栏构成不存在
fence.not.exist=围栏不存在
fence.name.exists=围栏名称已存在
fence.status.cannot.copied=围栏启用状态不可复制;
order.create.fail=订单创建失败
open.city.exists=该城市已存在
@@ -39,6 +40,7 @@
point.city.not.exist=城市信息不存在
point.number.lock.fail=点位编号生成繁忙,请稍后重试
point.number.parse.fail=点位编号生成失败(历史编号格式异常)
point.name.exists=点位名称已存在
point.delete.has.cruise.plan.point=操作失败,该点位有关联的巡游计划点位
point.enable.not.in.operating.area=当前点位不在围栏运营区域内,不能启用。
point.enable.in.prohibited.area=当前点位在禁行区内,不能启用。
xp-robotaxi-map-boot/src/main/resources/i18n/messages_en_US.properties
@@ -11,6 +11,7 @@
fence.structure.not.exist=The fence composition does not exist\
fence.status.cannot.copied=The enabled state of the fence cannot be copied;
fence.not.exist=The fence does not exist.
fence.name.exists=Fence name already exists
order.create.fail=Order creation failed
open.city.exists=This city already exists
pricing.exists=Pricing for this vehicle model/channel/city already exists
@@ -32,6 +33,7 @@
point.city.not.exist=City information does not exist
point.number.lock.fail=Point number generation is busy, please try again later
point.number.parse.fail=Point number generation failed (invalid historical number format)
point.name.exists=Point name already exists
point.delete.has.cruise.plan.point=Operation failed. This point is associated with cruise plan points.
point.enable.not.in.operating.area=This point is not within the fence operating area and cannot be enabled.
point.enable.in.prohibited.area=This point is in a prohibited area and cannot be enabled.
xp-robotaxi-map-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -10,6 +10,7 @@
area.overlap.error=运营区域{0}与现有运营区域{1}发生重叠,请编辑已有的运营区域;
fence.structure.not.exist=围栏构成不存在
fence.not.exist=围栏不存在
fence.name.exists=围栏名称已存在
fence.status.cannot.copied=围栏启用状态不可复制
order.create.fail=订单创建失败
open.city.exists=该城市已存在
@@ -32,6 +33,7 @@
point.city.not.exist=城市信息不存在
point.number.lock.fail=点位编号生成繁忙,请稍后重试
point.number.parse.fail=点位编号生成失败(历史编号格式异常)
point.name.exists=点位名称已存在
point.delete.has.cruise.plan.point=操作失败,该点位有关联的巡游计划点位
point.enable.not.in.operating.area=当前点位不在围栏运营区域内,不能启用。
point.enable.in.prohibited.area=当前点位在禁行区内,不能启用。