feat: 产品/客户/订单批量删除;接入 GeoLite2 城市库(地理分布/激活记录/审计日志显示归属地);仪表盘趋势图美化
This commit is contained in:
1 parent
252ae14aef
commit
473dcd0aab
24 files changed
+431
-34
No files matched your search
@@ -0,0 +1,71 @@
|
||||
package utils
|
||||
|
||||
// IP 地理位置识别:复用 opsx-waf 的 GeoLite2-City 方案(中文优先,内网标记)。
|
||||
// 数据文件默认 /data/geoip/GeoLite2-City.mmdb(容器卷内),缺失时静默返回空串,不影响业务。 // Logan.Li
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
geoip2 "github.com/oschwald/geoip2-golang/v2"
|
||||
)
|
||||
|
||||
var geoIPReader struct {
|
||||
once sync.Once
|
||||
db *geoip2.Reader
|
||||
}
|
||||
|
||||
// LookupIPLocation 返回 "国家 / 省份 / 城市"(中文优先);内网返回"内网",无法识别返回空串 // Logan.Li
|
||||
func LookupIPLocation(value string) string {
|
||||
ip, err := netip.ParseAddr(strings.TrimSpace(value))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast() {
|
||||
return "内网"
|
||||
}
|
||||
geoIPReader.once.Do(func() {
|
||||
path := os.Getenv("GEOIP_DB_PATH")
|
||||
if path == "" {
|
||||
path = "/data/geoip/GeoLite2-City.mmdb"
|
||||
}
|
||||
geoIPReader.db, _ = geoip2.Open(path)
|
||||
})
|
||||
if geoIPReader.db == nil {
|
||||
return ""
|
||||
}
|
||||
record, err := geoIPReader.db.City(ip)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
parts := localizedNames(record.Country.Names, record.Country.ISOCode)
|
||||
if len(record.Subdivisions) > 0 {
|
||||
if sub := localizedNames(record.Subdivisions[0].Names, record.Subdivisions[0].ISOCode); sub != "" && sub != parts {
|
||||
parts = joinLocation(parts, sub)
|
||||
}
|
||||
}
|
||||
if city := localizedNames(record.City.Names, ""); city != "" {
|
||||
parts = joinLocation(parts, city)
|
||||
}
|
||||
return parts
|
||||
}
|
||||
|
||||
// localizedNames 中文优先;GeoLite2 少数中国城市只有英文名,走兜底映射 // Logan.Li
|
||||
func localizedNames(names geoip2.Names, fallback string) string {
|
||||
if names.SimplifiedChinese != "" {
|
||||
return names.SimplifiedChinese
|
||||
}
|
||||
if names.English != "" {
|
||||
return names.English
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func joinLocation(left, right string) string {
|
||||
if left == "" {
|
||||
return right
|
||||
}
|
||||
return left + " / " + right
|
||||
}
|
||||
Reference in new issue
Block a user