diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index d17f70703..e4a9ea883 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -404,9 +404,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Organi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Emailing", "modules\common\LINGYUN.Abp.Notifications.Emailing\LINGYUN.Abp.Notifications.Emailing.csproj", "{88502844-D83C-4541-96AC-A8291E261F63}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Platform.Theme.VueVbenAdmin", "modules\platform\LINGYUN.Platform.Theme.VueVbenAdmin\LINGYUN.Platform.Theme.VueVbenAdmin.csproj", "{67DC7FA0-506A-4977-95F6-BC739B2BC4BA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Platform.Theme.VueVbenAdmin", "modules\platform\LINGYUN.Platform.Theme.VueVbenAdmin\LINGYUN.Platform.Theme.VueVbenAdmin.csproj", "{67DC7FA0-506A-4977-95F6-BC739B2BC4BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Platform.Settings.VueVbenAdmin", "modules\platform\LINGYUN.Platform.Settings.VueVbenAdmin\LINGYUN.Platform.Settings.VueVbenAdmin.csproj", "{8DF55DAB-4C1D-46F7-9324-0050F47B3BED}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Platform.Settings.VueVbenAdmin", "modules\platform\LINGYUN.Platform.Settings.VueVbenAdmin\LINGYUN.Platform.Settings.VueVbenAdmin.csproj", "{8DF55DAB-4C1D-46F7-9324-0050F47B3BED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.TextTemplating", "modules\common\LINGYUN.Abp.Notifications.TextTemplating\LINGYUN.Abp.Notifications.TextTemplating.csproj", "{06FF5EFA-DEDA-4E12-A482-8FCE4077F68A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1054,6 +1056,10 @@ Global {8DF55DAB-4C1D-46F7-9324-0050F47B3BED}.Debug|Any CPU.Build.0 = Debug|Any CPU {8DF55DAB-4C1D-46F7-9324-0050F47B3BED}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DF55DAB-4C1D-46F7-9324-0050F47B3BED}.Release|Any CPU.Build.0 = Release|Any CPU + {06FF5EFA-DEDA-4E12-A482-8FCE4077F68A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06FF5EFA-DEDA-4E12-A482-8FCE4077F68A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06FF5EFA-DEDA-4E12-A482-8FCE4077F68A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06FF5EFA-DEDA-4E12-A482-8FCE4077F68A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1253,6 +1259,7 @@ Global {88502844-D83C-4541-96AC-A8291E261F63} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {67DC7FA0-506A-4977-95F6-BC739B2BC4BA} = {F4923692-D343-4318-AECA-96F580B1A563} {8DF55DAB-4C1D-46F7-9324-0050F47B3BED} = {F4923692-D343-4318-AECA-96F580B1A563} + {06FF5EFA-DEDA-4E12-A482-8FCE4077F68A} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} 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 72a0bbc08..cdc027df6 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 @@ -38,7 +38,7 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications await notificationSender.SendNofiterAsync( AbpExceptionHandlingNotificationNames.NotificationName, notificationData, - null, + user: null, CurrentTenant.Id, NotificationSeverity.Error); } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/EmailingNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/EmailingNotificationPublishProvider.cs index 9321cc6c5..3a8daa709 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/EmailingNotificationPublishProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/EmailingNotificationPublishProvider.cs @@ -28,13 +28,11 @@ public class EmailingNotificationPublishProvider : NotificationPublishProvider protected INotificationDefinitionManager NotificationDefinitionManager { get; } public EmailingNotificationPublishProvider( - IServiceProvider serviceProvider, IEmailSender emailSender, ITemplateRenderer templateRenderer, IStringLocalizerFactory localizerFactory, IIdentityUserRepository userRepository, INotificationDefinitionManager notificationDefinitionManager) - : base(serviceProvider) { EmailSender = emailSender; TemplateRenderer = templateRenderer; 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 2a78d3fff..d69c61c75 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 @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; - + namespace LINGYUN.Abp.Notifications.SignalR { public class SignalRNotificationPublishProvider : NotificationPublishProvider @@ -19,16 +19,17 @@ namespace LINGYUN.Abp.Notifications.SignalR private readonly AbpNotificationsSignalROptions _options; public SignalRNotificationPublishProvider( - IHubContext hubContext, - IOptions options, - IServiceProvider serviceProvider) - : base(serviceProvider) + IHubContext hubContext, + IOptions options) { _options = options.Value; _hubContext = hubContext; } - protected override async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers, CancellationToken cancellationToken = default) + protected async override Task PublishAsync( + NotificationInfo notification, + IEnumerable identifiers, + CancellationToken cancellationToken = default) { if (identifiers?.Count() == 0) { @@ -53,6 +54,6 @@ namespace LINGYUN.Abp.Notifications.SignalR Logger.LogWarning("Send to user notifications error: {0}", ex.Message); } } - } + } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationPublishProvider.cs index 9e001a290..10b64289e 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationPublishProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationPublishProvider.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Options; -using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -11,18 +10,14 @@ namespace LINGYUN.Abp.Notifications.Sms { public const string ProviderName = NotificationProviderNames.Sms; - private IUserPhoneFinder _userPhoneFinder; - protected IUserPhoneFinder UserPhoneFinder => LazyGetRequiredService(ref _userPhoneFinder); - + protected IUserPhoneFinder UserPhoneFinder => ServiceProvider.LazyGetRequiredService(); protected ISmsNotificationSender Sender { get; } protected AbpNotificationsSmsOptions Options { get; } public SmsNotificationPublishProvider( - IServiceProvider serviceProvider, ISmsNotificationSender sender, IOptions options) - : base(serviceProvider) { Sender = sender; Options = options.Value; @@ -46,6 +41,6 @@ namespace LINGYUN.Abp.Notifications.Sms return; } await Sender.SendAsync(notification, sendToPhones.JoinAsString(",")); - } + } } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationSender.cs index 166e7e8e7..b55dc353d 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationSender.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationSender.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Sms; @@ -40,6 +41,7 @@ namespace LINGYUN.Abp.Notifications.Sms // TODO: 后期增强功能,增加短信模板、通知模板功能 message.Properties.Add("TemplateCode", templateCode); message.Properties.Add("SignName", notification.Data.TryGetData("SignName")); + message.Properties.AddIfNotContains(notification.Data.ExtraProperties); await SmsSender.SendAsync(message); } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/FodyWeavers.xml b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN.Abp.Notifications.TextTemplating.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN.Abp.Notifications.TextTemplating.csproj new file mode 100644 index 000000000..3f15a30e1 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN.Abp.Notifications.TextTemplating.csproj @@ -0,0 +1,19 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN/Abp/Notifications/TextTemplating/AbpNotificationsTextTemplatingModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN/Abp/Notifications/TextTemplating/AbpNotificationsTextTemplatingModule.cs new file mode 100644 index 000000000..3cfb08970 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN/Abp/Notifications/TextTemplating/AbpNotificationsTextTemplatingModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; +using Volo.Abp.TextTemplating; + +namespace LINGYUN.Abp.Notifications.TextTemplating; + +[DependsOn( + typeof(AbpNotificationModule), + typeof(AbpTextTemplatingCoreModule))] +public class AbpNotificationsTextTemplatingModule : AbpModule +{ + +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN/Abp/Notifications/TextTemplating/NotificationTemplateContentContributor.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN/Abp/Notifications/TextTemplating/NotificationTemplateContentContributor.cs new file mode 100644 index 000000000..f1708d705 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.TextTemplating/LINGYUN/Abp/Notifications/TextTemplating/NotificationTemplateContentContributor.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.DependencyInjection; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace LINGYUN.Abp.Notifications.TextTemplating; + +public class NotificationTemplateContentContributor : ITemplateContentContributor, ITransientDependency +{ + public async virtual Task GetOrNullAsync(TemplateContentContributorContext context) + { + var store = context.ServiceProvider.GetRequiredService(); + + return await store.GetOrNullAsync(context.TemplateDefinition.Name, context.Culture); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSender.cs index 9e9447359..8a7c2c632 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSender.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSender.cs @@ -14,28 +14,28 @@ namespace LINGYUN.Abp.Notifications /// /// 名称 /// 数据 - /// 用户,为空标识发给所有订阅用户 + /// 用户列表,为空标识发给所有订阅用户 /// 租户 /// 严重级别 /// 通知标识 Task SendNofiterAsync( string name, NotificationData data, - UserIdentifier user = null, + IEnumerable users = null, Guid? tenantId = null, NotificationSeverity severity = NotificationSeverity.Info); - /// - /// 发送通知 - /// - /// 名称 - /// 数据 - /// 用户列表,为空标识发给所有订阅用户 - /// 租户 - /// 严重级别 - /// 通知标识 - Task SendNofitersAsync( - string name, - NotificationData data, + /// + /// 发送模板通知 + /// + /// 名称 + /// 模板对象 + /// 用户列表,为空标识发给所有订阅用户 + /// 租户 + /// 严重级别 + /// + Task SendNofiterAsync( + string name, + NotificationTemplate template, IEnumerable users = null, Guid? tenantId = null, NotificationSeverity severity = NotificationSeverity.Info); diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSenderExtensions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSenderExtensions.cs new file mode 100644 index 000000000..d4a63729a --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationSenderExtensions.cs @@ -0,0 +1,66 @@ +using JetBrains.Annotations; +using System; +using System.Threading.Tasks; +using Volo.Abp; + +namespace LINGYUN.Abp.Notifications; +public static class INotificationSenderExtensions +{ + /// + /// 发送通知 + /// + /// 发送接口 + /// 名称 + /// 数据 + /// 用户,为空标识发给所有订阅用户 + /// 租户 + /// 严重级别 + /// 通知标识 + public async static Task SendNofiterAsync( + [NotNull] this INotificationSender sender, + [NotNull] string name, + [NotNull] NotificationData data, + UserIdentifier user = null, + Guid? tenantId = null, + NotificationSeverity severity = NotificationSeverity.Info) + { + Check.NotNull(sender, nameof(sender)); + Check.NotNullOrWhiteSpace(name, nameof(name)); + Check.NotNull(data, nameof(data)); + + if (user == null) + { + return await sender.SendNofiterAsync(name, data, tenantId: tenantId, severity: severity); + } + return await sender.SendNofiterAsync(name, data, new[] { user },tenantId: tenantId, severity: severity); + } + + /// + /// 发送模板通知 + /// + /// 发送接口 + /// 名称 + /// 模板对象 + /// 用户,为空发给所有订阅用户 + /// 租户 + /// 严重级别 + /// 通知标识 + public async static Task SendNofiterAsync( + [NotNull] this INotificationSender sender, + [NotNull] string name, + [NotNull] NotificationTemplate template, + UserIdentifier user = null, + Guid? tenantId = null, + NotificationSeverity severity = NotificationSeverity.Info) + { + Check.NotNull(sender, nameof(sender)); + Check.NotNullOrWhiteSpace(name, nameof(name)); + Check.NotNull(template, nameof(template)); + + if (user == null) + { + return await sender.SendNofiterAsync(name, template, tenantId: tenantId, severity: severity); + } + return await sender.SendNofiterAsync(name, template, new[] { user }, tenantId: tenantId, severity: severity); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs index 3e0f502f1..f6ac6a33e 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationStore.cs @@ -121,5 +121,12 @@ namespace LINGYUN.Abp.Notifications long notificationId, NotificationReadState readState, CancellationToken cancellationToken = default); + + Task ChangeUserNotificationsReadStateAsync( + Guid? tenantId, + Guid userId, + IEnumerable notificationIds, + NotificationReadState readState, + CancellationToken cancellationToken = default); } } diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationTemplateStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationTemplateStore.cs new file mode 100644 index 000000000..f2a39812e --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationTemplateStore.cs @@ -0,0 +1,9 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.Notifications; + +public interface INotificationTemplateStore +{ + Task GetOrNullAsync(string templateName, string culture = null, CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs index 1b6c905e9..2dcdd021c 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs @@ -1,5 +1,4 @@ using LINGYUN.Abp.IdGenerator; -using LINGYUN.Abp.RealTime; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -50,25 +49,7 @@ namespace LINGYUN.Abp.Notifications Logger = NullLogger.Instance; } - public async Task SendNofiterAsync( - string name, - NotificationData data, - UserIdentifier user = null, - Guid? tenantId = null, - NotificationSeverity severity = NotificationSeverity.Info) - { - if (user == null) - { - return await PublishNofiterAsync(name, data, null, tenantId, severity); - - } - else - { - return await PublishNofiterAsync(name, data, new List { user }, tenantId, severity); - } - } - - public async Task SendNofitersAsync( + public async virtual Task SendNofiterAsync( string name, NotificationData data, IEnumerable users = null, @@ -76,16 +57,26 @@ namespace LINGYUN.Abp.Notifications NotificationSeverity severity = NotificationSeverity.Info) { return await PublishNofiterAsync(name, data, users, tenantId, severity); - } - - protected async Task PublishNofiterAsync( - string name, - NotificationData data, + } + + public async virtual Task SendNofiterAsync( + string name, + NotificationTemplate template, + IEnumerable users = null, + Guid? tenantId = null, + NotificationSeverity severity = NotificationSeverity.Info) + { + return await PublishNofiterAsync(name, template, users, tenantId, severity); + } + + protected async virtual Task PublishNofiterAsync( + string name, + TData data, IEnumerable users = null, Guid? tenantId = null, NotificationSeverity severity = NotificationSeverity.Info) - { - var eto = new NotificationEto(data) + { + var eto = new NotificationEto(data) { Id = DistributedIdGenerator.Create(), TenantId = tenantId, @@ -108,6 +99,6 @@ namespace LINGYUN.Abp.Notifications } return eto.Id.ToString(); - } + } } } 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 5c8e89cf6..2a84d9225 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 @@ -49,7 +49,6 @@ namespace LINGYUN.Abp.Notifications /// 通知提供者 /// public List Providers { get; } - /// /// 额外属性 /// diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs index 20bf329eb..b5679c4e2 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using System; using System.Collections.Generic; @@ -14,40 +13,14 @@ namespace LINGYUN.Abp.Notifications { public abstract string Name { get; } - protected IServiceProvider ServiceProvider { get; } + public IAbpLazyServiceProvider ServiceProvider { protected get; set; } - protected readonly object ServiceProviderLock = new object(); - - public ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; + public ILoggerFactory LoggerFactory => ServiceProvider.LazyGetRequiredService(); protected ILogger Logger => _lazyLogger.Value; private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); - - protected TService LazyGetRequiredService(ref TService reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = ServiceProvider.GetRequiredService(); - } - } - } - - return reference; - } - - public ICancellationTokenProvider CancellationTokenProvider { get; set; } - - protected NotificationPublishProvider(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - CancellationTokenProvider = NullCancellationTokenProvider.Instance; - } + public ICancellationTokenProvider CancellationTokenProvider => ServiceProvider.LazyGetService(NullCancellationTokenProvider.Instance); public async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers) { diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationTemplate.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationTemplate.cs new file mode 100644 index 000000000..e57ee61f9 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationTemplate.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.EventBus; + +namespace LINGYUN.Abp.Notifications; + +/// +/// 通知模板消息 +/// +[Serializable] +[EventName("notifications.template")] +public class NotificationTemplate : IHasExtraProperties +{ + public string Name { get; set; } + public string Title { get; set; } + public string Culture { get; set; } + public string FormUser { get; set; } + public object this[string key] + { + get { + return this.GetProperty(key); + } + set { + this.SetProperty(key, value); + } + } + public ExtraPropertyDictionary ExtraProperties { get; set; } + public NotificationTemplate( + string name, + string title, + string culture = null, + string formUser = null, + IDictionary data = null) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + + Title = title; + Culture = culture; + FormUser = formUser; + + if (data != null) + { + ExtraProperties = new ExtraPropertyDictionary(data); + } + else + { + ExtraProperties = new ExtraPropertyDictionary(); + this.SetDefaultsForExtraProperties(); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationStore.cs index df221796b..483c6e541 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationStore.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationStore.cs @@ -9,6 +9,8 @@ namespace LINGYUN.Abp.Notifications [Dependency(TryRegister = true)] public class NullNotificationStore : INotificationStore, ISingletonDependency { + public readonly static INotificationStore Instance = new NullNotificationStore(); + public Task ChangeUserNotificationReadStateAsync( Guid? tenantId, Guid userId, @@ -19,6 +21,16 @@ namespace LINGYUN.Abp.Notifications return Task.CompletedTask; } + public Task ChangeUserNotificationsReadStateAsync( + Guid? tenantId, + Guid userId, + IEnumerable notificationIds, + NotificationReadState readState, + CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + public Task DeleteAllUserSubscriptionAsync( Guid? tenantId, string notificationName, diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationTemplateStore.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationTemplateStore.cs new file mode 100644 index 000000000..f5b4da58c --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NullNotificationTemplateStore.cs @@ -0,0 +1,16 @@ +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.Notifications; + +[Dependency(TryRegister = true)] +public class NullNotificationTemplateStore : INotificationTemplateStore, ISingletonDependency +{ + public readonly static INotificationTemplateStore Instance = new NullNotificationTemplateStore(); + + public Task GetOrNullAsync(string templateName, string culture = null, CancellationToken cancellationToken = default) + { + return Task.FromResult(null); + } +} diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/en.json b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/en.json index b43620235..8766016cf 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/en.json +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/en.json @@ -59,6 +59,14 @@ "DisplayName:SmsVerifyCode": "SMS verification code", "DisplayName:EmailVerifyCode": "Mail verification code", "DisplayName:WeChatCode": "Wechat login code", - "SendRepeatSmsVerifyCode": "Phone verification code cannot be sent repeatedly within {0} minutes!" + "SendRepeatSmsVerifyCode": "Phone verification code cannot be sent repeatedly within {0} minutes!", + "LockTime": "Lock Time", + "LockType": "Lock Type", + "Confirmed": "Confirmed", + "UnConfirmed": "UnConfirmed", + "UnActived": "UnActived", + "LockoutEnd": "Lockout End", + "Public": "Public", + "Static": "Static" } } \ No newline at end of file diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/zh-Hans.json b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/zh-Hans.json index 549de3a63..e641f79ff 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/zh-Hans.json +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain.Shared/LINGYUN/Abp/Identity/Localization/zh-Hans.json @@ -59,6 +59,14 @@ "DisplayName:SmsVerifyCode": "短信验证码", "DisplayName:EmailVerifyCode": "邮件验证码", "DisplayName:WeChatCode": "微信登录凭证", - "SendRepeatSmsVerifyCode": "手机验证码不能在 {0} 分钟内重复发送!" + "SendRepeatSmsVerifyCode": "手机验证码不能在 {0} 分钟内重复发送!", + "LockTime": "锁定时间", + "LockType": "锁定类型", + "Confirmed": "已确认", + "UnConfirmed": "未确认", + "UnActived": "未启用", + "LockoutEnd": "锁定截止期", + "Public": "公用", + "Static": "内置" } } \ No newline at end of file diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationMarkReadStateInput.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationMarkReadStateInput.cs new file mode 100644 index 000000000..8e28a3c97 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/NotificationMarkReadStateInput.cs @@ -0,0 +1,12 @@ +using LINGYUN.Abp.Notifications; +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.MessageService.Notifications; + +public class NotificationMarkReadStateInput +{ + [Required] + public long[] IdList { get; set; } + + public NotificationReadState State { get; set; } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/UserNotificationDto.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/UserNotificationDto.cs new file mode 100644 index 000000000..972117926 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/Dto/UserNotificationDto.cs @@ -0,0 +1,16 @@ +using LINGYUN.Abp.Notifications; +using System; + +namespace LINGYUN.Abp.MessageService.Notifications; + +public class UserNotificationDto +{ + public string Name { get; set; } + public string Id { get; set; } + public NotificationData Data { get; set; } + public DateTime CreationTime { get; set; } + public NotificationLifetime Lifetime { get; set; } + public NotificationType Type { get; set; } + public NotificationSeverity Severity { get; set; } + public NotificationReadState State { get; set; } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/IMyNotificationAppService.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/IMyNotificationAppService.cs index 0c328c8f7..05b5dbeae 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/IMyNotificationAppService.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application.Contracts/LINGYUN/Abp/MessageService/Notifications/IMyNotificationAppService.cs @@ -1,5 +1,4 @@ -using LINGYUN.Abp.Notifications; -using System.Threading.Tasks; +using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; @@ -8,12 +7,14 @@ namespace LINGYUN.Abp.MessageService.Notifications public interface IMyNotificationAppService : IReadOnlyAppService< - NotificationInfo, + UserNotificationDto, long, UserNotificationGetByPagedDto >, IDeleteAppService { + Task MarkReadStateAsync(NotificationMarkReadStateInput input); + Task> GetAssignableNotifiersAsync(); } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationAutoMapperProfile.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationAutoMapperProfile.cs new file mode 100644 index 000000000..363e6aa80 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationAutoMapperProfile.cs @@ -0,0 +1,28 @@ +using AutoMapper; +using LINGYUN.Abp.MessageService.Notifications; +using LINGYUN.Abp.Notifications; +using System; + +namespace LINGYUN.Abp.MessageService +{ + public class AbpMessageServiceApplicationAutoMapperProfile : Profile + { + public AbpMessageServiceApplicationAutoMapperProfile() + { + CreateMap() + .ForMember(dto => dto.Id, map => map.MapFrom(src => src.Id.ToString())) + .ForMember(dto => dto.Lifetime, map => map.Ignore()) + .ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) => + { + var dataType = Type.GetType(src.NotificationTypeName); + var data = Activator.CreateInstance(dataType); + if (data is NotificationData notificationData) + { + notificationData.ExtraProperties = src.ExtraProperties; + return notificationData; + } + return new NotificationData(); + })); + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationModule.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationModule.cs index 61620440f..5f657bd1f 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationModule.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/AbpMessageServiceApplicationModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Modularity; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; namespace LINGYUN.Abp.MessageService { @@ -7,6 +8,12 @@ namespace LINGYUN.Abp.MessageService typeof(AbpMessageServiceDomainModule))] public class AbpMessageServiceApplicationModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.AddProfile(validate: true); + }); + } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Notifications/MyNotificationAppService.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Notifications/MyNotificationAppService.cs index 3a2cef825..5427776d5 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Notifications/MyNotificationAppService.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Application/LINGYUN/Abp/MessageService/Notifications/MyNotificationAppService.cs @@ -15,19 +15,23 @@ namespace LINGYUN.Abp.MessageService.Notifications protected INotificationStore NotificationStore { get; } + protected IUserNotificationRepository UserNotificationRepository { get; } + protected INotificationDefinitionManager NotificationDefinitionManager { get; } public MyNotificationAppService( INotificationStore notificationStore, INotificationSender notificationSender, + IUserNotificationRepository userNotificationRepository, INotificationDefinitionManager notificationDefinitionManager) { NotificationStore = notificationStore; NotificationSender = notificationSender; + UserNotificationRepository = userNotificationRepository; NotificationDefinitionManager = notificationDefinitionManager; } - public virtual async Task SendNofiterAsync(NotificationSendDto input) + public async virtual Task SendNofiterAsync(NotificationSendDto input) { UserIdentifier user = null; if (input.ToUserId.HasValue) @@ -43,7 +47,16 @@ namespace LINGYUN.Abp.MessageService.Notifications input.Severity); } - public virtual async Task DeleteAsync(long id) + public async virtual Task MarkReadStateAsync(NotificationMarkReadStateInput input) + { + await NotificationStore.ChangeUserNotificationsReadStateAsync( + CurrentTenant.Id, + CurrentUser.GetId(), + input.IdList, + input.State); + } + + public async virtual Task DeleteAsync(long id) { await NotificationStore .DeleteUserNotificationAsync( @@ -94,28 +107,29 @@ namespace LINGYUN.Abp.MessageService.Notifications return Task.FromResult(new ListResultDto(groups)); } - public virtual async Task GetAsync(long id) + public async virtual Task GetAsync(long id) { - return await NotificationStore - .GetNotificationOrNullAsync(CurrentTenant.Id, id); + var notification = await UserNotificationRepository.GetByIdAsync(CurrentUser.GetId(), id); + + return ObjectMapper.Map(notification); } - public virtual async Task> GetListAsync(UserNotificationGetByPagedDto input) + public async virtual Task> GetListAsync(UserNotificationGetByPagedDto input) { - var notificationCount = await NotificationStore - .GetUserNotificationsCountAsync( - CurrentTenant.Id, + var totalCount = await UserNotificationRepository + .GetCountAsync( CurrentUser.GetId(), input.Filter, input.ReadState); - var notifications = await NotificationStore - .GetUserNotificationsAsync( - CurrentTenant.Id, CurrentUser.GetId(), + var notifications = await UserNotificationRepository + .GetListAsync( + CurrentUser.GetId(), input.Filter, input.Sorting, input.ReadState, input.SkipCount, input.MaxResultCount); - return new PagedResultDto(notificationCount, notifications); + return new PagedResultDto(totalCount, + ObjectMapper.Map, List>(notifications)); } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json index 6a6402285..a18782a54 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json @@ -18,6 +18,18 @@ "LINGYUN.Abp.Message:03404": "Sending the message failed: the user does not exist or is deactivated!", "LINGYUN.Abp.Message:03410": "Users refuse to add friends", "LINGYUN.Abp.Message:03411": "The other party is already your friend or has sent an authentication request. The operation cannot be repeated!", + "MarkSelectedAsRead": "Mark selected as read", + "MarkAs": "Mark as", + "Read": "Read", + "UnRead": "Un Read", + "Notifications": "Notifications", + "Notifications:Title": "Title", + "Notifications:Content": "Content", + "Notifications:Type": "Type", + "Notifications:SendTime": "SendTime", + "Notifications:System": "System", + "Notifications:Application": "Platform", + "Notifications:User": "User", "Notifications:MultiTenancy": "Multi Tenancy", "Notifications:Users": "Users", "Notifications:NewTenantRegisterd": "Tenant creation notification", diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json index 27b1e8ea8..d9435eaaf 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json @@ -18,6 +18,18 @@ "LINGYUN.Abp.Message:03404": "发送消息失败: 用户不存在或已注销账号!", "LINGYUN.Abp.Message:03410": "用户拒绝添加好友", "LINGYUN.Abp.Message:03411": "对方已是您的好友或已发送验证请求,不能重复操作!", + "MarkSelectedAsRead": "标记选中已读", + "MarkAs": "标记为", + "Read": "已读", + "UnRead": "未读", + "Notifications": "通知列表", + "Notifications:Title": "标题", + "Notifications:Content": "内容", + "Notifications:Type": "类型", + "Notifications:SendTime": "发送时间", + "Notifications:System": "系统", + "Notifications:Application": "平台", + "Notifications:User": "用户", "Notifications:MultiTenancy": "租户通知", "Notifications:Users": "用户通知", "Notifications:NewTenantRegisterd": "租户创建通知", @@ -33,5 +45,6 @@ "AddNewFriendBySearchId": "通过账号搜索添加", "WelcomeToApplicationFormUser": "用户:{User} 欢迎您的加入!", "Messages:NewFriend": "我已经添加您为好友,让我们一起聊天吧!" + } } \ No newline at end of file diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs index 94d274986..847c20072 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Mapper/MessageServiceDomainAutoMapperProfile.cs @@ -17,12 +17,13 @@ namespace LINGYUN.Abp.MessageService.Mapper { public MessageServiceDomainAutoMapperProfile() { - CreateMap() - .ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId)) - .ForMember(dto => dto.Name, map => map.MapFrom(src => src.NotificationName)) + CreateMap() + .ForMember(dto => dto.Id, map => map.MapFrom(src => src.Id.ToString())) + .ForMember(dto => dto.Name, map => map.MapFrom(src => src.Name)) .ForMember(dto => dto.Lifetime, map => map.Ignore()) .ForMember(dto => dto.Type, map => map.MapFrom(src => src.Type)) .ForMember(dto => dto.Severity, map => map.MapFrom(src => src.Severity)) + .ForMember(dto => dto.CreationTime, map => map.MapFrom(src => src.CreationTime)) .ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) => { var dataType = Type.GetType(src.NotificationTypeName); @@ -35,9 +36,6 @@ namespace LINGYUN.Abp.MessageService.Mapper return new NotificationData(); })); - //CreateMap() - // .ConvertUsing(); - CreateMap(); CreateMessageMap() diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs index 5af844aaf..9dcfd7b68 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/IUserNotificationRepository.cs @@ -14,16 +14,17 @@ namespace LINGYUN.Abp.MessageService.Notifications long notificationId, CancellationToken cancellationToken = default); - Task InsertUserNotificationsAsync( - IEnumerable userNotifications, + Task GetByIdAsync( + Guid userId, + long notificationId, CancellationToken cancellationToken = default); - Task GetByIdAsync( + Task> GetListAsync( Guid userId, - long notificationId, + IEnumerable notificationIds, CancellationToken cancellationToken = default); - Task> GetNotificationsAsync( + Task> GetNotificationsAsync( Guid userId, NotificationReadState? readState = null, int maxResultCount = 10, @@ -35,7 +36,7 @@ namespace LINGYUN.Abp.MessageService.Notifications NotificationReadState? readState = null, CancellationToken cancellationToken = default); - Task> GetListAsync( + Task> GetListAsync( Guid userId, string filter = "", string sorting = nameof(Notification.CreationTime), diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs index aacfde4b9..72c77c354 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationStore.cs @@ -57,15 +57,27 @@ namespace LINGYUN.Abp.MessageService.Notifications long notificationId, NotificationReadState readState, CancellationToken cancellationToken = default) + { + await ChangeUserNotificationsReadStateAsync( + tenantId, userId, new long[] { notificationId }, readState, cancellationToken); + } + + public async virtual Task ChangeUserNotificationsReadStateAsync( + Guid? tenantId, + Guid userId, + IEnumerable notificationIds, + NotificationReadState readState, + CancellationToken cancellationToken = default) { using (var unitOfWork = _unitOfWorkManager.Begin()) using (_currentTenant.Change(tenantId)) { - var notification = await _userNotificationRepository.GetByIdAsync(userId, notificationId); - if (notification != null) + var notifications = await _userNotificationRepository.GetListAsync(userId, notificationIds); + if (notifications.Any()) { - notification.ChangeReadState(readState); - await _userNotificationRepository.UpdateAsync(notification); + notifications.ForEach(notification => notification.ChangeReadState(readState)); + + await _userNotificationRepository.UpdateManyAsync(notifications); await unitOfWork.CompleteAsync(); } @@ -221,7 +233,7 @@ namespace LINGYUN.Abp.MessageService.Notifications var notifications = await _userNotificationRepository .GetNotificationsAsync(userId, readState, maxResultCount, cancellationToken); - return _objectMapper.Map, List>(notifications); + return _objectMapper.Map, List>(notifications); } } @@ -254,7 +266,7 @@ namespace LINGYUN.Abp.MessageService.Notifications var notifications = await _userNotificationRepository .GetListAsync(userId, filter, sorting, readState, skipCount, maxResultCount, cancellationToken); - return _objectMapper.Map, List>(notifications); + return _objectMapper.Map, List>(notifications); } } @@ -426,8 +438,7 @@ namespace LINGYUN.Abp.MessageService.Notifications userNofitications.Add(userNofitication); } } - await _userNotificationRepository - .InsertUserNotificationsAsync(userNofitications, cancellationToken); + await _userNotificationRepository.InsertManyAsync(userNofitications, cancellationToken: cancellationToken); await unitOfWork.CompleteAsync(cancellationToken); } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationTemplate.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationTemplate.cs new file mode 100644 index 000000000..0011079cf --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/NotificationTemplate.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.Domain.Entities.Auditing; + +namespace LINGYUN.Abp.MessageService.Notifications; + +public class NotificationTemplate : AuditedAggregateRoot +{ + +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/UserNotificationInfo.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/UserNotificationInfo.cs new file mode 100644 index 000000000..03a7dd28a --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/UserNotificationInfo.cs @@ -0,0 +1,18 @@ +using LINGYUN.Abp.Notifications; +using System; +using Volo.Abp.Data; + +namespace LINGYUN.Abp.MessageService.Notifications; + +public class UserNotificationInfo +{ + public Guid? TenantId { get; set; } + public string Name { get; set; } + public long Id { get; set; } + public ExtraPropertyDictionary ExtraProperties { get; set; } + public string NotificationTypeName { get; set; } + public DateTime CreationTime { get; set; } + public NotificationType Type { get; set; } + public NotificationSeverity Severity { get; set; } + public NotificationReadState State { get; set; } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs index b41411cfe..ff3f6440d 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.EntityFrameworkCore/LINGYUN/Abp/MessageService/Notifications/EfCoreUserNotificationRepository.cs @@ -32,26 +32,49 @@ namespace LINGYUN.Abp.MessageService.Notifications GetCancellationToken(cancellationToken)); } - public virtual async Task InsertUserNotificationsAsync( - IEnumerable userNotifications, + public virtual async Task GetByIdAsync( + Guid userId, + long notificationId, CancellationToken cancellationToken = default) { - await (await GetDbSetAsync()).AddRangeAsync(userNotifications, GetCancellationToken(cancellationToken)); + var dbContext = await GetDbContextAsync(); + var userNotifilerQuery = dbContext.Set() + .Where(x => x.UserId == userId); + + var notificationQuery = dbContext.Set(); + + var notifilerQuery = from un in userNotifilerQuery + join n in dbContext.Set() + on un.NotificationId equals n.NotificationId + where n.Id.Equals(notificationId) + select new UserNotificationInfo + { + Id = n.NotificationId, + TenantId = n.TenantId, + Name = n.NotificationName, + ExtraProperties = n.ExtraProperties, + CreationTime = n.CreationTime, + NotificationTypeName = n.NotificationTypeName, + Severity = n.Severity, + State = un.ReadStatus, + Type = n.Type + }; + + return await notifilerQuery + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); } - public virtual async Task GetByIdAsync( + public async virtual Task> GetListAsync( Guid userId, - long notificationId, + IEnumerable notificationIds, CancellationToken cancellationToken = default) { - var userNofitication = await (await GetDbSetAsync()) - .Where(x => x.NotificationId.Equals(notificationId) && x.UserId.Equals(userId)) - .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); - - return userNofitication; + return await (await GetDbSetAsync()) + .Where(x => x.UserId.Equals(userId) && notificationIds.Contains(x.Id)) + .ToListAsync(GetCancellationToken(cancellationToken)); } - public virtual async Task> GetNotificationsAsync( + public virtual async Task> GetNotificationsAsync( Guid userId, NotificationReadState? readState = null, int maxResultCount = 10, @@ -65,7 +88,18 @@ namespace LINGYUN.Abp.MessageService.Notifications var notifilerQuery = from un in userNotifilerQuery join n in dbContext.Set() on un.NotificationId equals n.NotificationId - select n; + select new UserNotificationInfo + { + Id = n.NotificationId, + TenantId = n.TenantId, + Name = n.NotificationName, + ExtraProperties = n.ExtraProperties, + CreationTime = n.CreationTime, + NotificationTypeName = n.NotificationTypeName, + Severity = n.Severity, + State = un.ReadStatus, + Type = n.Type + }; return await notifilerQuery .OrderBy(nameof(Notification.CreationTime) + " DESC") @@ -82,22 +116,24 @@ namespace LINGYUN.Abp.MessageService.Notifications { var dbContext = await GetDbContextAsync(); var userNotifilerQuery = dbContext.Set() - .Where(x => x.UserId == userId) - .WhereIf(readState.HasValue, x => x.ReadStatus == readState.Value); + .Where(x => x.UserId == userId) + .WhereIf(readState.HasValue, x => x.ReadStatus == readState.Value); + + var notificationQuery = dbContext.Set() + .WhereIf(!filter.IsNullOrWhiteSpace(), nf => + nf.NotificationName.Contains(filter) || + nf.NotificationTypeName.Contains(filter)); var notifilerQuery = from un in userNotifilerQuery - join n in dbContext.Set() + join n in notificationQuery on un.NotificationId equals n.NotificationId select n; return await notifilerQuery - .WhereIf(!filter.IsNullOrWhiteSpace(), nf => - nf.NotificationName.Contains(filter) || - nf.NotificationTypeName.Contains(filter)) .CountAsync(GetCancellationToken(cancellationToken)); } - public virtual async Task> GetListAsync( + public virtual async Task> GetListAsync( Guid userId, string filter = "", string sorting = nameof(Notification.CreationTime), @@ -109,18 +145,31 @@ namespace LINGYUN.Abp.MessageService.Notifications sorting ??= $"{nameof(Notification.CreationTime)} DESC"; var dbContext = await GetDbContextAsync(); var userNotifilerQuery = dbContext.Set() - .Where(x => x.UserId == userId) - .WhereIf(readState.HasValue, x => x.ReadStatus == readState.Value); + .Where(x => x.UserId == userId) + .WhereIf(readState.HasValue, x => x.ReadStatus == readState.Value); + + var notificationQuery = dbContext.Set() + .WhereIf(!filter.IsNullOrWhiteSpace(), nf => + nf.NotificationName.Contains(filter) || + nf.NotificationTypeName.Contains(filter)); var notifilerQuery = from un in userNotifilerQuery - join n in dbContext.Set() - on un.NotificationId equals n.NotificationId - select n; + join n in notificationQuery + on un.NotificationId equals n.NotificationId + select new UserNotificationInfo + { + Id = n.NotificationId, + TenantId = n.TenantId, + Name = n.NotificationName, + ExtraProperties = n.ExtraProperties, + CreationTime = n.CreationTime, + NotificationTypeName = n.NotificationTypeName, + Severity = n.Severity, + State = un.ReadStatus, + Type = n.Type + }; return await notifilerQuery - .WhereIf(!filter.IsNullOrWhiteSpace(), nf => - nf.NotificationName.Contains(filter) || - nf.NotificationTypeName.Contains(filter)) .OrderBy(sorting) .PageBy(skipCount, maxResultCount) .AsNoTracking() diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Notifications/MyNotificationController.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Notifications/MyNotificationController.cs index 76b1eac76..dc247ecab 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Notifications/MyNotificationController.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.HttpApi/LINGYUN/Abp/MessageService/Notifications/MyNotificationController.cs @@ -1,5 +1,4 @@ -using LINGYUN.Abp.Notifications; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; @@ -17,31 +16,38 @@ namespace LINGYUN.Abp.MessageService.Notifications IMyNotificationAppService myNotificationAppService) { MyNotificationAppService = myNotificationAppService; + } + + [HttpPut] + [Route("mark-read-state")] + public async virtual Task MarkReadStateAsync(NotificationMarkReadStateInput input) + { + await MyNotificationAppService.MarkReadStateAsync(input); } [HttpDelete] [Route("{id}")] - public virtual async Task DeleteAsync(long id) + public async virtual Task DeleteAsync(long id) { await MyNotificationAppService.DeleteAsync(id); } [HttpGet] [Route("assignables")] - public virtual async Task> GetAssignableNotifiersAsync() + public async virtual Task> GetAssignableNotifiersAsync() { return await MyNotificationAppService.GetAssignableNotifiersAsync(); } [HttpGet] [Route("{id}")] - public virtual async Task GetAsync(long id) + public async virtual Task GetAsync(long id) { return await MyNotificationAppService.GetAsync(id); } [HttpGet] - public virtual async Task> GetListAsync(UserNotificationGetByPagedDto input) + public async virtual Task> GetListAsync(UserNotificationGetByPagedDto input) { return await MyNotificationAppService.GetListAsync(input); } diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/en.json b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/en.json index 317bc7e18..7eebdbe16 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/en.json +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/en.json @@ -38,6 +38,7 @@ "Features:DisplayName:PublicAccess": "Public Access", "Features:Description:PublicAccess": "Whether to allow unauthorized users to access public directories", "Features:DisplayName:OssObject": "Oss Objects", + "Features:Description:OssObject": "Managing Object Storage", "Features:DisplayName:DownloadFile": "Download file", "Features:Description:DownloadFile": "Whether to allow users to download files", "Features:DisplayName:DownloadLimit": "Limit Of Downloads", diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/zh-Hans.json index 2169b16c4..ac2a2d2e2 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Domain.Shared/LINGYUN/Abp/OssManagement/Localization/Resources/zh-Hans.json @@ -38,6 +38,7 @@ "Features:DisplayName:PublicAccess": "公共访问", "Features:Description:PublicAccess": "是否允许未经授权的用户访问公共目录", "Features:DisplayName:OssObject": "Oss管理", + "Features:Description:OssObject": "管理对象存储", "Features:DisplayName:DownloadFile": "下载文件", "Features:Description:DownloadFile": "是否允许用户下载文件", "Features:DisplayName:DownloadLimit": "限制下载文件次数", diff --git a/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/en.json b/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/en.json index d651faef0..68f9989c1 100644 --- a/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/en.json +++ b/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/en.json @@ -39,6 +39,7 @@ "DisplayName:AdminEmailAddress": "Admin Email Address", "DisplayName:AdminPassword": "Admin Password", "TenantNotFoundById": "Tenant: {0} not found!", - "TenantNotFoundByName": "Tenant: {0} not found!" + "TenantNotFoundByName": "Tenant: {0} not found!", + "UnActived": "UnActived" } } \ No newline at end of file diff --git a/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/zh-Hans.json b/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/zh-Hans.json index a6214af08..1ffbecb35 100644 --- a/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain.Shared/LINGYUN/Abp/Saas/Localization/Resources/zh-Hans.json @@ -39,6 +39,7 @@ "DisplayName:AdminEmailAddress": "管理员电子邮件地址", "DisplayName:AdminPassword": "管理员密码", "TenantNotFoundById": "租户: {0} 不存在!", - "TenantNotFoundByName": "租户: {0} 不存在!" + "TenantNotFoundByName": "租户: {0} 不存在!", + "UnActived": "未启用" } } \ No newline at end of file diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs index 708208330..169c8d6a5 100644 --- a/aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs @@ -19,10 +19,8 @@ namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram protected ISubscribeMessager SubscribeMessager { get; } protected AbpNotificationsWeChatMiniProgramOptions Options { get; } public WeChatMiniProgramNotificationPublishProvider( - IServiceProvider serviceProvider, ISubscribeMessager subscribeMessager, IOptions options) - : base(serviceProvider) { Options = options.Value; SubscribeMessager = subscribeMessager; diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/BackgroundJobs/NotificationPublishJob.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/BackgroundJobs/NotificationPublishJob.cs index 2f447a3f4..081a85d33 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/BackgroundJobs/NotificationPublishJob.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/BackgroundJobs/NotificationPublishJob.cs @@ -11,35 +11,35 @@ namespace LY.MicroService.RealtimeMessage.BackgroundJobs; public class NotificationPublishJob : AsyncBackgroundJob, ITransientDependency { protected AbpNotificationOptions Options { get; } - protected INotificationStore Store { get; } - protected IServiceProvider ServiceProvider { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } public NotificationPublishJob( IOptions options, - INotificationStore store, - IServiceProvider serviceProvider) + IServiceScopeFactory serviceScopeFactory) { - Store = store; Options = options.Value; - ServiceProvider = serviceProvider; + ServiceScopeFactory = serviceScopeFactory; } public override async Task ExecuteAsync(NotificationPublishJobArgs args) { var providerType = Type.GetType(args.ProviderType); - - if (ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider) + using (var scope = ServiceScopeFactory.CreateScope()) { - var notification = await Store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); - notification.Data = NotificationDataConverter.Convert(notification.Data); - - var notifacationDataMapping = Options.NotificationDataMappings - .GetMapItemOrDefault(notification.Name, publishProvider.Name); - if (notifacationDataMapping != null) + if (scope.ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider) { - notification.Data = notifacationDataMapping.MappingFunc(notification.Data); + var store = scope.ServiceProvider.GetRequiredService(); + var notification = await store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId); + notification.Data = NotificationDataConverter.Convert(notification.Data); + + var notifacationDataMapping = Options.NotificationDataMappings + .GetMapItemOrDefault(notification.Name, publishProvider.Name); + if (notifacationDataMapping != null) + { + notification.Data = notifacationDataMapping.MappingFunc(notification.Data); + } + await publishProvider.PublishAsync(notification, args.UserIdentifiers); } - await publishProvider.PublishAsync(notification, args.UserIdentifiers); } } } diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs index 079e857db..cb33ada0c 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs @@ -1,5 +1,6 @@ using LINGYUN.Abp.Notifications; using LY.MicroService.RealtimeMessage.BackgroundJobs; +using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -12,6 +13,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Json; using Volo.Abp.MultiTenancy; +using Volo.Abp.TextTemplating; using Volo.Abp.Uow; namespace LY.MicroService.RealtimeMessage.EventBus.Distributed @@ -23,7 +25,10 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed /// 作用在于SignalR客户端只会与一台服务器建立连接, /// 只有启用了SignlR服务端的才能真正将消息发布到客户端 /// - public class NotificationEventHandler : IDistributedEventHandler>, ITransientDependency + public class NotificationEventHandler : + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency { /// /// Reference to . @@ -46,10 +51,18 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed /// protected IBackgroundJobManager BackgroundJobManager { get; } /// + /// Reference to . + /// + protected ITemplateRenderer TemplateRenderer { get; } + /// /// Reference to . /// protected INotificationStore NotificationStore { get; } /// + /// Reference to . + /// + protected IStringLocalizerFactory StringLocalizerFactory { get; } + /// /// Reference to . /// protected INotificationDefinitionManager NotificationDefinitionManager { get; } @@ -68,7 +81,9 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed public NotificationEventHandler( ICurrentTenant currentTenant, IJsonSerializer jsonSerializer, + ITemplateRenderer templateRenderer, IBackgroundJobManager backgroundJobManager, + IStringLocalizerFactory stringLocalizerFactory, IOptions options, INotificationStore notificationStore, INotificationDefinitionManager notificationDefinitionManager, @@ -78,7 +93,9 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed Options = options.Value; CurrentTenant = currentTenant; JsonSerializer = jsonSerializer; + TemplateRenderer = templateRenderer; BackgroundJobManager = backgroundJobManager; + StringLocalizerFactory = stringLocalizerFactory; NotificationStore = notificationStore; NotificationDefinitionManager = notificationDefinitionManager; NotificationSubscriptionManager = notificationSubscriptionManager; @@ -88,7 +105,65 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed } [UnitOfWork] - public virtual async Task HandleEventAsync(NotificationEto eventData) + public async virtual Task HandleEventAsync(NotificationEto eventData) + { + using (CurrentTenant.Change(eventData.TenantId)) + { + var notification = NotificationDefinitionManager.GetOrNull(eventData.Name); + if (notification == null) + { + return; + } + + var notificationInfo = new NotificationInfo + { + Name = notification.Name, + CreationTime = eventData.CreationTime, + Severity = eventData.Severity, + Lifetime = notification.NotificationLifetime, + TenantId = eventData.TenantId, + Type = notification.NotificationType + }; + notificationInfo.SetId(eventData.Id); + + var title = eventData.Data.Title; + if (title.IsNullOrWhiteSpace()) + { + title = notification.DisplayName.Localize(StringLocalizerFactory); + } + var message = await TemplateRenderer.RenderAsync( + templateName: eventData.Data.Name, + cultureName: eventData.Data.Culture, + globalContext: eventData.Data.ExtraProperties); + + var notificationData = new NotificationData(); + notificationData.WriteStandardData( + title: title, + message: message, + createTime: eventData.CreationTime, + formUser: eventData.Data.FormUser); + + notificationInfo.Data = notificationData; + + Logger.LogDebug($"Persistent notification {notificationInfo.Name}"); + + // 持久化通知 + await NotificationStore.InsertNotificationAsync(notificationInfo); + + var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers); + + // 过滤用户指定提供者 + if (notification.Providers.Any()) + { + providers = providers.Where(p => notification.Providers.Contains(p.Name)); + } + + await PublishFromProvidersAsync(providers, eventData.Users, notificationInfo); + } + } + + [UnitOfWork] + public async virtual Task HandleEventAsync(NotificationEto eventData) { using (CurrentTenant.Change(eventData.TenantId)) { @@ -119,8 +194,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed // 持久化通知 await NotificationStore.InsertNotificationAsync(notificationInfo); - var providers = Enumerable - .Reverse(NotificationPublishProviderManager.Providers); + var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers); // 过滤用户指定提供者 if (notification.Providers.Any()) @@ -196,7 +270,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed { Logger.LogDebug($"Sending notification with provider {provider.Name}"); var notifacationDataMapping = Options.NotificationDataMappings - .GetMapItemOrDefault(notificationInfo.Name, provider.Name); + .GetMapItemOrDefault(provider.Name, notificationInfo.Name); if (notifacationDataMapping != null) { notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);