diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xml b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/FodyWeavers.xml
similarity index 100%
rename from aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xml
rename to aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/FodyWeavers.xml
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xsd b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/FodyWeavers.xsd
similarity index 100%
rename from aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xsd
rename to aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/FodyWeavers.xsd
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN.Abp.AuditLogging.IP2Region.csproj b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN.Abp.AuditLogging.IP.Location.csproj
similarity index 56%
rename from aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN.Abp.AuditLogging.IP2Region.csproj
rename to aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN.Abp.AuditLogging.IP.Location.csproj
index d5b05534a..033d9583e 100644
--- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN.Abp.AuditLogging.IP2Region.csproj
+++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN.Abp.AuditLogging.IP.Location.csproj
@@ -7,19 +7,20 @@
netstandard2.0;netstandard2.1;net8.0
enable
Nullable
- LINGYUN.Abp.AuditLogging.IP2Region
- LINGYUN.Abp.AuditLogging.IP2Region
+ LINGYUN.Abp.AuditLogging.IP.Location
+ LINGYUN.Abp.AuditLogging.IP.Location
false
false
false
-
- netstandard2.0
-
+
+
+ netstandard2.0
+
-
-
-
-
+
+
+
+
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionModule.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/AbpAuditLoggingIPLocationModule.cs
similarity index 50%
rename from aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionModule.cs
rename to aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/AbpAuditLoggingIPLocationModule.cs
index a1b15a7e6..2885f495a 100644
--- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionModule.cs
+++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/AbpAuditLoggingIPLocationModule.cs
@@ -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(configuration.GetSection("AuditLogging:IP2Region"));
+ Configure(configuration.GetSection("AuditLogging:IPLocation"));
context.Services.Replace(
- ServiceDescriptor.Transient());
+ ServiceDescriptor.Transient());
context.Services.Replace(
- ServiceDescriptor.Transient());
+ ServiceDescriptor.Transient());
}
}
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/AbpAuditLoggingIPLocationOptions.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/AbpAuditLoggingIPLocationOptions.cs
new file mode 100644
index 000000000..04f90941f
--- /dev/null
+++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/AbpAuditLoggingIPLocationOptions.cs
@@ -0,0 +1,5 @@
+namespace LINGYUN.Abp.AuditLogging.IP.Location;
+public class AbpAuditLoggingIPLocationOptions
+{
+ public bool IsEnabled { get; set; }
+}
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/IPLocationAuditingStore.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/IPLocationAuditingStore.cs
new file mode 100644
index 000000000..ca078097d
--- /dev/null
+++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/IPLocationAuditingStore.cs
@@ -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 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);
+ }
+}
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/IPLocationSecurityLogStore.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/IPLocationSecurityLogStore.cs
new file mode 100644
index 000000000..ca65cfaed
--- /dev/null
+++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP.Location/LINGYUN/Abp/AuditLogging/IP/Location/IPLocationSecurityLogStore.cs
@@ -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 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);
+ }
+}
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionOptions.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionOptions.cs
deleted file mode 100644
index 50b3d2597..000000000
--- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionOptions.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace LINGYUN.Abp.AuditLogging.IP2Region;
-public class AbpAuditLoggingIP2RegionOptions
-{
- public bool IsEnabled { get; set; }
-}
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionAuditingStore.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionAuditingStore.cs
deleted file mode 100644
index 837bc2d23..000000000
--- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionAuditingStore.cs
+++ /dev/null
@@ -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 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);
- }
-}
diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionSecurityLogStore.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionSecurityLogStore.cs
deleted file mode 100644
index 44cf688c6..000000000
--- a/aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionSecurityLogStore.cs
+++ /dev/null
@@ -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 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);
- }
-}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/FodyWeavers.xml b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/FodyWeavers.xml
new file mode 100644
index 000000000..1715698cc
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/FodyWeavers.xsd b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/FodyWeavers.xsd
new file mode 100644
index 000000000..3f3946e28
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/FodyWeavers.xsd
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN.Abp.IP.Location.csproj b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN.Abp.IP.Location.csproj
new file mode 100644
index 000000000..242eb7e58
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN.Abp.IP.Location.csproj
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ netstandard2.0;netstandard2.1;net8.0
+ LINGYUN.Abp.IP.Location
+ LINGYUN.Abp.IP.Location
+ false
+ false
+ false
+ enable
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AbpIPLocationModule.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AbpIPLocationModule.cs
new file mode 100644
index 000000000..b891c3b39
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AbpIPLocationModule.cs
@@ -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(AsyncLocalCurrentIPLocationAccessor.Instance);
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AbpIPLocationResolveOptions.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AbpIPLocationResolveOptions.cs
new file mode 100644
index 000000000..2efd997b0
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AbpIPLocationResolveOptions.cs
@@ -0,0 +1,14 @@
+using JetBrains.Annotations;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.IP.Location;
+public class AbpIPLocationResolveOptions
+{
+ [NotNull]
+ public List IPLocationResolvers { get; }
+
+ public AbpIPLocationResolveOptions()
+ {
+ IPLocationResolvers = new List();
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AsyncLocalCurrentIPLocationAccessor.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AsyncLocalCurrentIPLocationAccessor.cs
new file mode 100644
index 000000000..e99f02019
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/AsyncLocalCurrentIPLocationAccessor.cs
@@ -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 _currentScope;
+
+ private AsyncLocalCurrentIPLocationAccessor()
+ {
+ _currentScope = new AsyncLocal();
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/CurrentIPLocation.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/CurrentIPLocation.cs
new file mode 100644
index 000000000..12d1e5b68
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/CurrentIPLocation.cs
@@ -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>(static (state) =>
+ {
+ var (currentIPLocationAccessor, parentScope) = state;
+ currentIPLocationAccessor.Current = parentScope;
+ }, (_currentIPLocationAccessor, parentScope));
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/ICurrentIPLocation.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/ICurrentIPLocation.cs
new file mode 100644
index 000000000..c832ff82a
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/ICurrentIPLocation.cs
@@ -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);
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/ICurrentIPLocationAccessor.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/ICurrentIPLocationAccessor.cs
new file mode 100644
index 000000000..a2ffed58d
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/ICurrentIPLocationAccessor.cs
@@ -0,0 +1,5 @@
+namespace LINGYUN.Abp.IP.Location;
+public interface ICurrentIPLocationAccessor
+{
+ IPLocation? Current { get; set; }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolveContext.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolveContext.cs
new file mode 100644
index 000000000..96a14b0b1
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolveContext.cs
@@ -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; }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolveContributor.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolveContributor.cs
new file mode 100644
index 000000000..203fb870c
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolveContributor.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.IP.Location;
+public interface IIPLocationResolveContributor
+{
+ string Name { get; }
+
+ Task ResolveAsync(IIPLocationResolveContext context);
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolver.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolver.cs
new file mode 100644
index 000000000..e148e54d9
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IIPLocationResolver.cs
@@ -0,0 +1,9 @@
+using JetBrains.Annotations;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.IP.Location;
+public interface IIPLocationResolver
+{
+ [NotNull]
+ Task ResolveAsync(string ipAddress);
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocation.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocation.cs
new file mode 100644
index 000000000..20b02b8a8
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocation.cs
@@ -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;
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveContext.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveContext.cs
new file mode 100644
index 000000000..900914e9e
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveContext.cs
@@ -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;
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveContributorBase.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveContributorBase.cs
new file mode 100644
index 000000000..4b0e4b633
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveContributorBase.cs
@@ -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);
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveResult.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveResult.cs
new file mode 100644
index 000000000..9bb44efff
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolveResult.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.IP.Location;
+public class IPLocationResolveResult
+{
+ public IPLocation? Location { get; set; }
+
+ public List AppliedResolvers { get; }
+
+ public IPLocationResolveResult()
+ {
+ AppliedResolvers = new List();
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolver.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolver.cs
new file mode 100644
index 000000000..b4c732758
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP.Location/LINGYUN/Abp/IP/Location/IPLocationResolver.cs
@@ -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 options, IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ _options = options.Value;
+ }
+
+ public virtual async Task 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;
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN.Abp.IP2Region.csproj b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN.Abp.IP2Region.csproj
index eda0e57f0..dcfd51a03 100644
--- a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN.Abp.IP2Region.csproj
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN.Abp.IP2Region.csproj
@@ -24,4 +24,8 @@
+
+
+
+
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/AbpIP2RegionModule.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/AbpIP2RegionModule.cs
index 7d3be1b5c..ab95964e9 100644
--- a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/AbpIP2RegionModule.cs
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/AbpIP2RegionModule.cs
@@ -1,12 +1,13 @@
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
+using LINGYUN.Abp.IP.Location;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.IP2Region;
+[DependsOn(typeof(AbpIPLocationModule))]
[DependsOn(typeof(AbpVirtualFileSystemModule))]
public class AbpIP2RegionModule : AbpModule
{
@@ -26,6 +27,9 @@ public class AbpIP2RegionModule : AbpModule
return searcher;
});
- context.Services.TryAddTransient();
+ Configure(options =>
+ {
+ options.IPLocationResolvers.Add(new IP2RegionIPLocationResolveContributorBase());
+ });
}
}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IIpLocationInfoProvider.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IIpLocationInfoProvider.cs
deleted file mode 100644
index 9b265b383..000000000
--- a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IIpLocationInfoProvider.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Threading.Tasks;
-
-namespace LINGYUN.Abp.IP2Region;
-public interface IIpLocationInfoProvider
-{
- ///
- /// 通过ip地址获取地理信息
- ///
- /// ip地址
- ///
- /// 如果解析成功返回地理信息,否则返回null
- ///
- Task GetLocationInfoAsync(string ipAddress);
-}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionIPLocationResolveContributorBase.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionIPLocationResolveContributorBase.cs
new file mode 100644
index 000000000..0cc4c2b44
--- /dev/null
+++ b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionIPLocationResolveContributorBase.cs
@@ -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();
+
+ 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;
+ }
+}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionLocationInfoProvider.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionLocationInfoProvider.cs
deleted file mode 100644
index d7dec2328..000000000
--- a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionLocationInfoProvider.cs
+++ /dev/null
@@ -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 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);
- }
-}
diff --git a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/LocationInfo.cs b/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/LocationInfo.cs
deleted file mode 100644
index 8ce689377..000000000
--- a/aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/LocationInfo.cs
+++ /dev/null
@@ -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; }
-}