package domain import ( "fmt" "net" "strings" "github.com/oschwald/maxminddb-golang" ) // GeoIP2Domain 抽象了 GeoIP2 国家数据库的领域逻辑。 type GeoIP2Domain struct { db *maxminddb.Reader } type countryRecord struct { Country struct { ISOCode string `maxminddb:"iso_code"` } `maxminddb:"country"` } // NewGeoIP2Domain 创建一个新的 GeoIP2 国家数据库领域对象。需要 maxminddb 文件的路径。 func NewGeoIP2Domain(path string) (*GeoIP2Domain, error) { db, err := maxminddb.Open(path) if err != nil { return nil, fmt.Errorf("无法打开 geoip2 国家数据库 %s: %w", path, err) } return &GeoIP2Domain{db}, nil } // GetCountryCodeForIP 返回给定 IP 的两字母国家代码(ISO 3166-1)。 func (d *GeoIP2Domain) GetCountryCodeForIP(ip net.IP) (string, error) { record := &countryRecord{} err := d.db.Lookup(ip, record) if err != nil { return "", fmt.Errorf("无法查找 IP %s 的国家: %w", ip, err) } return strings.ToLower(record.Country.ISOCode), nil } // Close 需要被调用以正确关闭内部的 maxminddb 数据库。 func (d *GeoIP2Domain) Close() { d.db.Close() }