Browse Source

add tencent map module; update apigateway init sql scripts

pull/24/head
cKey 6 years ago
parent
commit
3e040e8c1f
  1. 1600
      aspnet-core/database/ApiGateway-Init.sql
  2. 21
      aspnet-core/modules/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs
  3. 27
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml
  4. 17
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CAPDistributedEventBus.cs
  5. 138
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CustomDistributedEventSubscriber.cs
  6. 24
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/ICustomDistributedEventSubscriber.cs
  7. 9
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProvider.cs
  8. 37
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN.Abp.Location.Tencent.csproj
  9. 36
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/AbpTencentLocationModule.cs
  10. 11
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Localization/Resources/en.json
  11. 11
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Localization/Resources/zh-Hans.json
  12. 9
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Localization/TencentLocationResource.cs
  13. 41
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/AddressComponent.cs
  14. 53
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/AddressInfo.cs
  15. 56
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/AddressReference.cs
  16. 37
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Area.cs
  17. 21
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/FormattedAddress.cs
  18. 21
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Location.cs
  19. 46
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Poi.cs
  20. 44
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/TencentGeocode.cs
  21. 26
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/TencentIPGeocode.cs
  22. 46
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/TencentReGeocode.cs
  23. 14
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentGeocodeResponse.cs
  24. 14
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentIPGeocodeResponse.cs
  25. 52
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentLocationResponse.cs
  26. 14
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentReGeocodeResponse.cs
  27. 211
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpClient.cs
  28. 7
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpConsts.cs
  29. 12
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationOptions.cs
  30. 33
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationResolveProvider.cs
  31. 47
      aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Utils/TencentSecretKeyCaculater.cs
  32. 2
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ILocationResolveProvider.cs
  33. 43
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/IPGecodeLocation.cs
  34. 10
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Controllers/LocationController.cs
  35. 2
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
  36. 4
      aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs

1600
aspnet-core/database/ApiGateway-Init.sql

File diff suppressed because it is too large

21
aspnet-core/modules/common/LINGYUN.Abp.BlobStoring.Aliyun/LINGYUN/Abp/BlobStoring/Aliyun/AliyunBlobProvider.cs

@ -63,11 +63,8 @@ namespace LINGYUN.Abp.BlobStoring.Aliyun
{ {
var blobName = AliyunBlobNameCalculator.Calculate(args); var blobName = AliyunBlobNameCalculator.Calculate(args);
var configuration = args.Configuration.GetAliyunConfiguration(); var configuration = args.Configuration.GetAliyunConfiguration();
if (!args.OverrideExisting && await BlobExistsAsync(args, blobName))
{
throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the bucketName '{GetBucketName(args)}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
// 先检查Bucket
if (configuration.CreateBucketIfNotExists) if (configuration.CreateBucketIfNotExists)
{ {
await CreateBucketIfNotExists(args, configuration.CreateBucketReferer); await CreateBucketIfNotExists(args, configuration.CreateBucketReferer);
@ -76,11 +73,21 @@ namespace LINGYUN.Abp.BlobStoring.Aliyun
var bucketName = GetBucketName(args); var bucketName = GetBucketName(args);
var ossClient = GetOssClient(args); var ossClient = GetOssClient(args);
if (args.OverrideExisting && await BlobExistsAsync(args, blobName)) // 是否已存在
if (await BlobExistsAsync(args, blobName))
{ {
ossClient.DeleteObject(bucketName, blobName); // 是否覆盖
if (!args.OverrideExisting)
{
throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the bucketName '{GetBucketName(args)}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
else
{
// 删除原文件
ossClient.DeleteObject(bucketName, blobName);
}
} }
// 保存
ossClient.PutObject(bucketName, blobName, args.BlobStream); ossClient.PutObject(bucketName, blobName, args.BlobStream);
} }

27
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml

@ -136,6 +136,11 @@
CAP消息发布接口 CAP消息发布接口
</summary> </summary>
</member> </member>
<member name="P:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.CustomDistributedEventSubscriber">
<summary>
自定义事件注册接口
</summary>
</member>
<member name="P:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.HandlerFactories"> <member name="P:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.HandlerFactories">
<summary> <summary>
本地事件处理器工厂对象集合 本地事件处理器工厂对象集合
@ -146,13 +151,14 @@
本地事件集合 本地事件集合
</summary> </summary>
</member> </member>
<member name="M:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.#ctor(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,Microsoft.Extensions.Options.IOptions{Volo.Abp.EventBus.Distributed.AbpDistributedEventBusOptions},DotNetCore.CAP.ICapPublisher)"> <member name="M:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.#ctor(Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,Microsoft.Extensions.Options.IOptions{Volo.Abp.EventBus.Distributed.AbpDistributedEventBusOptions},DotNetCore.CAP.ICapPublisher,LINGYUN.Abp.EventBus.CAP.ICustomDistributedEventSubscriber)">
<summary> <summary>
constructor constructor
</summary> </summary>
<param name="serviceScopeFactory"></param> <param name="serviceScopeFactory"></param>
<param name="distributedEventBusOptions"></param> <param name="distributedEventBusOptions"></param>
<param name="capPublisher"></param> <param name="capPublisher"></param>
<param name="customDistributedEventSubscriber"></param>
</member> </member>
<member name="M:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.Subscribe(System.Type,Volo.Abp.EventBus.IEventHandlerFactory)"> <member name="M:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus.Subscribe(System.Type,Volo.Abp.EventBus.IEventHandlerFactory)">
<summary> <summary>
@ -212,6 +218,25 @@
<param name="eventType"></param> <param name="eventType"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:LINGYUN.Abp.EventBus.CAP.ICustomDistributedEventSubscriber">
<summary>
自定义事件订阅者
</summary>
</member>
<member name="M:LINGYUN.Abp.EventBus.CAP.ICustomDistributedEventSubscriber.Subscribe(System.Type,Volo.Abp.EventBus.IEventHandlerFactory)">
<summary>
订阅事件
</summary>
<param name="eventType"></param>
<param name="factory"></param>
</member>
<member name="M:LINGYUN.Abp.EventBus.CAP.ICustomDistributedEventSubscriber.UnSubscribe(System.Type,Volo.Abp.EventBus.IEventHandlerFactory)">
<summary>
取消订阅
</summary>
<param name="eventType"></param>
<param name="factory"></param>
</member>
<member name="T:LINGYUN.Abp.EventBus.CAP.MessageCleanupOptions"> <member name="T:LINGYUN.Abp.EventBus.CAP.MessageCleanupOptions">
<summary> <summary>
过期消息清理配置项 过期消息清理配置项

17
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CAPDistributedEventBus.cs

@ -29,7 +29,10 @@ namespace LINGYUN.Abp.EventBus.CAP
/// CAP消息发布接口 /// CAP消息发布接口
/// </summary> /// </summary>
protected readonly ICapPublisher CapPublisher; protected readonly ICapPublisher CapPublisher;
/// <summary>
/// 自定义事件注册接口
/// </summary>
protected ICustomDistributedEventSubscriber CustomDistributedEventSubscriber { get; }
/// <summary> /// <summary>
/// 本地事件处理器工厂对象集合 /// 本地事件处理器工厂对象集合
/// </summary> /// </summary>
@ -44,11 +47,15 @@ namespace LINGYUN.Abp.EventBus.CAP
/// <param name="serviceScopeFactory"></param> /// <param name="serviceScopeFactory"></param>
/// <param name="distributedEventBusOptions"></param> /// <param name="distributedEventBusOptions"></param>
/// <param name="capPublisher"></param> /// <param name="capPublisher"></param>
/// <param name="customDistributedEventSubscriber"></param>
public CAPDistributedEventBus(IServiceScopeFactory serviceScopeFactory, public CAPDistributedEventBus(IServiceScopeFactory serviceScopeFactory,
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions, IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions,
ICapPublisher capPublisher) : base(serviceScopeFactory) ICapPublisher capPublisher,
ICustomDistributedEventSubscriber customDistributedEventSubscriber)
: base(serviceScopeFactory)
{ {
CapPublisher = capPublisher; CapPublisher = capPublisher;
CustomDistributedEventSubscriber = customDistributedEventSubscriber;
AbpDistributedEventBusOptions = distributedEventBusOptions.Value; AbpDistributedEventBusOptions = distributedEventBusOptions.Value;
HandlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>(); HandlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>();
EventTypes = new ConcurrentDictionary<string, Type>(); EventTypes = new ConcurrentDictionary<string, Type>();
@ -61,8 +68,9 @@ namespace LINGYUN.Abp.EventBus.CAP
/// <returns></returns> /// <returns></returns>
public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory)
{ {
//This is handled by CAP ConsumerServiceSelector // 自定义的事件订阅者,可以不需要事件注册的事件类型
throw new NotImplementedException(); CustomDistributedEventSubscriber.Subscribe(eventType, factory);
return new DisposeAction(() => CustomDistributedEventSubscriber.UnSubscribe(eventType, factory));
} }
/// <summary> /// <summary>
/// 退订事件 /// 退订事件
@ -118,6 +126,7 @@ namespace LINGYUN.Abp.EventBus.CAP
public override void Unsubscribe(Type eventType, IEventHandlerFactory factory) public override void Unsubscribe(Type eventType, IEventHandlerFactory factory)
{ {
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory)); GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory));
CustomDistributedEventSubscriber.UnSubscribe(eventType, factory);
} }
/// <summary> /// <summary>
/// 退订所有事件 /// 退订所有事件

138
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/CustomDistributedEventSubscriber.cs

@ -0,0 +1,138 @@
using DotNetCore.CAP.Internal;
using DotNetCore.CAP.Transport;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Reflection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Threading;
using System.Linq;
using DotNetCore.CAP;
using Microsoft.Extensions.Options;
namespace LINGYUN.Abp.EventBus.CAP
{
internal class CustomDistributedEventSubscriber : ICustomDistributedEventSubscriber, ISingletonDependency
{
protected CapOptions CapOptions { get; }
protected IConsumerClientFactory ConsumerClientFactory { get; }
protected ConcurrentDictionary<Type, List<IEventHandlerFactory>> HandlerFactories { get; }
protected ConcurrentDictionary<string, CancellationTokenSource> EventStopingTokens { get; }
public CustomDistributedEventSubscriber(
IOptions<CapOptions> options,
IConsumerClientFactory consumerClientFactory)
{
CapOptions = options.Value;
ConsumerClientFactory = consumerClientFactory;
HandlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>();
EventStopingTokens = new ConcurrentDictionary<string, CancellationTokenSource>();
}
public void Subscribe(Type eventType, IEventHandlerFactory factory)
{
GetOrCreateHandlerFactories(eventType)
.Locking(factories =>
{
if (!factories.Contains(factory))
{
factories.Add(factory);
// TODO 客户端订阅
}
});
}
public void UnSubscribe(Type eventType, IEventHandlerFactory factory)
{
GetOrCreateHandlerFactories(eventType)
.Locking(factories =>
{
if (factories.Contains(factory))
{
factories.Remove(factory);
// TODO 客户端退订
}
});
}
private List<IEventHandlerFactory> GetOrCreateHandlerFactories(Type eventType)
{
return HandlerFactories.GetOrAdd(
eventType,
type =>
{
var eventName = EventNameAttribute.GetNameOrDefault(type);
EventStopingTokens[eventName] = new CancellationTokenSource();
return new List<IEventHandlerFactory>();
}
);
}
private IEnumerable<ConsumerExecutorDescriptor> GetHandlerDescription(Type eventType, Type typeInfo)
{
var serviceTypeInfo = typeof(IDistributedEventHandler<>)
.MakeGenericType(eventType);
var method = typeInfo
.GetMethod(
nameof(IDistributedEventHandler<object>.HandleEventAsync),
new[] { eventType }
);
var eventName = EventNameAttribute.GetNameOrDefault(eventType);
var topicAttr = method.GetCustomAttributes<TopicAttribute>(true);
var topicAttributes = topicAttr.ToList();
topicAttributes.Add(new CapSubscribeAttribute(eventName));
foreach (var attr in topicAttributes)
{
SetSubscribeAttribute(attr);
var parameters = method.GetParameters()
.Select(parameter => new ParameterDescriptor
{
Name = parameter.Name,
ParameterType = parameter.ParameterType,
IsFromCap = parameter.GetCustomAttributes(typeof(FromCapAttribute)).Any()
}).ToList();
yield return InitDescriptor(attr, method, typeInfo.GetTypeInfo(), serviceTypeInfo.GetTypeInfo(), parameters);
}
}
private void SetSubscribeAttribute(TopicAttribute attribute)
{
if (attribute.Group == null)
{
attribute.Group = CapOptions.DefaultGroup + "." + CapOptions.Version;
}
else
{
attribute.Group = attribute.Group + "." + CapOptions.Version;
}
}
private ConsumerExecutorDescriptor InitDescriptor(
TopicAttribute attr,
MethodInfo methodInfo,
TypeInfo implType,
TypeInfo serviceTypeInfo,
IList<ParameterDescriptor> parameters)
{
var descriptor = new ConsumerExecutorDescriptor
{
Attribute = attr,
MethodInfo = methodInfo,
ImplTypeInfo = implType,
ServiceTypeInfo = serviceTypeInfo,
Parameters = parameters
};
return descriptor;
}
}
}

24
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/ICustomDistributedEventSubscriber.cs

@ -0,0 +1,24 @@
using System;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.EventBus.CAP
{
/// <summary>
/// 自定义事件订阅者
/// </summary>
public interface ICustomDistributedEventSubscriber
{
/// <summary>
/// 订阅事件
/// </summary>
/// <param name="eventType"></param>
/// <param name="factory"></param>
void Subscribe(Type eventType, IEventHandlerFactory factory);
/// <summary>
/// 取消订阅
/// </summary>
/// <param name="eventType"></param>
/// <param name="factory"></param>
void UnSubscribe(Type eventType, IEventHandlerFactory factory);
}
}

9
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProvider.cs

@ -15,12 +15,17 @@ namespace LINGYUN.Abp.Location.Baidu
BaiduLocationHttpClient = baiduHttpRequestClient; BaiduLocationHttpClient = baiduHttpRequestClient;
} }
public async Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 50) public virtual Task<IPGecodeLocation> IPGeocodeAsync(string ipAddress)
{
return Task.FromResult(new IPGecodeLocation());
}
public virtual async Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 50)
{ {
return await BaiduLocationHttpClient.ReGeocodeAsync(lat, lng, radius); return await BaiduLocationHttpClient.ReGeocodeAsync(lat, lng, radius);
} }
public async Task<GecodeLocation> GeocodeAsync(string address, string city = null) public virtual async Task<GecodeLocation> GeocodeAsync(string address, string city = null)
{ {
return await BaiduLocationHttpClient.GeocodeAsync(address, city); return await BaiduLocationHttpClient.GeocodeAsync(address, city);
} }

37
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN.Abp.Location.Tencent.csproj

@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<Version>3.0.0</Version>
<Description>腾讯位置服务</Description>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>D:\LocalNuget</OutputPath>
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\Location\Tencent\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\Location\Tencent\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\Location\Tencent\Localization\Resources\en.json" />
<EmbeddedResource Include="LINGYUN\Abp\Location\Tencent\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="3.1.2" />
<PackageReference Include="Volo.Abp.Localization" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Json" Version="3.0.0" />
<PackageReference Include="Volo.Abp.Threading" Version="3.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Location\LINGYUN.Abp.Location.csproj" />
</ItemGroup>
</Project>

36
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/AbpTencentLocationModule.cs

@ -0,0 +1,36 @@
using LINYUN.Abp.Location.Tencent.Localization;
using Microsoft.Extensions.DependencyInjection;
using Polly;
using System;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Location.Tencent
{
[DependsOn(typeof(AbpLocationModule))]
public class AbpTencentLocationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<TencentLocationOptions>(configuration.GetSection("Location:Tencent"));
context.Services.AddHttpClient(TencentLocationHttpConsts.HttpClientName)
.AddTransientHttpErrorPolicy(builder =>
builder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))));
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpTencentLocationModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TencentLocationResource>("en")
.AddVirtualJson("/LINGYUN/Abp/Location/Tencent/Localization/Resources");
});
}
}
}

11
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Localization/Resources/en.json

@ -0,0 +1,11 @@
{
"culture": "en",
"texts": {
"ResolveLocationFailed": "Parse address error, error message :{0}",
"Message:RETURN_0": "OK",
"Message:RETURN_110": "The request parameter information is incorrect",
"Message:RETURN_306": "Key format error",
"Message:RETURN_310": "Check the string if the request has retention information",
"Message:RETURN_311": "The source of the request is not authorized"
}
}

11
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Localization/Resources/zh-Hans.json

@ -0,0 +1,11 @@
{
"culture": "zh-Hans",
"texts": {
"ResolveLocationFailed": "解析地址出错,错误信息:{0}",
"Message:RETURN_0": "正常",
"Message:RETURN_110": "请求参数信息有误",
"Message:RETURN_306": "Key格式错误",
"Message:RETURN_310": "请求有护持信息请检查字符串",
"Message:RETURN_311": "请求来源未被授权"
}
}

9
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Localization/TencentLocationResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINYUN.Abp.Location.Tencent.Localization
{
[LocalizationResourceName("TencentLocation")]
public class TencentLocationResource
{
}
}

41
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/AddressComponent.cs

@ -0,0 +1,41 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 地址部件,address不满足需求时可自行拼接
/// </summary>
public class AddressComponent
{
/// <summary>
/// 国家
/// </summary>
[JsonProperty("nation")]
public string Nation { get; set; }
/// <summary>
/// 省
/// </summary>
[JsonProperty("province")]
public string Province { get; set; }
/// <summary>
/// 市
/// </summary>
[JsonProperty("city")]
public string City { get; set; }
/// <summary>
/// 区,可能为空字串
/// </summary>
[JsonProperty("district")]
public string District { get; set; }
/// <summary>
/// 街道,可能为空字串
/// </summary>
[JsonProperty("street")]
public string Street { get; set; }
/// <summary>
/// 门牌,可能为空字串
/// </summary>
[JsonProperty("street_number")]
public string StreetNumber { get; set; }
}
}

53
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/AddressInfo.cs

@ -0,0 +1,53 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 行政区划信息
/// </summary>
public class AddressInfo
{
[JsonProperty("adcode")]
public string AdCode { get; set; }
/// <summary>
/// 城市代码
/// </summary>
[JsonProperty("city_code")]
public string CityCode { get; set; }
/// <summary>
/// 行政区划代码
/// </summary>
[JsonProperty("nation_code")]
public string NationCode { get; set; }
/// <summary>
/// 行政区划名称
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// 国家
/// </summary>
[JsonProperty("nation")]
public string Nation { get; set; }
/// <summary>
/// 省/直辖市
/// </summary>
[JsonProperty("province")]
public string Province { get; set; }
/// <summary>
/// 市/地级区 及同级行政区划
/// </summary>
[JsonProperty("city")]
public string City { get; set; }
/// <summary>
/// 区/县级市 及同级行政区划
/// </summary>
[JsonProperty("district")]
public string District { get; set; }
/// <summary>
/// 行政区划中心点坐标
/// </summary>
[JsonProperty("location")]
public Location Location { get; set; } = new Location();
}
}

56
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/AddressReference.cs

@ -0,0 +1,56 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 坐标相对位置参考
/// </summary>
public class AddressReference
{
/// <summary>
/// 商圈
/// </summary>
[JsonProperty("business_area")]
public Area BusinessArea { get; set; } = new Area();
/// <summary>
/// 知名区域,如商圈或人们普遍认为有较高知名度的区域
/// </summary>
[JsonProperty("famous_area")]
public Area FamousArea { get; set; } = new Area();
/// <summary>
/// 乡镇街道
/// </summary>
[JsonProperty("town")]
public Area Town { get; set; } = new Area();
/// <summary>
/// 一级地标,可识别性较强、规模较大的地点、小区等
/// </summary>
[JsonProperty("landmark_l1")]
public Area Landmark1 { get; set; } = new Area();
/// <summary>
/// 二级地标,较一级地标更为精确,规模更小
/// </summary>
[JsonProperty("landmark_l2")]
public Area Landmark2 { get; set; } = new Area();
/// <summary>
/// 街道
/// </summary>
[JsonProperty("street")]
public Area Street { get; set; } = new Area();
/// <summary>
/// 门牌
/// </summary>
[JsonProperty("street_number")]
public Area StreetNumber { get; set; } = new Area();
/// <summary>
/// 交叉路口
/// </summary>
[JsonProperty("crossroad")]
public Area CrossRoad { get; set; } = new Area();
/// <summary>
/// 水系
/// </summary>
[JsonProperty("water")]
public Area Water { get; set; } = new Area();
}
}

37
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Area.cs

@ -0,0 +1,37 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 区域信息
/// </summary>
public class Area
{
/// <summary>
/// 地点唯一标识
/// </summary>
[JsonProperty("id")]
public string Id { get; set; }
/// <summary>
/// 名称/标题
/// </summary>
[JsonProperty("title")]
public string Title { get; set; }
/// <summary>
/// 坐标
/// </summary>
[JsonProperty("location")]
public Location Location { get; set; } = new Location();
/// <summary>
/// 此参考位置到输入坐标的直线距离
/// </summary>
[JsonProperty("_distance")]
public string Distance { get; set; }
/// <summary>
/// 此参考位置到输入坐标的方位关系,
/// 如:北、南、内
/// </summary>
[JsonProperty("_dir_desc")]
public string DirDescription { get; set; }
}
}

21
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/FormattedAddress.cs

@ -0,0 +1,21 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 位置描述
/// </summary>
public class FormattedAddress
{
/// <summary>
/// 经过腾讯地图优化过的描述方式,更具人性化特点
/// </summary>
[JsonProperty("recommend")]
public string ReCommend { get; set; }
/// <summary>
/// 大致位置,可用于对位置的粗略描述
/// </summary>
[JsonProperty("rough")]
public string Rough { get; set; }
}
}

21
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Location.cs

@ -0,0 +1,21 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 行政区划中心点坐标
/// </summary>
public class Location
{
/// <summary>
/// 纬度
/// </summary>
[JsonProperty("lat")]
public double Lat { get; set; }
/// <summary>
/// 经度
/// </summary>
[JsonProperty("lng")]
public double Lng { get; set; }
}
}

46
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Poi.cs

@ -0,0 +1,46 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// POI对象
/// </summary>
public class Poi
{
/// <summary>
/// 地点唯一标识
/// </summary>
[JsonProperty("id")]
public string Id { get; set; }
/// <summary>
/// 名称/标题
/// </summary>
[JsonProperty("title")]
public string Title { get; set; }
/// <summary>
/// 地址
/// </summary>
[JsonProperty("address")]
public string Address { get; set; }
/// <summary>
/// POI分类
/// </summary>
[JsonProperty("category")]
public string CateGory { get; set; }
/// <summary>
/// 坐标
/// </summary>
[JsonProperty("location")]
public Location Location { get; set; } = new Location();
/// <summary>
/// 该POI到逆地址解析传入的坐标的直线距离
/// </summary>
[JsonProperty("_distance")]
public string Distance { get; set; }
/// <summary>
/// 行政区划信息
/// </summary>
[JsonProperty("ad_info")]
public AddressInfo AddressInfo { get; set; } = new AddressInfo();
}
}

44
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/TencentGeocode.cs

@ -0,0 +1,44 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
public class TencentGeocode
{
/// <summary>
/// 解析到的坐标
/// </summary>
[JsonProperty("location")]
public Location Location { get; set; } = new Location();
/// <summary>
/// 解析后的地址部件
/// </summary>
[JsonProperty("address_components")]
public AddressComponent AddressComponent { get; set; } = new AddressComponent();
/// <summary>
/// 行政区划信息
/// </summary>
[JsonProperty("ad_info")]
public GeocodeAddressInfo AddressInfo { get; set; } = new GeocodeAddressInfo();
/// <summary>
/// 可信度参考:值范围 1 <低可信> - 10 <高可信>
/// </summary>
[JsonProperty("reliability")]
public int Reliability { get; set; }
/// <summary>
/// 解析精度级别,分为11个级别,一般>=9即可采用(定位到点,精度较高) 也可根据实际业务需求自行调整
/// </summary>
[JsonProperty("level")]
public int Level { get; set; }
}
/// <summary>
/// 行政区划信息
/// </summary>
public class GeocodeAddressInfo
{
/// <summary>
/// 行政区划代码
/// </summary>
[JsonProperty("adcode")]
public string AdCode { get; set; }
}
}

26
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/TencentIPGeocode.cs

@ -0,0 +1,26 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// IP定位结果
/// </summary>
public class TencentIPGeocode
{
/// <summary>
/// 用于定位的IP地址
/// </summary>
[JsonProperty("ip")]
public string IpAddress { get; set; }
/// <summary>
/// 定位坐标
/// </summary>
[JsonProperty("location")]
public Location Location { get; set; } = new Location();
/// <summary>
/// 定位行政区划信息
/// </summary>
[JsonProperty("ad_info")]
public AddressInfo AddressInfo { get; set; } = new AddressInfo();
}
}

46
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/TencentReGeocode.cs

@ -0,0 +1,46 @@
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Model
{
/// <summary>
/// 逆地址解析结果
/// </summary>
public class TencentReGeocode
{
/// <summary>
/// 地址描述
/// </summary>
[JsonProperty("address")]
public string Address { get; set; }
/// <summary>
/// 位置描述
/// </summary>
[JsonProperty("formatted_addresses")]
public FormattedAddress FormattedAddress { get; set; } = new FormattedAddress();
/// <summary>
/// 地址部件,address不满足需求时可自行拼接
/// </summary>
[JsonProperty("address_component")]
public AddressComponent AddressComponent { get; set; } = new AddressComponent();
/// <summary>
/// 行政区划信息
/// </summary>
[JsonProperty("ad_info")]
public AddressInfo AddressInfo { get; set; } = new AddressInfo();
/// <summary>
/// 坐标相对位置参考
/// </summary>
[JsonProperty("address_reference")]
public AddressReference AddressReference { get; set; } = new AddressReference();
/// <summary>
/// 查询的周边poi的总数
/// </summary>
[JsonProperty("poi_count")]
public int PoiCount { get; set; }
/// <summary>
/// POI数组,对象中每个子项为一个POI对象
/// </summary>
[JsonProperty("pois")]
public Poi[] Pois { get; set; } = new Poi[0];
}
}

14
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentGeocodeResponse.cs

@ -0,0 +1,14 @@
using LINGYUN.Abp.Location.Tencent.Model;
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Response
{
public class TencentGeocodeResponse : TencentLocationResponse
{
/// <summary>
/// 地址解析结果
/// </summary>
[JsonProperty("result")]
public TencentGeocode Result { get; set; } = new TencentGeocode();
}
}

14
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentIPGeocodeResponse.cs

@ -0,0 +1,14 @@
using LINGYUN.Abp.Location.Tencent.Model;
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Response
{
public class TencentIPGeocodeResponse : TencentLocationResponse
{
/// <summary>
/// IP定位结果
/// </summary>
[JsonProperty("result")]
public TencentIPGeocode Result { get; set; } = new TencentIPGeocode();
}
}

52
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentLocationResponse.cs

@ -0,0 +1,52 @@
using LINYUN.Abp.Location.Tencent.Localization;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Location.Tencent.Response
{
public abstract class TencentLocationResponse
{
/// <summary>
/// 状态码,0为正常,
/// 310请求参数信息有误,
/// 311Key格式错误,
/// 306请求有护持信息请检查字符串,
/// 110请求来源未被授权
/// </summary>
[JsonProperty("status")]
public int Status { get; set; }
/// <summary>
/// 状态说明
/// </summary>
[JsonProperty("message")]
public string Message { get; set; }
/// <summary>
/// 本次请求的唯一标识
/// </summary>
[JsonProperty("request_id")]
public string RequestId { get; set; }
/// <summary>
/// 是否请求成功
/// </summary>
public bool IsSuccessed => Status.Equals(0);
public ILocalizableString GetErrorMessage()
{
switch (Status)
{
case 0:
return LocalizableString.Create<TencentLocationResource>("Message:RETURN_0");
case 110:
return LocalizableString.Create<TencentLocationResource>("Message:RETURN_110");
case 306:
return LocalizableString.Create<TencentLocationResource>("Message:RETURN_306");
case 310:
return LocalizableString.Create<TencentLocationResource>("Message:RETURN_310");
case 311:
return LocalizableString.Create<TencentLocationResource>("Message:RETURN_311");
default: throw new AbpException(Message);
}
}
}
}

14
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Response/TencentReGeocodeResponse.cs

@ -0,0 +1,14 @@
using LINGYUN.Abp.Location.Tencent.Model;
using Newtonsoft.Json;
namespace LINGYUN.Abp.Location.Tencent.Response
{
public class TencentReGeocodeResponse : TencentLocationResponse
{
/// <summary>
/// 逆地址解析结果
/// </summary>
[JsonProperty("result")]
public TencentReGeocode Result { get; set; } = new TencentReGeocode();
}
}

211
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpClient.cs

@ -0,0 +1,211 @@
using LINGYUN.Abp.Location.Tencent.Response;
using LINGYUN.Abp.Location.Tencent.Utils;
using LINYUN.Abp.Location.Tencent.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.Location.Tencent
{
public class TencentLocationHttpClient : ITransientDependency
{
protected TencentLocationOptions Options { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IServiceProvider ServiceProvider { get; }
protected IHttpClientFactory HttpClientFactory { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
public TencentLocationHttpClient(
IOptions<TencentLocationOptions> options,
IJsonSerializer jsonSerializer,
IServiceProvider serviceProvider,
IHttpClientFactory httpClientFactory,
ICancellationTokenProvider cancellationTokenProvider)
{
Options = options.Value;
JsonSerializer = jsonSerializer;
ServiceProvider = serviceProvider;
HttpClientFactory = httpClientFactory;
CancellationTokenProvider = cancellationTokenProvider;
}
public virtual async Task<IPGecodeLocation> IPGeocodeAsync(string ipAddress)
{
var requestParamters = new Dictionary<string, string>
{
{ "callback", Options.Callback },
{ "ip", ipAddress },
{ "key", Options.AccessKey },
{ "output", Options.Output }
};
var tencentMapUrl = "https://apis.map.qq.com";
var tencentMapPath = "/ws/location/v1/ip";
if (!Options.SecretKey.IsNullOrWhiteSpace())
{
var sig = TencentSecretKeyCaculater.CalcSecretKey(tencentMapPath, Options.SecretKey, requestParamters);
requestParamters.Add("sig", sig);
}
var tencentLocationResponse = await GetTencentMapResponseAsync<TencentIPGeocodeResponse>(tencentMapUrl, tencentMapPath, requestParamters);
var location = new IPGecodeLocation
{
IpAddress = tencentLocationResponse.Result.IpAddress,
AdCode = tencentLocationResponse.Result.AddressInfo.AdCode,
City = tencentLocationResponse.Result.AddressInfo.City,
Country = tencentLocationResponse.Result.AddressInfo.Nation,
District = tencentLocationResponse.Result.AddressInfo.District,
Location = new Location
{
Latitude = tencentLocationResponse.Result.Location.Lat,
Longitude = tencentLocationResponse.Result.Location.Lng
},
Province = tencentLocationResponse.Result.AddressInfo.Province
};
location.AddAdditional("TencentLocation", tencentLocationResponse.Result);
return location;
}
public virtual async Task<GecodeLocation> GeocodeAsync(string address, string city = null)
{
var requestParamters = new Dictionary<string, string>
{
{ "address", address },
{ "callback", Options.Callback },
{ "key", Options.AccessKey },
{ "output", Options.Output }
};
if (!city.IsNullOrWhiteSpace())
{
requestParamters.Add("region", city);
}
var tencentMapUrl = "https://apis.map.qq.com";
var tencentMapPath = "/ws/geocoder/v1";
if (!Options.SecretKey.IsNullOrWhiteSpace())
{
var sig = TencentSecretKeyCaculater.CalcSecretKey(tencentMapPath, Options.SecretKey, requestParamters);
requestParamters.Add("sig", sig);
}
var tencentLocationResponse = await GetTencentMapResponseAsync<TencentGeocodeResponse>(tencentMapUrl, tencentMapPath, requestParamters);
var location = new GecodeLocation
{
Confidence = tencentLocationResponse.Result.Reliability,
Latitude = tencentLocationResponse.Result.Location.Lat,
Longitude = tencentLocationResponse.Result.Location.Lng,
Level = tencentLocationResponse.Result.Level.ToString()
};
location.AddAdditional("TencentLocation", tencentLocationResponse.Result);
return location;
}
public virtual async Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 1000)
{
var requestParamters = new Dictionary<string, string>
{
{ "callback", Options.Callback },
{ "get_poi", Options.GetPoi },
{ "key", Options.AccessKey },
{ "location", $"{lat},{lng}" },
{ "output", Options.Output },
{ "poi_options", "radius=" + radius.ToString() }
};
var tencentMapUrl = "https://apis.map.qq.com";
var tencentMapPath = "/ws/geocoder/v1";
if (!Options.SecretKey.IsNullOrWhiteSpace())
{
var sig = TencentSecretKeyCaculater.CalcSecretKey(tencentMapPath, Options.SecretKey, requestParamters);
requestParamters.Add("sig", sig);
}
var tencentLocationResponse = await GetTencentMapResponseAsync<TencentReGeocodeResponse>(tencentMapUrl, tencentMapPath, requestParamters);
var location = new ReGeocodeLocation
{
Street = tencentLocationResponse.Result.AddressComponent.Street,
AdCode = tencentLocationResponse.Result.AddressInfo?.NationCode,
Address = tencentLocationResponse.Result.Address,
City = tencentLocationResponse.Result.AddressComponent.City,
Country = tencentLocationResponse.Result.AddressComponent.Nation,
District = tencentLocationResponse.Result.AddressComponent.District,
Number = tencentLocationResponse.Result.AddressComponent.StreetNumber,
Province = tencentLocationResponse.Result.AddressComponent.Province,
Town = tencentLocationResponse.Result.AddressReference.Town.Title,
Pois = tencentLocationResponse.Result.Pois.Select(p => new Poi
{
Address = p.Address,
Name = p.Title,
Tag = p.Id,
Type = p.CateGory
}).ToList()
};
location.AddAdditional("TencentLocation", tencentLocationResponse.Result);
return location;
}
protected virtual async Task<string> MakeRequestAndGetResultAsync(string url)
{
var client = HttpClientFactory.CreateClient(TencentLocationHttpConsts.HttpClientName);
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
var response = await client.SendAsync(requestMessage, GetCancellationToken());
if (!response.IsSuccessStatusCode)
{
throw new AbpException($"Tencent http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
}
var resultContent = await response.Content.ReadAsStringAsync();
return resultContent;
}
protected virtual CancellationToken GetCancellationToken()
{
return CancellationTokenProvider.Token;
}
protected virtual async Task<TResponse> GetTencentMapResponseAsync<TResponse>(string url, string path, IDictionary<string, string> paramters)
where TResponse : TencentLocationResponse
{
var requestUrl = BuildRequestUrl(url, path, paramters);
var responseContent = await MakeRequestAndGetResultAsync(requestUrl);
var tencentLocationResponse = JsonSerializer.Deserialize<TResponse>(responseContent);
if (!tencentLocationResponse.IsSuccessed)
{
if (Options.VisableErrorToClient)
{
var localizerFactory = ServiceProvider.GetRequiredService<IStringLocalizerFactory>();
var localizerErrorMessage = tencentLocationResponse.GetErrorMessage().Localize(localizerFactory);
var localizer = ServiceProvider.GetRequiredService<IStringLocalizer<TencentLocationResource>>();
localizerErrorMessage = localizer["ResolveLocationFailed", localizerErrorMessage];
throw new UserFriendlyException(localizerErrorMessage);
}
throw new AbpException($"Resolution address failed:{tencentLocationResponse.Message}!");
}
return tencentLocationResponse;
}
protected virtual string BuildRequestUrl(string uri, string path, IDictionary<string, string> paramters)
{
var requestUrlBuilder = new StringBuilder(128);
requestUrlBuilder.Append(uri);
requestUrlBuilder.Append(path).Append("?");
foreach (var paramter in paramters)
{
requestUrlBuilder.AppendFormat("{0}={1}", paramter.Key, paramter.Value);
requestUrlBuilder.Append("&");
}
requestUrlBuilder.Remove(requestUrlBuilder.Length - 1, 1);
return requestUrlBuilder.ToString();
}
}
}

7
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpConsts.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.Location.Tencent
{
public class TencentLocationHttpConsts
{
public const string HttpClientName = "TencentLocation";
}
}

12
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationOptions.cs

@ -0,0 +1,12 @@
namespace LINGYUN.Abp.Location.Tencent
{
public class TencentLocationOptions
{
public string AccessKey { get; set; }
public string SecretKey { get; set; }
public string GetPoi { get; set; } = "1";
public string Output { get; set; } = "JSON";
public string Callback { get; set; }
public bool VisableErrorToClient { get; set; } = false;
}
}

33
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationResolveProvider.cs

@ -0,0 +1,33 @@
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.Location.Tencent
{
[Dependency(ServiceLifetime.Transient)]
[ExposeServices(typeof(ILocationResolveProvider))]
public class TencentLocationResolveProvider : ILocationResolveProvider
{
protected TencentLocationHttpClient TencentLocationHttpClient { get; }
public TencentLocationResolveProvider(TencentLocationHttpClient tencentLocationHttpClient)
{
TencentLocationHttpClient = tencentLocationHttpClient;
}
public virtual async Task<IPGecodeLocation> IPGeocodeAsync(string ipAddress)
{
return await TencentLocationHttpClient.IPGeocodeAsync(ipAddress);
}
public virtual async Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 50)
{
return await TencentLocationHttpClient.ReGeocodeAsync(lat, lng, radius);
}
public virtual async Task<GecodeLocation> GeocodeAsync(string address, string city = null)
{
return await TencentLocationHttpClient.GeocodeAsync(address, city);
}
}
}

47
aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Utils/TencentSecretKeyCaculater.cs

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Abp.Location.Tencent.Utils
{
public class TencentSecretKeyCaculater
{
private static string MD5(string password)
{
try
{
System.Security.Cryptography.HashAlgorithm hash = System.Security.Cryptography.MD5.Create();
byte[] hash_out = hash.ComputeHash(Encoding.UTF8.GetBytes(password));
var md5_str = BitConverter.ToString(hash_out).Replace("-", "");
return md5_str.ToLower();
}
catch
{
throw;
}
}
private static string HttpBuildQuery(IDictionary<string, string> querystring_arrays)
{
StringBuilder sb = new StringBuilder();
foreach (var item in querystring_arrays)
{
sb.Append(item.Key);
sb.Append("=");
sb.Append(item.Value);
sb.Append("&");
}
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
public static string CalcSecretKey(string url, string secretKey, IDictionary<string, string> querystring_arrays)
{
var queryString = HttpBuildQuery(querystring_arrays);
return MD5(url + "?" + queryString + secretKey);
}
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ILocationResolveProvider.cs

@ -4,6 +4,8 @@ namespace LINGYUN.Abp.Location
{ {
public interface ILocationResolveProvider public interface ILocationResolveProvider
{ {
Task<IPGecodeLocation> IPGeocodeAsync(string ipAddress);
Task<GecodeLocation> GeocodeAsync(string address, string city = null); Task<GecodeLocation> GeocodeAsync(string address, string city = null);
Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 50); Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int radius = 50);

43
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/IPGecodeLocation.cs

@ -0,0 +1,43 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.Location
{
public class IPGecodeLocation
{
/// <summary>
/// IP地址
/// </summary>
public string IpAddress { get; set; }
/// <summary>
/// 定位坐标
/// </summary>
public Location Location { get; set; } = new Location();
/// <summary>
/// 国家
/// </summary>
public string Country { get; set; }
/// <summary>
/// 城市
/// </summary>
public string City { get; set; }
/// <summary>
/// 省份
/// </summary>
public string Province { get; set; }
/// <summary>
/// 区县
/// </summary>
public string District { get; set; }
/// <summary>
/// adcode
/// </summary>
public string AdCode { get; set; }
public IDictionary<string, object> Additionals { get; } = new Dictionary<string, object>();
public void AddAdditional(string key, object value)
{
Additionals.Add(key, value);
}
}
}

10
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/Controllers/LocationController.cs

@ -17,6 +17,14 @@ namespace LINGYUN.Platform.Controllers
LocationResolveProvider = locationResolveProvider; LocationResolveProvider = locationResolveProvider;
} }
[HttpGet]
[Route("IpGeocode")]
public async Task<IPGecodeLocation> IPGeocodeAsync(string ipAddress)
{
var location = await LocationResolveProvider.IPGeocodeAsync(ipAddress);
return location;
}
[HttpGet] [HttpGet]
[Route("Geocode")] [Route("Geocode")]
public async Task<GecodeLocation> GeocodeAsync(string address) public async Task<GecodeLocation> GeocodeAsync(string address)
@ -28,7 +36,7 @@ namespace LINGYUN.Platform.Controllers
[HttpGet] [HttpGet]
[Route("ReGeocode")] [Route("ReGeocode")]
public async Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng) public async Task<ReGeocodeLocation> ReGeocodeAsync(double lat, double lng, int redius = 50)
{ {
var location = await LocationResolveProvider.ReGeocodeAsync(lat, lng); var location = await LocationResolveProvider.ReGeocodeAsync(lat, lng);
return location; return location;

2
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj

@ -64,7 +64,7 @@
<ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.Application.Contracts\LINGYUN.ApiGateway.Application.Contracts.csproj" /> <ProjectReference Include="..\..\..\modules\apigateway\LINGYUN.ApiGateway.Application.Contracts\LINGYUN.ApiGateway.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Location.Baidu\LINGYUN.Abp.Location.Baidu.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Location.Tencent\LINGYUN.Abp.Location.Tencent.csproj" />
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.Application.Contracts\LINGYUN.Abp.MessageService.Application.Contracts.csproj" /> <ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.Application.Contracts\LINGYUN.Abp.MessageService.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj" /> <ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj" />
<ProjectReference Include="..\..\..\modules\identityServer\LINGYUN.Abp.IdentityServer.Application\LINGYUN.Abp.IdentityServer.Application.csproj" /> <ProjectReference Include="..\..\..\modules\identityServer\LINGYUN.Abp.IdentityServer.Application\LINGYUN.Abp.IdentityServer.Application.csproj" />

4
aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/PlatformHttpApiHostModule.cs

@ -4,7 +4,7 @@ using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.IdentityServer; using LINGYUN.Abp.IdentityServer;
using LINGYUN.Abp.Location.Baidu; using LINGYUN.Abp.Location.Tencent;
using LINGYUN.Abp.MessageService; using LINGYUN.Abp.MessageService;
using LINGYUN.Abp.SettingManagement; using LINGYUN.Abp.SettingManagement;
using LINGYUN.Abp.TenantManagement; using LINGYUN.Abp.TenantManagement;
@ -82,7 +82,7 @@ namespace LINGYUN.Platform
typeof(AbpCAPEventBusModule), typeof(AbpCAPEventBusModule),
typeof(AbpAliyunSmsModule), typeof(AbpAliyunSmsModule),
#if DEBUG #if DEBUG
typeof(AbpBaiduLocationModule), typeof(AbpTencentLocationModule),
#endif #endif
typeof(AbpAutofacModule) typeof(AbpAutofacModule)
)] )]

Loading…
Cancel
Save