22 changed files with 532 additions and 16 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,32 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\BackgroundTasks\Notifications\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\BackgroundTasks\Notifications\Localization\Resources\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\BackgroundTasks\Notifications\Templates\JobExecutedNotification.tpl" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\BackgroundTasks\Notifications\Templates\JobExecutedNotification.tpl" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.BackgroundTasks.Activities\LINGYUN.Abp.BackgroundTasks.Activities.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,29 @@ |
|||
using LINGYUN.Abp.BackgroundTasks.Activities; |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpBackgroundTasksActivitiesModule), |
|||
typeof(AbpNotificationModule))] |
|||
public class AbpBackgroundTasksNotificationsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpBackgroundTasksNotificationsModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<BackgroundTasksResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/BackgroundTasks/Notifications/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public class BackgroundTasksNotificationDefinitionProvider : NotificationDefinitionProvider |
|||
{ |
|||
public override void Define(INotificationDefinitionContext context) |
|||
{ |
|||
var backgroundTaskGroup = context.AddGroup( |
|||
BackgroundTasksNotificationNames.GroupName, |
|||
L("Notifications:BackgroundTasks")); |
|||
|
|||
backgroundTaskGroup.AddNotification( |
|||
BackgroundTasksNotificationNames.JobExecuteSucceeded, |
|||
L("Notifications:JobExecuteSucceeded"), |
|||
L("Notifications:JobExecuteSucceededDesc"), |
|||
notificationType: NotificationType.Application, |
|||
lifetime: NotificationLifetime.Persistent, |
|||
allowSubscriptionToClients: true) |
|||
.WithProviders( |
|||
NotificationProviderNames.SignalR, |
|||
NotificationProviderNames.Emailing); |
|||
backgroundTaskGroup.AddNotification( |
|||
BackgroundTasksNotificationNames.JobExecuteFailed, |
|||
L("Notifications:JobExecuteFailed"), |
|||
L("Notifications:JobExecuteFailedDesc"), |
|||
notificationType: NotificationType.Application, |
|||
lifetime: NotificationLifetime.Persistent, |
|||
allowSubscriptionToClients: true) |
|||
.WithProviders( |
|||
NotificationProviderNames.SignalR, |
|||
NotificationProviderNames.Emailing); |
|||
backgroundTaskGroup.AddNotification( |
|||
BackgroundTasksNotificationNames.JobExecuteCompleted, |
|||
L("Notifications:JobExecuteCompleted"), |
|||
L("Notifications:JobExecuteCompletedDesc"), |
|||
notificationType: NotificationType.Application, |
|||
lifetime: NotificationLifetime.Persistent, |
|||
allowSubscriptionToClients: true) |
|||
.WithProviders( |
|||
NotificationProviderNames.SignalR, |
|||
NotificationProviderNames.Emailing); |
|||
} |
|||
|
|||
protected LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<BackgroundTasksResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public static class BackgroundTasksNotificationNames |
|||
{ |
|||
public const string GroupName = "Abp.Notifications.BackgroundTasks"; |
|||
/// <summary>
|
|||
/// 作业执行成功
|
|||
/// </summary>
|
|||
public const string JobExecuteSucceeded = GroupName + ".ExecuteSucceeded"; |
|||
/// <summary>
|
|||
/// 作业执行失败
|
|||
/// </summary>
|
|||
public const string JobExecuteFailed = GroupName + ".ExecuteFailed"; |
|||
/// <summary>
|
|||
/// 作业执行完毕
|
|||
/// </summary>
|
|||
public const string JobExecuteCompleted = GroupName + ".ExecuteCompleted"; |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.BackgroundTasks.Activities; |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public class JobExecuteCompletedNotificationProvider : NotificationJobExecutedProvider |
|||
{ |
|||
public const string Name = "JobExecutedCompletedNofiter"; |
|||
|
|||
public JobExecuteCompletedNotificationProvider( |
|||
ICurrentTenant currentTenant, |
|||
INotificationSender notificationSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<BackgroundTasksResource> stringLocalizer) |
|||
: base(currentTenant, notificationSender, templateRenderer, stringLocalizer) |
|||
{ |
|||
} |
|||
|
|||
public async override Task NotifyComplateAsync([NotNull] JobActionExecuteContext context) |
|||
{ |
|||
var title = StringLocalizer["JobExecutedCompleted"].Value; |
|||
|
|||
await SendNofiterAsync(context, title, NotificationSeverity.Info); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.BackgroundTasks.Activities; |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public class JobExecuteFailedNotificationProvider : NotificationJobExecutedProvider |
|||
{ |
|||
public const string Name = "JobExecutedFailedNofiter"; |
|||
|
|||
public JobExecuteFailedNotificationProvider( |
|||
ICurrentTenant currentTenant, |
|||
INotificationSender notificationSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<BackgroundTasksResource> stringLocalizer) |
|||
: base(currentTenant, notificationSender, templateRenderer, stringLocalizer) |
|||
{ |
|||
} |
|||
|
|||
public async override Task NotifyErrorAsync([NotNull] JobActionExecuteContext context) |
|||
{ |
|||
var title = StringLocalizer["JobExecutedFailed"].Value; |
|||
|
|||
await SendNofiterAsync(context, title, NotificationSeverity.Error); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.BackgroundTasks.Activities; |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Microsoft.Extensions.Localization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public class JobExecutedSuccessedNotificationProvider : NotificationJobExecutedProvider |
|||
{ |
|||
public const string Name = "JobExecutedSuccessedNofiter"; |
|||
|
|||
public JobExecutedSuccessedNotificationProvider( |
|||
ICurrentTenant currentTenant, |
|||
INotificationSender notificationSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<BackgroundTasksResource> stringLocalizer) |
|||
: base(currentTenant, notificationSender, templateRenderer, stringLocalizer) |
|||
{ |
|||
} |
|||
|
|||
public async override Task NotifySuccessAsync([NotNull] JobActionExecuteContext context) |
|||
{ |
|||
var title = StringLocalizer["JobExecutedSucceeded"].Value; |
|||
|
|||
await SendNofiterAsync(context, title, NotificationSeverity.Success); |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Notifications:BackgroundTasks": "Background job Notification", |
|||
"Notifications:JobExecuteSucceeded": "Job Success Notification", |
|||
"Notifications:JobExecuteSucceededDesc": "After the background job is successfully executed, the notification is pushed.", |
|||
"Notifications:JobExecuteFailed": "Job Failure Notification", |
|||
"Notifications:JobExecuteFailedDesc": "Notification push after the execution of a background job failed.", |
|||
"Notifications:JobExecuteCompleted": "Job Completed Notification", |
|||
"Notifications:JobExecuteCompletedDesc": "After the background job is complated, the notification is pushed.", |
|||
"DisplayName:PushProvider": "Push Service Provider", |
|||
"Description:PushProvider": "If a push program is specified, the application will select it to push messages. The optional list is :SignalR(real-time notification), Sms(Sms notification), Emailing(email notification), wecht.miniprogram (WeChat MiniProgram), WxPusher(WxPusher WeChat push service), PushPlus (PushPlus multi-platform push service).", |
|||
"DisplayName:Template": "Template", |
|||
"Description:Template": "If the template content needs to be specified.", |
|||
"DisplayName:Context": "Context", |
|||
"Description:Context": "Specified when formatting template content.", |
|||
"DisplayName:Content": "Content", |
|||
"Description:Content": "If you specify the content, a plain text message is sent.", |
|||
"DisplayName:Culture": "Culture", |
|||
"Description:Culture": "Need to localize the message content specification" |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Notifications:BackgroundTasks": "后台作业通知", |
|||
"Notifications:JobExecuteSucceeded": "作业成功通知", |
|||
"Notifications:JobExecuteSucceededDesc": "后台作业执行成功后通知推送.", |
|||
"Notifications:JobExecuteFailed": "作业失败通知", |
|||
"Notifications:JobExecuteFailedDesc": "后台作业执行失败后通知推送.", |
|||
"Notifications:JobExecuteCompleted": "作业完成通知", |
|||
"Notifications:JobExecuteCompletedDesc": "后台作业执行完成后通知推送.", |
|||
"DisplayName:PushProvider": "推送程序", |
|||
"Description:PushProvider": "如果指定推送程序,应用将选择它进行消息推送,可选列表:SignalR(实时通知)、Sms(短信通知)、Emailing(邮件通知)、WeChat.MiniProgram(微信小程序)、WxPusher(WxPusher微信推送服务)、PushPlus(PushPlus多平台推送服务)", |
|||
"DisplayName:Template": "模板名称", |
|||
"Description:Template": "如果指定模板名称,将发送格式化模板消息.", |
|||
"DisplayName:Context": "上下文参数", |
|||
"Description:Context": "格式化模板内容时指定参数.", |
|||
"DisplayName:Content": "内容", |
|||
"Description:Content": "如果指定内容,将发送普通文本消息.", |
|||
"DisplayName:Culture": "文化名称", |
|||
"Description:Culture": "需要本地化内容指定." |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using LINGYUN.Abp.BackgroundTasks.Activities; |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public class NotificationJobActionDefinitionProvider : JobActionDefinitionProvider |
|||
{ |
|||
public override void Define(IJobActionDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new JobActionDefinition( |
|||
JobExecutedSuccessedNotificationProvider.Name, |
|||
JobActionType.Successed, |
|||
L("Notifications:JobExecuteSucceeded"), |
|||
NotificationJobExecutedProvider.Paramters, |
|||
L("Notifications:JobExecuteSucceededDesc")) |
|||
.WithProvider<JobExecutedSuccessedNotificationProvider>()); |
|||
context.Add( |
|||
new JobActionDefinition( |
|||
JobExecuteFailedNotificationProvider.Name, |
|||
JobActionType.Failed, |
|||
L("Notifications:JobExecuteFailed"), |
|||
NotificationJobExecutedProvider.Paramters, |
|||
L("Notifications:JobExecuteFailedDesc")) |
|||
.WithProvider<JobExecuteFailedNotificationProvider>()); |
|||
context.Add( |
|||
new JobActionDefinition( |
|||
JobExecuteCompletedNotificationProvider.Name, |
|||
JobActionType.Completed, |
|||
L("Notifications:JobExecuteCompleted"), |
|||
NotificationJobExecutedProvider.Paramters, |
|||
L("Notifications:JobExecuteCompletedDesc")) |
|||
.WithProvider<JobExecuteCompletedNotificationProvider>()); |
|||
} |
|||
|
|||
private static ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<BackgroundTasksResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.BackgroundTasks.Activities; |
|||
using LINGYUN.Abp.BackgroundTasks.Localization; |
|||
using LINGYUN.Abp.Notifications; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.BackgroundTasks.Notifications; |
|||
|
|||
public abstract class NotificationJobExecutedProvider : JobExecutedProvider, ITransientDependency |
|||
{ |
|||
public readonly static IList<JobActionParamter> Paramters = new List<JobActionParamter> |
|||
{ |
|||
new JobActionParamter(PropertyPushProvider, L("DisplayName:PushProvider"), L("Description:PushProvider")), |
|||
new JobActionParamter(PropertyUseTemplate, L("DisplayName:Template"), L("Description:Template")), |
|||
new JobActionParamter(PropertyContent, L("DisplayName:Content"), L("Description:Content")), |
|||
new JobActionParamter(PropertyCulture, L("DisplayName:Culture"), L("Description:Culture")), |
|||
}; |
|||
|
|||
/// <summary>
|
|||
/// 指定发送工具
|
|||
/// </summary>
|
|||
public const string PropertyPushProvider = "push-provider"; |
|||
/// <summary>
|
|||
/// 使用通知模板
|
|||
/// </summary>
|
|||
public const string PropertyUseTemplate = "use-template"; |
|||
/// <summary>
|
|||
/// 通知内容, 不使用模板时必须
|
|||
/// </summary>
|
|||
public const string PropertyContent = "content"; |
|||
/// <summary>
|
|||
/// 可选, 模板消息中的区域性
|
|||
/// </summary>
|
|||
public const string PropertyCulture = "culture"; |
|||
|
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
protected INotificationSender NotificationSender { get; } |
|||
protected ITemplateRenderer TemplateRenderer { get; } |
|||
protected IStringLocalizer<BackgroundTasksResource> StringLocalizer { get; } |
|||
|
|||
protected NotificationJobExecutedProvider( |
|||
ICurrentTenant currentTenant, |
|||
INotificationSender notificationSender, |
|||
ITemplateRenderer templateRenderer, |
|||
IStringLocalizer<BackgroundTasksResource> stringLocalizer) |
|||
{ |
|||
CurrentTenant = currentTenant; |
|||
NotificationSender = notificationSender; |
|||
TemplateRenderer = templateRenderer; |
|||
StringLocalizer = stringLocalizer; |
|||
} |
|||
|
|||
protected async virtual Task SendNofiterAsync( |
|||
[NotNull] JobActionExecuteContext context, |
|||
[NotNull] string title, |
|||
NotificationSeverity severity = NotificationSeverity.Info) |
|||
{ |
|||
var content = context.Action.Paramters.GetOrDefault(PropertyContent)?.ToString() ?? ""; |
|||
var templateName = context.Action.Paramters.GetOrDefault(PropertyUseTemplate)?.ToString() |
|||
?? BackgroundTasksNotificationNames.JobExecuteSucceeded; |
|||
|
|||
if (content.IsNullOrWhiteSpace() && !templateName.IsNullOrWhiteSpace()) |
|||
{ |
|||
var errorMessage = context.Event.EventData.Exception?.GetBaseException().Message; |
|||
var model = new |
|||
{ |
|||
Error = context.Event.EventData.Exception != null, |
|||
Errormessage = errorMessage, |
|||
Title = title, |
|||
Id = context.Event.EventData.Key, |
|||
Group = context.Event.EventData.Args.GetOrDefault(nameof(JobInfo.Group)) ?? context.Event.EventData.Group, |
|||
Name = context.Event.EventData.Args.GetOrDefault(nameof(JobInfo.Name)) ?? context.Event.EventData.Name, |
|||
Type = context.Event.EventData.Args.GetOrDefault(nameof(JobInfo.Type)) ?? context.Event.EventData.Type.Name, |
|||
Triggertime = context.Event.EventData.RunTime.ToString("yyyy-MM-dd HH:mm:ss"), |
|||
Tenantname = context.Event.EventData.Args.GetOrDefault(nameof(IMultiTenant.TenantId)), |
|||
}; |
|||
var culture = context.Action.Paramters.GetOrDefault(PropertyCulture)?.ToString() ?? CultureInfo.CurrentCulture.Name; |
|||
|
|||
content = await TemplateRenderer.RenderAsync(templateName, model, culture); |
|||
} |
|||
|
|||
var notificationData = new NotificationData(); |
|||
notificationData.WriteStandardData( |
|||
title: title, |
|||
message: content, |
|||
createTime: context.Event.EventData.RunTime, |
|||
formUser: "BackgroundTasks Engine"); |
|||
|
|||
await NotificationSender.SendNofiterAsync( |
|||
BackgroundTasksNotificationNames.JobExecuteSucceeded, |
|||
notificationData, |
|||
tenantId: CurrentTenant.Id, |
|||
severity: severity); |
|||
} |
|||
|
|||
private static ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<BackgroundTasksResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
# LINGYUN.Abp.BackgroundTasks.Notifications |
|||
|
|||
后台作业执行后通知事件 |
|||
|
|||
## 配置使用 |
|||
|
|||
模块按需引用 |
|||
|
|||
```csharp |
|||
[DependsOn(typeof(AbpBackgroundTasksNotificationsModule))] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
// other |
|||
} |
|||
``` |
|||
|
|||
## Action参数 |
|||
|
|||
** 通知内容格式化参数,在作业后将发送实时通知 |
|||
|
|||
* push-provider 可选, 用户指定消息推送提供程序; |
|||
* use-template 可选, 用于格式化通知内容的模板名称 |
|||
* content 可选, 通知内容(未指定模板名称则为必须参数) |
|||
* culture 可选, 使用模板时的模板区域性 |
|||
Loading…
Reference in new issue