Commit 33f8c86c authored by tianbo's avatar tianbo

feat(jg): 优化区域代码生成逻辑并增强缓存机制

- 引入 RedisUtils 和 RegionModel 支持远程数据获取与缓存 - 新增 selectCompanyRegionSeq 方法用于查询行政区划序列号 - 实现基于 Redis 的 regionSeq 到 regionCode 映射缓存 - 添加从远程接口加载区域树并转换为映射表的功能 - 使用 ConcurrentHashMap 提升并发访问性能 - 扩展监管机构类型判断以支持“行政审批局”类型 - 修复平台用户消息监听器中公司类型的过滤条件 - 调整企业信息服务中对监管机构的排除逻辑以兼容新类型
parent 4548986c
......@@ -108,6 +108,14 @@ public interface CommonMapper extends BaseMapper<EquipmentCategory> {
/**
* 按照 地市或者区县查询对应行政区划seq
*
* @param receiveCompanyCode 地市或者区县companyCode
* @return 地市对应行政区划seq
*/
String selectCompanyRegionSeq(@Param("receiveCompanyCode") String receiveCompanyCode);
/**
* 告知业务统计
*
* @param reportAnalysisSearchDTO 条件
......
......@@ -3553,4 +3553,13 @@
AND oi."CLAIM_STATUS" not in ('草稿','已拒领','待认领')
AND tt."NEXT_INSPECT_DATE" is not null
</select>
<select id="selectCompanyRegionSeq" resultType="java.lang.String">
select
region_seq
from
privilege_company
where
company_code = #{receiveCompanyCode}
</select>
</mapper>
package com.yeejoin.amos.boot.module.jg.biz.utils;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jg.api.dto.CodeGenerateDto;
import com.yeejoin.amos.boot.module.jg.api.mapper.CommonMapper;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import java.util.Arrays;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Administrator
*/
@Component
@Slf4j
public class CodeUtil {
......@@ -25,10 +32,16 @@ public class CodeUtil {
*/
private static String[] EXCLUSION_CITY_REGIONS = {"610403", "610581"};
private final RedisUtils redisUtils;
public CodeUtil(RedissonClient redissonClient, CommonMapper commonMapper) {
private final Map<String, String> REGIONSEQ_CODE_MAP = new ConcurrentHashMap<>();
private static final String REGION_SEQ_MAP_KEY = "region:seq_map";
public CodeUtil(RedissonClient redissonClient, CommonMapper commonMapper, RedisUtils redisUtils) {
this.redissonClient = redissonClient;
this.commonMapper = commonMapper;
this.redisUtils = redisUtils;
}
......@@ -88,7 +101,103 @@ public class CodeUtil {
if (Arrays.asList(EXCLUSION_CITY_REGIONS).contains(receiveCompanyCode)) {
return receiveCompanyCode;
} else {
return commonMapper.selectCityCompanyCode(receiveCompanyCode, EXCLUSION_CITY_REGIONS);
if (!ValidationUtil.isEmpty(receiveCompanyCode)) {
String regionSeq = commonMapper.selectCompanyRegionSeq(receiveCompanyCode);
return commonMapper.selectCityCompanyCode(this.getRegionCodeByRegionSeq(regionSeq), EXCLUSION_CITY_REGIONS);
}
return null;
}
}
public String getRegionCodeByRegionSeq(String regionSeq) {
return REGIONSEQ_CODE_MAP.computeIfAbsent(regionSeq, (k) -> getRegionCodeFromRedisOrRemote(regionSeq));
}
/**
* 从 Redis 或远程接口获取 regionCode
*/
private String getRegionCodeFromRedisOrRemote(String regionSeq) {
// 1. 先从 Redis 获取整个 seqToCodeMap
Map<String, RegionModel> seqToCodeMap = getRegionSeqToCodeMapFromRedis();
// 2. 如果在 Redis Map 中找到,直接返回
RegionModel regionModel = seqToCodeMap.get(regionSeq);
if (!ValidationUtil.isEmpty(regionModel)) {
return regionModel.getRegionCode().toString();
}
// 3. Redis 中没有,调用远程接口获取最新数据
return getRegionCodeFromRemoteAndRefreshCache(regionSeq);
}
/**
* 从 Redis 获取 seqToCodeMap
*/
@SuppressWarnings("unchecked")
private Map<String, RegionModel> getRegionSeqToCodeMapFromRedis() {
try {
Object cachedMap = redisUtils.get(REGION_SEQ_MAP_KEY);
if (cachedMap instanceof Map) {
return (Map<String, RegionModel>) cachedMap;
}
} catch (Exception e) {
log.warn("从 Redis 获取 seqToCodeMap 失败,将重新加载", e);
}
return new HashMap<>();
}
/**
* 调用远程接口获取数据,并刷新 Redis 缓存
*/
private String getRegionCodeFromRemoteAndRefreshCache(String regionSeq) {
// 1. 调用远程接口获取完整的树结构数据
Collection<RegionModel> regionTree = Systemctl.regionClient.queryForTreeByAgencyCodeRightLike(null).getResult();
// 2. 将树结构转换为 seqToCodeMap
Map<String, RegionModel> seqToCodeMap = convertRegionTreeToMap(regionTree);
// 3. 将转换后的 Map 写入 Redis
try {
redisUtils.set(REGION_SEQ_MAP_KEY, seqToCodeMap);
log.info("已更新 Redis 中的 region seqToCodeMap,包含 {} 条记录", seqToCodeMap.size());
} catch (Exception e) {
log.error("更新 Redis seqToCodeMap 失败", e);
}
// 4. 从新生成的 Map 中查找需要的值
return Optional.ofNullable(seqToCodeMap.get(regionSeq)).map(RegionModel::getRegionCode).map(String::valueOf).orElse(null);
}
/**
* 将 RegionModel 树结构转换为 Map<sequenceNbr, regionCode>
*/
private Map<String, RegionModel> convertRegionTreeToMap(Collection<RegionModel> regionTree) {
Map<String, RegionModel> seqToCodeMap = new HashMap<>();
for (RegionModel region : regionTree) {
traverseAndAddToMap(region, seqToCodeMap);
}
return seqToCodeMap;
}
/**
* 递归遍历 RegionModel 树,将每个节点的 sequenceNbr 和 regionCode 存入 Map
*/
private void traverseAndAddToMap(RegionModel region, Map<String, RegionModel> seqToCodeMap) {
if (region == null) {
return;
}
// 将当前节点存入 Map
if (region.getSequenceNbr() != null && region.getRegionCode() != null) {
seqToCodeMap.put(String.valueOf(region.getSequenceNbr()), region);
}
// 递归处理子节点
Collection<RegionModel> children = region.getChildren();
if (children != null && !children.isEmpty()) {
for (RegionModel child : children) {
traverseAndAddToMap(child, seqToCodeMap);
}
}
}
......
......@@ -117,7 +117,7 @@ public class PlatformUserTopicMessage extends EmqxListener {
}
if (!ValidationUtil.isEmpty(dataResult) && StringUtils.isNotEmpty(path)) {
if (path.contains("company")) {
if ("监管机构".equals(dataResult.get("companyType"))) {
if ("监管机构".equals(dataResult.get("companyType")) || "行政审批局".equals(dataResult.get("companyType"))) {
equipmentCategoryService.deleteAllRegulatorUnitTree();
}
tzBaseEnterpriseInfoService.refreshCompanyInfo(dataResult, method);
......
......@@ -1484,10 +1484,10 @@ public class TzBaseEnterpriseInfoServiceImpl
log.error("平台获取子单位失败");
return;
}
List<CompanyModel> companyModels = result.getResult().stream().filter(i -> !i.getCompanyType().equals("监管机构")).collect(Collectors.toList());
List<CompanyModel> companyModels = result.getResult().stream().filter(i -> !i.getCompanyType().equals("监管机构") && !i.getCompanyType().equals("行政审批局")).collect(Collectors.toList());
// 如果消息中的单位是企业
if (!companyBo.getCompanyType().equals("监管机构")) {
if (!companyBo.getCompanyType().equals("监管机构") && !companyBo.getCompanyType().equals("行政审批局")) {
switch (Objects.requireNonNull(PlatformOpMethodTypeEnum.getEnumByCode(method))) {
case CREATE:
case INSERT:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment