119 lines
3.0 KiB
Markdown
119 lines
3.0 KiB
Markdown
# rdms-spring-boot-starter-biz-ip
|
||
|
||
## 模块定位
|
||
这是一个本地静态工具模块,用于:
|
||
|
||
1. IP -> 地区编码查询
|
||
2. 地区树查询与地区名称格式化
|
||
|
||
不包含远程调用,不包含自动配置,不包含智能识别能力。
|
||
|
||
## 它做什么
|
||
|
||
1. 基于 `ip2region.xdb` 做 IP 归属地编码查询(离线、本地内存查询)
|
||
2. 基于 `area.csv` 提供地区树、地区路径、父级区域定位等工具方法
|
||
|
||
主要入口类:
|
||
|
||
1. `com.njcn.rdms.framework.ip.core.utils.IPUtils`
|
||
2. `com.njcn.rdms.framework.ip.core.utils.AreaUtils`
|
||
|
||
## 它不做什么
|
||
|
||
1. 不访问外部 IP 服务
|
||
2. 不保证行政区数据实时更新(数据随资源文件版本)
|
||
3. 不负责业务策略(如风控、推荐、画像)
|
||
|
||
## 资源与代价
|
||
|
||
1. 内置资源文件:
|
||
2. `src/main/resources/ip2region.xdb`(约 4MB)
|
||
3. `src/main/resources/area.csv`
|
||
4. 类加载时会预加载资源到内存,换取查询速度
|
||
|
||
## 前端地区树返回(重点)
|
||
|
||
本模块非常适合做省市区级联选择器的后端数据源。
|
||
|
||
典型接口:
|
||
|
||
1. 管理端:`GET /system/area/tree`
|
||
2. App 端:`GET /system/area/tree`
|
||
|
||
节点字段:
|
||
|
||
1. `id`:区域编码
|
||
2. `name`:区域名称
|
||
3. `children`:子节点列表
|
||
|
||
## 后端示例(获取“江苏区域树”)
|
||
|
||
### 1. 获取江苏节点
|
||
|
||
```java
|
||
import com.njcn.rdms.framework.ip.core.Area;
|
||
import com.njcn.rdms.framework.ip.core.utils.AreaUtils;
|
||
|
||
Area jiangsu = AreaUtils.parseArea("中国/江苏省");
|
||
if (jiangsu == null) {
|
||
return;
|
||
}
|
||
```
|
||
|
||
### 2. 直接返回江苏及其下级区域树
|
||
|
||
`Area` 本身就是树节点(包含 `children`),拿到江苏节点后即可把它作为一棵子树返回。
|
||
|
||
```java
|
||
import com.njcn.rdms.framework.ip.core.Area;
|
||
import com.njcn.rdms.framework.ip.core.utils.AreaUtils;
|
||
|
||
Area jiangsu = AreaUtils.parseArea("中国/江苏省");
|
||
return jiangsu; // children 中包含南京、苏州等下级节点
|
||
```
|
||
|
||
### 3. 转成前端常用结构(id/name/children)
|
||
|
||
```java
|
||
import com.njcn.rdms.framework.ip.core.Area;
|
||
import com.njcn.rdms.framework.ip.core.utils.AreaUtils;
|
||
import java.util.Collections;
|
||
import java.util.List;
|
||
import java.util.stream.Collectors;
|
||
|
||
record AreaNode(Integer id, String name, List<AreaNode> children) {}
|
||
|
||
private static AreaNode toNode(Area a) {
|
||
List<AreaNode> children = a.getChildren() == null
|
||
? Collections.emptyList()
|
||
: a.getChildren().stream().map(child -> toNode(child)).collect(Collectors.toList());
|
||
return new AreaNode(a.getId(), a.getName(), children);
|
||
}
|
||
|
||
Area jiangsu = AreaUtils.parseArea("中国/江苏省");
|
||
AreaNode jiangsuTree = jiangsu == null ? null : toNode(jiangsu);
|
||
```
|
||
|
||
返回示例:
|
||
|
||
```json
|
||
{
|
||
"id": 320000,
|
||
"name": "江苏省",
|
||
"children": [
|
||
{ "id": 320100, "name": "南京市", "children": [] },
|
||
{ "id": 320500, "name": "苏州市", "children": [] }
|
||
]
|
||
}
|
||
```
|
||
|
||
## 适用场景
|
||
|
||
1. 后端需要快速把 IP 转成地区信息
|
||
2. 需要返回地区树给前端做省市区联动
|
||
|
||
## 不需要它的场景
|
||
|
||
1. 项目没有 IP 归属地需求
|
||
2. 项目不需要地区树能力
|