diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 9ca58ff3b..8082d69c3 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -402,6 +402,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PermissionManag EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.OrganizaztionUnits", "modules\authorization\LINGYUN.Abp.Identity.OrganizaztionUnits\LINGYUN.Abp.Identity.OrganizaztionUnits.csproj", "{76A5564E-033B-4AA6-A22B-78B6EB134CC6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.Emailing", "modules\common\LINGYUN.Abp.Notifications.Emailing\LINGYUN.Abp.Notifications.Emailing.csproj", "{88502844-D83C-4541-96AC-A8291E261F63}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1036,6 +1038,10 @@ Global {76A5564E-033B-4AA6-A22B-78B6EB134CC6}.Debug|Any CPU.Build.0 = Debug|Any CPU {76A5564E-033B-4AA6-A22B-78B6EB134CC6}.Release|Any CPU.ActiveCfg = Release|Any CPU {76A5564E-033B-4AA6-A22B-78B6EB134CC6}.Release|Any CPU.Build.0 = Release|Any CPU + {88502844-D83C-4541-96AC-A8291E261F63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88502844-D83C-4541-96AC-A8291E261F63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88502844-D83C-4541-96AC-A8291E261F63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88502844-D83C-4541-96AC-A8291E261F63}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1232,6 +1238,7 @@ Global {902D822A-52B6-481C-96C5-ECD891FF83FC} = {9EC33D45-CCC7-41DF-829E-6B89A640FE35} {46244C99-3A0D-4D88-9F24-2B7B586ADBA4} = {CC362C67-6FC1-42B3-A130-8120AA8D790C} {76A5564E-033B-4AA6-A22B-78B6EB134CC6} = {9EC33D45-CCC7-41DF-829E-6B89A640FE35} + {88502844-D83C-4541-96AC-A8291E261F63} = {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/AbpExceptionHandlingNotificationDefinitionProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationDefinitionProvider.cs index 68260f3fb..effab95a1 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationDefinitionProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.ExceptionHandling.Notifications/LINGYUN/Abp/ExceptionHandling/Notifications/AbpExceptionHandlingNotificationDefinitionProvider.cs @@ -20,8 +20,13 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications notificationType: NotificationType.System, lifetime: NotificationLifetime.Persistent, allowSubscriptionToClients: false) - // TODO: 全局常量 - .WithProviders("SignalR"); + // 指定通知提供程序 + .WithProviders( + NotificationProviderNames.SignalR, + NotificationProviderNames.Emailing) + // 特定的通知提供程序属性 + // 此处为邮件通知定义的模板名称 + .WithProperty("Template", "ExceptionNotifier"); } protected LocalizableString L(string name) 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 d7b30abf9..72a0bbc08 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 @@ -25,7 +25,10 @@ namespace LINGYUN.Abp.ExceptionHandling.Notifications NotificationData notificationData = new NotificationData(); // 写入通知数据 - //TODO:集成TextTemplate完成格式化的推送 + notificationData.TrySetData("header", "An application exception has occurred"); + notificationData.TrySetData("footer", $"Copyright to LY Colin © {DateTime.Now.Year}"); + notificationData.TrySetData("loglevel", context.LogLevel.ToString()); + notificationData.TrySetData("stacktrace", context.Exception.ToString()); notificationData.WriteStandardData( context.Exception.GetType().FullName, context.Exception.Message, diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/FodyWeavers.xml b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/FodyWeavers.xsd b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/FodyWeavers.xsd new file mode 100644 index 000000000..11da52550 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN.Abp.Notifications.Emailing.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN.Abp.Notifications.Emailing.csproj new file mode 100644 index 000000000..d3e137a4e --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN.Abp.Notifications.Emailing.csproj @@ -0,0 +1,20 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/AbpNotificationsEmailingModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/AbpNotificationsEmailingModule.cs new file mode 100644 index 000000000..396df6602 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/AbpNotificationsEmailingModule.cs @@ -0,0 +1,22 @@ +using LINGYUN.Abp.Identity; +using Volo.Abp.Emailing; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.Notifications.Emailing; + +[DependsOn( + typeof(AbpNotificationModule), + typeof(AbpEmailingModule), + typeof(AbpIdentityDomainModule))] +public class AbpNotificationsEmailingModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.PublishProviders.Add(); + options.NotificationDataMappings + .MappingDefault(EmailingNotificationPublishProvider.ProviderName, data => data); + }); + } +} 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 new file mode 100644 index 000000000..9321cc6c5 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.Emailing/LINGYUN/Abp/Notifications/Emailing/EmailingNotificationPublishProvider.cs @@ -0,0 +1,77 @@ +using LINGYUN.Abp.Identity; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Emailing; +using Volo.Abp.TextTemplating; + +namespace LINGYUN.Abp.Notifications.Emailing; + +public class EmailingNotificationPublishProvider : NotificationPublishProvider +{ + public const string ProviderName = NotificationProviderNames.Emailing; + + public override string Name => ProviderName; + + protected IEmailSender EmailSender { get; } + + protected ITemplateRenderer TemplateRenderer { get; } + + protected IStringLocalizerFactory LocalizerFactory { get; } + + protected IIdentityUserRepository UserRepository { get; } + + protected INotificationDefinitionManager NotificationDefinitionManager { get; } + + public EmailingNotificationPublishProvider( + IServiceProvider serviceProvider, + IEmailSender emailSender, + ITemplateRenderer templateRenderer, + IStringLocalizerFactory localizerFactory, + IIdentityUserRepository userRepository, + INotificationDefinitionManager notificationDefinitionManager) + : base(serviceProvider) + { + EmailSender = emailSender; + TemplateRenderer = templateRenderer; + LocalizerFactory = localizerFactory; + UserRepository = userRepository; + NotificationDefinitionManager = notificationDefinitionManager; + } + + protected async override Task PublishAsync( + NotificationInfo notification, + IEnumerable identifiers, + CancellationToken cancellationToken = default) + { + var userIds = identifiers.Select(x => x.UserId).ToList(); + var userList = await UserRepository.GetListByIdListAsync(userIds, cancellationToken: cancellationToken); + var emailAddress = userList.Where(x => x.EmailConfirmed).Select(x => x.Email).Distinct().JoinAsString(","); + + if (emailAddress.IsNullOrWhiteSpace()) + { + Logger.LogWarning("The subscriber did not confirm the email address and could not send email notifications!"); + return; + } + + var notificationDefinition = NotificationDefinitionManager.Get(notification.Name); + var notificationDisplayName = notificationDefinition.DisplayName.Localize(LocalizerFactory).Value; + + notificationDefinition.Properties.TryGetValue("Template", out var template); + if (template == null) + { + Logger.LogWarning("The email template is not specified, so the email notification cannot be sent!"); + return; + } + + var content = await TemplateRenderer.RenderAsync( + template.ToString(), + globalContext: notification.Data.ExtraProperties); + + await EmailSender.SendAsync(emailAddress, notificationDisplayName, content); + } +} 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 82bf7a245..2a78d3fff 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 @@ -12,7 +12,7 @@ namespace LINGYUN.Abp.Notifications.SignalR { public class SignalRNotificationPublishProvider : NotificationPublishProvider { - public const string ProviderName = "SignalR"; + public const string ProviderName = NotificationProviderNames.SignalR; public override string Name => ProviderName; private readonly IHubContext _hubContext; 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 5aaa683f3..9e001a290 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 @@ -9,7 +9,7 @@ namespace LINGYUN.Abp.Notifications.Sms { public class SmsNotificationPublishProvider : NotificationPublishProvider { - public const string ProviderName = "Sms"; + public const string ProviderName = NotificationProviderNames.Sms; private IUserPhoneFinder _userPhoneFinder; protected IUserPhoneFinder UserPhoneFinder => LazyGetRequiredService(ref _userPhoneFinder); 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 d48ebbe15..5c8e89cf6 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 @@ -48,7 +48,13 @@ namespace LINGYUN.Abp.Notifications /// /// 通知提供者 /// - public List Providers { get; } + public List Providers { get; } + + /// + /// 额外属性 + /// + [NotNull] + public Dictionary Properties { get; } public NotificationDefinition( string name, @@ -66,6 +72,7 @@ namespace LINGYUN.Abp.Notifications AllowSubscriptionToClients = allowSubscriptionToClients; Providers = new List(); + Properties = new Dictionary(); } public virtual NotificationDefinition WithProviders(params string[] providers) @@ -78,6 +85,12 @@ namespace LINGYUN.Abp.Notifications return this; } + public virtual NotificationDefinition WithProperty(string key, object value) + { + Properties[key] = value; + return this; + } + public override string ToString() { return $"[{nameof(NotificationDefinition)} {Name}]"; diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationProviderNames.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationProviderNames.cs new file mode 100644 index 000000000..20c19ab30 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationProviderNames.cs @@ -0,0 +1,24 @@ +namespace LINGYUN.Abp.Notifications; + +/// +/// 内置通知提供者 +/// +public static class NotificationProviderNames +{ + /// + /// SignalR 实时通知 + /// + public const string SignalR = "SignalR"; + /// + /// 短信通知 + /// + public const string Sms = "Sms"; + /// + /// 邮件通知 + /// + public const string Emailing = "Emailing"; + /// + /// 微信小程序模板通知 + /// + public const string WechatMiniProgram = "WeChat.MiniProgram"; +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs index 5964af111..1eff5042c 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Notifications/AbpMessageServiceNotificationDefinitionProvider.cs @@ -23,7 +23,10 @@ namespace LINGYUN.Abp.MessageService.Notifications lifetime: NotificationLifetime.OnlyOne, allowSubscriptionToClients: false ) - .WithProviders(); + .WithProviders( + NotificationProviderNames.SignalR, + NotificationProviderNames.Emailing) + .WithProperty("Template", "NewTenantRegisterd"); var usersGroup = context.AddGroup( UserNotificationNames.GroupName, @@ -35,7 +38,11 @@ namespace LINGYUN.Abp.MessageService.Notifications L("Notifications:WelcomeToApplication"), notificationType: NotificationType.System, lifetime: NotificationLifetime.OnlyOne, - allowSubscriptionToClients: true); + allowSubscriptionToClients: true) + .WithProviders( + NotificationProviderNames.SignalR, + NotificationProviderNames.Emailing) + .WithProperty("Template", "WelcomeToApplication"); var imGroup = context.AddGroup( MessageServiceNotificationNames.IM.GroupName, @@ -46,35 +53,45 @@ namespace LINGYUN.Abp.MessageService.Notifications L("Notifications:FriendValidation"), notificationType: NotificationType.System, lifetime: NotificationLifetime.Persistent, - allowSubscriptionToClients: true); + allowSubscriptionToClients: true) + .WithProviders( + NotificationProviderNames.SignalR); imGroup.AddNotification( MessageServiceNotificationNames.IM.NewFriend, L("Notifications:NewFriend"), L("Notifications:NewFriend"), notificationType: NotificationType.System, lifetime: NotificationLifetime.Persistent, - allowSubscriptionToClients: true); + allowSubscriptionToClients: true) + .WithProviders( + NotificationProviderNames.SignalR); imGroup.AddNotification( MessageServiceNotificationNames.IM.JoinGroup, L("Notifications:JoinGroup"), L("Notifications:JoinGroup"), notificationType: NotificationType.System, lifetime: NotificationLifetime.Persistent, - allowSubscriptionToClients: true); + allowSubscriptionToClients: true) + .WithProviders( + NotificationProviderNames.SignalR); imGroup.AddNotification( MessageServiceNotificationNames.IM.ExitGroup, L("Notifications:ExitGroup"), L("Notifications:ExitGroup"), notificationType: NotificationType.System, lifetime: NotificationLifetime.Persistent, - allowSubscriptionToClients: true); + allowSubscriptionToClients: true) + .WithProviders( + NotificationProviderNames.SignalR); imGroup.AddNotification( MessageServiceNotificationNames.IM.DissolveGroup, L("Notifications:DissolveGroup"), L("Notifications:DissolveGroup"), notificationType: NotificationType.System, lifetime: NotificationLifetime.Persistent, - allowSubscriptionToClients: true); + allowSubscriptionToClients: true) + .WithProviders( + NotificationProviderNames.SignalR); } protected LocalizableString L(string name) diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs index 98842ec17..1852d5696 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs @@ -113,8 +113,11 @@ public class JobInfo /// 指定运行节点 /// public string NodeName { get; set; } - - public int GetCanBeTriggered() + /// + /// 计算作业可触发次数 + /// + /// + public int CalcCanBeTriggered() { // 无限次 var maxCount = -1; @@ -144,6 +147,12 @@ public class JobInfo { maxCount = 0; } + + if (maxCount > 0) + { + // 触发重试时,失败间隔时间调整 + Interval = 60; + } } return maxCount; diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs index 7977a8fad..eb51520e2 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs @@ -82,7 +82,7 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD Logger.LogWarning($"The task: {job.Group} - {job.Name} periodic task Cron expression was invalid and the task trigger could not be created."); return null; } - if (job.GetCanBeTriggered() == 0) + if (job.CalcCanBeTriggered() == 0) { Logger.LogWarning($"The task: {job.Group} - {job.Name} reached trigger peak and the task trigger could not be created."); return null; @@ -102,7 +102,7 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD case JobType.Once: case JobType.Persistent: default: - var maxCount = job.GetCanBeTriggered(); + var maxCount = job.CalcCanBeTriggered(); if (maxCount == 0) { Logger.LogWarning($"The task: {job.Group} - {job.Name} reached trigger peak and the task trigger could not be created."); diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs index 91722c18d..8460f3d36 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs @@ -53,6 +53,15 @@ public class JobExecutedEvent : JobEventBase, ITransientDepend { job.Priority = JobPriority.Low; } + + // 等待时间调整 + if (job.Interval <= 0) + { + job.Interval = 50; + } + + var retryInterval = job.Interval * 1.5; + job.Interval = Convert.ToInt32(retryInterval); } // 当未设置最大重试次数时不会标记停止 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 26bb7e181..708208330 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 @@ -14,7 +14,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram /// public class WeChatMiniProgramNotificationPublishProvider : NotificationPublishProvider { - public const string ProviderName = "WeChat.MiniProgram"; + public const string ProviderName = NotificationProviderNames.WechatMiniProgram; public override string Name => ProviderName; protected ISubscribeMessager SubscribeMessager { get; } protected AbpNotificationsWeChatMiniProgramOptions Options { get; } diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/RealtimeMessageTemplateProvider.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/RealtimeMessageTemplateProvider.cs new file mode 100644 index 000000000..84a30254d --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/RealtimeMessageTemplateProvider.cs @@ -0,0 +1,51 @@ +using Volo.Abp.TextTemplating; +using Volo.Abp.TextTemplating.Scriban; + +namespace LY.MicroService.RealtimeMessage.Emailing; + +public class RealtimeMessageTemplateProvider : TemplateDefinitionProvider +{ + public override void Define(ITemplateDefinitionContext context) + { + context.Add(CreateEmailTemplate()); + } + + protected virtual TemplateDefinition[] CreateEmailTemplate() + { + return new TemplateDefinition[] + { + new TemplateDefinition( + name: "EmailNotifierLayout", + defaultCultureName: "en", + isLayout: true) + .WithScribanEngine() + .WithVirtualFilePath( + "/Emailing/Templates/layout.tpl", + isInlineLocalized: false), + new TemplateDefinition( + name: "ExceptionNotifier", + defaultCultureName: "en", + layout: "EmailNotifierLayout") + .WithScribanEngine() + .WithVirtualFilePath( + "/Emailing/Templates/ExceptionNotifier", + isInlineLocalized: false), + new TemplateDefinition( + "NewTenantRegisterd", + defaultCultureName: "en", + layout: "EmailNotifierLayout") + .WithScribanEngine() + .WithVirtualFilePath( + "/Emailing/Templates/NewTenantRegisterd", + isInlineLocalized: false), + new TemplateDefinition( + "WelcomeToApplication", + defaultCultureName: "en", + layout: "EmailNotifierLayout") + .WithScribanEngine() + .WithVirtualFilePath( + "/Emailing/Templates/WelcomeToApplication", + isInlineLocalized: false), + }; + } +} diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/ExceptionNotifier/en.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/ExceptionNotifier/en.tpl new file mode 100644 index 000000000..38d937243 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/ExceptionNotifier/en.tpl @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + +
+
{{ header }} +
+
+
    +
  • Type  : {{ type }}
  • +
  • Message  : {{ message }}
  • +
  • Alarm level : {{ loglevel }}
  • +
  • TriggerTime : {{ createTime }}
  • +
+
+ Stack trace +
+
+
{{ stacktrace }}
+
+
+
+ {{ footer }} +
+
\ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/ExceptionNotifier/zh-Hans.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/ExceptionNotifier/zh-Hans.tpl new file mode 100644 index 000000000..3d4b1e53d --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/ExceptionNotifier/zh-Hans.tpl @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + +
+
{{ header }} +
+
+
    +
  • 异常类型 : {{ title }}
  • +
  • 异常信息 : {{ message }}
  • +
  • 告警级别 : {{ loglevel }}
  • +
  • 触发时间 : {{ createTime }}
  • +
+
+ 异常堆栈 +
+
+
{{ stacktrace }}
+
+
+
+ {{ footer }} +
+
\ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/NewTenantRegisterd/en.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/NewTenantRegisterd/en.tpl new file mode 100644 index 000000000..959d97561 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/NewTenantRegisterd/en.tpl @@ -0,0 +1 @@ +

A new tenant {{name}} has been created.

\ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/NewTenantRegisterd/zh-Hans.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/NewTenantRegisterd/zh-Hans.tpl new file mode 100644 index 000000000..25f545dc8 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/NewTenantRegisterd/zh-Hans.tpl @@ -0,0 +1 @@ +

一个新的租户 {{name}} 已建立,切换租户开始!

\ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/WelcomeToApplication/en.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/WelcomeToApplication/en.tpl new file mode 100644 index 000000000..2f5fa7959 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/WelcomeToApplication/en.tpl @@ -0,0 +1 @@ +

{{user}}, Welcome to my application!

\ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/WelcomeToApplication/zh-Hans.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/WelcomeToApplication/zh-Hans.tpl new file mode 100644 index 000000000..2f5fa7959 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/WelcomeToApplication/zh-Hans.tpl @@ -0,0 +1 @@ +

{{user}}, Welcome to my application!

\ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/layout.tpl b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/layout.tpl new file mode 100644 index 000000000..bdd5d22d8 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Emailing/Templates/layout.tpl @@ -0,0 +1,10 @@ + + + + + {{title}} + + + {{content}} + + \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/TenantSynchronizer.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/TenantSynchronizer.cs index 050510e7c..8fdb1f6fc 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/TenantSynchronizer.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Distributed/TenantSynchronizer.cs @@ -80,20 +80,21 @@ namespace LY.MicroService.RealtimeMessage.EventBus.Distributed TenantNotificationNames.NewTenantRegistered); var notificationData = new NotificationData(); + notificationData.TrySetData("name", eventData.Name); notificationData.WriteLocalizedData( new LocalizableStringInfo( LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)), "NewTenantRegisteredNotificationTitle", new Dictionary { - { "User", eventData.Name } + { "Name", eventData.Name }, }), new LocalizableStringInfo( LocalizationResourceNameAttribute.GetName(typeof(MessageServiceResource)), "NewTenantRegisteredNotificationMessage", new Dictionary { - { "User", eventData.Name} + { "Name", eventData.Name} }), DateTime.Now, eventData.AdminEmailAddress); diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs index 2e49efd08..0c9e57940 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/EventBus/Local/UserCreateSendWelcomeEventHandler.cs @@ -42,6 +42,7 @@ namespace LY.MicroService.RealtimeMessage.EventBus // L("WelcomeToApplicationFormUser", eventData.Entity.Name ?? eventData.Entity.UserName), // DateTime.Now, eventData.Entity.UserName); + userWelcomeNotifictionData.TrySetData("user", eventData.Entity.UserName); userWelcomeNotifictionData .WriteLocalizedData( new LocalizableStringInfo( diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj index 7b3103481..eabf4f0d1 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -7,6 +7,10 @@ + + + + @@ -48,8 +52,10 @@ + + diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs index f1fcece17..1ed2a4c22 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs @@ -7,12 +7,14 @@ using LINGYUN.Abp.BackgroundTasks.Quartz; using LINGYUN.Abp.Data.DbMigrator; using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling.Notifications; +using LINGYUN.Abp.Identity.EntityFrameworkCore; using LINGYUN.Abp.Identity.WeChat; using LINGYUN.Abp.IM.SignalR; using LINGYUN.Abp.Localization.CultureMap; using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore; using LINGYUN.Abp.MessageService; using LINGYUN.Abp.MessageService.EntityFrameworkCore; +using LINGYUN.Abp.Notifications.Emailing; using LINGYUN.Abp.Notifications.SignalR; using LINGYUN.Abp.Notifications.Sms; using LINGYUN.Abp.Notifications.WeChat.MiniProgram; @@ -31,7 +33,6 @@ using Volo.Abp.AspNetCore.Serilog; using Volo.Abp.Autofac; using Volo.Abp.BackgroundWorkers; using Volo.Abp.Caching.StackExchangeRedis; -using Volo.Abp.Identity.EntityFrameworkCore; using Volo.Abp.Modularity; using Volo.Abp.PermissionManagement.EntityFrameworkCore; using Volo.Abp.SettingManagement.EntityFrameworkCore; @@ -39,38 +40,39 @@ using Volo.Abp.SettingManagement.EntityFrameworkCore; namespace LY.MicroService.RealtimeMessage; [DependsOn( - typeof(AbpSerilogEnrichersApplicationModule), - typeof(AbpSerilogEnrichersUniqueIdModule), - typeof(AbpAspNetCoreSerilogModule), - typeof(AbpAuditLoggingElasticsearchModule), - typeof(AbpAspNetCoreMultiTenancyModule), - typeof(AbpMessageServiceApplicationModule), - typeof(AbpMessageServiceHttpApiModule), - typeof(AbpIdentityWeChatModule), - typeof(AbpBackgroundTasksQuartzModule), - typeof(AbpBackgroundTasksExceptionHandlingModule), - typeof(TaskManagementEntityFrameworkCoreModule), - typeof(AbpMessageServiceEntityFrameworkCoreModule), - typeof(AbpIdentityEntityFrameworkCoreModule), - typeof(AbpSaasEntityFrameworkCoreModule), - typeof(AbpSettingManagementEntityFrameworkCoreModule), - typeof(AbpPermissionManagementEntityFrameworkCoreModule), - typeof(AbpLocalizationManagementEntityFrameworkCoreModule), - typeof(AbpDataDbMigratorModule), - typeof(AbpAspNetCoreAuthenticationJwtBearerModule), - typeof(AbpAuthorizationOrganizationUnitsModule), - typeof(AbpBackgroundWorkersModule), - typeof(AbpIMSignalRModule), - typeof(AbpNotificationsSmsModule), - typeof(AbpNotificationsSignalRModule), - typeof(AbpNotificationsWeChatMiniProgramModule), - typeof(AbpNotificationsExceptionHandlingModule), - typeof(AbpCAPEventBusModule), - typeof(AbpCachingStackExchangeRedisModule), - typeof(AbpAspNetCoreHttpOverridesModule), - typeof(AbpLocalizationCultureMapModule), - typeof(AbpAutofacModule) - )] + typeof(AbpSerilogEnrichersApplicationModule), + typeof(AbpSerilogEnrichersUniqueIdModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpAuditLoggingElasticsearchModule), + typeof(AbpAspNetCoreMultiTenancyModule), + typeof(AbpMessageServiceApplicationModule), + typeof(AbpMessageServiceHttpApiModule), + typeof(AbpIdentityWeChatModule), + typeof(AbpBackgroundTasksQuartzModule), + typeof(AbpBackgroundTasksExceptionHandlingModule), + typeof(TaskManagementEntityFrameworkCoreModule), + typeof(AbpMessageServiceEntityFrameworkCoreModule), + typeof(AbpIdentityEntityFrameworkCoreModule), + typeof(AbpSaasEntityFrameworkCoreModule), + typeof(AbpSettingManagementEntityFrameworkCoreModule), + typeof(AbpPermissionManagementEntityFrameworkCoreModule), + typeof(AbpLocalizationManagementEntityFrameworkCoreModule), + typeof(AbpDataDbMigratorModule), + typeof(AbpAspNetCoreAuthenticationJwtBearerModule), + typeof(AbpAuthorizationOrganizationUnitsModule), + typeof(AbpBackgroundWorkersModule), + typeof(AbpIMSignalRModule), + typeof(AbpNotificationsSmsModule), + typeof(AbpNotificationsEmailingModule), + typeof(AbpNotificationsSignalRModule), + typeof(AbpNotificationsWeChatMiniProgramModule), + typeof(AbpNotificationsExceptionHandlingModule), + typeof(AbpCAPEventBusModule), + typeof(AbpCachingStackExchangeRedisModule), + typeof(AbpAspNetCoreHttpOverridesModule), + typeof(AbpLocalizationCultureMapModule), + typeof(AbpAutofacModule) + )] public partial class RealtimeMessageHttpApiHostModule : AbpModule { private const string DefaultCorsPolicyName = "Default";