From 0dd8ec867eb1ed398bc1b1e93538f55809df3679 Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期五, 13 二月 2026 22:24:27 +0800
Subject: [PATCH] feat:增加省市区级联接口
---
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRegionServiceImpl.java | 125 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 121 insertions(+), 4 deletions(-)
diff --git a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRegionServiceImpl.java b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRegionServiceImpl.java
index 1e849ff..b75f141 100644
--- a/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRegionServiceImpl.java
+++ b/xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpRegionServiceImpl.java
@@ -3,19 +3,27 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xiaopeng.api.model.operation.XpOpenCity;
+import com.xiaopeng.api.model.operation.XpRegion;
import com.xiaopeng.common.core.constant.CacheConstants;
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.operation.mapper.XpRegionMapper;
-import com.xiaopeng.api.model.operation.XpRegion;
+import com.xiaopeng.operation.service.XpOpenCityService;
import com.xiaopeng.operation.service.XpRegionService;
+import com.xiaopeng.operation.vo.RegionCascaderVO;
import com.xiaopeng.operation.vo.RegionDistrictSyncResultVO;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
import java.util.List;
-import java.util.Objects;
+import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -31,6 +39,8 @@
@Resource
private RedisService redisService;
+ @Resource
+ private XpOpenCityService openCityService;
@Override
public List<List<XpRegion>> getXpRegion() {
@@ -69,10 +79,116 @@
}
@Override
+ public List<RegionCascaderVO> getRegionCascader() {
+ List<Object> cacheList = redisService.getCacheList(CacheConstants.XP_REGION_CASCADER);
+ if (cacheList != null && !cacheList.isEmpty()) {
+ try {
+ return cacheList.stream()
+ .filter(item -> item instanceof RegionCascaderVO)
+ .map(item -> (RegionCascaderVO) item)
+ .collect(Collectors.toList());
+ } catch (ClassCastException e) {
+ redisService.deleteObject(CacheConstants.XP_REGION_CASCADER);
+ }
+ }
+
+ List<XpRegion> regionList = this.baseMapper.selectList(Wrappers.lambdaQuery(XpRegion.class));
+ if (regionList == null || regionList.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ List<XpOpenCity> openCityList = openCityService.list(Wrappers.lambdaQuery(XpOpenCity.class)
+ .eq(XpOpenCity::getStatus, 1));
+ Set<String> openCityCodeSet = openCityList.stream()
+ .map(XpOpenCity::getCityCode)
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toCollection(HashSet::new));
+ Set<String> openDistrictCodeSet = openCityList.stream()
+ .map(XpOpenCity::getDistrictCode)
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toCollection(HashSet::new));
+
+ Map<Long, List<XpRegion>> childrenMap = regionList.stream()
+ .collect(Collectors.groupingBy(region -> region.getParentId() == null ? 0L : region.getParentId()));
+ List<XpRegion> provinceList = childrenMap.getOrDefault(0L, Collections.emptyList()).stream()
+ .sorted(REGION_COMPARATOR)
+ .collect(Collectors.toList());
+ List<RegionCascaderVO> result = provinceList.stream()
+ .map(region -> buildRegionNode(region, childrenMap, openCityCodeSet, openDistrictCodeSet))
+ .collect(Collectors.toList());
+
+ redisService.setCacheList(CacheConstants.XP_REGION_CASCADER, result);
+ return result;
+ }
+
+ private RegionCascaderVO buildRegionNode(XpRegion current,
+ Map<Long, List<XpRegion>> childrenMap,
+ Set<String> openCityCodeSet,
+ Set<String> openDistrictCodeSet) {
+ List<XpRegion> children = childrenMap.getOrDefault(current.getId(), Collections.emptyList()).stream()
+ .sorted(REGION_COMPARATOR)
+ .collect(Collectors.toList());
+ List<RegionCascaderVO> childNodes = children.stream()
+ .map(child -> buildRegionNode(child, childrenMap, openCityCodeSet, openDistrictCodeSet))
+ .collect(Collectors.toList());
+
+ Integer level = resolveRegionLevel(current.getCode());
+ Integer selfOpen = resolveSelfOpen(level, current.getCode(), openCityCodeSet, openDistrictCodeSet);
+ boolean hasOpenChild = childNodes.stream().anyMatch(node -> Integer.valueOf(1).equals(node.getIsOpen()));
+
+ RegionCascaderVO node = new RegionCascaderVO();
+ node.setCode(current.getCode());
+ node.setName(current.getName());
+ node.setLeaf(Integer.valueOf(3).equals(level));
+ node.setChildren(childNodes);
+ node.setIsOpen(selfOpen == 1 || hasOpenChild ? 1 : 0);
+ return node;
+ }
+
+ private Integer resolveRegionLevel(String code) {
+ if (StringUtils.isBlank(code) || code.length() < 4) {
+ return 3;
+ }
+ if (code.endsWith("0000")) {
+ return 1;
+ }
+ if (code.endsWith("00")) {
+ return 2;
+ }
+ return 3;
+ }
+
+ private Integer resolveSelfOpen(Integer level,
+ String code,
+ Set<String> openCityCodeSet,
+ Set<String> openDistrictCodeSet) {
+ if (StringUtils.isBlank(code)) {
+ return 0;
+ }
+ if (Integer.valueOf(2).equals(level)) {
+ return openCityCodeSet.contains(code) ? 1 : 0;
+ }
+ if (Integer.valueOf(3).equals(level)) {
+ return openDistrictCodeSet.contains(code) ? 1 : 0;
+ }
+ return 0;
+ }
+
+ private static final Comparator<XpRegion> REGION_COMPARATOR = Comparator
+ .comparing((XpRegion region) -> StringUtils.defaultString(region.getInitial()))
+ .thenComparing((XpRegion region) -> StringUtils.defaultString(region.getCode()));
+
+ @Override
@Transactional(rollbackFor = Exception.class)
public RegionDistrictSyncResultVO syncDistrictFromRegionAll() {
- Long cityCount = Objects.requireNonNullElse(this.baseMapper.countCityForDistrictSync(), 0L);
- Long candidateDistrictCount = Objects.requireNonNullElse(this.baseMapper.countCandidateDistrictForSync(), 0L);
+ Long cityCount = this.baseMapper.countCityForDistrictSync();
+ if (cityCount == null) {
+ cityCount = 0L;
+ }
+ Long candidateDistrictCount = this.baseMapper.countCandidateDistrictForSync();
+ if (candidateDistrictCount == null) {
+ candidateDistrictCount = 0L;
+ }
List<XpRegion> missingDistrictList = this.baseMapper.selectMissingDistrictFromRegionAll();
long insertedCount = 0L;
@@ -83,6 +199,7 @@
redisService.deleteObject(CacheConstants.XP_REGION);
redisService.deleteObject(CacheConstants.XP_REGION_CITY);
+ redisService.deleteObject(CacheConstants.XP_REGION_CASCADER);
RegionDistrictSyncResultVO result = new RegionDistrictSyncResultVO();
result.setCityCount(cityCount);
--
Gitblit v1.7.1