Files
nl-im-service/internal/utils/ip_location.go

103 lines
2.3 KiB
Go
Raw Normal View History

2025-12-03 11:00:47 +08:00
/**
* package utils
2026-07-08 08:18:58 +08:00
* 作用IP 归属地查询基于本地 ip2region.xdb 离线库
2025-12-03 11:00:47 +08:00
*/
package utils
import (
2026-07-08 08:18:58 +08:00
"log"
2025-12-03 11:00:47 +08:00
"strings"
2026-07-08 08:18:58 +08:00
"sync"
2025-12-03 11:00:47 +08:00
2026-07-08 08:18:58 +08:00
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
)
2025-12-03 11:00:47 +08:00
var (
2026-07-08 08:18:58 +08:00
ipSearcher *xdb.Searcher
ipSearcherOnce sync.Once
ipSearcherErr error
ipCache sync.Map
2025-12-03 11:00:47 +08:00
)
2026-07-08 08:18:58 +08:00
/**
* InitIP2Region
* 功能加载 ip2region.xdb服务启动时调用一次
*/
func InitIP2Region(dbPath string) error {
ipSearcherOnce.Do(func() {
ipSearcher, ipSearcherErr = xdb.NewWithFileOnly(xdb.IPv4, dbPath)
if ipSearcherErr != nil {
log.Printf("❌ [IP2Region] 加载失败: %v", ipSearcherErr)
return
}
log.Printf("✅ [IP2Region] 已加载: %s", dbPath)
})
return ipSearcherErr
}
2025-12-03 11:00:47 +08:00
/**
* GetIPLocation
2026-07-08 08:18:58 +08:00
* 功能查询 IP 归属地内网/本地返回本地
2025-12-03 11:00:47 +08:00
*/
func GetIPLocation(ip string) string {
if isLocalIP(ip) {
return "本地"
}
2026-07-08 08:18:58 +08:00
if ip == "" {
return "未知"
2025-12-03 11:00:47 +08:00
}
2026-07-08 08:18:58 +08:00
if cached, ok := ipCache.Load(ip); ok {
return cached.(string)
}
2025-12-03 11:00:47 +08:00
2026-07-08 08:18:58 +08:00
if ipSearcher == nil {
return "未知"
}
2025-12-03 11:00:47 +08:00
2026-07-08 08:18:58 +08:00
region, err := ipSearcher.Search(ip)
if err != nil || region == "" {
return "未知"
2025-12-03 11:00:47 +08:00
}
2026-07-08 08:18:58 +08:00
// 格式: 国家|区域|省份|城市|ISP
parts := strings.Split(region, "|")
labels := []string{}
for _, p := range parts {
p = strings.TrimSpace(p)
if p != "" && p != "0" {
labels = append(labels, p)
}
}
result := "未知"
if len(labels) > 0 {
result = strings.Join(labels, " ")
}
ipCache.Store(ip, result)
return result
2025-12-03 11:00:47 +08:00
}
/**
* isLocalIP
2026-07-08 08:18:58 +08:00
* 功能判断是否为本地/内网 IP
2025-12-03 11:00:47 +08:00
*/
func isLocalIP(ip string) bool {
if ip == "127.0.0.1" || ip == "localhost" || ip == "::1" {
return true
}
2026-07-08 08:18:58 +08:00
if strings.HasPrefix(ip, "192.168.") || strings.HasPrefix(ip, "10.") {
2025-12-03 11:00:47 +08:00
return true
}
2026-07-08 08:18:58 +08:00
if strings.HasPrefix(ip, "172.16.") || strings.HasPrefix(ip, "172.17.") ||
strings.HasPrefix(ip, "172.18.") || strings.HasPrefix(ip, "172.19.") ||
strings.HasPrefix(ip, "172.20.") || strings.HasPrefix(ip, "172.21.") ||
strings.HasPrefix(ip, "172.22.") || strings.HasPrefix(ip, "172.23.") ||
strings.HasPrefix(ip, "172.24.") || strings.HasPrefix(ip, "172.25.") ||
strings.HasPrefix(ip, "172.26.") || strings.HasPrefix(ip, "172.27.") ||
strings.HasPrefix(ip, "172.28.") || strings.HasPrefix(ip, "172.29.") ||
strings.HasPrefix(ip, "172.30.") || strings.HasPrefix(ip, "172.31.") {
return true
2025-12-03 11:00:47 +08:00
}
2026-07-08 08:18:58 +08:00
return false
2025-12-03 11:00:47 +08:00
}