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