mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-10 06:46:04 +08:00
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:
@@ -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
5895
_config/sql/table.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user