// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn . package iplibrary import ( "github.com/iwind/TeaGo/lists" "strings" ) type QueryResult struct { item any meta *Meta } func (this *QueryResult) IsOk() bool { return this.item != nil } func (this *QueryResult) CountryId() int64 { return int64(this.realCountryId()) } func (this *QueryResult) CountryName() string { if this.item == nil { return "" } // MaxMind 结果:直接使用名称 if maxItem, ok := this.item.(*maxMindItem); ok { // 优先使用中文名称 if len(maxItem.Record.Country.Names["zh-CN"]) > 0 { return maxItem.Record.Country.Names["zh-CN"] } // 其次使用英文名称 if len(maxItem.Record.Country.Names["en"]) > 0 { return maxItem.Record.Country.Names["en"] } // 使用任何可用的名称 for _, name := range maxItem.Record.Country.Names { if len(name) > 0 { return name } } return "" } // 原有逻辑 var countryId = this.realCountryId() if countryId > 0 { var country = this.meta.CountryWithId(countryId) if country != nil { return country.Name } } return "" } func (this *QueryResult) CountryCodes() []string { if this.item == nil { return nil } // MaxMind 结果:使用 Country.IsoCode(ISO 3166-1 alpha-2),供智能 DNS 线路解析等使用 if maxItem, ok := this.item.(*maxMindItem); ok { if len(maxItem.Record.Country.IsoCode) > 0 { return []string{maxItem.Record.Country.IsoCode} } return nil } var countryId = this.realCountryId() if countryId > 0 { var country = this.meta.CountryWithId(countryId) if country != nil { return country.Codes } } return nil } func (this *QueryResult) ProvinceId() int64 { return int64(this.realProvinceId()) } func (this *QueryResult) ProvinceName() string { if this.item == nil { return "" } // MaxMind 结果:使用 Subdivisions(省份/州) if maxItem, ok := this.item.(*maxMindItem); ok { if len(maxItem.Record.Subdivisions) > 0 { subdivision := maxItem.Record.Subdivisions[0] // 优先使用中文名称 if len(subdivision.Names["zh-CN"]) > 0 { return subdivision.Names["zh-CN"] } // 其次使用英文名称 if len(subdivision.Names["en"]) > 0 { return subdivision.Names["en"] } // 使用任何可用的名称 for _, name := range subdivision.Names { if len(name) > 0 { return name } } } return "" } // 原有逻辑 var provinceId = this.realProvinceId() if provinceId > 0 { var province = this.meta.ProvinceWithId(provinceId) if province != nil { return province.Name } } return "" } func (this *QueryResult) ProvinceCodes() []string { if this.item == nil { return nil } var provinceId = this.realProvinceId() if provinceId > 0 { var province = this.meta.ProvinceWithId(provinceId) if province != nil { return province.Codes } } return nil } func (this *QueryResult) CityId() int64 { return int64(this.realCityId()) } func (this *QueryResult) CityName() string { if this.item == nil { return "" } // MaxMind 结果:直接使用名称 if maxItem, ok := this.item.(*maxMindItem); ok { // 优先使用中文名称 if len(maxItem.Record.City.Names["zh-CN"]) > 0 { return maxItem.Record.City.Names["zh-CN"] } // 其次使用英文名称 if len(maxItem.Record.City.Names["en"]) > 0 { return maxItem.Record.City.Names["en"] } // 使用任何可用的名称 for _, name := range maxItem.Record.City.Names { if len(name) > 0 { return name } } return "" } // 原有逻辑 var cityId = this.realCityId() if cityId > 0 { var city = this.meta.CityWithId(cityId) if city != nil { return city.Name } } return "" } func (this *QueryResult) TownId() int64 { return int64(this.realTownId()) } func (this *QueryResult) TownName() string { if this.item == nil { return "" } var townId = this.realTownId() if townId > 0 { var town = this.meta.TownWithId(townId) if town != nil { return town.Name } } return "" } func (this *QueryResult) ProviderId() int64 { return int64(this.realProviderId()) } func (this *QueryResult) ProviderName() string { if this.item == nil { return "" } // MaxMind 结果:使用 ASN 组织作为 ISP if maxItem, ok := this.item.(*maxMindItem); ok { if len(maxItem.ASNOrg) > 0 { return maxItem.ASNOrg } return "" } // 原有逻辑 var providerId = this.realProviderId() if providerId > 0 { var provider = this.meta.ProviderWithId(providerId) if provider != nil { return provider.Name } } return "" } func (this *QueryResult) ProviderCodes() []string { if this.item == nil { return nil } var providerId = this.realProviderId() if providerId > 0 { var provider = this.meta.ProviderWithId(providerId) if provider != nil { return provider.Codes } } return nil } func (this *QueryResult) Summary() string { if this.item == nil { return "" } var pieces = []string{} var countryName = this.CountryName() var provinceName = this.ProvinceName() var cityName = this.CityName() var townName = this.TownName() var providerName = this.ProviderName() if len(countryName) > 0 { pieces = append(pieces, countryName) } if len(provinceName) > 0 && !lists.ContainsString(pieces, provinceName) { pieces = append(pieces, provinceName) } if len(cityName) > 0 && !lists.ContainsString(pieces, cityName) && !lists.ContainsString(pieces, strings.TrimSuffix(cityName, "市")) { pieces = append(pieces, cityName) } if len(townName) > 0 && !lists.ContainsString(pieces, townName) && !lists.ContainsString(pieces, strings.TrimSuffix(townName, "县")) { pieces = append(pieces, townName) } if len(providerName) > 0 && !lists.ContainsString(pieces, providerName) { if len(pieces) > 0 { pieces = append(pieces, "|") } pieces = append(pieces, providerName) } return strings.Join(pieces, " ") } func (this *QueryResult) RegionSummary() string { if this.item == nil { return "" } var pieces = []string{} var countryName = this.CountryName() var provinceName = this.ProvinceName() var cityName = this.CityName() var townName = this.TownName() if len(countryName) > 0 { pieces = append(pieces, countryName) } if len(provinceName) > 0 && !lists.ContainsString(pieces, provinceName) { pieces = append(pieces, provinceName) } if len(cityName) > 0 && !lists.ContainsString(pieces, cityName) && !lists.ContainsString(pieces, strings.TrimSuffix(cityName, "市")) { pieces = append(pieces, cityName) } if len(townName) > 0 && !lists.ContainsString(pieces, townName) && !lists.ContainsString(pieces, strings.TrimSuffix(townName, "县")) { pieces = append(pieces, townName) } return strings.Join(pieces, " ") } func (this *QueryResult) realCountryId() uint16 { if this.item != nil { switch item := this.item.(type) { case *ipv4ItemV1: return item.Region.CountryId case ipv4ItemV1: return item.Region.CountryId case *ipv6ItemV1: return item.Region.CountryId case ipv6ItemV1: return item.Region.CountryId case *ipv4ItemV2: return item.Region.CountryId case ipv4ItemV2: return item.Region.CountryId case *ipv6ItemV2: return item.Region.CountryId case ipv6ItemV2: return item.Region.CountryId case *maxMindItem: // MaxMind 不使用 ID,返回 0 return 0 } } return 0 } func (this *QueryResult) realProvinceId() uint16 { if this.item != nil { switch item := this.item.(type) { case *ipv4ItemV1: return item.Region.ProvinceId case ipv4ItemV1: return item.Region.ProvinceId case *ipv6ItemV1: return item.Region.ProvinceId case ipv6ItemV1: return item.Region.ProvinceId case *ipv4ItemV2: return item.Region.ProvinceId case ipv4ItemV2: return item.Region.ProvinceId case *ipv6ItemV2: return item.Region.ProvinceId case ipv6ItemV2: return item.Region.ProvinceId case *maxMindItem: // MaxMind 不使用 ID,返回 0 return 0 } } return 0 } func (this *QueryResult) realCityId() uint32 { if this.item != nil { switch item := this.item.(type) { case *ipv4ItemV1: return item.Region.CityId case ipv4ItemV1: return item.Region.CityId case *ipv6ItemV1: return item.Region.CityId case ipv6ItemV1: return item.Region.CityId case *ipv4ItemV2: return item.Region.CityId case ipv4ItemV2: return item.Region.CityId case *ipv6ItemV2: return item.Region.CityId case ipv6ItemV2: return item.Region.CityId case *maxMindItem: // MaxMind 不使用 ID,返回 0 return 0 } } return 0 } func (this *QueryResult) realTownId() uint32 { if this.item != nil { switch item := this.item.(type) { case *ipv4ItemV1: return item.Region.TownId case ipv4ItemV1: return item.Region.TownId case *ipv6ItemV1: return item.Region.TownId case ipv6ItemV1: return item.Region.TownId case *ipv4ItemV2: return item.Region.TownId case ipv4ItemV2: return item.Region.TownId case *ipv6ItemV2: return item.Region.TownId case ipv6ItemV2: return item.Region.TownId case *maxMindItem: // MaxMind 不使用 ID,返回 0 return 0 } } return 0 } func (this *QueryResult) realProviderId() uint16 { if this.item != nil { switch item := this.item.(type) { case *ipv4ItemV1: return item.Region.ProviderId case ipv4ItemV1: return item.Region.ProviderId case *ipv6ItemV1: return item.Region.ProviderId case ipv6ItemV1: return item.Region.ProviderId case *ipv4ItemV2: return item.Region.ProviderId case ipv4ItemV2: return item.Region.ProviderId case *ipv6ItemV2: return item.Region.ProviderId case ipv6ItemV2: return item.Region.ProviderId case *maxMindItem: // MaxMind 不使用 ID,返回 0 return 0 } } return 0 }