diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 86ec35372..0d0459cd5 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -284,7 +284,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.F EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.SettingManagement", "modules\oss-management\LINGYUN.Abp.OssManagement.SettingManagement\LINGYUN.Abp.OssManagement.SettingManagement.csproj", "{BD74BE00-54E4-4979-8797-E8027695F396}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Features.LimitValidation.Redis.Client", "modules\common\LINGYUN.Abp.Features.LimitValidation.Redis.Client\LINGYUN.Abp.Features.LimitValidation.Redis.Client.csproj", "{48DE251A-3482-4934-BC26-F99D2235AC9F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Features.LimitValidation.Redis.Client", "modules\common\LINGYUN.Abp.Features.LimitValidation.Redis.Client\LINGYUN.Abp.Features.LimitValidation.Redis.Client.csproj", "{48DE251A-3482-4934-BC26-F99D2235AC9F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Location.Tencent.Tests", "tests\LINGYUN.Abp.Location.Tencent.Tests\LINGYUN.Abp.Location.Tencent.Tests.csproj", "{94B47385-E47F-4FD7-A3A9-A7AA122EFC93}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Location.Baidu.Tests", "tests\LINGYUN.Abp.Location.Baidu.Tests\LINGYUN.Abp.Location.Baidu.Tests.csproj", "{C892CD81-50AE-49E5-BF44-A0C28A1614CC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -752,6 +756,14 @@ Global {48DE251A-3482-4934-BC26-F99D2235AC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {48DE251A-3482-4934-BC26-F99D2235AC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU {48DE251A-3482-4934-BC26-F99D2235AC9F}.Release|Any CPU.Build.0 = Release|Any CPU + {94B47385-E47F-4FD7-A3A9-A7AA122EFC93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {94B47385-E47F-4FD7-A3A9-A7AA122EFC93}.Debug|Any CPU.Build.0 = Debug|Any CPU + {94B47385-E47F-4FD7-A3A9-A7AA122EFC93}.Release|Any CPU.ActiveCfg = Release|Any CPU + {94B47385-E47F-4FD7-A3A9-A7AA122EFC93}.Release|Any CPU.Build.0 = Release|Any CPU + {C892CD81-50AE-49E5-BF44-A0C28A1614CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C892CD81-50AE-49E5-BF44-A0C28A1614CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C892CD81-50AE-49E5-BF44-A0C28A1614CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C892CD81-50AE-49E5-BF44-A0C28A1614CC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -894,6 +906,8 @@ Global {3E5EBCEC-78C9-4A1A-BF04-A216AA6A921F} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} {BD74BE00-54E4-4979-8797-E8027695F396} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} {48DE251A-3482-4934-BC26-F99D2235AC9F} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} + {94B47385-E47F-4FD7-A3A9-A7AA122EFC93} = {370D7CD5-1E17-4F3D-BBFA-03429F6D4F2F} + {C892CD81-50AE-49E5-BF44-A0C28A1614CC} = {370D7CD5-1E17-4F3D-BBFA-03429F6D4F2F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/LINGYUN.MicroService.Common.sln b/aspnet-core/LINGYUN.MicroService.Common.sln index bd2ebe432..e9df59cff 100644 --- a/aspnet-core/LINGYUN.MicroService.Common.sln +++ b/aspnet-core/LINGYUN.MicroService.Common.sln @@ -111,6 +111,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Aliyun.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Sms.Aliyun.Tests", "tests\LINGYUN.Abp.Sms.Aliyun.Tests\LINGYUN.Abp.Sms.Aliyun.Tests.csproj", "{93DD5A05-B67A-4E11-BB56-F6B4E7F1489C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Location.Baidu.Tests", "tests\LINGYUN.Abp.Location.Baidu.Tests\LINGYUN.Abp.Location.Baidu.Tests.csproj", "{221725FF-6C01-4F41-9F29-AC04C7D52611}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Location.Tencent.Tests", "tests\LINGYUN.Abp.Location.Tencent.Tests\LINGYUN.Abp.Location.Tencent.Tests.csproj", "{1B494EA1-28CF-4A61-B0BE-70BBA425C316}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -289,6 +293,14 @@ Global {93DD5A05-B67A-4E11-BB56-F6B4E7F1489C}.Debug|Any CPU.Build.0 = Debug|Any CPU {93DD5A05-B67A-4E11-BB56-F6B4E7F1489C}.Release|Any CPU.ActiveCfg = Release|Any CPU {93DD5A05-B67A-4E11-BB56-F6B4E7F1489C}.Release|Any CPU.Build.0 = Release|Any CPU + {221725FF-6C01-4F41-9F29-AC04C7D52611}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {221725FF-6C01-4F41-9F29-AC04C7D52611}.Debug|Any CPU.Build.0 = Debug|Any CPU + {221725FF-6C01-4F41-9F29-AC04C7D52611}.Release|Any CPU.ActiveCfg = Release|Any CPU + {221725FF-6C01-4F41-9F29-AC04C7D52611}.Release|Any CPU.Build.0 = Release|Any CPU + {1B494EA1-28CF-4A61-B0BE-70BBA425C316}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B494EA1-28CF-4A61-B0BE-70BBA425C316}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B494EA1-28CF-4A61-B0BE-70BBA425C316}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B494EA1-28CF-4A61-B0BE-70BBA425C316}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -346,6 +358,8 @@ Global {8FB74B18-CA5C-4DC3-8DFA-600133A05712} = {8D2AD50B-DD4B-48A2-88EC-0E8E8236D883} {3DBF0975-B09D-49CA-9AF8-69175EDB9D52} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} {93DD5A05-B67A-4E11-BB56-F6B4E7F1489C} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} + {221725FF-6C01-4F41-9F29-AC04C7D52611} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} + {1B494EA1-28CF-4A61-B0BE-70BBA425C316} = {B86C21A4-73B7-471E-B73A-B4B905EC9435} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/AbpBaiduLocationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/AbpBaiduLocationModule.cs index 8971597d4..cc2dc5991 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/AbpBaiduLocationModule.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/AbpBaiduLocationModule.cs @@ -5,13 +5,15 @@ using System; using Volo.Abp.Json; using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.Threading; using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.Location.Baidu { [DependsOn( - typeof(AbpLocationModule), - typeof(AbpJsonModule))] + typeof(AbpLocationModule), + typeof(AbpJsonModule), + typeof(AbpThreadingModule))] public class AbpBaiduLocationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationHttpClient.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationHttpClient.cs index f7f5864a7..bd977d743 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationHttpClient.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationHttpClient.cs @@ -40,6 +40,54 @@ namespace LINGYUN.Abp.Location.Baidu CancellationTokenProvider = cancellationTokenProvider; } + public virtual async Task IPGeocodeAsync(string ipAddress) + { + var requestParamters = new Dictionary + { + { "ip", ipAddress }, + { "ak", Options.AccessKey }, + { "coor", Options.CoordType } + }; + var baiduMapUrl = "http://api.map.baidu.com"; + var baiduMapPath = "/location/ip"; + if (Options.CaculateAKSN) + { + // TODO: 百度的文档不明不白,sn的算法在遇到特殊字符会验证失败,有待完善 + var sn = BaiduAKSNCaculater.CaculateAKSN(Options.AccessSecret, baiduMapPath, requestParamters); + requestParamters.Add("sn", sn); + } + var requestUrl = BuildRequestUrl(baiduMapUrl, baiduMapPath, requestParamters); + var responseContent = await MakeRequestAndGetResultAsync(requestUrl); + var baiduLocationResponse = JsonSerializer.Deserialize(responseContent); + if (!baiduLocationResponse.IsSuccess()) + { + var localizerFactory = ServiceProvider.GetRequiredService(); + var localizerErrorMessage = baiduLocationResponse.GetErrorMessage(Options.VisableErrorToClient).Localize(localizerFactory); + var localizerErrorDescription = baiduLocationResponse.GetErrorMessage(Options.VisableErrorToClient).Localize(localizerFactory); + var localizer = ServiceProvider.GetRequiredService>(); + localizerErrorMessage = localizer["ResolveLocationFailed", localizerErrorMessage, localizerErrorDescription]; + if (Options.VisableErrorToClient) + { + throw new UserFriendlyException(localizerErrorMessage); + } + throw new AbpException($"Resolution address failed:{localizerErrorMessage}!"); + } + var location = new IPGecodeLocation + { + Province = baiduLocationResponse.Content.AddressDetail?.Province, + City = baiduLocationResponse.Content.AddressDetail?.City, + AdCode = baiduLocationResponse.Content.AddressDetail?.CityCode.ToString(), + }; + var point = baiduLocationResponse.Content.Point.ToPoint(); + location.Location.Latitude = point.Y; + location.Location.Longitude = point.X; + + location.AddAdditional("Address", baiduLocationResponse.Address); + location.AddAdditional("Content", baiduLocationResponse.Content); + + return location; + } + public virtual async Task GeocodeAsync(string address, string city = null) { var requestParamters = new Dictionary @@ -133,25 +181,42 @@ namespace LINGYUN.Abp.Location.Baidu { Street = baiduLocationResponse.Result.AddressComponent.Street, AdCode = baiduLocationResponse.Result.AddressComponent.AdCode.ToString(), - Address = baiduLocationResponse.Result.Address, + Address = baiduLocationResponse.Result.FormattedAddress, + FormattedAddress = baiduLocationResponse.Result.SematicDescription, City = baiduLocationResponse.Result.AddressComponent.City, Country = baiduLocationResponse.Result.AddressComponent.Country, District = baiduLocationResponse.Result.AddressComponent.District, Number = baiduLocationResponse.Result.AddressComponent.StreetNumber, Province = baiduLocationResponse.Result.AddressComponent.Province, Town = baiduLocationResponse.Result.AddressComponent.Town, - Pois = baiduLocationResponse.Result.Pois.Select(p => new Poi + Pois = baiduLocationResponse.Result.Pois.Select(p => { - Address = p.Address, - Name = p.Name, - Tag = p.Tag, - Type = p.PoiType + var poi = new Poi + { + Address = p.Address, + Name = p.Name, + Tag = p.Tag, + Type = p.PoiType + }; + if (int.TryParse(p.Distance, out int distance)) + { + poi.Distance = distance; + } + + return poi; }).ToList(), Roads = baiduLocationResponse.Result.Roads.Select(r => new Road { Name = r.Name }).ToList() }; + // 如果存在Poi组,取最近的一个poi作为实际地址 + if (location.Pois.Any()) + { + var nearPoi = location.Pois.OrderBy(x => x.Distance).FirstOrDefault(); + location.Address = nearPoi.Address; + location.FormattedAddress = nearPoi.Name; + } location.AddAdditional("BaiduLocation", baiduLocationResponse.Result); return location; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationOptions.cs index c0283b8e7..7140a297b 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationOptions.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationOptions.cs @@ -35,7 +35,7 @@ namespace LINGYUN.Abp.Location.Baidu /// extensions_poi=1,返回pois数据, /// 默认显示周边1000米内的poi。 /// - public string ExtensionsPoi { get; set; } = "0"; + public string ExtensionsPoi { get; set; } = "1"; /// /// 当取值为true时,召回坐标周围最近的3条道路数据。 /// 区别于行政区划中的street参数(street参数为行政区划中的街道,和普通道路不对应) diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProvider.cs index 1348703c1..9c34d83d4 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProvider.cs @@ -15,9 +15,9 @@ namespace LINGYUN.Abp.Location.Baidu BaiduLocationHttpClient = baiduHttpRequestClient; } - public virtual Task IPGeocodeAsync(string ipAddress) + public virtual async Task IPGeocodeAsync(string ipAddress) { - return Task.FromResult(new IPGecodeLocation()); + return await BaiduLocationHttpClient.IPGeocodeAsync(ipAddress); } public virtual async Task ReGeocodeAsync(double lat, double lng, int radius = 50) diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressComponent.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressComponent.cs index 3ec32d0ba..5018da4f4 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressComponent.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressComponent.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Text.Json.Serialization; namespace LINGYUN.Abp.Location.Baidu.Model { @@ -15,16 +16,19 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 国家国家编码 /// [JsonProperty("country_code")] + [JsonPropertyName("country_code")] public int CountryCode { get; set; } /// /// 国家英文缩写(三位) /// [JsonProperty("country_code_iso")] + [JsonPropertyName("country_code_iso")] public string CountryCodeIso { get; set; } /// /// 国家英文缩写(两位) /// [JsonProperty("country_code_iso2")] + [JsonPropertyName("country_code_iso2")] public string CountryCodeIso2 { get; set; } /// /// 省名 @@ -40,6 +44,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// country、province、city、district、town分别对应0-4级,若city_level=3,则district层级为该国家的city层级) /// [JsonProperty("city_level")] + [JsonPropertyName("city_level")] public int CityLevel { get; set; } /// /// 区县名 @@ -53,6 +58,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 乡镇id /// [JsonProperty("town_code")] + [JsonPropertyName("town_code")] public string TownCode { get; set; } /// /// 街道名(行政区划中的街道层级) @@ -62,6 +68,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 街道门牌号 /// [JsonProperty("street_number")] + [JsonPropertyName("street_number")] public string StreetNumber { get; set; } /// /// 行政区划代码 diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressDetail.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressDetail.cs new file mode 100644 index 000000000..e8c3ea16f --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/AddressDetail.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace LINGYUN.Abp.Location.Baidu.Model +{ + public class AddressDetail + { + [JsonProperty("city")] + [JsonPropertyName("city")] + public string City { get; set; } + + [JsonProperty("city_code")] + [JsonPropertyName("city_code")] + public int CityCode { get; set; } + + [JsonProperty("province")] + [JsonPropertyName("province")] + public string Province { get; set; } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduPoi.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduPoi.cs index b370f8093..a52800469 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduPoi.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduPoi.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace LINGYUN.Abp.Location.Baidu.Model { @@ -8,6 +9,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 地址信息 /// [JsonProperty("addr")] + [JsonPropertyName("addr")] public string Address { get; set; } /// /// 名称 @@ -38,6 +40,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 电话 /// [JsonProperty("tel")] + [JsonPropertyName("tel")] public string TelPhone { get; set; } /// /// poi唯一标识 @@ -47,12 +50,14 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 邮编 /// [JsonProperty("zip")] + [JsonPropertyName("zip")] public string Post { get; set; } /// /// poi对应的主点poi(如,海底捞的主点为上地华联,该字段则为上地华联的poi信息。 /// 如无,该字段为空),包含子字段和pois基础召回字段相同。 /// - [JsonProperty("parent_poi")] + [JsonProperty("parent_poi")] + [JsonPropertyName("parent_poi")] public BaiduPoi ParentPoi { get; set; } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduReGeocode.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduReGeocode.cs index 969854caf..b8385a0ba 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduReGeocode.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/BaiduReGeocode.cs @@ -1,15 +1,23 @@ using Newtonsoft.Json; using System.Collections.Generic; +using System.Text.Json.Serialization; namespace LINGYUN.Abp.Location.Baidu.Model { public class BaiduReGeocode { + /// + /// 经纬度坐标 + /// + [JsonProperty("location")] + [JsonPropertyName("location")] + public BaiduLocation Location { get; set; } /// /// 结构化地址信息 /// [JsonProperty("formatted_address")] - public string Address { get; set; } + [JsonPropertyName("formatted_address")] + public string FormattedAddress { get; set; } /// /// 坐标所在商圈信息,如 "人民大学,中关村,苏州街"。 /// 最多返回3个。 @@ -35,6 +43,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 当前位置结合POI的语义化结果描述 /// [JsonProperty("sematic_description")] + [JsonPropertyName("sematic_description")] public string SematicDescription { get; set; } public BaiduReGeocode() { diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/Content.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/Content.cs new file mode 100644 index 000000000..1efd2b74b --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/Content.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; +using System.Text.Json.Serialization; + +namespace LINGYUN.Abp.Location.Baidu.Model +{ + public class Content + { + public string Address { get; set; } + + [JsonProperty("address_detail")] + [JsonPropertyName("address_detail")] + public AddressDetail AddressDetail { get; set; } = new AddressDetail(); + + public IpPoint Point { get; set; } = new IpPoint(); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/IpPoint.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/IpPoint.cs new file mode 100644 index 000000000..0fff0e04c --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/IpPoint.cs @@ -0,0 +1,29 @@ +using System; + +namespace LINGYUN.Abp.Location.Baidu.Model +{ + public class IpPoint + { + public string X { get; set; } + public string Y { get; set; } + + public Point ToPoint() + { + if (!X.IsNullOrWhiteSpace() && + !Y.IsNullOrWhiteSpace()) + { + if (float.TryParse(X, out float x) && + float.TryParse(Y, out float y)) + { + return new Point + { + X = x, + Y = y + }; + } + } + + return new Point(); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/PoiRegion.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/PoiRegion.cs index bc487ad11..0bd757462 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/PoiRegion.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Model/PoiRegion.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace LINGYUN.Abp.Location.Baidu.Model { @@ -19,6 +20,7 @@ namespace LINGYUN.Abp.Location.Baidu.Model /// 请求中的坐标与所归属区域面的相对位置关系 /// [JsonProperty("direction_desc")] + [JsonPropertyName("direction_desc")] public string DirectionDesc { get; set; } /// /// poi唯一标识 diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Response/BaiduIpGeocodeResponse.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Response/BaiduIpGeocodeResponse.cs new file mode 100644 index 000000000..ef3d4cab7 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Response/BaiduIpGeocodeResponse.cs @@ -0,0 +1,11 @@ +using LINGYUN.Abp.Location.Baidu.Model; + +namespace LINGYUN.Abp.Location.Baidu.Response +{ + public class BaiduIpGeocodeResponse : BaiduLocationResponse + { + public string Address { get; set; } + + public Content Content { get; set; } = new Content(); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/AbpTencentLocationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/AbpTencentLocationModule.cs index 33eb3254d..8e918b6c8 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/AbpTencentLocationModule.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/AbpTencentLocationModule.cs @@ -2,13 +2,18 @@ using Microsoft.Extensions.DependencyInjection; using Polly; using System; +using Volo.Abp.Json; using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.Threading; using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.Location.Tencent { - [DependsOn(typeof(AbpLocationModule))] + [DependsOn( + typeof(AbpLocationModule), + typeof(AbpJsonModule), + typeof(AbpThreadingModule))] public class AbpTencentLocationModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Poi.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Poi.cs index 15a87000a..9849ab8ae 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Poi.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/Model/Poi.cs @@ -36,7 +36,7 @@ namespace LINGYUN.Abp.Location.Tencent.Model /// 该POI到逆地址解析传入的坐标的直线距离 /// [JsonProperty("_distance")] - public string Distance { get; set; } + public double Distance { get; set; } /// /// 行政区划信息 /// diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpClient.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpClient.cs index c346d1403..cf15b4b9c 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpClient.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location.Tencent/LINGYUN/Abp/Location/Tencent/TencentLocationHttpClient.cs @@ -134,20 +134,35 @@ namespace LINGYUN.Abp.Location.Tencent Street = tencentLocationResponse.Result.AddressComponent.Street, AdCode = tencentLocationResponse.Result.AddressInfo?.NationCode, Address = tencentLocationResponse.Result.Address, + FormattedAddress = tencentLocationResponse.Result.FormattedAddress?.ReCommend, 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 + Pois = tencentLocationResponse.Result.Pois.Select(p => { - Address = p.Address, - Name = p.Title, - Tag = p.Id, - Type = p.CateGory + var poi = new Poi + { + Address = p.Address, + Name = p.Title, + Tag = p.Id, + Type = p.CateGory, + Distance = Convert.ToInt32(p.Distance) + }; + + return poi; }).ToList() }; + if ((location.Address.IsNullOrWhiteSpace() || + location.FormattedAddress.IsNullOrWhiteSpace()) && + location.Pois.Any()) + { + var nearPoi = location.Pois.OrderBy(x => x.Distance).FirstOrDefault(); + location.Address = nearPoi.Address; + location.FormattedAddress = nearPoi.Name; + } location.AddAdditional("TencentLocation", tencentLocationResponse.Result); return location; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Poi.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Poi.cs index 271229f3a..d110a0744 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Poi.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Poi.cs @@ -6,5 +6,6 @@ public string Name { get; set; } public string Type { get; set; } public string Address { get; set; } + public int? Distance { get; set; } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ReGeocodeLocation.cs b/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ReGeocodeLocation.cs index daee2609e..45908ceef 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ReGeocodeLocation.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ReGeocodeLocation.cs @@ -12,6 +12,10 @@ namespace LINGYUN.Abp.Location /// public string Address { get; set; } /// + /// 格式化的地址描述 + /// + public string FormattedAddress { get; set; } + /// /// 国家 /// public string Country { get; set; } diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN.Abp.Location.Baidu.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN.Abp.Location.Baidu.Tests.csproj new file mode 100644 index 000000000..b04e5828d --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN.Abp.Location.Baidu.Tests.csproj @@ -0,0 +1,27 @@ + + + + net5.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/AbpLocationBaiduTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/AbpLocationBaiduTestBase.cs new file mode 100644 index 000000000..9f1aff69c --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/AbpLocationBaiduTestBase.cs @@ -0,0 +1,9 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.Location.Baidu +{ + public class AbpLocationBaiduTestBase : AbpTestsBase + { + + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/AbpLocationBaiduTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/AbpLocationBaiduTestModule.cs new file mode 100644 index 000000000..559886ab9 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/AbpLocationBaiduTestModule.cs @@ -0,0 +1,24 @@ +using LINGYUN.Abp.Tests; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Location.Baidu +{ + [DependsOn( + typeof(AbpBaiduLocationModule), + typeof(AbpTestsBaseModule))] + public class AbpLocationBaiduTestModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configurationOptions = new AbpConfigurationBuilderOptions + { + BasePath = @"D:\Projects\Development\Abp\Location\Baidu", + EnvironmentName = "Development" + }; + + context.Services.ReplaceConfiguration(ConfigurationHelper.BuildConfiguration(configurationOptions)); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProviderTests.cs b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProviderTests.cs new file mode 100644 index 000000000..b60a5036c --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Baidu.Tests/LINGYUN/Abp/Location/Baidu/BaiduLocationResolveProviderTests.cs @@ -0,0 +1,58 @@ +using Shouldly; +using System.Threading.Tasks; +using Xunit; + +namespace LINGYUN.Abp.Location.Baidu +{ + public class BaiduLocationResolveProviderTests : AbpLocationBaiduTestBase + { + private readonly ILocationResolveProvider _provider; + + public BaiduLocationResolveProviderTests() + { + _provider = GetRequiredService(); + _provider.ShouldBeOfType(); + } + + [Theory] + [InlineData(39.906049, 116.398773, 1000)] + public async Task ReGeocode_Test(double lat, double lng, int radius = 50) + { + var location = await _provider.ReGeocodeAsync(lat, lng, radius); + + location.ShouldNotBeNull(); + location.Address.ShouldBe("北京市西城区前门西大街正阳市场4号楼"); + location.FormattedAddress.ShouldBe("前门西大街正阳市场4号楼"); + + // TODO + } + + [Theory] + [InlineData("北京市东城区广场东侧路", "北京")] + public async Task Geocode_Test(string address, string city = "") + { + var location = await _provider.GeocodeAsync(address, city); + + location.ShouldNotBeNull(); + location.Latitude.ShouldBe(39.91125781161926); + location.Longitude.ShouldBe(116.40588581321788); + location.Level.ShouldBe("道路"); + location.Pomprehension.ShouldBe(0); + + // TODO + } + + [Theory] + [InlineData("111.206.145.41")] + public async Task IPGeocode_Test(string ipAddress) + { + var location = await _provider.IPGeocodeAsync(ipAddress); + + location.ShouldNotBeNull(); + location.Location.Latitude.ShouldBe(39.91489028930664); + location.Location.Longitude.ShouldBe(116.40387725830078); + + // TODO + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN.Abp.Location.Tencent.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN.Abp.Location.Tencent.Tests.csproj new file mode 100644 index 000000000..c76c30559 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN.Abp.Location.Tencent.Tests.csproj @@ -0,0 +1,27 @@ + + + + net5.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/AbpLocationTencentTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/AbpLocationTencentTestBase.cs new file mode 100644 index 000000000..258ce06a6 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/AbpLocationTencentTestBase.cs @@ -0,0 +1,9 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.Location.Tencent +{ + public class AbpLocationTencentTestBase : AbpTestsBase + { + + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/AbpLocationTencentTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/AbpLocationTencentTestModule.cs new file mode 100644 index 000000000..0f5cb2044 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/AbpLocationTencentTestModule.cs @@ -0,0 +1,24 @@ +using LINGYUN.Abp.Tests; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Location.Tencent +{ + [DependsOn( + typeof(AbpTencentLocationModule), + typeof(AbpTestsBaseModule))] + public class AbpLocationTencentTestModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + var configurationOptions = new AbpConfigurationBuilderOptions + { + BasePath = @"D:\Projects\Development\Abp\Location\Tencent", + EnvironmentName = "Development" + }; + + context.Services.ReplaceConfiguration(ConfigurationHelper.BuildConfiguration(configurationOptions)); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/TencentLocationResolveProviderTests.cs b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/TencentLocationResolveProviderTests.cs new file mode 100644 index 000000000..b403f28c6 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.Location.Tencent.Tests/LINGYUN/Abp/Location/Tencent/TencentLocationResolveProviderTests.cs @@ -0,0 +1,58 @@ +using Shouldly; +using System.Threading.Tasks; +using Xunit; + +namespace LINGYUN.Abp.Location.Tencent +{ + public class TencentLocationResolveProviderTests : AbpLocationTencentTestBase + { + private readonly ILocationResolveProvider _provider; + + public TencentLocationResolveProviderTests() + { + _provider = GetRequiredService(); + _provider.ShouldBeOfType(); + } + + [Theory] + [InlineData(39.906049, 116.398773, 1000)] + public async Task ReGeocode_Test(double lat, double lng, int radius = 50) + { + var location = await _provider.ReGeocodeAsync(lat, lng, radius); + + location.ShouldNotBeNull(); + location.Address.ShouldBe("北京市东城区东长安街"); + location.FormattedAddress.ShouldBe("天安门广场"); + + // TODO + } + + [Theory] + [InlineData("北京市东城区广场东侧路")] + public async Task Geocode_Test(string address, string city = "") + { + var location = await _provider.GeocodeAsync(address, city); + + location.ShouldNotBeNull(); + location.Latitude.ShouldBe(39.907631); + location.Longitude.ShouldBe(116.399384); + location.Level.ShouldBe("7"); + location.Pomprehension.ShouldBe(0); + + // TODO + } + + [Theory] + [InlineData("111.206.145.41")] + public async Task IPGeocode_Test(string ipAddress) + { + var location = await _provider.IPGeocodeAsync(ipAddress); + + location.ShouldNotBeNull(); + location.Location.Latitude.ShouldBe(40.0403); + location.Location.Longitude.ShouldBe(116.2734); + + // TODO + } + } +} diff --git a/build/build-aspnetcore-common.ps1 b/build/build-aspnetcore-common.ps1 index c833493bd..c689cfbbf 100644 --- a/build/build-aspnetcore-common.ps1 +++ b/build/build-aspnetcore-common.ps1 @@ -3,15 +3,15 @@ $rootFolder = (Get-Item -Path "./" -Verbose).FullName # List of solutions used only in development mode -$batchCommandPaths = @( - "../aspnet-core/services/start-auth-server.bat", - "../aspnet-core/services/start-identity-server.bat", - "../aspnet-core/services/start-backend-admin.bat", - "../aspnet-core/services/start-apigateway-host.bat", - "../aspnet-core/services/start-apigateway-admin.bat", - "../aspnet-core/services/start-messages.bat", - "../aspnet-core/services/start-platform.bat" - ) +[PsObject[]]$serviceArray = @() + +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/account/AuthServer.Host"; Service = "identityserver" } +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/admin/LINGYUN.Abp.BackendAdmin.HttpApi.Host"; Service = "admin" } +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/identity-server/LINGYUN.Abp.IdentityServer4.HttpApi.Host"; Service = "identityserver4-admin" } +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host"; Service = "apigateway-host" } +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host"; Service = "apigateway-admin" } +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host"; Service = "messages" } +$serviceArray += [PsObject]@{ Path = $rootFolder + "/../aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host"; Service = "platform" } Write-host "" Write-host ":::::::::::::: !!! You are in development mode !!! ::::::::::::::" -ForegroundColor red -BackgroundColor yellow diff --git a/build/build-aspnetcore-ef-update.ps1 b/build/build-aspnetcore-ef-update.ps1 index 55dc70a6a..626935f6e 100644 --- a/build/build-aspnetcore-ef-update.ps1 +++ b/build/build-aspnetcore-ef-update.ps1 @@ -1,11 +1,9 @@ . "./build-aspnetcore-common.ps1" # Build all solutions -foreach ($batchCommandPath in $batchCommandPaths) { - $file = [io.fileinfo]$batchCommandPath; - Write-Host $file.DirectoryName - Set-Location $file.DirectoryName - CMD /c $file.Name --ef-u -Wait +foreach ($service in $serviceArray) { + Set-Location $service.Path + dotnet ef database update } Set-Location $rootFolder \ No newline at end of file diff --git a/build/build-aspnetcore-release.ps1 b/build/build-aspnetcore-release.ps1 index f5a1f37df..5c25845f8 100644 --- a/build/build-aspnetcore-release.ps1 +++ b/build/build-aspnetcore-release.ps1 @@ -1,11 +1,10 @@ . "./build-aspnetcore-common.ps1" # Build all solutions -foreach ($batchCommandPath in $batchCommandPaths) { - $file = [io.fileinfo]$batchCommandPath; - Write-Host $file.DirectoryName - Set-Location $file.DirectoryName - CMD /c $file.Name --publish -Wait +foreach ($service in $serviceArray) { + Set-Location $service.Path + $publishPath = $service.Path + "/../../Publish/" + $service.Service + dotnet publish -c Release -o $publishPath --no-cache --no-restore } Set-Location $rootFolder \ No newline at end of file