33 changed files with 469 additions and 183 deletions
@ -1,26 +1,26 @@ |
|||
using LINGYUN.Abp.IP2Region; |
|||
using LINGYUN.Abp.IP.Location; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.SecurityLog; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
namespace LINGYUN.Abp.AuditLogging.IP.Location; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpIP2RegionModule), |
|||
typeof(AbpIPLocationModule), |
|||
typeof(AbpAuditLoggingModule))] |
|||
public class AbpAuditLoggingIP2RegionModule : AbpModule |
|||
public class AbpAuditLoggingIPLocationModule : AbpModule |
|||
{ |
|||
public override void PostConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
Configure<AbpAuditLoggingIP2RegionOptions>(configuration.GetSection("AuditLogging:IP2Region")); |
|||
Configure<AbpAuditLoggingIPLocationOptions>(configuration.GetSection("AuditLogging:IPLocation")); |
|||
|
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient<IAuditingStore, IP2RegionAuditingStore>()); |
|||
ServiceDescriptor.Transient<IAuditingStore, IPLocationAuditingStore>()); |
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient<ISecurityLogStore, IP2RegionSecurityLogStore>()); |
|||
ServiceDescriptor.Transient<ISecurityLogStore, IPLocationSecurityLogStore>()); |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
namespace LINGYUN.Abp.AuditLogging.IP.Location; |
|||
public class AbpAuditLoggingIPLocationOptions |
|||
{ |
|||
public bool IsEnabled { get; set; } |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using LINGYUN.Abp.IP.Location; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP.Location; |
|||
public class IPLocationAuditingStore : AuditingStore |
|||
{ |
|||
private readonly AbpAuditLoggingIPLocationOptions _options; |
|||
private readonly IIPLocationResolver _iPLocationResolver; |
|||
public IPLocationAuditingStore( |
|||
IOptionsMonitor<AbpAuditLoggingIPLocationOptions> options, |
|||
IIPLocationResolver iPLocationResolver, |
|||
IAuditLogManager manager) |
|||
: base(manager) |
|||
{ |
|||
_options = options.CurrentValue; |
|||
_iPLocationResolver = iPLocationResolver; |
|||
} |
|||
|
|||
public async override Task SaveAsync(AuditLogInfo auditInfo) |
|||
{ |
|||
if (_options.IsEnabled && !auditInfo.ClientIpAddress.IsNullOrWhiteSpace()) |
|||
{ |
|||
var result = await _iPLocationResolver.ResolveAsync(auditInfo.ClientIpAddress); |
|||
|
|||
if (result.Location?.Remarks?.IsNullOrWhiteSpace() == false) |
|||
{ |
|||
auditInfo.ExtraProperties.Add("Location", $"{result.Location.Remarks}"); |
|||
} |
|||
} |
|||
await base.SaveAsync(auditInfo); |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using LINGYUN.Abp.IP.Location; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.SecurityLog; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP.Location; |
|||
|
|||
public class IPLocationSecurityLogStore : SecurityLogStore |
|||
{ |
|||
private readonly AbpAuditLoggingIPLocationOptions _options; |
|||
private readonly IIPLocationResolver _iPLocationResolver; |
|||
public IPLocationSecurityLogStore( |
|||
IOptionsMonitor<AbpAuditLoggingIPLocationOptions> options, |
|||
IIPLocationResolver iPLocationResolver, |
|||
ISecurityLogManager manager) |
|||
: base(manager) |
|||
{ |
|||
_options = options.CurrentValue; |
|||
_iPLocationResolver = iPLocationResolver; |
|||
} |
|||
|
|||
public async override Task SaveAsync(SecurityLogInfo securityLogInfo) |
|||
{ |
|||
if (_options.IsEnabled && !securityLogInfo.ClientIpAddress.IsNullOrWhiteSpace()) |
|||
{ |
|||
var result = await _iPLocationResolver.ResolveAsync(securityLogInfo.ClientIpAddress); |
|||
|
|||
if (result.Location?.Remarks?.IsNullOrWhiteSpace() == false) |
|||
{ |
|||
securityLogInfo.ExtraProperties.Add("Location", $"{result.Location.Remarks}"); |
|||
} |
|||
} |
|||
|
|||
await base.SaveAsync(securityLogInfo); |
|||
} |
|||
} |
|||
@ -1,5 +0,0 @@ |
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
public class AbpAuditLoggingIP2RegionOptions |
|||
{ |
|||
public bool IsEnabled { get; set; } |
|||
} |
|||
@ -1,34 +0,0 @@ |
|||
using LINGYUN.Abp.IP2Region; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
public class IP2RegionAuditingStore : AuditingStore |
|||
{ |
|||
private readonly AbpAuditLoggingIP2RegionOptions _options; |
|||
private readonly IIpLocationInfoProvider _ipLocationInfoProvider; |
|||
public IP2RegionAuditingStore( |
|||
IOptionsMonitor<AbpAuditLoggingIP2RegionOptions> options, |
|||
IIpLocationInfoProvider ipLocationInfoProvider, |
|||
IAuditLogManager manager) |
|||
: base(manager) |
|||
{ |
|||
_options = options.CurrentValue; |
|||
_ipLocationInfoProvider = ipLocationInfoProvider; |
|||
} |
|||
|
|||
public async override Task SaveAsync(AuditLogInfo auditInfo) |
|||
{ |
|||
if (_options.IsEnabled && !auditInfo.ClientIpAddress.IsNullOrWhiteSpace()) |
|||
{ |
|||
var locationInfo = await _ipLocationInfoProvider.GetLocationInfoAsync(auditInfo.ClientIpAddress); |
|||
if (locationInfo?.Remarks?.IsNullOrWhiteSpace() == false) |
|||
{ |
|||
auditInfo.ExtraProperties.Add("Location", $"{locationInfo.Remarks}"); |
|||
} |
|||
} |
|||
await base.SaveAsync(auditInfo); |
|||
} |
|||
} |
|||
@ -1,36 +0,0 @@ |
|||
using LINGYUN.Abp.IP2Region; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.SecurityLog; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
|
|||
public class IP2RegionSecurityLogStore : SecurityLogStore |
|||
{ |
|||
private readonly AbpAuditLoggingIP2RegionOptions _options; |
|||
private readonly IIpLocationInfoProvider _ipLocationInfoProvider; |
|||
public IP2RegionSecurityLogStore( |
|||
IOptionsMonitor<AbpAuditLoggingIP2RegionOptions> options, |
|||
IIpLocationInfoProvider ipLocationInfoProvider, |
|||
ISecurityLogManager manager) |
|||
: base(manager) |
|||
{ |
|||
_options = options.CurrentValue; |
|||
_ipLocationInfoProvider = ipLocationInfoProvider; |
|||
} |
|||
|
|||
public async override Task SaveAsync(SecurityLogInfo securityLogInfo) |
|||
{ |
|||
if (_options.IsEnabled && !securityLogInfo.ClientIpAddress.IsNullOrWhiteSpace()) |
|||
{ |
|||
var locationInfo = await _ipLocationInfoProvider.GetLocationInfoAsync(securityLogInfo.ClientIpAddress); |
|||
if (locationInfo?.Remarks?.IsNullOrWhiteSpace() == false) |
|||
{ |
|||
securityLogInfo.ExtraProperties.Add("Location", $"{locationInfo.Remarks}"); |
|||
} |
|||
} |
|||
|
|||
await base.SaveAsync(securityLogInfo); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,21 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.IP.Location</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.IP.Location</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Core" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,12 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
|
|||
public class AbpIPLocationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddSingleton<ICurrentIPLocationAccessor>(AsyncLocalCurrentIPLocationAccessor.Instance); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using JetBrains.Annotations; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class AbpIPLocationResolveOptions |
|||
{ |
|||
[NotNull] |
|||
public List<IIPLocationResolveContributor> IPLocationResolvers { get; } |
|||
|
|||
public AbpIPLocationResolveOptions() |
|||
{ |
|||
IPLocationResolvers = new List<IIPLocationResolveContributor>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Threading; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class AsyncLocalCurrentIPLocationAccessor : ICurrentIPLocationAccessor |
|||
{ |
|||
public static AsyncLocalCurrentIPLocationAccessor Instance { get; } = new(); |
|||
|
|||
public IPLocation? Current { |
|||
get => _currentScope.Value; |
|||
set => _currentScope.Value = value; |
|||
} |
|||
|
|||
private readonly AsyncLocal<IPLocation?> _currentScope; |
|||
|
|||
private AsyncLocalCurrentIPLocationAccessor() |
|||
{ |
|||
_currentScope = new AsyncLocal<IPLocation?>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class CurrentIPLocation : ICurrentIPLocation, ITransientDependency |
|||
{ |
|||
public string? Country => _currentIPLocationAccessor.Current?.Country; |
|||
|
|||
public string? Province => _currentIPLocationAccessor.Current?.Province; |
|||
|
|||
public string? City => _currentIPLocationAccessor.Current?.City; |
|||
|
|||
public string? Remarks => _currentIPLocationAccessor.Current?.Remarks; |
|||
|
|||
|
|||
private readonly ICurrentIPLocationAccessor _currentIPLocationAccessor; |
|||
|
|||
public CurrentIPLocation(ICurrentIPLocationAccessor currentIPLocationAccessor) |
|||
{ |
|||
_currentIPLocationAccessor = currentIPLocationAccessor; |
|||
} |
|||
|
|||
public IDisposable Change(IPLocation? location = null) |
|||
{ |
|||
return SetCurrent(location); |
|||
} |
|||
|
|||
private IDisposable SetCurrent(IPLocation? location = null) |
|||
{ |
|||
var parentScope = _currentIPLocationAccessor.Current; |
|||
_currentIPLocationAccessor.Current = location; |
|||
|
|||
return new DisposeAction<ValueTuple<ICurrentIPLocationAccessor, IPLocation?>>(static (state) => |
|||
{ |
|||
var (currentIPLocationAccessor, parentScope) = state; |
|||
currentIPLocationAccessor.Current = parentScope; |
|||
}, (_currentIPLocationAccessor, parentScope)); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public interface ICurrentIPLocation |
|||
{ |
|||
string? Country { get; } |
|||
|
|||
string? Province { get; } |
|||
|
|||
string? City { get; } |
|||
|
|||
string? Remarks { get; } |
|||
|
|||
IDisposable Change(IPLocation? location = null); |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public interface ICurrentIPLocationAccessor |
|||
{ |
|||
IPLocation? Current { get; set; } |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public interface IIPLocationResolveContext : IServiceProviderAccessor |
|||
{ |
|||
string IpAddress { get; } |
|||
|
|||
IPLocation? Location { get; set; } |
|||
|
|||
bool Handled { get; set; } |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public interface IIPLocationResolveContributor |
|||
{ |
|||
string Name { get; } |
|||
|
|||
Task ResolveAsync(IIPLocationResolveContext context); |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using JetBrains.Annotations; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public interface IIPLocationResolver |
|||
{ |
|||
[NotNull] |
|||
Task<IPLocationResolveResult> ResolveAsync(string ipAddress); |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class IPLocation |
|||
{ |
|||
public string? Country { get; } |
|||
public string? Province { get;} |
|||
public string? City { get; } |
|||
public string? Remarks { get; set; } |
|||
public IPLocation( |
|||
string? country = null, |
|||
string? province = null, |
|||
string? city = null, |
|||
string? remarks = null) |
|||
{ |
|||
Country = country; |
|||
Province = province; |
|||
City = city; |
|||
Remarks = remarks; |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class IPLocationResolveContext : IIPLocationResolveContext |
|||
{ |
|||
public IServiceProvider ServiceProvider { get; } |
|||
|
|||
public string IpAddress { get; } |
|||
|
|||
public IPLocation? Location { get; set; } |
|||
|
|||
public bool Handled { get; set; } |
|||
|
|||
public bool HasResolvedIPLocation() |
|||
{ |
|||
return Handled || Location != null; |
|||
} |
|||
|
|||
public IPLocationResolveContext(string ipAddress, IServiceProvider serviceProvider) |
|||
{ |
|||
IpAddress = ipAddress; |
|||
ServiceProvider = serviceProvider; |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public abstract class IPLocationResolveContributorBase : IIPLocationResolveContributor |
|||
{ |
|||
public abstract string Name { get; } |
|||
|
|||
public abstract Task ResolveAsync(IIPLocationResolveContext context); |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class IPLocationResolveResult |
|||
{ |
|||
public IPLocation? Location { get; set; } |
|||
|
|||
public List<string> AppliedResolvers { get; } |
|||
|
|||
public IPLocationResolveResult() |
|||
{ |
|||
AppliedResolvers = new List<string>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.IP.Location; |
|||
public class IPLocationResolver : IIPLocationResolver, ITransientDependency |
|||
{ |
|||
private readonly IServiceProvider _serviceProvider; |
|||
private readonly AbpIPLocationResolveOptions _options; |
|||
|
|||
public IPLocationResolver(IOptions<AbpIPLocationResolveOptions> options, IServiceProvider serviceProvider) |
|||
{ |
|||
_serviceProvider = serviceProvider; |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public virtual async Task<IPLocationResolveResult> ResolveAsync(string ipAddress) |
|||
{ |
|||
var result = new IPLocationResolveResult(); |
|||
|
|||
using (var serviceScope = _serviceProvider.CreateScope()) |
|||
{ |
|||
var context = new IPLocationResolveContext(ipAddress, serviceScope.ServiceProvider); |
|||
|
|||
foreach (var ipLocationResolver in _options.IPLocationResolvers) |
|||
{ |
|||
await ipLocationResolver.ResolveAsync(context); |
|||
|
|||
result.AppliedResolvers.Add(ipLocationResolver.Name); |
|||
|
|||
if (context.HasResolvedIPLocation()) |
|||
{ |
|||
result.Location = context.Location; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP2Region; |
|||
public interface IIpLocationInfoProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 通过ip地址获取地理信息
|
|||
/// </summary>
|
|||
/// <param name="ipAddress">ip地址</param>
|
|||
/// <returns>
|
|||
/// 如果解析成功返回地理信息,否则返回null
|
|||
/// </returns>
|
|||
Task<LocationInfo?> GetLocationInfoAsync(string ipAddress); |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using IP2Region.Net.Abstractions; |
|||
using LINGYUN.Abp.IP.Location; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP2Region; |
|||
public class IP2RegionIPLocationResolveContributorBase : IPLocationResolveContributorBase |
|||
{ |
|||
public const string ContributorName = "IP2Region"; |
|||
public override string Name => ContributorName; |
|||
|
|||
public override Task ResolveAsync(IIPLocationResolveContext context) |
|||
{ |
|||
var searcher = context.ServiceProvider.GetRequiredService<ISearcher>(); |
|||
|
|||
var region = searcher.Search(context.IpAddress); |
|||
|
|||
if (string.IsNullOrWhiteSpace(region)) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
var regions = region!.Split('|'); |
|||
// | 0 | 1 | 2 |3| 4 | 5 | 6 |
|
|||
// 39.128.0.0|39.128.31.255|中国|0|云南省|昆明市|移动
|
|||
// regions:
|
|||
// 中国 0 云南省 昆明市 移动
|
|||
|
|||
var ipLocation = new IPLocation( |
|||
regions.Length >= 1 && !string.Equals(regions[0], "0") ? regions[0] : null, |
|||
regions.Length >= 3 && !string.Equals(regions[2], "0") ? regions[2] : null, |
|||
regions.Length >= 4 && !string.Equals(regions[3], "0") ? regions[3] : null); |
|||
|
|||
// 36.133.108.0|36.133.119.255|中国|0|重庆|重庆市|移动
|
|||
if (!ipLocation.Province.IsNullOrWhiteSpace() && !ipLocation.City.IsNullOrWhiteSpace()) |
|||
{ |
|||
if (ipLocation.Province.Length < ipLocation.City.Length && |
|||
ipLocation.City.StartsWith(ipLocation.Province, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
// 重庆市
|
|||
ipLocation.Remarks = $"{ipLocation.City}"; |
|||
} |
|||
// 111.26.31.0|111.26.31.127|中国|0|吉林省|吉林市|移动
|
|||
else |
|||
{ |
|||
// 吉林省吉林市
|
|||
ipLocation.Remarks = $"{ipLocation.Province}{ipLocation.City}"; |
|||
} |
|||
} |
|||
// 220.246.0.0|220.246.255.255|中国|0|香港|0|电讯盈科
|
|||
else if (!ipLocation.Country.IsNullOrWhiteSpace() && !ipLocation.Province.IsNullOrWhiteSpace()) |
|||
{ |
|||
// 中国香港
|
|||
ipLocation.Remarks = $"{ipLocation.Country}{ipLocation.Province}"; |
|||
} |
|||
// 220.247.4.0|220.247.31.255|日本|0|0|0|0
|
|||
else |
|||
{ |
|||
// 日本
|
|||
ipLocation.Remarks = $"{ipLocation.Country}"; |
|||
} |
|||
|
|||
context.Location = ipLocation; |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -1,68 +0,0 @@ |
|||
using IP2Region.Net.Abstractions; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP2Region; |
|||
|
|||
public class IP2RegionLocationInfoProvider : IIpLocationInfoProvider |
|||
{ |
|||
protected static readonly LocationInfo? _nullCache = null; |
|||
|
|||
protected ISearcher Searcher { get; } |
|||
public IP2RegionLocationInfoProvider(ISearcher searcher) |
|||
{ |
|||
Searcher = searcher; |
|||
} |
|||
|
|||
public virtual Task<LocationInfo?> GetLocationInfoAsync(string ipAddress) |
|||
{ |
|||
var region = Searcher.Search(ipAddress); |
|||
if (string.IsNullOrWhiteSpace(region)) |
|||
{ |
|||
return Task.FromResult(_nullCache); |
|||
} |
|||
|
|||
var regions = region!.Split('|'); |
|||
// | 0 | 1 | 2 |3| 4 | 5 | 6 |
|
|||
// 39.128.0.0|39.128.31.255|中国|0|云南省|昆明市|移动
|
|||
// regions:
|
|||
// 中国 0 云南省 昆明市 移动
|
|||
var locationInfo = new LocationInfo |
|||
{ |
|||
Country = regions.Length >= 1 && !string.Equals(regions[0], "0") ? regions[0] : null, |
|||
Province = regions.Length >= 3 && !string.Equals(regions[2], "0") ? regions[2] : null, |
|||
City = regions.Length >= 4 && !string.Equals(regions[3], "0") ? regions[3] : null, |
|||
}; |
|||
|
|||
// 36.133.108.0|36.133.119.255|中国|0|重庆|重庆市|移动
|
|||
if (!locationInfo.Province.IsNullOrWhiteSpace() && !locationInfo.City.IsNullOrWhiteSpace()) |
|||
{ |
|||
if (locationInfo.Province.Length < locationInfo.City.Length && |
|||
locationInfo.City.StartsWith(locationInfo.Province, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
// 重庆市
|
|||
locationInfo.Remarks = $"{locationInfo.City}"; |
|||
} |
|||
// 111.26.31.0|111.26.31.127|中国|0|吉林省|吉林市|移动
|
|||
else |
|||
{ |
|||
// 吉林省吉林市
|
|||
locationInfo.Remarks = $"{locationInfo.Province}{locationInfo.City}"; |
|||
} |
|||
} |
|||
// 220.246.0.0|220.246.255.255|中国|0|香港|0|电讯盈科
|
|||
else if (!locationInfo.Country.IsNullOrWhiteSpace() && !locationInfo.Province.IsNullOrWhiteSpace()) |
|||
{ |
|||
// 中国香港
|
|||
locationInfo.Remarks = $"{locationInfo.Country}{locationInfo.Province}"; |
|||
} |
|||
// 220.247.4.0|220.247.31.255|日本|0|0|0|0
|
|||
else |
|||
{ |
|||
// 日本
|
|||
locationInfo.Remarks = $"{locationInfo.Country}"; |
|||
} |
|||
|
|||
return Task.FromResult<LocationInfo?>(locationInfo); |
|||
} |
|||
} |
|||
@ -1,8 +0,0 @@ |
|||
namespace LINGYUN.Abp.IP2Region; |
|||
public class LocationInfo |
|||
{ |
|||
public string? Country { get; set; } |
|||
public string? Province { get; set; } |
|||
public string? City { get; set; } |
|||
public string? Remarks { get; set; } |
|||
} |
|||
Loading…
Reference in new issue