Browse Source

增加区域工具类

master
WendyYang 1 year ago
parent
commit
08b0d2e640
20 changed files with 430 additions and 489 deletions
  1. +43
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/constant/RegionConst.java
  2. +0
    -19
      pmapi/src/main/java/com/ningdatech/pmapi/common/constant/RegionLevelConst.java
  3. +27
    -55
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/RegionCacheHelper.java
  4. +0
    -138
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/basic/AbstractRegionCache.java
  5. +69
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/basic/AbstractRegionCacheHelper.java
  6. +1
    -1
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/basic/AbstractRegionLimitHelper.java
  7. +8
    -8
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/impl/RegionLimitHelperImpl.java
  8. +167
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/impl/RegionsCacheHelperImpl.java
  9. +0
    -205
      pmapi/src/main/java/com/ningdatech/pmapi/common/helper/impl/RegionsCacheImpl.java
  10. +6
    -7
      pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/MeetingManage.java
  11. +2
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/InitProcessTask.java
  12. +0
    -26
      pmapi/src/main/java/com/ningdatech/pmapi/sys/contant/RegionConst.java
  13. +4
    -4
      pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/RegionController.java
  14. +19
    -11
      pmapi/src/main/java/com/ningdatech/pmapi/sys/convert/RegionConverter.java
  15. +4
    -11
      pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/RegionManage.java
  16. +2
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/model/dto/RegionDTO.java
  17. +2
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/model/entity/Region.java
  18. +9
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRegionService.java
  19. +9
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RegionServiceImpl.java
  20. +58
    -0
      pmapi/src/test/java/com/ningdatech/pmapi/sys/service/IRegionServiceTest.java

+ 43
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/constant/RegionConst.java View File

@@ -0,0 +1,43 @@
package com.ningdatech.pmapi.common.constant;

/**
* <p>
* RegionConst
* </p>
*
* @author WendyYang
* @since 13:57 2023/3/1
*/
public interface RegionConst {

//---------------------------------------地区层级(缩写RL)-------------------------------------------------------------

int RL_PROVINCE = 1;

int RL_CITY = 2;

int RL_COUNTY = 3;

//---------------------------------------地区编码(缩写RC)-------------------------------------------------------------

/**
* 丽水行政区划编码
*/
String RC_LS = "331100";

/**
* 中国行政区划编码
*/
String RC_CHINA = "100000";


/**
* 浙江行政区划编码
*/
String RC_ZJ = "330000";

//----------------------------------------地区父级ID(缩写PID)---------------------------------------------------------

long PID_CHINA = 0;

}

+ 0
- 19
pmapi/src/main/java/com/ningdatech/pmapi/common/constant/RegionLevelConst.java View File

@@ -1,19 +0,0 @@
package com.ningdatech.pmapi.common.constant;

/**
* <p>
* RegionLevelConst
* </p>
*
* @author WendyYang
* @since 13:57 2023/3/1
*/
public interface RegionLevelConst {

int PROVINCE = 1;

int CITY = 2;

int COUNTY = 3;

}

+ 27
- 55
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/RegionCacheHelper.java View File

@@ -2,10 +2,10 @@ package com.ningdatech.pmapi.common.helper;


import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.dto.RegionTreeDTO;
import com.ningdatech.pmapi.sys.model.vo.RegionTreeVO;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* <p>
@@ -23,52 +23,14 @@ public interface RegionCacheHelper {
*
* @return /
*/
List<RegionTreeDTO> all();

/**
* 获取用于前端回显示使用的unionList 仅用于返回前端的时候使用
*
* @param code 区域编码
* @param level 区域层级
* @return
*/
String getUnionPathStr(String code, Integer level);

/**
* 原专家库数据导入使用 返回名称区域Map
*
* @return
*/
Map<String, RegionDTO> getNameRegionMap();


/**
* key.getRegionCode() + "###" + key.getRegionLevel() ,regionMap.get(key)
*
* @return
*/
Map<String, RegionDTO> getRegionMap();

/**
* 获取市级区域列表
*
* @return
*/
List<RegionDTO> getMunicipalRegion();

/**
* 获取省级区域列表
*
* @return /
*/
List<RegionDTO> getProvincialRegion();
List<RegionDTO> all();

/**
* 根据区域code 区域层级获取 区域类
*
* @param code 区域编码
* @param level 区域层级
* @return /
* @return {@link RegionDTO}
*/
RegionDTO getByCodeAndLevel(String code, int level);

@@ -83,29 +45,39 @@ public interface RegionCacheHelper {
List<RegionDTO> listParents(String code, int level);

/**
* 获取所有区域编码「parent -> child」
* 获取当前区域所有的子区域(包括自己)
*
* @param regionCode 区域编码
* @param regionLevel 级别
* @param code 区域编码
* @param level 级别
* @return /
*/
List<String> getRegionCodes(String regionCode, int regionLevel);
Collection<String> listChildRegionCodeList(String code, int level);

/**
* 获取当前区域所有的子集
* 获取当前节点开始的区域树
*
* @param code 区域编码
* @param level 级别
* @return /
* @param regionCode 区域编码
* @param regionLevel 区域层级
* @return 区域树
*/
List<String> getAllChildrenRegionCodeList(String code, int level);
RegionTreeVO getRegionTree(String regionCode, Integer regionLevel);

/**
* 获取展示名称(浙江省/杭州市/滨江区)
*
* @param regionCode 区域编码
* @param regionLevel 区域层级
* @return java.lang.String
**/
String getFullDisplayName(String regionCode, Integer regionLevel);

/**
* 获取 根节点 区域层级编码
* 获取展示名称(杭州市/滨江区)
*
* @return /
*/
String getParentCodeRoot();
* @param regionCode 区域编码
* @param regionLevel 区域层级
* @return java.lang.String
**/
String getDisplayName(String regionCode, Integer regionLevel);

}

+ 0
- 138
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/basic/AbstractRegionCache.java View File

@@ -1,138 +0,0 @@
package com.ningdatech.pmapi.common.helper.basic;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.pmapi.common.helper.RegionCacheHelper;
import com.ningdatech.pmapi.common.model.RegionMapKey;
import com.ningdatech.pmapi.sys.convert.RegionConverter;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.dto.RegionTreeDTO;
import com.ningdatech.pmapi.sys.service.IRegionService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* <p>
* AbstractRegionCache
* </p>
*
* @author WendyYang
* @since 14:41 2023/3/1
*/
public abstract class AbstractRegionCache implements InitializingBean, RegionCacheHelper {

@Autowired
private IRegionService regionService;
/**
* 当前支持最大层级
*/
private static final int REGION_LEVEL_MAX = 3;

private LoadingCache<String, List<RegionTreeDTO>> regionsCache;

/**
* 中国行政区划编码
*/
private static final String PARENT_CODE_ROOT = "100000";

protected Map<RegionMapKey, RegionDTO> regionMap;

@Override
public void afterPropertiesSet() {
regionsCache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.refreshAfterWrite(5, TimeUnit.MINUTES)
.build(key -> {
// 查询全部
List<RegionDTO> regionDTOList = regionService.all();
if (regionDTOList.isEmpty()) {
throw BizException.wrap("区域元数据不能为空");
}
regionMap = buildCacheMap(regionDTOList);
List<RegionDTO> regionInLevel = regionMap.values().stream()
.filter(regionDTO -> {
// 只过滤出小于等于level的region
if (Objects.isNull(regionDTO.getRegionLevel())) {
return false;
}
return Integer.parseInt(key) >= regionDTO.getRegionLevel();
}).collect(Collectors.toList());
List<RegionTreeDTO> treeDtos = RegionConverter.toRegionTreeDTOList(regionInLevel);
return toTreeStructure(treeDtos);
});
warmUp();
}

protected List<RegionTreeDTO> getByLevel(int level) {
return regionsCache.get(String.valueOf(level));
}

private Map<RegionMapKey, RegionDTO> buildCacheMap(List<RegionDTO> regionDTOList) {
Map<RegionMapKey, RegionDTO> regionDtoMap = new ConcurrentHashMap<>(256);
regionDTOList.forEach(region -> {
RegionMapKey key = RegionMapKey.builder()
.regionCode(region.getRegionCode())
.regionLevel(region.getRegionLevel())
.build();
regionDtoMap.put(key, region);
});
return regionDtoMap;
}

private List<RegionTreeDTO> toTreeStructure(List<RegionTreeDTO> rootList) {
List<RegionTreeDTO> nodeList = new ArrayList<>();
for (RegionTreeDTO treeNode : rootList) {
if (PARENT_CODE_ROOT.equals(treeNode.getParentCode()) || Objects.isNull(treeNode.getParentCode())) {
nodeList.add(treeNode);
}
treeNode.setChildren(getChildren(treeNode.getRegionCode(), treeNode.getLevel(), rootList));
}
return nodeList;
}

private List<RegionTreeDTO> getChildren(String regionCode, int regionLevel, List<RegionTreeDTO> list) {
List<RegionTreeDTO> childList = new ArrayList<>();
for (RegionTreeDTO regionTreeDTO : list) {
if (regionCode.equals(regionTreeDTO.getParentCode()) && regionLevel + 1 == regionTreeDTO.getLevel()) {
childList.add(regionTreeDTO);
}
}
for (RegionTreeDTO regionTreeDTO : childList) {
regionTreeDTO.setChildren(getChildren(regionTreeDTO.getRegionCode(), regionTreeDTO.getLevel(), list));
}
if (CollectionUtils.isEmpty(childList)) {
return Collections.emptyList();
}
childList.sort(Comparator.comparing(RegionTreeDTO::getRegionCode));
return childList;
}


private void warmUp() {
for (int level = 1; level <= REGION_LEVEL_MAX; level++) {
getByLevel(level);
}
}

protected List<RegionTreeDTO> getCopyListByLevel(int level) {
List<RegionTreeDTO> regionTreeDtos = regionsCache.get(String.valueOf(level));
List<RegionTreeDTO> copyRegionTreeDtos = new ArrayList<>();
if (CollectionUtils.isNotEmpty(regionTreeDtos)) {
copyRegionTreeDtos.addAll(regionTreeDtos);
}
return copyRegionTreeDtos;
}


@Override
public String getParentCodeRoot() {
return PARENT_CODE_ROOT;
}
}

+ 69
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/basic/AbstractRegionCacheHelper.java View File

@@ -0,0 +1,69 @@
package com.ningdatech.pmapi.common.helper.basic;

import cn.hutool.core.lang.Assert;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.ningdatech.pmapi.common.model.RegionMapKey;
import com.ningdatech.pmapi.sys.convert.RegionConverter;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.service.IRegionService;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* <p>
* AbstractRegionCache
* </p>
*
* @author WendyYang
* @since 14:41 2023/3/1
*/
@Slf4j
public abstract class AbstractRegionCacheHelper implements InitializingBean {

@Autowired
private IRegionService regionService;

private LoadingCache<RegionMapKey, RegionDTO> regionsCache;

private void initRegionCache() {
List<RegionDTO> allRegions = regionService.all();
if (allRegions.isEmpty()) {
log.warn("区域元数据未初始化");
return;
}
allRegions.forEach(w -> {
RegionMapKey key = RegionMapKey.of(w.getRegionCode(), w.getRegionLevel());
regionsCache.put(key, w);
});
}

protected RegionDTO get(RegionMapKey key) {
return regionsCache.get(key);
}

protected List<RegionDTO> all() {
return Lists.newArrayList(regionsCache.asMap().values());
}

@Override
public void afterPropertiesSet() {
regionsCache = Caffeine.newBuilder()
.refreshAfterWrite(7, TimeUnit.DAYS)
.maximumSize(512)
.build(key -> {
Region region = regionService.getOne(key.getRegionCode(), key.getRegionLevel());
Assert.notNull(region, "区域不存在:%s", key);
return RegionConverter.toRegionDTO(region);
});
// 初始化所有区域数据到缓存
initRegionCache();
}

}

+ 1
- 1
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/basic/AbstractRegionLimitHelper.java View File

@@ -20,7 +20,7 @@ import java.util.Objects;
@AllArgsConstructor
public abstract class AbstractRegionLimitHelper implements RegionLimitHelper {

protected final RegionCacheHelper regionCacheHelper;
protected final RegionCacheHelper regionCache;
protected final IExpertUserFullInfoService expertUserFullInfoService;




+ 8
- 8
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/impl/RegionLimitHelperImpl.java View File

@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -24,8 +25,8 @@ public class RegionLimitHelperImpl extends AbstractRegionLimitHelper {

private static final Logger logger = LoggerFactory.getLogger(RegionLimitHelperImpl.class);

public RegionLimitHelperImpl(RegionCacheHelper regionCacheHelper, IExpertUserFullInfoService expertUserFullInfoService) {
super(regionCacheHelper, expertUserFullInfoService);
public RegionLimitHelperImpl(RegionCacheHelper regionCache, IExpertUserFullInfoService expertUserFullInfoService) {
super(regionCache, expertUserFullInfoService);
}

public static Boolean contains(Integer adminRegionLevel, List<String> adminAllContainsRegionCodes
@@ -88,12 +89,11 @@ public class RegionLimitHelperImpl extends AbstractRegionLimitHelper {

@Override
public RegionContainsBO getContainsRegionBo(Integer regionLevel, String regionCode) {
List<String> regionCodes = regionCacheHelper
.getAllChildrenRegionCodeList(regionCode, regionLevel);
RegionContainsBO regionContainsBO = new RegionContainsBO();
regionContainsBO.setContainsRegionCodeList(regionCodes);
regionContainsBO.setParentRegionTreeLevel(regionLevel);
return regionContainsBO;
Collection<String> regionCodes = regionCache.listChildRegionCodeList(regionCode, regionLevel);
RegionContainsBO regionContains = new RegionContainsBO();
regionContains.setContainsRegionCodeList(new ArrayList<>(regionCodes));
regionContains.setParentRegionTreeLevel(regionLevel);
return regionContains;
}

@Override


+ 167
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/impl/RegionsCacheHelperImpl.java View File

@@ -0,0 +1,167 @@
package com.ningdatech.pmapi.common.helper.impl;

import cn.hutool.core.text.StrPool;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.constant.RegionConst;
import com.ningdatech.pmapi.common.helper.RegionCacheHelper;
import com.ningdatech.pmapi.common.helper.basic.AbstractRegionCacheHelper;
import com.ningdatech.pmapi.common.model.RegionMapKey;
import com.ningdatech.pmapi.common.util.StrUtils;
import com.ningdatech.pmapi.sys.convert.RegionConverter;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.dto.RegionTreeDTO;
import com.ningdatech.pmapi.sys.model.vo.RegionTreeVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author liuxinxin
* @date 2022/7/22 上午8:58
* 构建地区码 地区树
*/
@Slf4j
@Component
public class RegionsCacheHelperImpl extends AbstractRegionCacheHelper implements RegionCacheHelper {

@Override
public RegionDTO getByCodeAndLevel(String code, int level) {
return super.get(RegionMapKey.of(code, level));
}

@Override
public List<RegionDTO> all() {
return super.all();
}

@Override
public Collection<String> listChildRegionCodeList(String regionCode, int regionLevel) {
RegionDTO currRegion = getByCodeAndLevel(regionCode, regionLevel);
if (currRegion.getParentCode().equals(regionCode)) {
return Collections.singletonList(regionCode);
}
List<RegionDTO> allRegions = all();
return allRegions.stream().filter(w -> StrUtils.split(w.getRegionCodePath()).contains(regionCode))
.map(RegionDTO::getRegionCode).collect(Collectors.toSet());
}

@Override
public RegionTreeVO getRegionTree(String regionCode, Integer regionLevel) {
Map<Long, List<RegionDTO>> regions;
Long parentId;
if (regionCode == null || regionCode.equals(RegionConst.RC_CHINA)) {
regions = CollUtils.group(all(), RegionDTO::getParentId);
parentId = RegionConst.PID_CHINA;
} else {
RegionDTO currRegion = getByCodeAndLevel(regionCode, regionLevel);
if (currRegion.getParentCode().equals(regionCode)) {
return RegionConverter.toRegionTreeVO(currRegion);
}
regions = all().stream()
.filter(w -> StrUtils.split(w.getRegionCodePath()).contains(regionCode))
.collect(Collectors.groupingBy(RegionDTO::getParentId));
parentId = currRegion.getParentId();
}
regions.values().forEach(w -> w.sort(Comparator.comparing(x -> Long.parseLong(x.getRegionCode()))));
return RegionConverter.toRegionTree(parentId, regions, false).get(0);
}

@Override
public String getFullDisplayName(String regionCode, Integer regionLevel) {
RegionDTO regionCurr = getByCodeAndLevel(regionCode, regionLevel);
return getDisplayName(regionCurr, RegionConst.RL_PROVINCE);
}

@Override
public String getDisplayName(String regionCode, Integer regionLevel) {
RegionDTO regionCurr = getByCodeAndLevel(regionCode, regionLevel);
return getDisplayName(regionCurr, RegionConst.RL_CITY);
}

//------------------------------------------------------------------------------------------------------------------

/**
* 获取指定层级的展示名称
*
* @param region 当前区域
* @param sLevel 开始层级
* @return 展示名称
*/
private String getDisplayName(RegionDTO region, int sLevel) {
Integer level = region.getRegionLevel();
if (RegionConst.RL_PROVINCE > sLevel || sLevel > level) {
throw BizException.wrap("区域层级无效");
}
if (sLevel == level) {
return region.getRegionName();
}
StringBuilder builder = new StringBuilder();
List<String> regionCodes = StrUtils.split(region.getRegionCodePath());
for (int i = regionCodes.size() - 1; i > 0; i--) {
if (level <= sLevel) {
break;
}
RegionDTO tmp = getByCodeAndLevel(regionCodes.get(i), --level);
builder.append(tmp.getRegionName()).append(StrPool.SLASH);
}
builder.append(region.getRegionName());
return builder.toString();
}

protected List<RegionTreeDTO> getCopyListByLevel(int level) {
List<RegionDTO> regions = all().stream()
.filter(w -> w.getRegionLevel() <= level)
.collect(Collectors.toList());
return RegionConverter.toRegionTreeDTOList(regions);
}

/**
* 获取某一个地区开始的层级树
*
* @param list 地区集合
* @param code 地区编码
* @param level 地区层级
* @return /
*/
private RegionTreeDTO getTreeByRegionAndCode(List<RegionTreeDTO> list, String code, int level) {
if (CollectionUtils.isEmpty(list)) {
list = getCopyListByLevel(3);
if (CollectionUtils.isEmpty(list)) {
return null;
}
}
Optional<RegionTreeDTO> first = list.stream()
.filter(w -> w.getRegionCode().equals(code) && w.getLevel() == level)
.findFirst();
if (first.isPresent()) {
return first.get();
}
for (RegionTreeDTO dto : list) {
if (CollectionUtils.isEmpty(dto.getChildren())) {
continue;
}
RegionTreeDTO temp = getTreeByRegionAndCode(dto.getChildren(), code, level);
if (temp != null) {
return temp;
}
}
return null;
}

@Override
public List<RegionDTO> listParents(String code, int level) {
List<RegionDTO> result = new ArrayList<>();
RegionDTO dto = getByCodeAndLevel(code, level);
result.add(0, dto);
if (RegionConst.RC_CHINA.equals(dto.getParentCode())) {
return result;
}
result.addAll(0, listParents(dto.getParentCode(), dto.getRegionLevel() - 1));
return result;
}

}

+ 0
- 205
pmapi/src/main/java/com/ningdatech/pmapi/common/helper/impl/RegionsCacheImpl.java View File

@@ -1,205 +0,0 @@
package com.ningdatech.pmapi.common.helper.impl;

import cn.hutool.core.lang.Assert;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.helper.basic.AbstractRegionCache;
import com.ningdatech.pmapi.common.model.RegionMapKey;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.dto.RegionTreeDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author liuxinxin
* @date 2022/7/22 上午8:58
* 构建地区码 地区树
*/
@Slf4j
@Component
public class RegionsCacheImpl extends AbstractRegionCache {

@Override
public List<RegionTreeDTO> all() {
return getByLevel(3);
}

@Override
public List<String> getAllChildrenRegionCodeList(String code, int level) {
List<RegionTreeDTO> regionTreeDTOList = all();
Set<String> childrenRegionCodeSet = new HashSet<>();
childrenRegionCodeSet.add(code);
RegionTreeDTO currentRegionTree = getCurrentRegionTree(code, level, regionTreeDTOList);
if (Objects.isNull(currentRegionTree)) {
List<String> childrenRegionCodeList = new ArrayList<>();
childrenRegionCodeList.add(code);
return childrenRegionCodeList;
}
getAllChildrenRegionCodeList(currentRegionTree.getChildren(), childrenRegionCodeSet);
return new ArrayList<>(childrenRegionCodeSet);
}

private RegionTreeDTO getCurrentRegionTree(String code, int level, List<RegionTreeDTO> regionTreeDtos) {
for (RegionTreeDTO regionTreeDTO : regionTreeDtos) {
if (level == regionTreeDTO.getLevel() && code.equals(regionTreeDTO.getRegionCode())) {
return regionTreeDTO;
}
if (CollectionUtils.isNotEmpty(regionTreeDTO.getChildren())) {
return getCurrentRegionTree(code, level, regionTreeDTO.getChildren());
}
}
return null;
}

private void getAllChildrenRegionCodeList(List<RegionTreeDTO> regionTreeDtos, Set<String> childrenRegionCodeSet) {
if (CollectionUtils.isEmpty(regionTreeDtos)) {
return;
}
for (RegionTreeDTO regionTreeDTO : regionTreeDtos) {
childrenRegionCodeSet.add(regionTreeDTO.getRegionCode());
getAllChildrenRegionCodeList(regionTreeDTO.getChildren(), childrenRegionCodeSet);

}
}

@Override
public List<String> getRegionCodes(String regionCode, int regionLevel) {
RegionTreeDTO regionTreeNode = getTreeByRegionAndCode(null, regionCode, regionLevel);
Assert.notNull(regionTreeNode, "不存在此级别区域信息:{}", regionLevel);
List<String> regionCodes = new ArrayList<>();
if (regionTreeNode != null) {
regionCodes.addAll(CollUtils.fieldList(treeToList(Collections.singletonList(regionTreeNode)), RegionTreeDTO::getRegionCode));
}
if (!regionCodes.contains(regionCode)) {
regionCodes.add(regionCode);
}
return regionCodes;
}

protected List<RegionTreeDTO> treeToList(List<RegionTreeDTO> treeList) {
ArrayList<RegionTreeDTO> result = new ArrayList<>();
treeList.forEach(w -> {
result.add(w);
if (CollectionUtils.isNotEmpty(w.getChildren())) {
result.addAll(treeToList(w.getChildren()));
}
});
return result;
}


/**
* 获取某一个地区开始的层级树
*
* @param list 地区集合
* @param code 地区编码
* @param level 地区层级
* @return /
*/
protected RegionTreeDTO getTreeByRegionAndCode(List<RegionTreeDTO> list, String code, int level) {
if (CollectionUtils.isEmpty(list)) {
list = super.getCopyListByLevel(3);
if (CollectionUtils.isEmpty(list)) {
return null;
}
}
Optional<RegionTreeDTO> first = list.stream()
.filter(w -> w.getRegionCode().equals(code) && w.getLevel() == level)
.findFirst();
if (first.isPresent()) {
return first.get();
}
for (RegionTreeDTO dto : list) {
if (CollectionUtils.isEmpty(dto.getChildren())) {
continue;
}
RegionTreeDTO temp = getTreeByRegionAndCode(dto.getChildren(), code, level);
if (temp != null) {
return temp;
}
}
return null;
}

@Override
public List<RegionDTO> listParents(String code, int level) {
List<RegionDTO> result = new ArrayList<>();
RegionDTO dto = regionMap.get(RegionMapKey.of(code, level));
result.add(0, dto);
if (dto.getParentCode().equals(super.getParentCodeRoot())) {
return result;
}
result.addAll(0, listParents(dto.getParentCode(), dto.getRegionLevel() - 1));
return result;
}

@Override
public RegionDTO getByCodeAndLevel(String code, int level) {
return regionMap.get(RegionMapKey.of(code, level));
}

@Override
public List<RegionDTO> getProvincialRegion() {
List<RegionDTO> provincialRegionList = new ArrayList<>();
regionMap.values().forEach(v -> {
if (v.getRegionCode().equals(v.getParentCode()) && v.getRegionLevel() == 2) {
provincialRegionList.add(v);
}
});
return provincialRegionList;
}

@Override
public List<RegionDTO> getMunicipalRegion() {
List<RegionDTO> municipalRegionList = new ArrayList<>();
regionMap.values().forEach(v -> {
if (v.getRegionCode().equals(v.getParentCode()) && v.getRegionLevel() == 3) {
municipalRegionList.add(v);
}
});
return municipalRegionList;
}

@Override
public Map<String, RegionDTO> getRegionMap() {
Map<String, RegionDTO> regionDtoMap = new ConcurrentHashMap<>(512);
regionMap.forEach((k, v) -> regionDtoMap.put(k.getRegionCode() + "###" + k.getRegionLevel(), v));
return regionDtoMap;
}

@Override
public Map<String, RegionDTO> getNameRegionMap() {
Map<String, RegionDTO> nameRegionDtoMap = new ConcurrentHashMap<>(512);
regionMap.forEach((k, v) -> nameRegionDtoMap.put(v.getRegionName(), v));
return nameRegionDtoMap;
}

@Override
public String getUnionPathStr(String code, Integer level) {
if (StringUtils.isBlank(code) || Objects.isNull(level)) {
return null;
}
List<String> unionPathStrList = new ArrayList<>();
buildUnionPathStrList(code, level, unionPathStrList);
Collections.reverse(unionPathStrList);
if (CollectionUtils.isEmpty(unionPathStrList)) {
return null;
}
return String.join("@@", unionPathStrList);
}

protected void buildUnionPathStrList(String code, Integer level, List<String> unionPathStrList) {
if (level <= 0 || super.getParentCodeRoot().equals(code)) {
return;
}
RegionDTO regionDTO = regionMap.get(RegionMapKey.of(code, level));
unionPathStrList.add(regionDTO.getRegionCode() + "##" + regionDTO.getRegionName() + "##" + regionDTO.getRegionLevel());
if (!super.getParentCodeRoot().equals(regionDTO.getParentCode())) {
buildUnionPathStrList(regionDTO.getParentCode(), level - 1, unionPathStrList);
}
}
}

+ 6
- 7
pmapi/src/main/java/com/ningdatech/pmapi/meeting/manage/MeetingManage.java View File

@@ -38,6 +38,7 @@ import com.ningdatech.pmapi.meeting.service.*;
import com.ningdatech.pmapi.meeting.task.ExpertInviteTask;
import com.ningdatech.pmapi.meta.helper.DictionaryCache;
import com.ningdatech.pmapi.meta.helper.TagCache;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
@@ -65,7 +66,7 @@ import static com.ningdatech.pmapi.meeting.helper.ExpertInviteHelper.getExpertIn
@RequiredArgsConstructor
public class MeetingManage {

private final RegionCacheHelper regionCacheHelper;
private final RegionCacheHelper regionCache;
private final IMeetingService meetingService;
private final IExpertInviteAvoidRuleService inviteAvoidRuleService;
private final IExpertInviteRuleService inviteRuleService;
@@ -453,14 +454,12 @@ public class MeetingManage {
});
}
if (StrUtil.isNotEmpty(randomRule.getIntentionRegionCode())) {
// TODO 履职意向地
/*List<RegionDTO> intentionRegions = regionCache.listParents(randomRule.getIntentionRegionCode(), randomRule.getIntentionRegionLevel());
randomRule.setIntentionRegions(intentionRegions);*/
List<RegionDTO> intentionRegions = regionCache.listParents(randomRule.getIntentionRegionCode(), randomRule.getIntentionRegionLevel());
randomRule.setIntentionRegions(intentionRegions);
}
if (StrUtil.isNotEmpty(randomRule.getExpertRegionCode())) {
// TODO 专家层级
/*List<RegionDTO> expertRegions = regionCache.listParents(randomRule.getExpertRegionCode(), randomRule.getExpertRegionLevel());
randomRule.setExpertRegions(expertRegions);*/
List<RegionDTO> expertRegions = regionCache.listParents(randomRule.getExpertRegionCode(), randomRule.getExpertRegionLevel());
randomRule.setExpertRegions(expertRegions);
}
result.getRandomRules().add(randomRule);
});


+ 2
- 2
pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/InitProcessTask.java View File

@@ -6,9 +6,9 @@ import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.pmapi.common.constant.RegionConst;
import com.ningdatech.pmapi.common.enumeration.ProjectProcessStageEnum;
import com.ningdatech.pmapi.scheduler.contants.TaskContant;
import com.ningdatech.pmapi.sys.contant.RegionConst;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.service.IRegionService;
import com.wflow.bean.dto.WflowModelHistorysDto;
@@ -53,7 +53,7 @@ public class InitProcessTask {
//1.查出丽水市下的 区县 分别去初始化 表单和流程配置数据
List<Region> regions = regionService.list(Wrappers.lambdaQuery(Region.class)
.eq(Region::getDeleted,Boolean.FALSE)
.eq(Region::getParentCode, RegionConst.LS_REGION_CODE));
.eq(Region::getParentCode, RegionConst.RC_LS));

if(CollUtil.isEmpty(regions)){
throw new BizException("丽水地区数据为空 任务结束!");


+ 0
- 26
pmapi/src/main/java/com/ningdatech/pmapi/sys/contant/RegionConst.java View File

@@ -1,26 +0,0 @@
package com.ningdatech.pmapi.sys.contant;

/**
* <p>
* 地区常量
* </p>
*
* @author WendyYang
* @since 18:54 2023/1/28
*/
public interface RegionConst {

Integer FIRST_LEVEL = 1;

Integer SECOND_LEVEL = 2;

Integer THIRD_LEVEL = 3;

Long EMPTY_PARENT_ID = 0L;

/**
* 丽水地区CODE
*/
String LS_REGION_CODE = "331100";

}

+ 4
- 4
pmapi/src/main/java/com/ningdatech/pmapi/sys/controller/RegionController.java View File

@@ -8,10 +8,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
* <p>
* 前端控制器
@@ -31,8 +30,9 @@ public class RegionController {

@GetMapping("/tree")
@ApiOperation("获取区域编码的树状结构")
public List<RegionTreeVO> getRegionTree() {
return regionManage.getRegionTree();
public RegionTreeVO getRegionTree(@RequestParam(required = false) String regionCode,
@RequestParam(required = false) Integer regionLevel) {
return regionManage.getRegionTree(regionCode, regionLevel);
}

}

+ 19
- 11
pmapi/src/main/java/com/ningdatech/pmapi/sys/convert/RegionConverter.java View File

@@ -1,5 +1,6 @@
package com.ningdatech.pmapi.sys.convert;

import cn.hutool.core.collection.CollUtil;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.dto.RegionTreeDTO;
@@ -32,6 +33,7 @@ public class RegionConverter {
dto.setDeleted(region.getDeleted());
dto.setGovUnit(region.getGovUnit());
dto.setParentId(region.getParentId());
dto.setRegionCodePath(region.getRegionCodePath());
dto.unionCode();
return dto;
}
@@ -56,6 +58,19 @@ public class RegionConverter {
return treeDto;
}

public static RegionTreeVO toRegionTreeVO(RegionDTO region) {
RegionTreeVO node = new RegionTreeVO();
node.setRegionLevel(region.getRegionLevel());
node.setName(region.getRegionName());
node.setParentCode(region.getParentCode());
node.setRegionCode(region.getRegionCode());
node.setUnionCode(region.getUnionCode());
node.setId(region.getId());
node.setUnionCode(region.getUnionCode());
node.setGovUnit(region.getGovUnit());
return node;
}

public static List<RegionTreeVO> toRegionTree(Long parentId, Map<Long, List<RegionDTO>> regions,
boolean showDeleted) {
List<RegionTreeVO> treeList = new ArrayList<>();
@@ -64,19 +79,12 @@ public class RegionConverter {
if (!showDeleted && region.getDeleted()) {
continue;
}
RegionTreeVO treeNode = new RegionTreeVO();
treeNode.setRegionLevel(region.getRegionLevel());
treeNode.setName(region.getRegionName());
treeNode.setParentCode(region.getParentCode());
treeNode.setRegionCode(region.getRegionCode());
RegionTreeVO node = toRegionTreeVO(region);
List<RegionDTO> regionList = regions.get(region.getId());
if (CollectionUtils.isNotEmpty(regionList)) {
treeNode.setChildren(toRegionTree(region.getId(), regions, showDeleted));
if (CollUtil.isNotEmpty(regionList)) {
node.setChildren(toRegionTree(region.getId(), regions, showDeleted));
}
treeNode.setId(region.getId());
treeNode.setUnionCode(region.getUnionCode());
treeNode.setGovUnit(region.getGovUnit());
treeList.add(treeNode);
treeList.add(node);
}
return treeList;
}


+ 4
- 11
pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/RegionManage.java View File

@@ -1,14 +1,10 @@
package com.ningdatech.pmapi.sys.manage;

import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.sys.convert.RegionConverter;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.common.helper.RegionCacheHelper;
import com.ningdatech.pmapi.sys.model.vo.RegionTreeVO;
import com.ningdatech.pmapi.sys.service.IRegionService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;

/**
* <p>
@@ -23,13 +19,10 @@ import java.util.Map;
public class RegionManage {

private final IRegionService regionService;
private final RegionCacheHelper regionCache;

private final static Long ROOT_PARENT_ID = 0L;

public List<RegionTreeVO> getRegionTree() {
List<RegionDTO> regions = regionService.all();
Map<Long, List<RegionDTO>> regionMap = CollUtils.group(regions, RegionDTO::getParentId);
return RegionConverter.toRegionTree(ROOT_PARENT_ID, regionMap, false);
public RegionTreeVO getRegionTree(String regionCode, Integer regionLevel) {
return regionCache.getRegionTree(regionCode, regionLevel);
}

}

+ 2
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/model/dto/RegionDTO.java View File

@@ -49,6 +49,8 @@ public class RegionDTO {

private Long parentId;

private String regionCodePath;

public void unionCode() {
this.unionCode = String.format("%s##%s##%s", this.regionCode, this.regionName, this.regionLevel);
}


+ 2
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/model/entity/Region.java View File

@@ -41,6 +41,8 @@ public class Region implements Serializable {

private LocalDateTime updateOn;

private String regionCodePath;

private Boolean deleted;

}

+ 9
- 0
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/IRegionService.java View File

@@ -24,6 +24,15 @@ public interface IRegionService extends IService<Region> {
List<RegionDTO> all();

/**
* 查询区域
*
* @param regionCode 区域编码
* @param regionLevel 区域层级
* @return {@link Region}
*/
Region getOne(String regionCode, int regionLevel);

/**
* 查询大于等与该级别的所有区域
*
* @param regionLevel


+ 9
- 2
pmapi/src/main/java/com/ningdatech/pmapi/sys/service/impl/RegionServiceImpl.java View File

@@ -4,9 +4,9 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.sys.convert.RegionConverter;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.mapper.RegionMapper;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.service.IRegionService;
import org.springframework.stereotype.Service;

@@ -29,6 +29,13 @@ public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> impleme
}

@Override
public Region getOne(String regionCode, int regionLevel) {
return getOne(Wrappers.lambdaQuery(Region.class)
.eq(Region::getRegionCode, regionCode)
.eq(Region::getRegionLevel, regionLevel));
}

@Override
public List<RegionDTO> listGeLevel(int regionLevel) {
List<Region> regionsByLevel = lambdaQuery().ne(Region::getId, -1)
.le(Region::getRegionLevel, regionLevel).list();


+ 58
- 0
pmapi/src/test/java/com/ningdatech/pmapi/sys/service/IRegionServiceTest.java View File

@@ -0,0 +1,58 @@
package com.ningdatech.pmapi.sys.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.AppTests;
import com.ningdatech.pmapi.common.helper.RegionCacheHelper;
import com.ningdatech.pmapi.sys.model.entity.Region;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
* <p>
* IRegionServiceTest
* </p>
*
* @author WendyYang
* @since 16:57 2023/3/1
*/
public class IRegionServiceTest extends AppTests {

@Autowired
private IRegionService regionService;

@Test
public void init() {
AtomicLong idIncr = new AtomicLong(1);
Map<Integer, List<Region>> map = CollUtils.group(regionService.list(), Region::getRegionLevel);
regionService.remove(null);
map.keySet().stream().sorted().forEach(w -> {
List<Region> list = new ArrayList<>();
List<Region> regions = map.get(w);
for (Region region : regions) {
if (w == 1) {
region.setRegionCodePath(region.getParentCode() + "," + region.getRegionCode());
region.setParentId(0L);
} else {
Region parent = regionService.getOne(Wrappers.lambdaQuery(Region.class)
.eq(Region::getRegionCode, region.getParentCode())
.eq(Region::getRegionLevel, region.getRegionLevel() - 1));
region.setRegionCodePath(parent.getRegionCodePath() + "," + region.getRegionCode());
region.setParentId(parent.getId());
}
region.setId(idIncr.getAndIncrement());
list.add(region);
}
regionService.saveBatch(list);
System.out.println("============================================================================");
});
}


}

Loading…
Cancel
Save