10 changed files with 306 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,26 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net10.0</TargetFramework> |
||||
|
<AssemblyName>LINGYUN.Abp.ElsaNext.Notifications</AssemblyName> |
||||
|
<PackageId>LINGYUN.Abp.ElsaNext.Notifications</PackageId> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Content Remove="LINGYUN\Abp\ElsaNext\Notifications\Localization\**\*.json" /> |
||||
|
<EmbeddedResource Include="LINGYUN\Abp\ElsaNext\Notifications\Localization\**\*.json" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\realtime-notifications\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> |
||||
|
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext\LINGYUN.Abp.ElsaNext.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -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<IModule>(elsa => |
||||
|
{ |
||||
|
elsa.UseAbpNotifications(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpVirtualFileSystemOptions>(options => |
||||
|
{ |
||||
|
options.FileSets.AddEmbedded<AbpElsaNextNotificationsModule>(); |
||||
|
}); |
||||
|
|
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.Resources |
||||
|
.Get<ElsaNextResource>() |
||||
|
.AddVirtualJson("/LINGYUN/Abp/ElsaNext/Notifications/Localization/Resources"); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -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<string> NotificationName { get; set; } = default!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The notification title.", |
||||
|
UIHint = InputUIHints.MultiLine |
||||
|
)] |
||||
|
public Input<string?> Title { get; set; } = default!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The notification content.", |
||||
|
UIHint = InputUIHints.MultiLine |
||||
|
)] |
||||
|
public Input<string?> Content { get; set; } = default!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The notification description.", |
||||
|
UIHint = InputUIHints.MultiLine |
||||
|
)] |
||||
|
public Input<string?> Description { get; set; } = default!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The notification template name.", |
||||
|
UIHint = InputUIHints.MultiLine |
||||
|
)] |
||||
|
public Input<string?> Template { get; set; } = default!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The notification additional attributes.", |
||||
|
UIHint = InputUIHints.Dictionary |
||||
|
)] |
||||
|
public Input<Dictionary<string, object?>> Propertites { get; set; } = default!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The tenant id for sending the notification.", |
||||
|
UIHint = AbpElsaUIHints.TenantPicker)] |
||||
|
public Input<Guid?> TenantId { get; set; } = null!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The recipients email addresses.", |
||||
|
UIHint = AbpElsaUIHints.UserPicker)] |
||||
|
public Input<ICollection<Guid>> To { get; set; } = null!; |
||||
|
|
||||
|
[Input( |
||||
|
Description = "The notifications severity.", |
||||
|
Options = new[] { "Success", "Info", "Warn", "Error", "Fatal" }, |
||||
|
DefaultValue = "Info", |
||||
|
UIHint = InputUIHints.DropDown)] |
||||
|
public Input<string?> Severity { get; set; } = null!; |
||||
|
|
||||
|
[Output(Description = "The notification id.")] |
||||
|
public Output<string?> NotificationId { get; set; } = null!; |
||||
|
|
||||
|
protected async override ValueTask ExecuteAsync(ActivityExecutionContext context) |
||||
|
{ |
||||
|
var notificationSender = context.GetRequiredService<INotificationSender>(); |
||||
|
var currentTenant = context.GetRequiredService<ICurrentTenant>(); |
||||
|
var clock = context.GetRequiredService<IClock>(); |
||||
|
|
||||
|
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<NotificationSeverity>(severitySet, true, out var severity)) |
||||
|
{ |
||||
|
return severity; |
||||
|
} |
||||
|
} |
||||
|
return NotificationSeverity.Info; |
||||
|
} |
||||
|
|
||||
|
private IEnumerable<UserIdentifier>? GetUserIdentifiers(ActivityExecutionContext context) |
||||
|
{ |
||||
|
var userIdentifiers = To.GetOrDefault(context); |
||||
|
return userIdentifiers?.Select(to => new UserIdentifier(to, to.ToString())); |
||||
|
} |
||||
|
} |
||||
@ -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<NotificationsFeature>? configure = null) |
||||
|
{ |
||||
|
configuration.Configure(configure); |
||||
|
return configuration; |
||||
|
} |
||||
|
} |
||||
@ -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<NotificationsFeature>(); |
||||
|
} |
||||
|
} |
||||
@ -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." |
||||
|
} |
||||
|
} |
||||
@ -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。" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,6 @@ |
|||||
|
namespace LINGYUN.Abp.ElsaNext.Notifications.UIHints; |
||||
|
|
||||
|
public static class NotificationsUIHints |
||||
|
{ |
||||
|
public const string NotificationPicker = "notification-picker"; |
||||
|
} |
||||
Loading…
Reference in new issue