diff --git a/aspnet-core/LINGYUN.MicroService.sln b/aspnet-core/LINGYUN.MicroService.sln
index af232f52f..bf559bea3 100644
--- a/aspnet-core/LINGYUN.MicroService.sln
+++ b/aspnet-core/LINGYUN.MicroService.sln
@@ -209,9 +209,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.EntityFrameworkCore", "modules\identityServer\LINGYUN.Abp.IdentityServer.EntityFrameworkCore\LINGYUN.Abp.IdentityServer.EntityFrameworkCore.csproj", "{5D0ED1FC-3A7C-4531-9512-832E73AD9555}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.Domain", "modules\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj", "{2BF7FB73-0C62-4ECF-99F0-0583855D2777}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Domain", "modules\identity\LINGYUN.Abp.Identity.Domain\LINGYUN.Abp.Identity.Domain.csproj", "{2BF7FB73-0C62-4ECF-99F0-0583855D2777}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.EntityFrameworkCore", "modules\identity\LINGYUN.Abp.Identity.EntityFrameworkCore\LINGYUN.Abp.Identity.EntityFrameworkCore.csproj", "{6FE7E243-2D99-4567-8786-6C9283D608EF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.EntityFrameworkCore", "modules\identity\LINGYUN.Abp.Identity.EntityFrameworkCore\LINGYUN.Abp.Identity.EntityFrameworkCore.csproj", "{6FE7E243-2D99-4567-8786-6C9283D608EF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Domain.Entities.Events", "modules\common\LINGYUN.Abp.Domain.Entities.Events\LINGYUN.Abp.Domain.Entities.Events.csproj", "{AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -567,6 +569,10 @@ Global
{6FE7E243-2D99-4567-8786-6C9283D608EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FE7E243-2D99-4567-8786-6C9283D608EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FE7E243-2D99-4567-8786-6C9283D608EF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -674,6 +680,7 @@ Global
{5D0ED1FC-3A7C-4531-9512-832E73AD9555} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{2BF7FB73-0C62-4ECF-99F0-0583855D2777} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{6FE7E243-2D99-4567-8786-6C9283D608EF} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
+ {AAD8EF65-1FBF-4F3F-8B33-8B76E1EBA4A5} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}
diff --git a/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json b/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json
index aa82f1d34..171925d67 100644
--- a/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json
+++ b/aspnet-core/configuration/account/AuthServer.Host/appsettings.Development.json
@@ -48,9 +48,10 @@
"VirtualHost": "multi.service.test"
}
},
- "RedisCache": {
- "ConnectString": "127.0.0.1",
- "RedisPrefix": "AuthServer"
+ "Redis": {
+ "Configuration": "127.0.0.1",
+ "InstanceName": "LINGYUN.AbpApplication",
+ "DefaultDatabase": 10
},
"AuthServer": {
"Authority": "http://localhost:44385/",
diff --git a/aspnet-core/configuration/admin/LINGYUN.BackendAdminApp.Host/appsettings.Development.json b/aspnet-core/configuration/admin/LINGYUN.BackendAdminApp.Host/appsettings.Development.json
index 20218b346..a8d83e330 100644
--- a/aspnet-core/configuration/admin/LINGYUN.BackendAdminApp.Host/appsettings.Development.json
+++ b/aspnet-core/configuration/admin/LINGYUN.BackendAdminApp.Host/appsettings.Development.json
@@ -69,9 +69,10 @@
"VirtualHost": "Name of your RabbitMQ server VirtualHost"
}
},
- "RedisCache": {
- "RedisPrefix": "Platform_Test_Cache",
- "ConnectString": "127.0.0.1"
+ "Redis": {
+ "Configuration": "127.0.0.1",
+ "InstanceName": "LINGYUN.AbpApplication",
+ "DefaultDatabase": 10
},
"AuthServer": {
"Authority": "http://localhost:44385/",
diff --git a/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json b/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json
index e5e3214da..1542e3bb5 100644
--- a/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json
+++ b/aspnet-core/configuration/apigateway/LINGYUN.ApiGateway.HttpApi.Host/appsettings.Development.json
@@ -6,9 +6,10 @@
"AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456"
},
- "RedisCache": {
- "RedisPrefix": "ApiGateway_Test_Cache",
- "ConnectString": "127.0.0.1"
+ "Redis": {
+ "Configuration": "127.0.0.1",
+ "InstanceName": "LINGYUN.AbpApplication",
+ "DefaultDatabase": 10
},
"CAP": {
"EventBus": {
diff --git a/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json b/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json
index 74da04c9c..97b761933 100644
--- a/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json
+++ b/aspnet-core/configuration/messages/LINGYUN.Abp.MessageService.HttpApi.Host/appsettings.Development.json
@@ -6,9 +6,10 @@
"AbpSettingManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456"
},
- "RedisCache": {
- "RedisPrefix": "Platform_Test_Cache",
- "ConnectString": "127.0.0.1"
+ "Redis": {
+ "Configuration": "127.0.0.1",
+ "InstanceName": "LINGYUN.AbpApplication",
+ "DefaultDatabase": 10
},
"AuthServer": {
"Authority": "http://localhost:44385/",
diff --git a/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json b/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json
index f2457af77..1df50d6b4 100644
--- a/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json
+++ b/aspnet-core/configuration/platform/LINGYUN.Platform.HttpApi.Host/appsettings.Development.json
@@ -22,9 +22,10 @@
"VirtualHost": "Name of your RabbitMQ server VirtualHost"
}
},
- "RedisCache": {
- "RedisPrefix": "Platform_Test_Cache",
- "ConnectString": "127.0.0.1"
+ "Redis": {
+ "Configuration": "127.0.0.1",
+ "InstanceName": "LINGYUN.AbpApplication",
+ "DefaultDatabase": 10
},
"AuthServer": {
"Authority": "http://localhost:44385/",
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN.Abp.Domain.Entities.Events.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN.Abp.Domain.Entities.Events.csproj
new file mode 100644
index 000000000..5949bdecb
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN.Abp.Domain.Entities.Events.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/AbpDddDomainEntitesEventsModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/AbpDddDomainEntitesEventsModule.cs
new file mode 100644
index 000000000..1e58ef752
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/AbpDddDomainEntitesEventsModule.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.Domain;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Domain.Entities.Events
+{
+ [DependsOn(typeof(AbpDddDomainModule))]
+ public class AbpDddDomainEntitesEventsModule : AbpModule
+ {
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/EntityChangeEventHelper.cs b/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/EntityChangeEventHelper.cs
new file mode 100644
index 000000000..69d29eee0
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Domain.Entities.Events/LINGYUN/Abp/Domain/Entites/Events/EntityChangeEventHelper.cs
@@ -0,0 +1,151 @@
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Entities.Events;
+using Volo.Abp.Domain.Entities.Events.Distributed;
+using Volo.Abp.DynamicProxy;
+using Volo.Abp.EventBus;
+using Volo.Abp.Uow;
+
+namespace LINGYUN.Abp.Domain.Entities.Events
+{
+ [Dependency(Microsoft.Extensions.DependencyInjection.ServiceLifetime.Transient, ReplaceServices = true)]
+ [ExposeServices(typeof(IEntityChangeEventHelper), typeof(Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper))]
+ [Obsolete("the component will be removed when the abp framework is upgraded to 3.1.0")]
+ public class EntityChangeEventHelper : Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper
+ {
+ public EntityChangeEventHelper(
+ IUnitOfWorkManager unitOfWorkManager,
+ IEntityToEtoMapper entityToEtoMapper,
+ IOptions distributedEntityEventOptions)
+ : base(unitOfWorkManager, entityToEtoMapper, distributedEntityEventOptions)
+ {
+ }
+
+ protected override async Task TriggerEventWithEntity(
+ IEventBus eventPublisher,
+ Type genericEventType,
+ object entityOrEto,
+ object originalEntity,
+ bool triggerInCurrentUnitOfWork)
+ {
+ var entityType = ProxyHelper.UnProxy(entityOrEto).GetType();
+ var eventType = genericEventType.MakeGenericType(entityType);
+ var currentUow = UnitOfWorkManager.Current;
+
+ if (triggerInCurrentUnitOfWork || currentUow == null)
+ {
+ await eventPublisher.PublishAsync(
+ eventType,
+ Activator.CreateInstance(eventType, entityOrEto)
+ );
+
+ return;
+ }
+
+ var eventList = GetEventList(currentUow);
+ var isFirstEvent = !eventList.Any();
+
+ eventList.AddUniqueEvent(eventPublisher, eventType, entityOrEto, originalEntity);
+
+ /* Register to OnCompleted if this is the first item.
+ * Other items will already be in the list once the UOW completes.
+ */
+ if (isFirstEvent)
+ {
+ currentUow.OnCompleted(
+ async () =>
+ {
+ foreach (var eventEntry in eventList)
+ {
+ try
+ {
+ // TODO: abp.io 3.1修复
+ await eventEntry.EventBus.PublishAsync(
+ eventEntry.EventType,
+ Activator.CreateInstance(eventEntry.EventType, eventEntry.EntityOrEto)
+ );
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(
+ $"Caught an exception while publishing the event '{eventType.FullName}' for the entity '{entityOrEto}'");
+ Logger.LogException(ex);
+ }
+ }
+ }
+ );
+ }
+ }
+
+ private EntityChangeEventList GetEventList(IUnitOfWork currentUow)
+ {
+ return (EntityChangeEventList)currentUow.Items.GetOrAdd(
+ "AbpEntityChangeEventList",
+ () => new EntityChangeEventList()
+ );
+ }
+
+ private class EntityChangeEventList : List
+ {
+ public void AddUniqueEvent(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity)
+ {
+ var newEntry = new EntityChangeEventEntry(eventBus, eventType, entityOrEto, originalEntity);
+
+ //Latest "same" event overrides the previous events.
+ for (var i = 0; i < Count; i++)
+ {
+ if (this[i].IsSameEvent(newEntry))
+ {
+ this[i] = newEntry;
+ return;
+ }
+ }
+
+ //If this is a "new" event, add to the end
+ Add(newEntry);
+ }
+ }
+
+ private class EntityChangeEventEntry
+ {
+ public IEventBus EventBus { get; }
+
+ public Type EventType { get; }
+
+ public object EntityOrEto { get; }
+
+ public object OriginalEntity { get; }
+
+ public EntityChangeEventEntry(IEventBus eventBus, Type eventType, object entityOrEto, object originalEntity)
+ {
+ EventType = eventType;
+ EntityOrEto = entityOrEto;
+ OriginalEntity = originalEntity;
+ EventBus = eventBus;
+ }
+
+ public bool IsSameEvent(EntityChangeEventEntry otherEntry)
+ {
+ if (EventBus != otherEntry.EventBus || EventType != otherEntry.EventType)
+ {
+ return false;
+ }
+
+ var originalEntityRef = OriginalEntity as IEntity;
+ var otherOriginalEntityRef = otherEntry.OriginalEntity as IEntity;
+ if (originalEntityRef == null || otherOriginalEntityRef == null)
+ {
+ return false;
+ }
+
+ return EntityHelper.EntityEquals(originalEntityRef, otherOriginalEntityRef);
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs b/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs
index 3dd7f4fda..26c2a5c2a 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpNotificationsExceptionSubscriber.cs
@@ -24,7 +24,15 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications
var notificationDispatcher = context.ServiceProvider.GetRequiredService();
var notificationName = NotificationNameNormalizer
.NormalizerName(AbpExceptionHandlingNotificationNames.NotificationName);
- var notificationData = new NotificationData();
+ NotificationData notificationData;
+ if (CurrentTenant.IsAvailable)
+ {
+ notificationData = NotificationData.CreateTenantNotificationData(CurrentTenant.Id.Value);
+ }
+ else
+ {
+ notificationData = NotificationData.CreateNotificationData();
+ }
// 写入通知数据
//TODO:集成TextTemplate完成格式化的推送
notificationData.WriteStandardData(
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs
index 04c341cb6..f091ecf06 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/OnlineClientHubBase.cs
@@ -1,6 +1,5 @@
using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;
@@ -26,6 +25,11 @@ namespace LINGYUN.Abp.Notifications.SignalR
IOnlineClient onlineClient = CreateClientForCurrentConnection();
Logger.LogDebug("A client is connected: " + onlineClient.ToString());
OnlineClientManager.Add(onlineClient);
+ if (onlineClient.TenantId.HasValue)
+ {
+ // 以租户为分组,将用户加入租户通讯组
+ await Groups.AddToGroupAsync(onlineClient.ConnectionId, onlineClient.TenantId.Value.ToString());
+ }
}
public override async Task OnDisconnectedAsync(Exception exception)
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
index 04afc41a8..0bfa29e70 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
@@ -30,31 +30,48 @@ namespace LINGYUN.Abp.Notifications.SignalR
public override async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers)
{
- // 返回标准数据给前端
- notification.Data = NotificationData.ToStandardData(notification.Data);
- foreach (var identifier in identifiers)
+ if (notification.Data.HasTenantNotification(out Guid tenantId))
{
- Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}");
- var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId);
- var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
- foreach (var onlineClient in onlineClients)
+ // 返回标准数据给前端
+ notification.Data = NotificationData.ToStandardData(notification.Data);
+ var singalRGroup = _hubContext.Clients.Group(tenantId.ToString());
+ if (singalRGroup == null)
{
- try
+ Logger.LogDebug("Can not get group " + tenantId + " from SignalR hub!");
+ return;
+ }
+ // 租户通知群发
+ Logger.LogDebug($"Found a singalr group, begin senging notifications");
+ await singalRGroup.SendAsync("getNotification", notification);
+ }
+ else
+ {
+ // 返回标准数据给前端
+ notification.Data = NotificationData.ToStandardData(notification.Data);
+ foreach (var identifier in identifiers)
+ {
+ Logger.LogDebug($"Find online client with user {identifier.UserId} - {identifier.UserName}");
+ var onlineClientContext = new OnlineClientContext(notification.TenantId, identifier.UserId);
+ var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext);
+ foreach (var onlineClient in onlineClients)
{
- Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}");
- var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
- if (signalRClient == null)
+ try
{
- Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
- continue;
+ Logger.LogDebug($"Find online client {onlineClient.UserId} - {onlineClient.ConnectionId}");
+ var signalRClient = _hubContext.Clients.Client(onlineClient.ConnectionId);
+ if (signalRClient == null)
+ {
+ Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
+ continue;
+ }
+ Logger.LogDebug($"Found a singalr client, begin senging notifications");
+ await signalRClient.SendAsync("getNotification", notification);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
+ Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
}
- Logger.LogDebug($"Found a singalr client, begin senging notifications");
- await signalRClient.SendAsync("getNotification", notification);
- }
- catch (Exception ex)
- {
- Logger.LogWarning("Could not send notifications to user: {0}", identifier.UserId);
- Logger.LogWarning("Send to user notifications error: {0}", ex.Message);
}
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
index ea6e40578..c9955adba 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
@@ -5,6 +5,10 @@ namespace LINGYUN.Abp.Notifications
{
public class NotificationData
{
+ public const string NotificationKey = "N:G";
+ public const string UserIdNotificationKey = "N:UI";
+ public const string UserNameNotificationKey = "N:UN";
+ public const string TenantNotificationKey = "N:T";
public virtual string Type => GetType().FullName;
public object this[string key]
@@ -45,6 +49,29 @@ namespace LINGYUN.Abp.Notifications
{
_properties = new Dictionary();
}
+
+ public static NotificationData CreateNotificationData()
+ {
+ var data = new NotificationData();
+ data.TrySetData(NotificationKey, "AbpNotification");
+ return data;
+ }
+
+ public static NotificationData CreateUserNotificationData(Guid userId, string userName)
+ {
+ var data = new NotificationData();
+ data.TrySetData(UserIdNotificationKey, userId);
+ data.TrySetData(UserNameNotificationKey, userName);
+ return data;
+ }
+
+ public static NotificationData CreateTenantNotificationData(Guid tenantId)
+ {
+ var data = new NotificationData();
+ data.TrySetData(TenantNotificationKey, tenantId);
+ return data;
+ }
+
///
/// 写入标准数据
///
@@ -123,5 +150,28 @@ namespace LINGYUN.Abp.Notifications
Properties[key] = value;
}
}
+
+ public bool HasUserNotification(out Guid userId, out string userName)
+ {
+ if (Properties.TryGetValue(UserIdNotificationKey, out object userKey))
+ {
+ userId = (Guid)userKey;
+ var name = TryGetData(UserNameNotificationKey);
+ userName = name != null ? name.ToString() : "";
+ return true;
+ }
+ userName = "";
+ return false;
+ }
+
+ public bool HasTenantNotification(out Guid tenantId)
+ {
+ if (Properties.TryGetValue(TenantNotificationKey, out object tenantKey))
+ {
+ tenantId = (Guid)tenantKey;
+ return true;
+ }
+ return false;
+ }
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
index f585fbafb..3a0c8f3c5 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
@@ -9,6 +9,11 @@ using Volo.Abp.Localization;
* 而是规范通知的一些属性,因此不应该是自定义通知名称,而是定义通知的类目,类似于Catalog
* 或者Prefix
*
+ * TODO: 2020-08-26 如果需要用户或者租户特定的消息该如何来发送通知?
+ * 是否追加字段:通知类别(宿主、租户、用户、通用),主要可以在运行时判断发布消息的来源,
+ * 如果是用户通知(NotificationData[FormUser])则只会查询用户对于用户通知的订阅(用户互动:站内信、私信、好友请求、留言等),优先级最低
+ * 租户通知(NotificationData[FormTenant])则只会查询用户对于租户通知的订阅(系统发布、应用通知),优先级次于用户
+ * 全局通知(NotificationData[FormGlobal])则查询用户对于全局通知的订阅(一般用于系统发布、应用通知),优先级最高
*/
namespace LINGYUN.Abp.Notifications
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationType.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationType.cs
index ce5db6c6c..f13b34542 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationType.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationType.cs
@@ -6,12 +6,16 @@
public enum NotificationType
{
///
- /// 应用
+ /// 应用(对应租户)
///
Application = 0,
///
- /// 系统
+ /// 系统(对应宿主)
///
- System = 10
+ System = 10,
+ ///
+ /// 用户(对应用户)
+ ///
+ User = 20
}
}
diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
index 672f1cb08..d2b53d23a 100644
--- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
+++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/EventBus/Local/UserCreateSendWelcomeEventHandler.cs
@@ -61,7 +61,7 @@ namespace LINGYUN.Abp.MessageService.EventBus
//await _notificationStore.InsertUserSubscriptionAsync(eventData.Entity.TenantId,
// userIdentifer, UserNotificationNames.WelcomeToApplication);
- var userWelcomeNotifictionData = new NotificationData();
+ var userWelcomeNotifictionData = NotificationData.CreateUserNotificationData(eventData.Entity.Id, eventData.Entity.UserName);
userWelcomeNotifictionData.WriteStandardData(
L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName),
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantCreateEventHandler.cs b/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantCreateEventHandler.cs
index aeeeb16a6..c207ab918 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantCreateEventHandler.cs
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantCreateEventHandler.cs
@@ -6,29 +6,30 @@ using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
+using Volo.Abp.Uow;
namespace LINGYUN.Abp.MultiTenancy.DbFinder.EventBus.Distributed
{
public class TenantCreateEventHandler : IDistributedEventHandler>, ITransientDependency
{
- private readonly IDataFilter _dataFilter;
+ private readonly ICurrentTenant _currentTenant;
private readonly ITenantRepository _tenantRepository;
private readonly IDistributedCache _cache;
public TenantCreateEventHandler(
- IDataFilter dataFilter,
+ ICurrentTenant currentTenant,
ITenantRepository tenantRepository,
IDistributedCache cache)
{
_cache = cache;
- _dataFilter = dataFilter;
+ _currentTenant = currentTenant;
_tenantRepository = tenantRepository;
}
+ [UnitOfWork]
public virtual async Task HandleEventAsync(EntityCreatedEto eventData)
{
- // 禁用租户过滤器
- using (_dataFilter.Disable())
+ using (_currentTenant.Change(null))
{
var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true);
if (tenant == null)
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantUpdateEventHandler.cs b/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantUpdateEventHandler.cs
index 2d0c597a2..4fe9dd599 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantUpdateEventHandler.cs
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/EventBus/Distributed/TenantUpdateEventHandler.cs
@@ -6,29 +6,30 @@ using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
+using Volo.Abp.Uow;
namespace LINGYUN.Abp.MultiTenancy.DbFinder.EventBus.Distributed
{
public class TenantUpdateEventHandler : IDistributedEventHandler>, ITransientDependency
{
- private readonly IDataFilter _dataFilter;
+ private readonly ICurrentTenant _currentTenant;
private readonly ITenantRepository _tenantRepository;
private readonly IDistributedCache _cache;
public TenantUpdateEventHandler(
- IDataFilter dataFilter,
+ ICurrentTenant currentTenant,
ITenantRepository tenantRepository,
IDistributedCache cache)
{
_cache = cache;
- _dataFilter = dataFilter;
+ _currentTenant = currentTenant;
_tenantRepository = tenantRepository;
}
+ [UnitOfWork]
public virtual async Task HandleEventAsync(EntityUpdatedEto eventData)
{
- // 禁用租户过滤器
- using (_dataFilter.Disable())
+ using (_currentTenant.Change(null))
{
var tenant = await _tenantRepository.FindAsync(eventData.Entity.Id, true);
if (tenant == null)
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/TenantStore.cs b/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/TenantStore.cs
index b42114d7c..f3979f5f5 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/TenantStore.cs
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.MultiTenancy.DbFinder/LINGYUN/Abp/MultiTenancy/DbFinder/TenantStore.cs
@@ -19,16 +19,16 @@ namespace LINGYUN.Abp.MultiTenancy.DbFinder
{
public ILogger Logger { protected get; set; }
private readonly IDistributedCache _cache;
- private readonly IDataFilter _dataFilter;
+ private readonly ICurrentTenant _currentTenant;
private readonly ITenantRepository _tenantRepository;
public TenantStore(
- IDataFilter dataFilter,
+ ICurrentTenant currentTenant,
ITenantRepository tenantRepository,
IDistributedCache cache)
{
_cache = cache;
- _dataFilter = dataFilter;
+ _currentTenant = currentTenant;
_tenantRepository = tenantRepository;
Logger = NullLogger.Instance;
@@ -91,8 +91,7 @@ namespace LINGYUN.Abp.MultiTenancy.DbFinder
}
Logger.LogDebug($"Not found in the cache, getting from the repository: {cacheKey}");
- // 禁用租户过滤器
- using (_dataFilter.Disable())
+ using (_currentTenant.Change(null))
{
var tenant = await _tenantRepository.FindAsync(id, true);
if (tenant == null)
@@ -129,7 +128,7 @@ namespace LINGYUN.Abp.MultiTenancy.DbFinder
}
Logger.LogDebug($"Not found in the cache, getting from the repository: {cacheKey}");
- using (_dataFilter.Disable())
+ using (_currentTenant.Change(null))
{
var tenant = await _tenantRepository.FindByNameAsync(name);
if (tenant == null)
diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/TenantAppService.cs b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/TenantAppService.cs
index 6c40eb4c7..9772d2bde 100644
--- a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/TenantAppService.cs
+++ b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/TenantAppService.cs
@@ -146,7 +146,16 @@ namespace LINGYUN.Abp.TenantManagement
{
var tenant = await TenantRepository.GetAsync(id);
tenant.SetConnectionString(tenantConnectionStringCreateOrUpdate.Name, tenantConnectionStringCreateOrUpdate.Value);
-
+ var updateEventData = new UpdateEventData
+ {
+ Id = tenant.Id,
+ OriginName = tenant.Name,
+ Name = tenant.Name
+ };
+ // abp当前版本(3.0.0)在EntityChangeEventHelper中存在一个问题,无法发送框架默认的Eto,预计3.1.0修复
+ // 发送自定义的事件数据来确保缓存被更新
+ await EventBus.PublishAsync(updateEventData);
+
return new TenantConnectionStringDto
{
Name = tenantConnectionStringCreateOrUpdate.Name,
@@ -160,6 +169,15 @@ namespace LINGYUN.Abp.TenantManagement
var tenant = await TenantRepository.GetAsync(tenantConnectionGetByName.Id);
tenant.RemoveConnectionString(tenantConnectionGetByName.Name);
+
+ var updateEventData = new UpdateEventData
+ {
+ Id = tenant.Id,
+ OriginName = tenant.Name,
+ Name = tenant.Name
+ };
+ await EventBus.PublishAsync(updateEventData);
+
await TenantRepository.UpdateAsync(tenant);
}
}
diff --git a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
index baffec853..543961a9c 100644
--- a/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
+++ b/aspnet-core/services/account/AuthServer.Host/AuthIdentityServerModule.cs
@@ -1,10 +1,13 @@
using DotNetCore.CAP;
+using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.IdentityServer;
+using LINGYUN.Abp.MultiTenancy.DbFinder;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -17,6 +20,7 @@ using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
using Volo.Abp.Caching;
+using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
@@ -39,6 +43,9 @@ namespace AuthServer.Host
typeof(AbpAutofacModule),
typeof(AbpCAPEventBusModule),
typeof(AbpIdentityAspNetCoreModule),
+ typeof(AbpDbFinderMultiTenancyModule),
+ typeof(AbpDddDomainEntitesEventsModule),
+ typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpIdentityServerSmsValidatorModule),
typeof(AbpIdentityServerWeChatValidatorModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
@@ -88,13 +95,27 @@ namespace AuthServer.Host
Configure(options =>
{
+ // 最好统一命名,不然某个缓存变动其他应用服务有例外发生
+ options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
- options.GlobalCacheEntryOptions.AbsoluteExpiration = DateTimeOffset.Now.AddDays(60);
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
});
+ Configure(options =>
+ {
+ var redisConfig = ConfigurationOptions.Parse(options.Configuration);
+ // 单独一个缓存数据库
+ var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
+ if (databaseConfig.Exists())
+ {
+ redisConfig.DefaultDatabase = databaseConfig.Get();
+ }
+ options.ConfigurationOptions = redisConfig;
+ options.InstanceName = configuration["Redis:InstanceName"];
+ });
+
Configure(options =>
{
options.Languages.Add(new LanguageInfo("en", "en", "English"));
@@ -121,13 +142,6 @@ namespace AuthServer.Host
options.IsEnabled = true;
});
- context.Services.AddStackExchangeRedisCache(options =>
- {
- options.Configuration = configuration["RedisCache:ConnectString"];
- var instanceName = configuration["RedisCache:RedisPrefix"];
- options.InstanceName = instanceName.IsNullOrEmpty() ? "MessageService_Cache" : instanceName;
- });
-
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);
diff --git a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
index fb3b42540..8b53e7a06 100644
--- a/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
+++ b/aspnet-core/services/account/AuthServer.Host/AuthServer.Host.csproj
@@ -15,12 +15,12 @@
-
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
@@ -33,9 +33,11 @@
+
+
diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
index dcb6e577c..99abb0a3b 100644
--- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
+++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
@@ -1,11 +1,13 @@
using DotNetCore.CAP;
using IdentityModel;
+using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.FileManagement;
using LINGYUN.Abp.Location.Tencent;
using LINGYUN.Abp.MessageService;
+using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.SettingManagement;
using LINGYUN.Abp.TenantManagement;
using LINGYUN.ApiGateway;
@@ -16,6 +18,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -31,10 +34,10 @@ using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac;
using Volo.Abp.Caching;
+using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
-using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Identity.Localization;
using Volo.Abp.IdentityServer.EntityFrameworkCore;
using Volo.Abp.Localization;
@@ -87,6 +90,9 @@ namespace LINGYUN.BackendAdmin
typeof(AbpCAPEventBusModule),
typeof(AbpAliyunSmsModule),
typeof(AbpTencentLocationModule),
+ typeof(AbpDbFinderMultiTenancyModule),
+ typeof(AbpCachingStackExchangeRedisModule),
+ typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule)
)]
public class BackendAdminHostModule : AbpModule
@@ -158,12 +164,27 @@ namespace LINGYUN.BackendAdmin
Configure(options =>
{
+ // 最好统一命名,不然某个缓存变动其他应用服务有例外发生
+ options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
});
+ Configure(options =>
+ {
+ var redisConfig = ConfigurationOptions.Parse(options.Configuration);
+ // 单独一个缓存数据库
+ var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
+ if (databaseConfig.Exists())
+ {
+ redisConfig.DefaultDatabase = databaseConfig.Get();
+ }
+ options.ConfigurationOptions = redisConfig;
+ options.InstanceName = configuration["Redis:InstanceName"];
+ });
+
Configure(options =>
{
options.FileSets.AddEmbedded("LINGYUN.BackendAdmin");
@@ -222,13 +243,6 @@ namespace LINGYUN.BackendAdmin
AbpClaimTypes.Email = JwtClaimTypes.Email;
});
- context.Services.AddStackExchangeRedisCache(options =>
- {
- options.Configuration = configuration["RedisCache:ConnectString"];
- var instanceName = configuration["RedisCache:RedisPrefix"];
- options.InstanceName = instanceName.IsNullOrEmpty() ? "BackendAdmin_Cache" : instanceName;
- });
-
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);
diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
index b68c8b473..cda240fd0 100644
--- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
+++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
@@ -26,12 +26,11 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
@@ -40,6 +39,7 @@
+
@@ -60,6 +60,7 @@
+
@@ -75,6 +76,7 @@
+
diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs
index 6006e0251..991272cb8 100644
--- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs
+++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/ApiGatewayHttpApiHostModule.cs
@@ -1,12 +1,15 @@
using DotNetCore.CAP;
using DotNetCore.CAP.Messages;
using IdentityModel;
+using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP;
+using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.ApiGateway.EntityFrameworkCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -18,6 +21,8 @@ using System.Text;
using Volo.Abp;
using Volo.Abp.Autofac;
using Volo.Abp.AutoMapper;
+using Volo.Abp.Caching;
+using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
@@ -42,6 +47,9 @@ namespace LINGYUN.ApiGateway
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpCAPEventBusModule),
+ typeof(AbpDbFinderMultiTenancyModule),
+ typeof(AbpCachingStackExchangeRedisModule),
+ typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule)
)]
public class ApiGatewayHttpApiHostModule : AbpModule
@@ -79,6 +87,29 @@ namespace LINGYUN.ApiGateway
options.DefaultSalt = Encoding.ASCII.GetBytes("sf&5)s3#");
});
+ Configure(options =>
+ {
+ // 最好统一命名,不然某个缓存变动其他应用服务有例外发生
+ options.KeyPrefix = "LINGYUN.Abp.Application";
+ // 滑动过期30天
+ options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
+ // 绝对过期60天
+ options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(60);
+ });
+
+ Configure(options =>
+ {
+ var redisConfig = ConfigurationOptions.Parse(options.Configuration);
+ // 单独一个缓存数据库
+ var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
+ if (databaseConfig.Exists())
+ {
+ redisConfig.DefaultDatabase = databaseConfig.Get();
+ }
+ options.ConfigurationOptions = redisConfig;
+ options.InstanceName = configuration["Redis:InstanceName"];
+ });
+
// 多租户
Configure(options =>
{
@@ -119,13 +150,6 @@ namespace LINGYUN.ApiGateway
AbpClaimTypes.Email = JwtClaimTypes.Email;
});
- context.Services.AddStackExchangeRedisCache(options =>
- {
- options.Configuration = configuration["RedisCache:ConnectString"];
- var instanceName = configuration["RedisCache:RedisPrefix"];
- options.InstanceName = instanceName.IsNullOrEmpty() ? "ApiGateway_Cache" : instanceName;
- });
-
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);
diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
index 2c4fb1915..e7b4803ec 100644
--- a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
+++ b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.HttpApi.Host/LINGYUN.ApiGateway.HttpApi.Host.csproj
@@ -11,15 +11,14 @@
-
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
@@ -28,6 +27,7 @@
+
@@ -39,7 +39,9 @@
+
+
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
index a3ffed6e2..ec9408620 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
@@ -39,6 +39,10 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
///
protected INotificationStore NotificationStore { get; }
///
+ /// Reference to .
+ ///
+ protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
+ ///
/// Reference to .
///
protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
@@ -50,11 +54,13 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
IBackgroundJobManager backgroundJobManager,
IOptions options,
INotificationStore notificationStore,
+ INotificationSubscriptionManager notificationSubscriptionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
BackgroundJobManager = backgroundJobManager;
Options = options.Value;
NotificationStore = notificationStore;
+ NotificationSubscriptionManager = notificationSubscriptionManager;
NotificationPublishProviderManager = notificationPublishProviderManager;
Logger = NullLogger.Instance;
@@ -85,9 +91,16 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
// 持久化通知
await NotificationStore.InsertNotificationAsync(notificationInfo);
+ // TODO: 某些情况下,不能直接在服务内订阅消息,目前只能通过将订阅内容放进消息内部,需要重构通知系统设计了
+ if (notificationInfo.Data.HasUserNotification(out Guid userId, out string userName))
+ {
+ await NotificationSubscriptionManager.SubscribeAsync(notificationInfo.TenantId,
+ new UserIdentifier(userId, userName), notificationInfo.Name);
+ }
+
Logger.LogDebug($"Gets a list of user subscriptions {notificationInfo.Name}");
// 获取用户订阅列表
- var userSubscriptions = await NotificationStore.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
+ var userSubscriptions = await NotificationSubscriptionManager.GetSubscriptionsAsync(notificationInfo.TenantId, notificationInfo.Name);
Logger.LogDebug($"Persistent user notifications {notificationInfo.Name}");
// 持久化用户通知
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs
index 9053a16e9..f7aeb94ec 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/TenantCreateEventHandler.cs
@@ -55,7 +55,7 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
// 管理用户订阅租户创建通知
await NotificationSubscriptionManager.SubscribeAsync(eventData.Id, tenantAdminUserIdentifier, noticeNormalizerName.Name);
- var notificationData = new NotificationData();
+ var notificationData = NotificationData.CreateTenantNotificationData(eventData.Id);
notificationData.WriteStandardData(
L("NewTenantRegisteredNotificationTitle"),
L("NewTenantRegisteredNotificationMessage", eventData.Name),
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
index a70f01c71..7f323bee6 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
@@ -19,12 +19,11 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
@@ -33,6 +32,7 @@
+
@@ -43,6 +43,7 @@
+
@@ -53,6 +54,7 @@
+
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs
index 8a4b61c99..4b7729474 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN/Abp/MessageService/AbpMessageServiceHttpApiHostModule.cs
@@ -2,6 +2,7 @@
using Hangfire;
using IdentityModel;
using LINGYUN.Abp.BackgroundJobs.Hangfire;
+using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Notifications;
@@ -10,11 +11,13 @@ using LINGYUN.Abp.IM.SignalR;
using LINGYUN.Abp.MessageService.EntityFrameworkCore;
using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.MultiTenancy;
+using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.Notifications.SignalR;
using LINGYUN.Abp.Notifications.WeChat.WeApp;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -27,6 +30,7 @@ using Volo.Abp.AspNetCore.Authentication.JwtBearer;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.Autofac;
using Volo.Abp.Caching;
+using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
@@ -56,6 +60,9 @@ namespace LINGYUN.Abp.MessageService
typeof(AbpCAPEventBusModule),
typeof(AbpBackgroundJobsHangfireModule),
typeof(AbpHangfireMySqlStorageModule),
+ typeof(AbpDbFinderMultiTenancyModule),
+ typeof(AbpCachingStackExchangeRedisModule),
+ typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule)
)]
public class AbpMessageServiceHttpApiHostModule : AbpModule
@@ -124,6 +131,29 @@ namespace LINGYUN.Abp.MessageService
options.TenantResolvers.Insert(0, new AuthorizationTenantResolveContributor());
});
+ Configure(options =>
+ {
+ // 最好统一命名,不然某个缓存变动其他应用服务有例外发生
+ options.KeyPrefix = "LINGYUN.Abp.Application";
+ // 滑动过期30天
+ options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
+ // 绝对过期60天
+ options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
+ });
+
+ Configure(options =>
+ {
+ var redisConfig = ConfigurationOptions.Parse(options.Configuration);
+ // 单独一个缓存数据库
+ var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
+ if (databaseConfig.Exists())
+ {
+ redisConfig.DefaultDatabase = databaseConfig.Get();
+ }
+ options.ConfigurationOptions = redisConfig;
+ options.InstanceName = configuration["Redis:InstanceName"];
+ });
+
// Swagger
context.Services.AddSwaggerGen(
options =>
@@ -156,13 +186,6 @@ namespace LINGYUN.Abp.MessageService
AbpClaimTypes.Email = JwtClaimTypes.Email;
});
- context.Services.AddStackExchangeRedisCache(options =>
- {
- options.Configuration = configuration["RedisCache:ConnectString"];
- var instanceName = configuration["RedisCache:RedisPrefix"];
- options.InstanceName = instanceName.IsNullOrEmpty() ? "MessageService_Cache" : instanceName;
- });
-
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);
diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs
index f1a4587ff..1a23b6508 100644
--- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs
+++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs
@@ -1,9 +1,11 @@
using DotNetCore.CAP;
using IdentityModel;
+using LINGYUN.Abp.Domain.Entities.Events;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.FileManagement;
+using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.Notifications;
using LINGYUN.Platform.EntityFrameworkCore;
using LINGYUN.Platform.HttpApi;
@@ -12,6 +14,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -27,6 +30,7 @@ using Volo.Abp.Autofac;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Caching;
+using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
@@ -55,6 +59,9 @@ namespace LINGYUN.Platform
typeof(AbpEmailingExceptionHandlingModule),
typeof(AbpCAPEventBusModule),
typeof(AbpBlobStoringFileSystemModule),
+ typeof(AbpDbFinderMultiTenancyModule),
+ typeof(AbpCachingStackExchangeRedisModule),
+ typeof(AbpDddDomainEntitesEventsModule),
typeof(AbpAutofacModule)
)]
public class AppPlatformHttpApiHostModule : AbpModule
@@ -129,12 +136,27 @@ namespace LINGYUN.Platform
Configure(options =>
{
+ // 最好统一命名,不然某个缓存变动其他应用服务有例外发生
+ options.KeyPrefix = "LINGYUN.Abp.Application";
// 滑动过期30天
options.GlobalCacheEntryOptions.SlidingExpiration = TimeSpan.FromDays(30);
// 绝对过期60天
options.GlobalCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
});
+ Configure(options =>
+ {
+ var redisConfig = ConfigurationOptions.Parse(options.Configuration);
+ // 单独一个缓存数据库
+ var databaseConfig = configuration.GetSection("Redis:DefaultDatabase");
+ if (databaseConfig.Exists())
+ {
+ redisConfig.DefaultDatabase = databaseConfig.Get();
+ }
+ options.ConfigurationOptions = redisConfig;
+ options.InstanceName = configuration["Redis:InstanceName"];
+ });
+
Configure(options =>
{
options.FileSets.AddEmbedded("LINGYUN.Platform");
@@ -190,13 +212,6 @@ namespace LINGYUN.Platform
AbpClaimTypes.Email = JwtClaimTypes.Email;
});
- context.Services.AddStackExchangeRedisCache(options =>
- {
- options.Configuration = configuration["RedisCache:ConnectString"];
- var instanceName = configuration["RedisCache:RedisPrefix"];
- options.InstanceName = instanceName.IsNullOrEmpty() ? "Platform_Cache" : instanceName;
- });
-
if (!hostingEnvironment.IsDevelopment())
{
var redis = ConnectionMultiplexer.Connect(configuration["RedisCache:ConnectString"]);
diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
index ac8e55757..00aa72acf 100644
--- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
+++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj
@@ -21,12 +21,11 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
@@ -35,6 +34,7 @@
+
@@ -46,6 +46,7 @@
+
@@ -54,6 +55,7 @@
+