Browse Source

增加地址解析模块;变更Abp.Cap过期消息清理为可配置任务

pull/1/head
cKey 6 years ago
parent
commit
04290042ec
  1. 1
      aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application.Contracts/LINGYUN/ApiGateway/Ocelot/Dto/RouteGroupCreateDto.cs
  2. 6
      aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application/LINGYUN/ApiGateway/Ocelot/RouteGroupAppService.cs
  3. 74
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/Processor/AbpCapExpiresMessageCleanupBackgroundWorker.cs
  4. 115
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/Processor/AbpCapProcessingServer.cs
  5. 1
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.csproj
  6. 88
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml
  7. 23
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/AbpCAPEventBusModule.cs
  8. 19
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/MessageCleanupOptions.cs
  9. 14
      aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs
  10. 12
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN.Abp.Location.Baidu.csproj
  11. 15
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduInverseLocationResponse.cs
  12. 11
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduLocationHttpClient.cs
  13. 14
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduLocationResponse.cs
  14. 10
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduPositiveLocationResponse.cs
  15. 8
      aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/Location.cs
  16. 12
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN.Abp.Location.csproj
  17. 8
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/AbpLocationModule.cs
  18. 9
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/ILocationResolveProvider.cs
  19. 45
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/InverseLocation.cs
  20. 97
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Location.cs
  21. 55
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Position.cs
  22. 27
      aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/PositiveLocation.cs
  23. 11
      vueJs/src/App.vue
  24. 10
      vueJs/src/api/abpconfiguration.ts
  25. 4
      vueJs/src/api/apigateway.ts
  26. 3
      vueJs/src/lang/zh.ts
  27. 16
      vueJs/src/utils/localStorage.ts
  28. 7
      vueJs/src/views/admin/apigateway/components/GlobalCreateOrEditForm.vue
  29. 4
      vueJs/src/views/admin/apigateway/components/RouteGroupCreateOrEditForm.vue
  30. 57
      vueJs/src/views/login/components/TenantSelect.vue
  31. 17
      vueJs/src/views/login/index.vue

1
aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application.Contracts/LINGYUN/ApiGateway/Ocelot/Dto/RouteGroupCreateDto.cs

@ -16,6 +16,7 @@ namespace LINGYUN.ApiGateway.Ocelot
[StringLength(100)]
public string AppName { get; set; }
[Required]
[StringLength(256)]
public string AppIpAddress { get; set; }

6
aspnet-core/modules/apigateway/LINGYUN.ApiGateway.Application/LINGYUN/ApiGateway/Ocelot/RouteGroupAppService.cs

@ -60,11 +60,11 @@ namespace LINGYUN.ApiGateway.Ocelot
{
using (DataFilter.Disable<IActivation>())
{
var routerTupes = await RouterRepository.GetPagedListAsync(routerGetByPagedInput.Filter,
var (Routers, TotalCount) = await RouterRepository.GetPagedListAsync(routerGetByPagedInput.Filter,
routerGetByPagedInput.Sorting, routerGetByPagedInput.SkipCount, routerGetByPagedInput.MaxResultCount);
var routers = ObjectMapper.Map<List<RouteGroup>, List<RouteGroupDto>>(routerTupes.Routers);
var routers = ObjectMapper.Map<List<RouteGroup>, List<RouteGroupDto>>(Routers);
return new PagedResultDto<RouteGroupDto>(routerTupes.TotalCount, routers);
return new PagedResultDto<RouteGroupDto>(TotalCount, routers);
}
}

74
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/Processor/AbpCapExpiresMessageCleanupBackgroundWorker.cs

@ -0,0 +1,74 @@
using DotNetCore.CAP.Persistence;
using LINGYUN.Abp.EventBus.CAP;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Threading;
namespace DotNetCore.CAP.Processor
{
/// <summary>
/// 过期消息清理任务
/// </summary>
public class AbpCapExpiresMessageCleanupBackgroundWorker : AsyncPeriodicBackgroundWorkerBase
{
/// <summary>
/// 过期消息清理配置
/// </summary>
protected MessageCleanupOptions Options { get; }
/// <summary>
/// Initializer
/// </summary>
protected IStorageInitializer Initializer { get; }
/// <summary>
/// Storage
/// </summary>
protected IDataStorage Storage{ get; }
/// <summary>
/// 创建过期消息清理任务
/// </summary>
/// <param name="timer"></param>
/// <param name="storage"></param>
/// <param name="initializer"></param>
/// <param name="options"></param>
/// <param name="serviceScopeFactory"></param>
public AbpCapExpiresMessageCleanupBackgroundWorker(
AbpTimer timer,
IDataStorage storage,
IStorageInitializer initializer,
IOptions<MessageCleanupOptions> options,
IServiceScopeFactory serviceScopeFactory)
: base(timer, serviceScopeFactory)
{
Storage = storage;
Options = options.Value;
Initializer = initializer;
timer.Period = Options.Interval;
}
/// <summary>
/// 异步执行任务
/// </summary>
/// <param name="workerContext"></param>
/// <returns></returns>
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
var tables = new[]
{
Initializer.GetPublishedTableName(),
Initializer.GetReceivedTableName()
};
foreach (var table in tables)
{
Logger.LogDebug($"Collecting expired data from table: {table}");
var time = DateTime.Now;
await Storage.DeleteExpiresAsync(table, time, Options.ItemBatch);
}
}
}
}

115
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/DotNetCore/CAP/Processor/AbpCapProcessingServer.cs

@ -0,0 +1,115 @@
using DotNetCore.CAP.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace DotNetCore.CAP.Processor
{
/// <summary>
/// CapProcessingServer
/// </summary>
public class AbpCapProcessingServer : IProcessingServer
{
private readonly CancellationTokenSource _cts;
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IServiceProvider _provider;
private Task _compositeTask;
private ProcessingContext _context;
private bool _disposed;
/// <summary>
/// CapProcessingServer
/// </summary>
/// <param name="logger"></param>
/// <param name="loggerFactory"></param>
/// <param name="provider"></param>
public AbpCapProcessingServer(
ILogger<AbpCapProcessingServer> logger,
ILoggerFactory loggerFactory,
IServiceProvider provider)
{
_logger = logger;
_loggerFactory = loggerFactory;
_provider = provider;
_cts = new CancellationTokenSource();
}
/// <summary>
/// Start
/// </summary>
public void Start()
{
_logger.LogInformation("Starting the processing server.");
_context = new ProcessingContext(_provider, _cts.Token);
var processorTasks = GetProcessors()
.Select(InfiniteRetry)
.Select(p => p.ProcessAsync(_context));
_compositeTask = Task.WhenAll(processorTasks);
}
/// <summary>
/// Pulse
/// </summary>
public void Pulse()
{
_logger.LogTrace("Pulsing the processor.");
}
/// <summary>
/// Dispose
/// </summary>
public void Dispose()
{
if (_disposed)
{
return;
}
try
{
_disposed = true;
_logger.LogInformation("Shutting down the processing server...");
_cts.Cancel();
_compositeTask?.Wait((int)TimeSpan.FromSeconds(10).TotalMilliseconds);
}
catch (AggregateException ex)
{
var innerEx = ex.InnerExceptions[0];
if (!(innerEx is OperationCanceledException))
{
_logger.LogWarning(innerEx, $"Expected an OperationCanceledException, but found '{innerEx.Message}'.");
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "An exception was occured when disposing.");
}
finally
{
_logger.LogInformation("### CAP shutdown!");
}
}
private IProcessor InfiniteRetry(IProcessor inner)
{
return new InfiniteRetryProcessor(inner, _loggerFactory);
}
private IProcessor[] GetProcessors()
{
var returnedProcessors = new List<IProcessor>
{
_provider.GetRequiredService<TransportCheckProcessor>(),
_provider.GetRequiredService<MessageNeedToRetryProcessor>(),
};
return returnedProcessors.ToArray();
}
}
}

1
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.csproj

@ -15,6 +15,7 @@
<ItemGroup>
<PackageReference Include="DotNetCore.CAP" Version="3.0.3" />
<PackageReference Include="Volo.Abp.BackgroundWorkers" Version="2.8.0" />
<PackageReference Include="Volo.Abp.EventBus" Version="2.8.0" />
</ItemGroup>

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

@ -39,6 +39,71 @@
<param name="typeInfo"></param>
<returns></returns>
</member>
<member name="T:DotNetCore.CAP.Processor.AbpCapExpiresMessageCleanupBackgroundWorker">
<summary>
过期消息清理任务
</summary>
</member>
<member name="P:DotNetCore.CAP.Processor.AbpCapExpiresMessageCleanupBackgroundWorker.Options">
<summary>
过期消息清理配置
</summary>
</member>
<member name="P:DotNetCore.CAP.Processor.AbpCapExpiresMessageCleanupBackgroundWorker.Initializer">
<summary>
Initializer
</summary>
</member>
<member name="P:DotNetCore.CAP.Processor.AbpCapExpiresMessageCleanupBackgroundWorker.Storage">
<summary>
Storage
</summary>
</member>
<member name="M:DotNetCore.CAP.Processor.AbpCapExpiresMessageCleanupBackgroundWorker.#ctor(Volo.Abp.Threading.AbpTimer,DotNetCore.CAP.Persistence.IDataStorage,DotNetCore.CAP.Persistence.IStorageInitializer,Microsoft.Extensions.Options.IOptions{LINGYUN.Abp.EventBus.CAP.MessageCleanupOptions},Microsoft.Extensions.DependencyInjection.IServiceScopeFactory)">
<summary>
创建过期消息清理任务
</summary>
<param name="timer"></param>
<param name="storage"></param>
<param name="initializer"></param>
<param name="options"></param>
<param name="serviceScopeFactory"></param>
</member>
<member name="M:DotNetCore.CAP.Processor.AbpCapExpiresMessageCleanupBackgroundWorker.DoWorkAsync(Volo.Abp.BackgroundWorkers.PeriodicBackgroundWorkerContext)">
<summary>
异步执行任务
</summary>
<param name="workerContext"></param>
<returns></returns>
</member>
<member name="T:DotNetCore.CAP.Processor.AbpCapProcessingServer">
<summary>
CapProcessingServer
</summary>
</member>
<member name="M:DotNetCore.CAP.Processor.AbpCapProcessingServer.#ctor(Microsoft.Extensions.Logging.ILogger{DotNetCore.CAP.Processor.AbpCapProcessingServer},Microsoft.Extensions.Logging.ILoggerFactory,System.IServiceProvider)">
<summary>
CapProcessingServer
</summary>
<param name="logger"></param>
<param name="loggerFactory"></param>
<param name="provider"></param>
</member>
<member name="M:DotNetCore.CAP.Processor.AbpCapProcessingServer.Start">
<summary>
Start
</summary>
</member>
<member name="M:DotNetCore.CAP.Processor.AbpCapProcessingServer.Pulse">
<summary>
Pulse
</summary>
</member>
<member name="M:DotNetCore.CAP.Processor.AbpCapProcessingServer.Dispose">
<summary>
Dispose
</summary>
</member>
<member name="T:LINGYUN.Abp.EventBus.CAP.AbpCAPEventBusModule">
<summary>
AbpCAPEventBusModule
@ -50,6 +115,12 @@
</summary>
<param name="context"></param>
</member>
<member name="M:LINGYUN.Abp.EventBus.CAP.AbpCAPEventBusModule.OnApplicationInitialization(Volo.Abp.ApplicationInitializationContext)">
<summary>
OnApplicationInitialization
</summary>
<param name="context"></param>
</member>
<member name="T:LINGYUN.Abp.EventBus.CAP.CAPDistributedEventBus">
<summary>
CAP分布式事件总线
@ -141,6 +212,23 @@
<param name="eventType"></param>
<returns></returns>
</member>
<member name="T:LINGYUN.Abp.EventBus.CAP.MessageCleanupOptions">
<summary>
过期消息清理配置项
</summary>
</member>
<member name="P:LINGYUN.Abp.EventBus.CAP.MessageCleanupOptions.ItemBatch">
<summary>
批量清理数量
default: 1000
</summary>
</member>
<member name="P:LINGYUN.Abp.EventBus.CAP.MessageCleanupOptions.Interval">
<summary>
执行间隔(ms)
default: 3600000 (1 hours)
</summary>
</member>
<member name="T:Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions">
<summary>
CAP ServiceCollectionExtensions

23
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/AbpCAPEventBusModule.cs

@ -1,5 +1,8 @@
using Microsoft.Extensions.Configuration;
using DotNetCore.CAP.Processor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.EventBus;
using Volo.Abp.Modularity;
@ -8,7 +11,9 @@ namespace LINGYUN.Abp.EventBus.CAP
/// <summary>
/// AbpCAPEventBusModule
/// </summary>
[DependsOn(typeof(AbpEventBusModule))]
[DependsOn(
typeof(AbpEventBusModule),
typeof(AbpBackgroundWorkersModule))]
public class AbpCAPEventBusModule : AbpModule
{
/// <summary>
@ -24,5 +29,19 @@ namespace LINGYUN.Abp.EventBus.CAP
context.Services.ExecutePreConfiguredActions(options);
});
}
/// <summary>
/// OnApplicationInitialization
/// </summary>
/// <param name="context"></param>
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
context.ServiceProvider
.GetRequiredService<IBackgroundWorkerManager>()
.Add(
context.ServiceProvider
.GetRequiredService<AbpCapExpiresMessageCleanupBackgroundWorker>()
);
}
}
}

19
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN/Abp/EventBus/CAP/MessageCleanupOptions.cs

@ -0,0 +1,19 @@
namespace LINGYUN.Abp.EventBus.CAP
{
/// <summary>
/// 过期消息清理配置项
/// </summary>
public class MessageCleanupOptions
{
/// <summary>
/// 批量清理数量
/// default: 1000
/// </summary>
public int ItemBatch { get; set; } = 1000;
/// <summary>
/// 执行间隔(ms)
/// default: 3600000 (1 hours)
/// </summary>
public int Interval { get; set; } = 3600000;
}
}

14
aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/Microsoft/Extensions/DependencyInjection/ServiceCollectionExtensions.cs

@ -1,5 +1,9 @@
using DotNetCore.CAP;
using DotNetCore.CAP.Internal;
using DotNetCore.CAP.Processor;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System;
using System.Linq;
namespace Microsoft.Extensions.DependencyInjection
{
@ -17,6 +21,16 @@ namespace Microsoft.Extensions.DependencyInjection
public static IServiceCollection AddCAPEventBus(this IServiceCollection services, Action<CapOptions> capAction)
{
services.AddCap(capAction);
// 移除默认的定时清理过期消息任务
// 默认的五分钟,不可配置,时间间隔过短,使用自定义的后台任务
services.RemoveAll(typeof(CollectorProcessor));
var capProcessingServiceDescriptor = services
.FirstOrDefault(x => typeof(CapProcessingServer).Equals(x.ImplementationType));
if(capProcessingServiceDescriptor != null)
{
services.Remove(capProcessingServiceDescriptor);
}
services.TryAddEnumerable(ServiceDescriptor.Singleton<IProcessingServer, AbpCapProcessingServer>());
return services;
}
}

12
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN.Abp.Location.Baidu.csproj

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.Location\LINGYUN.Abp.Location.csproj" />
</ItemGroup>
</Project>

15
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduInverseLocationResponse.cs

@ -0,0 +1,15 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Abp.Location.Baidu.Http
{
public class BaiduInverseLocationResponse : BaiduLocationResponse
{
[JsonProperty("formatted_address")]
public string Address { get; set; }
}
}

11
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduLocationHttpClient.cs

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Abp.Location.Baidu.Http
{
public class BaiduLocationHttpClient
{
}
}

14
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduLocationResponse.cs

@ -0,0 +1,14 @@
namespace LINGYUN.Abp.Location.Baidu.Http
{
public abstract class BaiduLocationResponse
{
public int Status { get; set; }
public Location Location { get; set; }
public bool IsSuccess()
{
return Status == 0;
}
}
}

10
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/BaiduPositiveLocationResponse.cs

@ -0,0 +1,10 @@
namespace LINGYUN.Abp.Location.Baidu.Http
{
public class BaiduPositiveLocationResponse : BaiduLocationResponse
{
public int Precise { get; set; }
public int Confidence { get; set; }
public int Comprehension { get; set; }
public string Level { get; set; }
}
}

8
aspnet-core/modules/common/LINGYUN.Abp.Location.Baidu/LINGYUN/Abp/Location/Baidu/Http/Location.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp.Location.Baidu.Http
{
public class Location
{
public double Lat { get; set; }
public double Lng { get; set; }
}
}

12
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN.Abp.Location.csproj

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Core" Version="2.8.0" />
</ItemGroup>
</Project>

8
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/AbpLocationModule.cs

@ -0,0 +1,8 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Location
{
public class AbpLocationModule : AbpModule
{
}
}

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

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.Location
{
public interface ILocationResolveProvider
{
PositiveLocation GetPositiveLocation(string address);
InverseLocation GetInverseLocation(double lat, double lng);
}
}

45
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/InverseLocation.cs

@ -0,0 +1,45 @@
namespace LINGYUN.Abp.Location
{
/// <summary>
/// 逆地址
/// </summary>
public class InverseLocation
{
/// <summary>
/// 详细地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 国家
/// </summary>
public string Country { get; set; }
/// <summary>
/// 省份
/// </summary>
public string Province { get; set; }
/// <summary>
/// 城市
/// </summary>
public string City { get; set; }
/// <summary>
/// 区县
/// </summary>
public string District { get; set; }
/// <summary>
/// 街道
/// </summary>
public string Street { get; set; }
/// <summary>
/// adcode
/// </summary>
public string AdCode { get; set; }
/// <summary>
/// 乡镇
/// </summary>
public string Town { get; set; }
/// <summary>
/// 门牌号
/// </summary>
public string Number { get; set; }
}
}

97
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Location.cs

@ -0,0 +1,97 @@
using System;
namespace LINGYUN.Abp.Location
{
public abstract class Location
{
/// <summary>
/// 地球半径(米)
/// </summary>
public const double EARTH_RADIUS = 6378137;
/// <summary>
/// 纬度
/// </summary>
public double Latitude { get; set; }
/// <summary>
/// 经度
/// </summary>
public double Longitude { get; set; }
/// <summary>
/// 计算两个位置的距离,返回两点的距离,单位 米
/// 该公式为GOOGLE提供,误差小于0.2米
/// </summary>
/// <param name="location">参与计算的位置信息</param>
/// <returns>返回两个位置的距离</returns>
public double CalcDistance(Location location)
{
return CalcDistance(this, location);
}
/// <summary>
/// 计算两个位置的距离,返回两点的距离,单位 米
/// 该公式为GOOGLE提供,误差小于0.2米
/// </summary>
/// <param name="location1">参与计算的位置信息</param>
/// <param name="location2">参与计算的位置信息</param>
/// <returns>返回两个位置的距离</returns>
public static double CalcDistance(Location location1, Location location2)
{
double radLat1 = Rad(location1.Latitude);
double radLng1 = Rad(location1.Longitude);
double radLat2 = Rad(location2.Latitude);
double radLng2 = Rad(location2.Longitude);
double a = radLat1 - radLat2;
double b = radLng1 - radLng2;
double result = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
result *= EARTH_RADIUS;
return result;
}
/// <summary>
/// 计算位置的偏移距离
/// </summary>
/// <param name="location">参与计算的位置</param>
/// <param name="distance">位置偏移量,单位 米</param>
/// <returns></returns>
public static Position CalcOffsetDistance(Location location, double distance)
{
double dlng = 2 * Math.Asin(Math.Sin(distance / (2 * EARTH_RADIUS)) / Math.Cos(Rad(location.Latitude)));
dlng = Deg(dlng);
double dlat = distance / EARTH_RADIUS;
dlat = Deg(dlat);
double leftTopLat = location.Latitude + dlat;
double leftTopLng = location.Longitude - dlng;
double leftBottomLat = location.Latitude - dlat;
double leftBottomLng = location.Longitude - dlng;
double rightTopLat = location.Latitude + dlat;
double rightTopLng = location.Longitude + dlng;
double rightBottomLat = location.Latitude - dlat;
double rightBottomLng = location.Longitude + dlng;
return new Position(leftTopLat, leftBottomLat, leftTopLng, leftBottomLng,
rightTopLat, rightBottomLat, rightTopLng, rightBottomLng);
}
/// <summary>
/// 角度转换为弧度
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
public static double Rad(double d)
{
return d * Math.PI / 180d;
}
/// <summary>
/// 弧度转换为角度
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
public static double Deg(double d)
{
return d * (180 / Math.PI);
}
}
}

55
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/Position.cs

@ -0,0 +1,55 @@
namespace LINGYUN.Abp.Location
{
/// <summary>
/// 位置量
/// </summary>
public class Position
{
/// <summary>
/// 左上纬度
/// </summary>
public double LeftTopLatitude { get; }
/// <summary>
/// 左上经度
/// </summary>
public double LeftTopLongitude { get; }
/// <summary>
/// 左下纬度
/// </summary>
public double LeftBottomLatitude { get; }
/// <summary>
/// 左下经度
/// </summary>
public double LeftBottomLongitude { get; }
/// <summary>
/// 右上纬度
/// </summary>
public double RightTopLatitude { get; }
/// <summary>
/// 右上经度
/// </summary>
public double RightTopLongitude { get; }
/// <summary>
/// 右下纬度
/// </summary>
public double RightBottomLatitude { get; }
/// <summary>
/// 右下经度
/// </summary>
public double RightBottomLongitude { get; }
internal Position(double leftTopLat, double leftBottomLat, double leftTopLng, double leftBottomLng,
double rightTopLat, double rightBottomLat, double rightTopLng, double rightBottomLng)
{
LeftTopLatitude = leftTopLat;
LeftBottomLatitude = leftBottomLat;
LeftTopLongitude = leftTopLng;
LeftBottomLongitude = leftBottomLng;
RightTopLatitude = rightTopLat;
RightTopLongitude = rightTopLng;
RightBottomLatitude = rightBottomLat;
RightBottomLongitude = rightBottomLng;
}
}
}

27
aspnet-core/modules/common/LINGYUN.Abp.Location/LINGYUN/Abp/Location/PositiveLocation.cs

@ -0,0 +1,27 @@
namespace LINGYUN.Abp.Location
{
/// <summary>
/// 正地址
/// </summary>
public class PositiveLocation : Location
{
/// <summary>
/// 附加信息
/// </summary>
public int Precise { get; set; }
/// <summary>
/// 绝对精度
/// </summary>
public int Confidence { get; set; }
/// <summary>
/// 理解程度
/// 分值范围0-100
/// 分值越大,服务对地址理解程度越高
/// </summary>
public int Pomprehension { get; set; }
/// <summary>
/// 能精确理解的地址类型
/// </summary>
public string Level { get; set; }
}
}

11
vueJs/src/App.vue

@ -6,6 +6,7 @@
</template>
<script lang="ts">
import { AbpConfigurationModule } from '@/store/modules/abp'
import { Component, Vue } from 'vue-property-decorator'
import ServiceWorkerUpdatePopup from '@/pwa/components/ServiceWorkerUpdatePopup.vue'
@ -15,5 +16,13 @@ import ServiceWorkerUpdatePopup from '@/pwa/components/ServiceWorkerUpdatePopup.
ServiceWorkerUpdatePopup
}
})
export default class extends Vue {}
export default class extends Vue {
mounted() {
this.initializeAbpConfiguration()
}
private async initializeAbpConfiguration() {
await AbpConfigurationModule.GetAbpConfiguration()
}
}
</script>

10
vueJs/src/api/abpconfiguration.ts

@ -96,4 +96,14 @@ export class AbpConfiguration implements IAbpConfiguration {
multiTenancy!: MultiTenancy
objectExtensions!: any
setting!: Setting
constructor() {
this.auth = new Auth()
this.setting = new Setting()
this.features = new Feature()
this.currentUser = new CurrentUser()
this.localization = new Localization()
this.multiTenancy = new MultiTenancy()
this.currentTenant = new CurrentTenant()
}
}

4
vueJs/src/api/apigateway.ts

@ -277,7 +277,7 @@ export class GlobalConfigurationBase {
export class GlobalConfigurationDto extends GlobalConfigurationBase {
appId!: string
itemId!: number
itemId!: string
}
export class GlobalConfigurationCreateDto extends GlobalConfigurationBase {
@ -285,7 +285,7 @@ export class GlobalConfigurationCreateDto extends GlobalConfigurationBase {
}
export class GlobalConfigurationUpdateDto extends GlobalConfigurationBase {
itemId!: number
itemId!: string
}
export class GlobalGetByPagedDto extends PagedAndSortedResultRequestDto {

3
vueJs/src/lang/zh.ts

@ -105,7 +105,8 @@ export default {
tokenExprition: '身份令牌已过期,请重新登录!',
confirmLogout: '确认登出',
relogin: '重新登录',
cancel: '取消'
cancel: '取消',
tenantIsNotAvailable: '给定的租户不可用: {name}'
},
documentation: {
documentation: '文档',

16
vueJs/src/utils/localStorage.ts

@ -16,9 +16,21 @@ export const removeAbpConfig = () => localStorage.removeItem(abpConfigKey)
// User
const tokenKey = 'vue_typescript_admin_token'
const refreshTokenKey = 'vue_typescript_admin_refresh_token'
export const getToken = () => localStorage.getItem(tokenKey)
export function getToken() {
const tokenItem = localStorage.getItem(tokenKey)
if (tokenItem) {
return tokenItem
}
return ''
}
export const setToken = (token: string) => localStorage.setItem(tokenKey, token)
export const getRefreshToken = () => localStorage.getItem(refreshTokenKey)
export const getRefreshToken = () => {
const tokenItem = localStorage.getItem(refreshTokenKey)
if (tokenItem) {
return tokenItem
}
return ''
}
export const setRefreshToken = (token: string) => localStorage.setItem(refreshTokenKey, token)
export const removeToken = () => {
localStorage.removeItem(tokenKey)

7
vueJs/src/views/admin/apigateway/components/GlobalCreateOrEditForm.vue

@ -13,7 +13,7 @@
>
<el-select
v-model="globalConfiguration.appId"
:readonly="hasEdit"
:disabled="hasEdit"
class="global-select"
:placeholder="$t('pleaseSelectBy', {name: $t('apiGateWay.appId')})"
>
@ -386,7 +386,7 @@ export default class extends Vue {
}
get hasEdit() {
if (this.globalConfiguration.itemId && this.globalConfiguration.itemId !== 0) {
if (this.globalConfiguration.itemId) {
return true
}
return false
@ -411,6 +411,8 @@ export default class extends Vue {
private handleAppIdChanged(appId: string) {
if (appId) {
this.handleGetGlobalConfiguration()
} else {
this.globalConfiguration = new GlobalConfigurationDto()
}
}
@ -443,6 +445,7 @@ export default class extends Vue {
}
private onCancel() {
this.appId = ''
const formGlobal = this.$refs.formGlobal as any
formGlobal.resetFields()
this.$emit('closed', false)

4
vueJs/src/views/admin/apigateway/components/RouteGroupCreateOrEditForm.vue

@ -97,6 +97,9 @@ export default class extends Vue {
],
appName: [
{ required: true, message: this.l('pleaseInputBy', { key: this.l('apiGateWay.appName') }), trigger: 'blur' }
],
appIpAddress: [
{ required: true, message: this.l('pleaseInputBy', { key: this.l('apiGateWay.appIpAddress') }), trigger: 'blur' }
]
}
@ -143,6 +146,7 @@ export default class extends Vue {
}
private onCancel() {
this.apiGateWayRouteGroup = new RouteGroupDto()
const routerEditForm = this.$refs.formRouteGroup as any
routerEditForm.resetFields()
this.$emit('closed', false)

57
vueJs/src/views/login/components/TenantSelect.vue

@ -0,0 +1,57 @@
<template>
<div>
<el-row justify="center">
<el-col :span="4">
<label>{{ $t('AbpUiMultiTenancy.Tenant') }}</label>
</el-col>
<el-col :span="16">
<label>{{ value }}</label>
</el-col>
<el-col :span="4">
<el-link
type="info"
@click="handleSwitchTenant"
>
{{ $t('AbpUiMultiTenancy.SwitchTenant') }}
</el-link>
</el-col>
</el-row>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
import TenantService from '@/api/tenant'
import { setTenant, removeTenant } from '@/utils/sessions'
@Component({
name: 'TenantSelect'
})
export default class extends Vue {
@Prop({ default: '' })
private value?: string
private handleSwitchTenant() {
this.$prompt(this.$t('AbpUiMultiTenancy.SwitchTenantHint').toString(),
this.$t('AbpUiMultiTenancy.SwitchTenant').toString(), {
showInput: true
}).then((val: any) => {
removeTenant()
if (val.value) {
TenantService.getTenantByName(val.value).then(tenant => {
if (tenant.success) {
setTenant(tenant.tenantId)
this.$emit('input', tenant.name)
} else {
this.$message.warning(this.$t('login.tenantIsNotAvailable', { name: val.value }).toString())
}
})
} else {
this.$emit('input', '')
}
}).catch(() => {
console.log()
})
}
}
</script>

17
vueJs/src/views/login/index.vue

@ -14,6 +14,10 @@
</h3>
<lang-select class="set-language" />
</div>
<TenantSelect
v-if="isMultiEnabled"
v-model="loginForm.tenantName"
/>
<el-tabs
stretch
@tab-click="handleLoginTabChanged"
@ -117,14 +121,17 @@ import { Input } from 'element-ui'
import { Route } from 'vue-router'
import { UserModule } from '@/store/modules/user'
import { Dictionary } from 'vue-router/types/router'
import TenantSelect from './components/TenantSelect.vue'
import LangSelect from '@/components/LangSelect/index.vue'
import { Component, Vue, Watch } from 'vue-property-decorator'
import UserService, { PhoneVerify, VerifyType } from '@/api/users'
import { AbpConfigurationModule } from '@/store/modules/abp'
@Component({
name: 'Login',
components: {
LangSelect
LangSelect,
TenantSelect
}
})
export default class extends Vue {
@ -144,6 +151,10 @@ export default class extends Vue {
verifyCode: ''
}
get isMultiEnabled() {
return AbpConfigurationModule.configuration.multiTenancy.isEnabled
}
private validatePhoneNumberValue = (rule: any, value: string, callback: any) => {
const phoneReg = /^1[34578]\d{9}$/
if (!value || !phoneReg.test(value)) {
@ -301,7 +312,6 @@ export default class extends Vue {
.title {
font-size: 26px;
color: $lightGray;
margin: 0px auto 20px auto;
text-align: center;
font-weight: bold;
@ -320,7 +330,6 @@ export default class extends Vue {
}
.set-language {
color: #fff;
position: absolute;
top: 3px;
font-size: 18px;
@ -347,7 +356,7 @@ export default class extends Vue {
padding: 35px 35px 15px;
border: 1px solid #8c9494;
box-shadow: 0 0 25px #454646;
background-color:rgb(110, 115, 116);
background-color:rgb(247, 255, 255);
.loginTab.el-tabs__item {
width: 180px;

Loading…
Cancel
Save