xuhy
2026-03-14 cf7fde24bf5a20ca8328729406f85ee16984da7a
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpElectronicFenceManagementController.java
@@ -5,8 +5,8 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceAreaUpdateStatusDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceOperationStrategyValidateDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto;
import com.xiaopeng.api.feignClient.operation.XpElectronicClient;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
import com.xiaopeng.api.model.operation.XpPoint;
@@ -17,27 +17,29 @@
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.service.TokenService;
import com.xiaopeng.map.constant.I18nKeyConstant;
import com.xiaopeng.map.service.XpElectronicFenceAreaService;
import com.xiaopeng.map.service.XpElectronicFenceService;
import com.xiaopeng.map.service.XpPointService;
import com.xiaopeng.map.service.XpRegionService;
import com.xiaopeng.map.utils.OperationStrategyIndex;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.locationtech.jts.geom.Coordinate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.xiaopeng.map.service.serviceimpl.XpElectronicFenceServiceImpl.getPinyinInitials;
@@ -66,6 +68,9 @@
    private XpRegionService regionService;
    @Autowired
    private XpRegionService xpRegionService;
    @Autowired
    private XpPointService xpPointService;
    /**
     * 查询省市管理
     */
@@ -146,11 +151,76 @@
     */
    @PostMapping("/edit")
    @ApiOperation(value = "编辑电子围栏")
    @Transactional
    @ShardingSphereTransactionType(TransactionType.BASE)
    public R edit(@Validated @RequestBody ElectronicFenceUpdateDto dto) {
        return xpElectronicFenceService.editElectronic(dto);
    }
    /**
     * 校验编辑围栏时运营时间段缩短影响的点位数量
     * <p>
     * 统计:围栏下 operation_type=2(自定义运营时间段) 的点位中,
     * 当围栏运营时间范围发生缩短时,不在新运营时间范围(Union)内的点位数量(需要停用)。
     * </p>
     */
    @PostMapping("/validateOperationStrategyShorten")
    @ApiOperation(value = "校验围栏运营时间段缩短影响点位数量")
    public R<Integer> validateOperationStrategyShorten(@Valid @RequestBody ElectronicFenceOperationStrategyValidateDto dto) {
        XpElectronicFence fence = xpElectronicFenceService.getById(dto.getId());
        if (fence == null) {
            throw new ServiceException("围栏不存在", I18nKeyConstant.FENCE_NOT_EXIST);
        }
        OperationStrategyIndex oldIndex = OperationStrategyIndex.parse(fence.getOperationStrategy());
        OperationStrategyIndex newIndex = OperationStrategyIndex.parse(dto.getOperationStrategy());
        if (oldIndex.equalsNormalized(newIndex)) {
            return R.ok(0);
        }
        if (!oldIndex.hasAnyShrinkComparedTo(newIndex)) {
            return R.ok(0);
        }
        List<Long> fenceAreaIds = xpElectronicFenceAreaService.lambdaQuery()
                .eq(XpElectronicFenceArea::getElectronicId, dto.getId())
                .list()
                .stream()
                .map(XpElectronicFenceArea::getId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (CollUtil.isEmpty(fenceAreaIds)) {
            return R.ok(0);
        }
        List<XpPoint> customPoints = xpPointService.lambdaQuery()
                .in(XpPoint::getElectronicAreaId, fenceAreaIds)
                .eq(XpPoint::getPointType, 1)
                .eq(XpPoint::getOperationType, 2)
                .list();
        if (CollUtil.isEmpty(customPoints)) {
            return R.ok(0);
        }
        int disableCount = 0;
        for (XpPoint point : customPoints) {
            if (point == null || point.getEffectiveTimePeriod() == null || point.getEffectiveTimePeriod().isEmpty()) {
                continue;
            }
            List<OperationStrategyIndex.TimeInterval> pointIntervals = OperationStrategyIndex.parsePointEffectiveTimePeriod(point.getEffectiveTimePeriod());
            if (pointIntervals.isEmpty()) {
                continue;
            }
            boolean shouldDisable = !newIndex.isPointScheduleWithin(pointIntervals);
            if (shouldDisable) {
                disableCount++;
            }
        }
        return R.ok(disableCount);
    }
    /**
     * 复制电子围栏
     */
    @PostMapping("/copy")