feat(demo): 新增 IP 归属地查询 demo + 菜单权限, 调整 ip2region 文件路径

daxpay-demo 新增 ipregion 模块(Controller/Result), iam_perm_menu 新增 demos:ip-region 菜单,
application-dev.yml ip2region 文件路径从 D盘调整到 E盘。
This commit is contained in:
DaxPay Dev
2026-07-27 23:29:56 +08:00
parent eff2875e23
commit 116e81417f
6 changed files with 6020 additions and 1 deletions

View File

@@ -131,6 +131,7 @@ INSERT INTO "public"."iam_perm_menu" VALUES (901, 4, 'device:qrcode', 'admin', '
INSERT INTO "public"."iam_perm_menu" VALUES (8, NULL, 'develop', 'admin', 'Develop', 'menu.develop', 'lucide:wrench', 'f', 'f', NULL, '/develop', NULL, 5, 'f', 't', 'f', 1, 1, 0, 'f', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-23 16:00:00+00', '2026-06-23 16:00:00+00');
INSERT INTO "public"."iam_perm_menu" VALUES (9, NULL, 'device', 'admin', 'DeviceManagement', 'menu.device', 'lucide:qr-code', 'f', 'f', NULL, '/device', NULL, 4.2, 'f', 't', 'f', 1, 1, 1, 't', 'catalog', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-25 01:21:34.631155+00', '2026-07-21 06:30:00+00');
INSERT INTO "public"."iam_perm_menu" VALUES (204, 2, 'demos:artemis', 'admin', 'ArtemisDemo', 'menu.demos.artemis', 'lucide:send', 'f', 'f', '/demos/artemis/ArtemisDemo', '/demos/artemis', NULL, 4, 'f', 't', 'f', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-18 00:00:00+00', '2026-06-18 00:00:00+00');
INSERT INTO "public"."iam_perm_menu" VALUES (205, 2, 'demos:ip-region', 'admin', 'IpRegionDemo', 'menu.demos.ipRegion', 'lucide:locate-fixed', 'f', 'f', '/demos/ip-region/IpRegionDemo', '/demos/ip-region', NULL, 5, 'f', 't', 'f', 0, NULL, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-07-27 16:00:00+00', '2026-07-27 16:00:00+00');
INSERT INTO "public"."iam_perm_menu" VALUES (900001, 304, 'iam:social', 'admin', 'ThirdPlatform', 'menu.system.config.thirdPlatform', 'lucide:share-2', 'f', 'f', '/system/config/third-platform/ThirdPlatform', '/system/config/third-platform', NULL, 5, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2026-07-13 02:15:41.505142+00');
INSERT INTO "public"."iam_perm_menu" VALUES (4040103, 4040130, 'merchant:profile', 'admin', 'MchInfoManage', 'menu.payment.merchant.profile', NULL, 't', 'f', '/payment/merchant/manage/info/MchInfoManage', '/payment/merchant/manage/info', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'subpage', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2026-07-11 03:37:15.424776+00');
INSERT INTO "public"."iam_perm_menu" VALUES (801, 8, 'develop:trade', 'admin', 'DevelopTrade', 'menu.develop.trade', 'lucide:credit-card', 'f', 'f', '/payment/develop/trade/DevelopTrade', '/develop/trade', NULL, 1, 'f', 't', 'f', 1, 1, 0, 'f', 'menu', NULL, NULL, NULL, NULL, NULL, NULL, '2026-06-23 16:00:00+00', '2026-06-23 16:00:00+00');

5895
_config/sql/table.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -35,6 +35,13 @@
<artifactId>common-artemis</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 审计日志模块(提供 IpToRegionService用于 IP 归属地查询演示) -->
<dependency>
<groupId>cn.daxpay.open</groupId>
<artifactId>capability-audit-log</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,76 @@
package cn.daxpay.open.demo.ipregion.controller;
import cn.daxpay.open.demo.ipregion.result.IpRegionDemoResult;
import cn.daxpay.open.platform.capability.audit.log.service.ip2region.IpRegion;
import cn.daxpay.open.platform.capability.audit.log.service.ip2region.IpToRegionService;
import cn.daxpay.open.platform.core.annotation.IgnoreAuth;
import cn.daxpay.open.platform.core.rest.Res;
import cn.daxpay.open.platform.core.rest.result.Result;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
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.Objects;
/// # IP归属地查询演示接口
///
/// 基于 ip2region 离线库(与审计日志 location 字段同源),演示 IP 归属地查询能力。
///
/// 鉴权URL 前缀 `/demo/**` 已在白名单,类上叠加 `@IgnoreAuth` 双保险。
@IgnoreAuth
@Tag(name = "IP归属地查询演示")
@RestController
@RequestMapping("/demo/ip-region")
@RequiredArgsConstructor
public class IpRegionDemoController {
private final IpToRegionService ipToRegionService;
/// 查询指定 IP 的归属地
@Operation(summary = "根据 IP 查询归属地")
@GetMapping("/query")
public Result<IpRegionDemoResult> query(
@Parameter(description = "IPv4 地址") @RequestParam("ip") String ip) {
return Res.ok(buildResult(ip));
}
/// 自动获取当前请求者的 IP 并查询归属地
@Operation(summary = "查询当前请求者 IP 归属地")
@GetMapping("/current")
public Result<IpRegionDemoResult> current(HttpServletRequest request) {
// getClientIP 会自动解析 X-Forwarded-For 等代理头
String ip = JakartaServletUtil.getClientIP(request);
return Res.ok(buildResult(ip));
}
/// 组装查询结果:先取格式化文本,再补结构化字段
private IpRegionDemoResult buildResult(String ip) {
IpRegionDemoResult result = new IpRegionDemoResult().setIp(ip);
if (StrUtil.isBlank(ip)) {
// 未拿到 IP如本地无网络栈统一回“未知”
return result.setRegionStr("未知");
}
// 格式化文本(与审计日志写入逻辑同源)
result.setRegionStr(ipToRegionService.getRegionStrByIp(ip));
// 结构化字段(查询失败时 region 为 null结构化字段保持空
IpRegion region = ipToRegionService.getRegionByIp(ip);
if (Objects.nonNull(region)) {
result.setCountry(region.getCountry())
.setRegion(region.getRegion())
.setProvince(region.getProvince())
.setCity(region.getCity())
.setIsp(region.getIsp())
.setInnerIp(region.isInnerIp())
.setChinaIp(region.isChinaIp());
}
return result;
}
}

View File

@@ -0,0 +1,40 @@
package cn.daxpay.open.demo.ipregion.result;
import lombok.Data;
import lombok.experimental.Accessors;
/// # IP归属地查询演示结果
///
/// 与审计日志(`operateLocation` / `loginLocation`)写入逻辑同源,
/// 同时返回结构化字段与格式化文本,方便前端直观展示。
@Data
@Accessors(chain = true)
public class IpRegionDemoResult {
/// 查询的 IP 地址
private String ip;
/// 国家
private String country;
/// 区域
private String region;
/// 省份
private String province;
/// 城市
private String city;
/// ISP 运营商
private String isp;
/// 格式化后的归属地文本(与审计日志 location 字段同源)
private String regionStr;
/// 是否内网地址
private boolean innerIp;
/// 是否国内地址
private boolean chinaIp;
}

View File

@@ -105,7 +105,7 @@ daxpay:
audit-log:
ip2region:
# ip2region.xdb 文件路径
file-path: D:/data/ip/ip2region_v4.xdb
file-path: E:/data/ip2region/ip2region_v4.xdb
# 查询模式: VECTOR_INDEX(推荐) 或 CACHE
search-type: VECTOR_INDEX
config: