diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/FodyWeavers.xml b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/FodyWeavers.xml new file mode 100644 index 000000000..5d6962159 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/FodyWeavers.xsd b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/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/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN.Abp.ElsaNext.Notifications.csproj b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN.Abp.ElsaNext.Notifications.csproj new file mode 100644 index 000000000..0c1e95496 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN.Abp.ElsaNext.Notifications.csproj @@ -0,0 +1,26 @@ + + + + + + + net10.0 + LINGYUN.Abp.ElsaNext.Notifications + LINGYUN.Abp.ElsaNext.Notifications + false + false + false + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/AbpElsaNextNotificationsModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/AbpElsaNextNotificationsModule.cs new file mode 100644 index 000000000..afa8b0da0 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/AbpElsaNextNotificationsModule.cs @@ -0,0 +1,38 @@ +using Elsa.Features.Services; +using LINGYUN.Abp.ElsaNext.Localization; +using LINGYUN.Abp.ElsaNext.Notifications.Extensions; +using LINGYUN.Abp.Notifications; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.ElsaNext.Notifications; + +[DependsOn( + typeof(AbpNotificationsModule), + typeof(AbpElsaNextModule))] +public class AbpElsaNextNotificationsModule : AbpModule +{ + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(elsa => + { + elsa.UseAbpNotifications(); + }); + } + + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Get() + .AddVirtualJson("/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources"); + }); + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Activities/SendNotification.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Activities/SendNotification.cs new file mode 100644 index 000000000..c4d4ea9cb --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Activities/SendNotification.cs @@ -0,0 +1,136 @@ +using Elsa.Extensions; +using Elsa.Workflows; +using Elsa.Workflows.Attributes; +using Elsa.Workflows.Models; +using Elsa.Workflows.UIHints; +using LINGYUN.Abp.ElsaNext.Notifications.UIHints; +using LINGYUN.Abp.ElsaNext.UIHints; +using LINGYUN.Abp.Notifications; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; +using INotificationSender = LINGYUN.Abp.Notifications.INotificationSender; + +namespace LINGYUN.Abp.ElsaNext.Notifications.Activities; + +[Activity("Elsa", "Notifications", "Send an notification.", Kind = ActivityKind.Task)] +public class SendNotification : CodeActivity +{ + [Input( + Description = "The name of the registered notification.", + UIHint = NotificationsUIHints.NotificationPicker)] + public Input NotificationName { get; set; } = default!; + + [Input( + Description = "The notification title.", + UIHint = InputUIHints.MultiLine + )] + public Input Title { get; set; } = default!; + + [Input( + Description = "The notification content.", + UIHint = InputUIHints.MultiLine + )] + public Input Content { get; set; } = default!; + + [Input( + Description = "The notification description.", + UIHint = InputUIHints.MultiLine + )] + public Input Description { get; set; } = default!; + + [Input( + Description = "The notification template name.", + UIHint = InputUIHints.MultiLine + )] + public Input Template { get; set; } = default!; + + [Input( + Description = "The notification additional attributes.", + UIHint = InputUIHints.Dictionary + )] + public Input> Propertites { get; set; } = default!; + + [Input( + Description = "The tenant id for sending the notification.", + UIHint = AbpElsaUIHints.TenantPicker)] + public Input TenantId { get; set; } = null!; + + [Input( + Description = "The recipients email addresses.", + UIHint = AbpElsaUIHints.UserPicker)] + public Input> To { get; set; } = null!; + + [Input( + Description = "The notifications severity.", + Options = new[] { "Success", "Info", "Warn", "Error", "Fatal" }, + DefaultValue = "Info", + UIHint = InputUIHints.DropDown)] + public Input Severity { get; set; } = null!; + + [Output(Description = "The notification id.")] + public Output NotificationId { get; set; } = null!; + + protected async override ValueTask ExecuteAsync(ActivityExecutionContext context) + { + var notificationSender = context.GetRequiredService(); + var currentTenant = context.GetRequiredService(); + var clock = context.GetRequiredService(); + + var tenantId = TenantId.GetOrDefault(context, () => currentTenant.Id); + var userIdentifiers = GetUserIdentifiers(context); + var severity = GetNotificationSeverity(context); + var propertites = Propertites.GetOrDefault(context); + var notificationName = NotificationName.Get(context); + var template = Template.GetOrDefault(context); + if (!string.IsNullOrWhiteSpace(template)) + { + var notificationTemplate = new NotificationTemplate(template, data: propertites); + var notificationTemplateId = await notificationSender.SendNofiterAsync( + notificationName, + notificationTemplate, + userIdentifiers, + tenantId, + severity); + NotificationId.Set(context, notificationTemplateId); + } + else + { + var title = Title.Get(context); + var message = Content.Get(context); + var description = Description.GetOrDefault(context) ?? ""; + + var notificationData = new NotificationData(); + notificationData.WriteStandardData(title!, message!, clock.Now, "elsa-workflow", description); + var notificationId = await notificationSender.SendNofiterAsync( + notificationName, + notificationData, + userIdentifiers, + tenantId, + severity); + NotificationId.Set(context, notificationId); + } + } + + private NotificationSeverity GetNotificationSeverity(ActivityExecutionContext context) + { + var severitySet = Severity.GetOrDefault(context); + if (!string.IsNullOrWhiteSpace(severitySet)) + { + if (Enum.TryParse(severitySet, true, out var severity)) + { + return severity; + } + } + return NotificationSeverity.Info; + } + + private IEnumerable? GetUserIdentifiers(ActivityExecutionContext context) + { + var userIdentifiers = To.GetOrDefault(context); + return userIdentifiers?.Select(to => new UserIdentifier(to, to.ToString())); + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Extensions/ModuleExtensions.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Extensions/ModuleExtensions.cs new file mode 100644 index 000000000..2573ab38f --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Extensions/ModuleExtensions.cs @@ -0,0 +1,14 @@ +using Elsa.Features.Services; +using LINGYUN.Abp.ElsaNext.Notifications.Features; +using System; + +namespace LINGYUN.Abp.ElsaNext.Notifications.Extensions; + +public static class ModuleExtensions +{ + public static IModule UseAbpNotifications(this IModule configuration, Action? configure = null) + { + configuration.Configure(configure); + return configuration; + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Features/NotificationsFeature.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Features/NotificationsFeature.cs new file mode 100644 index 000000000..8d6ef3b04 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Features/NotificationsFeature.cs @@ -0,0 +1,17 @@ +using Elsa.Extensions; +using Elsa.Features.Abstractions; +using Elsa.Features.Services; + +namespace LINGYUN.Abp.ElsaNext.Notifications.Features; + +public class NotificationsFeature : FeatureBase +{ + public NotificationsFeature(IModule module) : base(module) + { + } + + public override void Configure() + { + Module.AddActivitiesFrom(); + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources/en.json b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources/en.json new file mode 100644 index 000000000..477772584 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources/en.json @@ -0,0 +1,18 @@ +{ + "culture": "en", + "texts": { + "Notifications": "Notifications", + "Send Notification": "Send Notification", + "Send an notification.": "Send an notification.", + "The name of the registered notification.": "The name of the registered notification.", + "The notification title.": "The notification title.", + "The notification content.": "The notification content.", + "The notification description.": "The notification description.", + "The notification template name.": "The notification template name.", + "The notification additional attributes.": "The notification additional attributes.", + "The tenant id for sending the notification.": "The tenant id for sending the notification.", + "The recipients email addresses.": "The recipients email addresses.", + "The notifications severity.": "The notifications severity.", + "The notification id.": "The notification id." + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources/zh-Hans.json b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..c6717a413 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources/zh-Hans.json @@ -0,0 +1,18 @@ +{ + "culture": "zh-Hans", + "texts": { + "Notifications": "消息通知", + "Send Notification": "发送通知", + "Send an notification.": "发送通知。", + "The name of the registered notification.": "已注册的通知名称。", + "The notification title.": "通知标题。", + "The notification content.": "通知内容。", + "The notification description.": "通知描述。", + "The notification template name.": "通知模板,使用模板消息时标题、内容、描述内容无效。", + "The notification additional attributes.": "通知属性。", + "The tenant id for sending the notification.": "将要发送通知的租户Id。", + "The recipients email addresses.": "接收通知的用户Id集合。", + "The notifications severity.": "通知严重程度。", + "The notification id.": "通知Id。" + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/UIHints/NotificationsUIHints.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/UIHints/NotificationsUIHints.cs new file mode 100644 index 000000000..2d5dfa3e4 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Notifications/LINGYUN/Abp/ElsaNext/Notifications/UIHints/NotificationsUIHints.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.ElsaNext.Notifications.UIHints; + +public static class NotificationsUIHints +{ + public const string NotificationPicker = "notification-picker"; +}