From d81de6b3cc02ce24b4918a1bdef2818c61eb8cce Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期六, 14 三月 2026 23:00:47 +0800
Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi

---
 xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java |  110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 109 insertions(+), 1 deletions(-)

diff --git a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
index e494533..effc1d7 100644
--- a/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
+++ b/xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpElectronicFenceServiceImpl.java
@@ -1,6 +1,7 @@
 package com.xiaopeng.map.service.serviceimpl;
 
 
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -27,6 +28,8 @@
 import com.xiaopeng.map.mapper.XpRegionMapper;
 import com.xiaopeng.map.service.XpElectronicFenceAreaService;
 import com.xiaopeng.map.service.XpElectronicFenceService;
+import com.xiaopeng.map.service.XpPointService;
+import com.xiaopeng.map.utils.OperationStrategyIndex;
 import com.xiaopeng.map.utils.GDMapGeocodingUtil;
 import com.xiaopeng.map.utils.PolygonOverlapService;
 import lombok.extern.slf4j.Slf4j;
@@ -72,6 +75,10 @@
     private MongoTemplate mongoTemplate;
     @Autowired
     private XpPointMapper xpPointMapper;
+
+    @Autowired
+    private XpPointService xpPointService;
+
     @Autowired
     private XpRegionMapper xpRegionMapper;
     @Autowired
@@ -427,6 +434,8 @@
 
         XpElectronicFence electronicFence = this.getById(dto.getId());
         Integer status = electronicFence.getStatus();
+        String oldOperationStrategy = electronicFence.getOperationStrategy();
+        String newOperationStrategy = dto.getOperationStrategy();
 
 
         // 更新主表数据
@@ -651,7 +660,6 @@
                                 UpdateWrapper<XpPoint> xpPointUpdateWrapper = new UpdateWrapper<>();
                                 xpPointUpdateWrapper.eq("id", xpPoint.getId());
                                 xpPointUpdateWrapper.set("point_type", 2);
-                                xpPointUpdateWrapper.set("electronic_areaId", null);
                                 xpPointMapper.update(xpPoint, xpPointUpdateWrapper);
                             }
                         }
@@ -666,9 +674,109 @@
                 xpPointMapper.updateById(xpPoint);
             }
         }
+
+        OperationStrategyIndex oldIndex = OperationStrategyIndex.parse(oldOperationStrategy);
+        OperationStrategyIndex newIndex = OperationStrategyIndex.parse(newOperationStrategy);
+        boolean needAutoDisableByUnion = !oldIndex.equalsNormalized(newIndex) && oldIndex.hasAnyShrinkComparedTo(newIndex);
+
+        List<Long> addPointIds = normalizePointIds(dto.getAddPointIdList());
+        List<Long> delPointIds = normalizePointIds(dto.getDelPointIdList());
+        List<Long> disablePointIds = normalizePointIds(dto.getDisablePointIdList());
+        boolean needPointHandling = CollUtil.isNotEmpty(addPointIds)
+                || CollUtil.isNotEmpty(delPointIds)
+                || CollUtil.isNotEmpty(disablePointIds);
+        boolean needFenceAreaIds = needPointHandling || needAutoDisableByUnion;
+        XpElectronicFenceArea operationArea = needFenceAreaIds
+                ? xpElectronicFenceAreaService.lambdaQuery()
+                .eq(XpElectronicFenceArea::getElectronicId, dto.getId())
+                .eq(XpElectronicFenceArea::getAreaType, 1)
+                .orderByDesc(XpElectronicFenceArea::getId)
+                .last("limit 1")
+                .one()
+                : null;
+        Long operationAreaId = operationArea == null ? null : operationArea.getId();
+        if (needPointHandling && operationAreaId == null) {
+            throw new ServiceException("运营区域不存在", I18nKeyConstant.POINT_ELECTRONIC_AREA_NOT_EXIST);
+        }
+
+        if (CollUtil.isNotEmpty(addPointIds)) {
+            if (operationAreaId == null) {
+                throw new ServiceException("运营区域不存在", I18nKeyConstant.POINT_ELECTRONIC_AREA_NOT_EXIST);
+            }
+            xpPointService.lambdaUpdate()
+                    .in(XpPoint::getId, addPointIds)
+                    .set(XpPoint::getElectronicAreaId, operationAreaId)
+                    .set(XpPoint::getVerificationStatus, 1)
+                    .update();
+        }
+
+        if (CollUtil.isNotEmpty(disablePointIds)) {
+            // operation_status: 3=已停用
+            xpPointService.lambdaUpdate()
+                    .in(XpPoint::getId, disablePointIds)
+                    .eq(XpPoint::getElectronicAreaId, operationAreaId)
+                    .set(XpPoint::getOperationStatus, 3)
+                    .update();
+        }
+
+        if (CollUtil.isNotEmpty(delPointIds)) {
+            // operation_status: 4=已失效
+            xpPointService.lambdaUpdate()
+                    .in(XpPoint::getId, delPointIds)
+                    .eq(XpPoint::getElectronicAreaId, operationAreaId)
+                    .set(XpPoint::getOperationStatus, 4)
+                    .update();
+        }
+
+        // 围栏运营时间缩短校验:若缩短后点位时间段不在新范围内,则更新为已停用(operation_status=3)
+        if (needAutoDisableByUnion && operationAreaId != null) {
+            LambdaQueryWrapper<XpPoint> pointQuery = new LambdaQueryWrapper<>();
+            pointQuery.eq(XpPoint::getElectronicAreaId, operationAreaId)
+                    .eq(XpPoint::getPointType, 1)
+                    .eq(XpPoint::getOperationType, 2);
+            List<XpPoint> points = xpPointMapper.selectList(pointQuery);
+            if (points != null && !points.isEmpty()) {
+                List<Long> disablePointIdList = new ArrayList<>();
+                for (XpPoint pointItem : points) {
+                    if (pointItem == null) {
+                        continue;
+                    }
+                    if (pointItem.getOperationStatus() != null && pointItem.getOperationStatus() == 4) {
+                        continue;
+                    }
+                    String effectiveTimePeriod = pointItem.getEffectiveTimePeriod();
+                    if (effectiveTimePeriod == null || effectiveTimePeriod.isEmpty()) {
+                        continue;
+                    }
+                    List<OperationStrategyIndex.TimeInterval> pointIntervals = OperationStrategyIndex.parsePointEffectiveTimePeriod(effectiveTimePeriod);
+                    if (pointIntervals.isEmpty()) {
+                        continue;
+                    }
+                    boolean shouldDisable = !newIndex.isPointScheduleWithin(pointIntervals);
+                    if (shouldDisable && pointItem.getId() != null) {
+                        disablePointIdList.add(pointItem.getId());
+                    }
+                }
+                if (!disablePointIdList.isEmpty()) {
+                    XpPoint updatePoint = new XpPoint();
+                    updatePoint.setOperationStatus(3);
+                    UpdateWrapper<XpPoint> updateWrapper = new UpdateWrapper<>();
+                    updateWrapper.in("id", disablePointIdList);
+                    updateWrapper.and(w -> w.isNull("operation_status").or().ne("operation_status", 4));
+                    xpPointMapper.update(updatePoint, updateWrapper);
+                    log.info("围栏运营时间缩短停用点位完成 fenceId={}, disableCount={}", dto.getId(), disablePointIdList.size());
+                }
+            }
+        }
         return R.ok();
 
     }
+    private static List<Long> normalizePointIds(List<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
+        return ids.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
+    }
 
     /**
      * 判断点是否在多边形内

--
Gitblit v1.7.1