diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln
index 6958e012f..79bda6c14 100644
--- a/aspnet-core/LINGYUN.MicroService.All.sln
+++ b/aspnet-core/LINGYUN.MicroService.All.sln
@@ -442,7 +442,25 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.CachingManageme
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.CachingManagement.HttpApi", "modules\caching\LINGYUN.Abp.CachingManagement.HttpApi\LINGYUN.Abp.CachingManagement.HttpApi.csproj", "{B507D18B-770E-4581-854B-15579AC7074F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DistributedLocking.Dapr", "modules\dapr\LINGYUN.Abp.DistributedLocking.Dapr\LINGYUN.Abp.DistributedLocking.Dapr.csproj", "{178AF3DE-1C24-41A9-8CA0-64A7D85DDFFE}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DistributedLocking.Dapr", "modules\dapr\LINGYUN.Abp.DistributedLocking.Dapr\LINGYUN.Abp.DistributedLocking.Dapr.csproj", "{178AF3DE-1C24-41A9-8CA0-64A7D85DDFFE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wx-pusher", "wx-pusher", "{53DF60C5-AE45-4FCE-9C9B-EE15F0E33BD4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WxPusher", "modules\wx-pusher\LINGYUN.Abp.WxPusher\LINGYUN.Abp.WxPusher.csproj", "{7C4C266C-DC2A-4A48-AB87-185E284B86E9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WxPusher", "modules\wx-pusher\LINGYUN.Abp.Notifications.WxPusher\LINGYUN.Abp.Notifications.WxPusher.csproj", "{0380623A-EC74-430B-AA59-A6D23BC5E108}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WxPusher.SettingManagement", "modules\wx-pusher\LINGYUN.Abp.WxPusher.SettingManagement\LINGYUN.Abp.WxPusher.SettingManagement.csproj", "{C6BDAB62-0B82-4ED2-8455-2FEA1F1B1EAD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.WxPusher", "modules\wx-pusher\LINGYUN.Abp.Identity.WxPusher\LINGYUN.Abp.Identity.WxPusher.csproj", "{C9BB4BB2-97B8-4CDE-B961-2F0A4CB5D7B1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pushplus", "pushplus", "{A8F1C9FA-4F16-43F9-8CC6-CCD124154440}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PushPlus", "modules\pushplus\LINGYUN.Abp.PushPlus\LINGYUN.Abp.PushPlus.csproj", "{82CB7E17-ED5A-4D26-B116-BA7B4226E43C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PushPlus.SettingManagement", "modules\pushplus\LINGYUN.Abp.PushPlus.SettingManagement\LINGYUN.Abp.PushPlus.SettingManagement.csproj", "{102C3711-135E-446D-9A35-AEFB79993CAA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.PushPlus", "modules\pushplus\LINGYUN.Abp.Notifications.PushPlus\LINGYUN.Abp.Notifications.PushPlus.csproj", "{2B7C1441-8801-4121-ABFB-03771E9DFE46}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1154,6 +1172,34 @@ Global
{178AF3DE-1C24-41A9-8CA0-64A7D85DDFFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{178AF3DE-1C24-41A9-8CA0-64A7D85DDFFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{178AF3DE-1C24-41A9-8CA0-64A7D85DDFFE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7C4C266C-DC2A-4A48-AB87-185E284B86E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C4C266C-DC2A-4A48-AB87-185E284B86E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C4C266C-DC2A-4A48-AB87-185E284B86E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C4C266C-DC2A-4A48-AB87-185E284B86E9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0380623A-EC74-430B-AA59-A6D23BC5E108}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0380623A-EC74-430B-AA59-A6D23BC5E108}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0380623A-EC74-430B-AA59-A6D23BC5E108}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0380623A-EC74-430B-AA59-A6D23BC5E108}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6BDAB62-0B82-4ED2-8455-2FEA1F1B1EAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6BDAB62-0B82-4ED2-8455-2FEA1F1B1EAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6BDAB62-0B82-4ED2-8455-2FEA1F1B1EAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6BDAB62-0B82-4ED2-8455-2FEA1F1B1EAD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C9BB4BB2-97B8-4CDE-B961-2F0A4CB5D7B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C9BB4BB2-97B8-4CDE-B961-2F0A4CB5D7B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C9BB4BB2-97B8-4CDE-B961-2F0A4CB5D7B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C9BB4BB2-97B8-4CDE-B961-2F0A4CB5D7B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {82CB7E17-ED5A-4D26-B116-BA7B4226E43C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {82CB7E17-ED5A-4D26-B116-BA7B4226E43C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {82CB7E17-ED5A-4D26-B116-BA7B4226E43C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {82CB7E17-ED5A-4D26-B116-BA7B4226E43C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {102C3711-135E-446D-9A35-AEFB79993CAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {102C3711-135E-446D-9A35-AEFB79993CAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {102C3711-135E-446D-9A35-AEFB79993CAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {102C3711-135E-446D-9A35-AEFB79993CAA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2B7C1441-8801-4121-ABFB-03771E9DFE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2B7C1441-8801-4121-ABFB-03771E9DFE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2B7C1441-8801-4121-ABFB-03771E9DFE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2B7C1441-8801-4121-ABFB-03771E9DFE46}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1371,6 +1417,15 @@ Global
{08CC528E-98D7-41D9-957D-9F9064645788} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95}
{B507D18B-770E-4581-854B-15579AC7074F} = {63FCC71F-1CEF-44D3-B95B-23EE58DE8C95}
{178AF3DE-1C24-41A9-8CA0-64A7D85DDFFE} = {DC33925B-264D-421B-96CC-46F853CBCC70}
+ {53DF60C5-AE45-4FCE-9C9B-EE15F0E33BD4} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
+ {7C4C266C-DC2A-4A48-AB87-185E284B86E9} = {53DF60C5-AE45-4FCE-9C9B-EE15F0E33BD4}
+ {0380623A-EC74-430B-AA59-A6D23BC5E108} = {53DF60C5-AE45-4FCE-9C9B-EE15F0E33BD4}
+ {C6BDAB62-0B82-4ED2-8455-2FEA1F1B1EAD} = {53DF60C5-AE45-4FCE-9C9B-EE15F0E33BD4}
+ {C9BB4BB2-97B8-4CDE-B961-2F0A4CB5D7B1} = {53DF60C5-AE45-4FCE-9C9B-EE15F0E33BD4}
+ {A8F1C9FA-4F16-43F9-8CC6-CCD124154440} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
+ {82CB7E17-ED5A-4D26-B116-BA7B4226E43C} = {A8F1C9FA-4F16-43F9-8CC6-CCD124154440}
+ {102C3711-135E-446D-9A35-AEFB79993CAA} = {A8F1C9FA-4F16-43F9-8CC6-CCD124154440}
+ {2B7C1441-8801-4121-ABFB-03771E9DFE46} = {A8F1C9FA-4F16-43F9-8CC6-CCD124154440}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}
diff --git a/aspnet-core/LINGYUN.MicroService.Common.sln b/aspnet-core/LINGYUN.MicroService.Common.sln
index 43f6a5e48..6167bb21c 100644
--- a/aspnet-core/LINGYUN.MicroService.Common.sln
+++ b/aspnet-core/LINGYUN.MicroService.Common.sln
@@ -260,9 +260,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.W
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.WxPusher", "modules\wx-pusher\LINGYUN.Abp.Identity.WxPusher\LINGYUN.Abp.Identity.WxPusher.csproj", "{30FA01ED-921A-4E7D-9E83-6719538FB866}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WxPusher.SettingManagement", "modules\wx-pusher\LINGYUN.Abp.WxPusher.SettingManagement\LINGYUN.Abp.WxPusher.SettingManagement.csproj", "{E6FDAD7B-4A7F-4CEB-9891-F8FC4E556C36}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WxPusher.SettingManagement", "modules\wx-pusher\LINGYUN.Abp.WxPusher.SettingManagement\LINGYUN.Abp.WxPusher.SettingManagement.csproj", "{E6FDAD7B-4A7F-4CEB-9891-F8FC4E556C36}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.PushPlus.SettingManagement", "modules\pushplus\LINGYUN.Abp.PushPlus.SettingManagement\LINGYUN.Abp.PushPlus.SettingManagement.csproj", "{4CBB4A0C-6D23-44DD-BAF4-49D69ED35839}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.PushPlus.SettingManagement", "modules\pushplus\LINGYUN.Abp.PushPlus.SettingManagement\LINGYUN.Abp.PushPlus.SettingManagement.csproj", "{4CBB4A0C-6D23-44DD-BAF4-49D69ED35839}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.WxPusher.Tests", "tests\LINGYUN.Abp.Notifications.WxPusher.Tests\LINGYUN.Abp.Notifications.WxPusher.Tests.csproj", "{C2801414-550F-4A25-AD8D-68AC508211DC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Tests", "tests\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj", "{868A1718-4970-48D2-A256-08EF468302D8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests", "tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests.csproj", "{B78E53AC-6BB8-402D-90CF-BEF1BD9558EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -678,6 +684,18 @@ Global
{4CBB4A0C-6D23-44DD-BAF4-49D69ED35839}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CBB4A0C-6D23-44DD-BAF4-49D69ED35839}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CBB4A0C-6D23-44DD-BAF4-49D69ED35839}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C2801414-550F-4A25-AD8D-68AC508211DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C2801414-550F-4A25-AD8D-68AC508211DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C2801414-550F-4A25-AD8D-68AC508211DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C2801414-550F-4A25-AD8D-68AC508211DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {868A1718-4970-48D2-A256-08EF468302D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {868A1718-4970-48D2-A256-08EF468302D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {868A1718-4970-48D2-A256-08EF468302D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {868A1718-4970-48D2-A256-08EF468302D8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B78E53AC-6BB8-402D-90CF-BEF1BD9558EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B78E53AC-6BB8-402D-90CF-BEF1BD9558EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B78E53AC-6BB8-402D-90CF-BEF1BD9558EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B78E53AC-6BB8-402D-90CF-BEF1BD9558EB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -809,6 +827,9 @@ Global
{30FA01ED-921A-4E7D-9E83-6719538FB866} = {7862CE70-76EF-4228-A703-C2E2A9704D14}
{E6FDAD7B-4A7F-4CEB-9891-F8FC4E556C36} = {7862CE70-76EF-4228-A703-C2E2A9704D14}
{4CBB4A0C-6D23-44DD-BAF4-49D69ED35839} = {0F5A2591-CE08-4184-A5F3-89F6FB3B2B10}
+ {C2801414-550F-4A25-AD8D-68AC508211DC} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
+ {868A1718-4970-48D2-A256-08EF468302D8} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
+ {B78E53AC-6BB8-402D-90CF-BEF1BD9558EB} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
index 730db1bc3..8f7e43a2e 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.BackgroundWorkers;
+using Volo.Abp.EventBus;
using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Localization;
@@ -23,6 +24,7 @@ namespace LINGYUN.Abp.Notifications
typeof(AbpJsonModule),
typeof(AbpLocalizationModule),
typeof(AbpRealTimeModule),
+ typeof(AbpEventBusModule),
typeof(AbpTextTemplatingCoreModule))]
public class AbpNotificationModule : AbpModule
{
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs
index b4c84068f..95901fc42 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications
@@ -18,6 +19,8 @@ namespace LINGYUN.Abp.Notifications
/// 通知信息
/// 接收用户列表
///
- Task PublishAsync(NotificationInfo notification, IEnumerable identifiers);
+ Task PublishAsync(
+ NotificationInfo notification,
+ IEnumerable identifiers);
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
index b5679c4e2..e6c23c109 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
@@ -22,9 +22,27 @@ namespace LINGYUN.Abp.Notifications
public ICancellationTokenProvider CancellationTokenProvider => ServiceProvider.LazyGetService(NullCancellationTokenProvider.Instance);
- public async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers)
+ public async Task PublishAsync(
+ NotificationInfo notification,
+ IEnumerable identifiers)
{
- await PublishAsync(notification, identifiers, CancellationTokenProvider.Token);
+ if (await CanPublishAsync(notification))
+ {
+ await PublishAsync(
+ notification,
+ identifiers,
+ GetCancellationToken());
+ }
+ }
+ protected virtual Task CanPublishAsync(
+ NotificationInfo notification,
+ CancellationToken cancellationToken = default)
+ {
+ return Task.FromResult(true);
+ }
+ protected virtual CancellationToken GetCancellationToken(CancellationToken cancellationToken = default)
+ {
+ return CancellationTokenProvider.FallbackToProvider(cancellationToken);
}
///
/// 重写实现通知发布
diff --git a/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDataExtensions.cs b/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDataExtensions.cs
new file mode 100644
index 000000000..defe147ca
--- /dev/null
+++ b/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDataExtensions.cs
@@ -0,0 +1,33 @@
+namespace LINGYUN.Abp.Notifications;
+public static class NotificationDataExtensions
+{
+ private const string Prefix = "push-plus:";
+ private const string WebhookKey = Prefix + "webhook";
+ private const string CallbackUrlKey = Prefix + "callback";
+
+ public static void SetWebhook(
+ this NotificationData notificationData,
+ string url)
+ {
+ notificationData.TrySetData(WebhookKey, url);
+ }
+
+ public static string GetWebhookOrNull(
+ this NotificationData notificationData)
+ {
+ return notificationData.TryGetData(WebhookKey)?.ToString();
+ }
+
+ public static void SetCallbackUrl(
+ this NotificationData notificationData,
+ string callbackUrl)
+ {
+ notificationData.TrySetData(CallbackUrlKey, callbackUrl);
+ }
+
+ public static string GetCallbackUrlOrNull(
+ this NotificationData notificationData)
+ {
+ return notificationData.TryGetData(CallbackUrlKey)?.ToString();
+ }
+}
diff --git a/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs b/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
index 765a2da2d..a2feca472 100644
--- a/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
+++ b/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
@@ -1,9 +1,44 @@
using LINGYUN.Abp.PushPlus.Channel;
+using LINGYUN.Abp.PushPlus.Message;
using System;
namespace LINGYUN.Abp.Notifications;
public static class NotificationDefinitionExtensions
{
+ private const string Prefix = "push-plus:";
+ private const string TemplateKey = Prefix + "template";
+ private const string ChannelTypeKey = Prefix + "channel";
+ private const string TopicKey = Prefix + "topic";
+ ///
+ /// 设定消息模板
+ ///
+ ///
+ ///
+ ///
+ public static NotificationDefinition WithTemplate(
+ this NotificationDefinition notification,
+ PushPlusMessageTemplate template = PushPlusMessageTemplate.Text)
+ {
+ return notification.WithProperty(TemplateKey, template);
+ }
+ ///
+ /// 获取消息模板
+ ///
+ ///
+ ///
+ ///
+ public static PushPlusMessageTemplate GetTemplateOrDefault(
+ this NotificationDefinition notification,
+ PushPlusMessageTemplate defaultTemplate = PushPlusMessageTemplate.Text)
+ {
+ if (notification.Properties.TryGetValue(TemplateKey, out var defineTemplate) == true &&
+ defineTemplate is PushPlusMessageTemplate template)
+ {
+ return template;
+ }
+
+ return defaultTemplate;
+ }
///
/// 设定消息发送通道
///
@@ -14,7 +49,7 @@ public static class NotificationDefinitionExtensions
this NotificationDefinition notification,
PushPlusChannelType channelType)
{
- return notification.WithProperty("channel", channelType);
+ return notification.WithProperty(ChannelTypeKey, channelType);
}
///
/// 获取消息发送通道
@@ -26,7 +61,7 @@ public static class NotificationDefinitionExtensions
this NotificationDefinition notification,
PushPlusChannelType defaultChannelType = PushPlusChannelType.WeChat)
{
- if (notification.Properties.TryGetValue("channel", out var defineChannelType) == true &&
+ if (notification.Properties.TryGetValue(ChannelTypeKey, out var defineChannelType) == true &&
defineChannelType is PushPlusChannelType channelType)
{
return channelType;
@@ -47,7 +82,7 @@ public static class NotificationDefinitionExtensions
this NotificationDefinition notification,
string topic)
{
- return notification.WithProperty("topic", topic);
+ return notification.WithProperty(TopicKey, topic);
}
///
/// 获取消息群发群组编码
@@ -59,7 +94,7 @@ public static class NotificationDefinitionExtensions
public static string GetTopicOrNull(
this NotificationDefinition notification)
{
- if (notification.Properties.TryGetValue("topic", out var topicDefine) == true)
+ if (notification.Properties.TryGetValue(TopicKey, out var topicDefine) == true)
{
return topicDefine.ToString();
}
diff --git a/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/PushPlus/PushPlusNotificationPublishProvider.cs b/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/PushPlus/PushPlusNotificationPublishProvider.cs
index 1e1c75c97..4fc1746cc 100644
--- a/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/PushPlus/PushPlusNotificationPublishProvider.cs
+++ b/aspnet-core/modules/pushplus/LINGYUN.Abp.Notifications.PushPlus/LINGYUN/Abp/Notifications/PushPlus/PushPlusNotificationPublishProvider.cs
@@ -1,13 +1,16 @@
using LINGYUN.Abp.PushPlus.Channel;
+using LINGYUN.Abp.PushPlus.Features;
using LINGYUN.Abp.PushPlus.Message;
using LINGYUN.Abp.RealTime.Localization;
using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Volo.Abp.Features;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Notifications.PushPlus;
@@ -18,6 +21,8 @@ public class PushPlusNotificationPublishProvider : NotificationPublishProvider
public override string Name => ProviderName;
+ protected IFeatureChecker FeatureChecker { get; }
+
protected IPushPlusMessageSender PushPlusMessageSender { get; }
protected IStringLocalizerFactory LocalizerFactory { get; }
@@ -27,17 +32,32 @@ public class PushPlusNotificationPublishProvider : NotificationPublishProvider
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
public PushPlusNotificationPublishProvider(
+ IFeatureChecker featureChecker,
IPushPlusMessageSender pushPlusMessageSender,
IStringLocalizerFactory localizerFactory,
IOptions localizationOptions,
INotificationDefinitionManager notificationDefinitionManager)
{
+ FeatureChecker = featureChecker;
PushPlusMessageSender = pushPlusMessageSender;
LocalizerFactory = localizerFactory;
LocalizationOptions = localizationOptions.Value;
NotificationDefinitionManager = notificationDefinitionManager;
}
+ protected async override Task CanPublishAsync(NotificationInfo notification, CancellationToken cancellationToken = default)
+ {
+ if (!await FeatureChecker.IsEnabledAsync(PushPlusFeatureNames.Message.Enable))
+ {
+ Logger.LogWarning(
+ "{0} cannot push messages because the feature {0} is not enabled",
+ Name,
+ PushPlusFeatureNames.Message.Enable);
+ return false;
+ }
+ return true;
+ }
+
protected async override Task PublishAsync(
NotificationInfo notification,
IEnumerable identifiers,
@@ -53,6 +73,10 @@ public class PushPlusNotificationPublishProvider : NotificationPublishProvider
}
var channel = notificationDefine?.GetChannelOrDefault(PushPlusChannelType.Email)
?? PushPlusChannelType.Email;
+ var template = notificationDefine?.GetTemplateOrDefault(PushPlusMessageTemplate.Text)
+ ?? PushPlusMessageTemplate.Text;
+ var webhook = notification.Data.GetWebhookOrNull() ?? "";
+ var callbackUrl = notification.Data.GetCallbackUrlOrNull() ?? "";
if (!notification.Data.NeedLocalizer())
{
@@ -64,6 +88,9 @@ public class PushPlusNotificationPublishProvider : NotificationPublishProvider
message,
topic,
channelType: channel,
+ template: template,
+ webhook: webhook,
+ callbackUrl: callbackUrl,
cancellationToken: cancellationToken);
}
else
@@ -81,6 +108,9 @@ public class PushPlusNotificationPublishProvider : NotificationPublishProvider
message,
topic,
channelType: channel,
+ template: template,
+ webhook: webhook,
+ callbackUrl: callbackUrl,
cancellationToken: cancellationToken);
}
}
diff --git a/aspnet-core/modules/pushplus/LINGYUN.Abp.PushPlus/LINGYUN/Abp/PushPlus/Features/PushPlusFeatureDefinitionProvider.cs b/aspnet-core/modules/pushplus/LINGYUN.Abp.PushPlus/LINGYUN/Abp/PushPlus/Features/PushPlusFeatureDefinitionProvider.cs
index 57797b2eb..14c675e82 100644
--- a/aspnet-core/modules/pushplus/LINGYUN.Abp.PushPlus/LINGYUN/Abp/PushPlus/Features/PushPlusFeatureDefinitionProvider.cs
+++ b/aspnet-core/modules/pushplus/LINGYUN.Abp.PushPlus/LINGYUN/Abp/PushPlus/Features/PushPlusFeatureDefinitionProvider.cs
@@ -14,7 +14,7 @@ public class PushPlusFeatureDefinitionProvider : FeatureDefinitionProvider
group.AddFeature(
name: PushPlusFeatureNames.Message.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:MessageEnable"),
description: L("Features:MessageEnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
@@ -35,7 +35,7 @@ public class PushPlusFeatureDefinitionProvider : FeatureDefinitionProvider
description: L("Features:Channel.WeChat"));
weChatChannel.CreateChild(
name: PushPlusFeatureNames.Channel.WeChat.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:Channel.WeChat.Enable"),
description: L("Features:Channel.WeChat.EnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
@@ -62,7 +62,7 @@ public class PushPlusFeatureDefinitionProvider : FeatureDefinitionProvider
description: L("Features:Channel.WeWork"));
weWorkChannel.CreateChild(
name: PushPlusFeatureNames.Channel.WeWork.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:Channel.WeWork.Enable"),
description: L("Features:Channel.WeWork.EnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
@@ -89,7 +89,7 @@ public class PushPlusFeatureDefinitionProvider : FeatureDefinitionProvider
description: L("Features:Channel.Webhook"));
webhookChannel.CreateChild(
name: PushPlusFeatureNames.Channel.Webhook.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:Channel.Webhook.Enable"),
description: L("Features:Channel.Webhook.EnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
@@ -116,7 +116,7 @@ public class PushPlusFeatureDefinitionProvider : FeatureDefinitionProvider
description: L("Features:Channel.Email"));
emailChannel.CreateChild(
name: PushPlusFeatureNames.Channel.Email.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:Channel.Email.Enable"),
description: L("Features:Channel.Email.EnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
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 169c8d6a5..8548aa9ea 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
@@ -1,4 +1,5 @@
-using LINGYUN.Abp.WeChat.MiniProgram.Messages;
+using LINGYUN.Abp.WeChat.MiniProgram.Features;
+using LINGYUN.Abp.WeChat.MiniProgram.Messages;
using LINGYUN.Abp.WeChat.Security.Claims;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -6,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using Volo.Abp.Features;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
@@ -16,16 +18,32 @@ namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
public const string ProviderName = NotificationProviderNames.WechatMiniProgram;
public override string Name => ProviderName;
+ protected IFeatureChecker FeatureChecker { get; }
protected ISubscribeMessager SubscribeMessager { get; }
protected AbpNotificationsWeChatMiniProgramOptions Options { get; }
public WeChatMiniProgramNotificationPublishProvider(
+ IFeatureChecker featureChecker,
ISubscribeMessager subscribeMessager,
IOptions options)
{
Options = options.Value;
+ FeatureChecker = featureChecker;
SubscribeMessager = subscribeMessager;
}
+ protected async override Task CanPublishAsync(NotificationInfo notification, CancellationToken cancellationToken = default)
+ {
+ if (!await FeatureChecker.IsEnabledAsync(WeChatMiniProgramFeatures.Messages.Enable))
+ {
+ Logger.LogWarning(
+ "{0} cannot push messages because the feature {0} is not enabled",
+ Name,
+ WeChatMiniProgramFeatures.Messages.Enable);
+ return false;
+ }
+ return true;
+ }
+
protected override async Task PublishAsync(NotificationInfo notification, IEnumerable identifiers, CancellationToken cancellationToken = default)
{
// step1 默认微信openid绑定的就是username,
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Identity.WxPusher/LINGYUN/Abp/Identity/WxPusher/User/IdentityWxPusherUserStore.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Identity.WxPusher/LINGYUN/Abp/Identity/WxPusher/User/IdentityWxPusherUserStore.cs
index c55d763e9..15662db4e 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Identity.WxPusher/LINGYUN/Abp/Identity/WxPusher/User/IdentityWxPusherUserStore.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Identity.WxPusher/LINGYUN/Abp/Identity/WxPusher/User/IdentityWxPusherUserStore.cs
@@ -30,12 +30,12 @@ public class IdentityWxPusherUserStore : IWxPusherUserStore
{
var user = await UserManager.FindByIdAsync(userId.ToString());
- var userUidClaim = user?.Claims
- .Where(c => c.ClaimType.Equals(AbpWxPusherClaimTypes.Uid))
+ var userTopicClaim = user?.Claims
+ .Where(c => c.ClaimType.Equals(AbpWxPusherClaimTypes.Topic))
.FirstOrDefault();
- if (userUidClaim != null &&
- int.TryParse(userUidClaim.ClaimValue, out var topic))
+ if (userTopicClaim != null &&
+ int.TryParse(userTopicClaim.ClaimValue, out var topic))
{
topics.Add(topic);
}
@@ -43,4 +43,27 @@ public class IdentityWxPusherUserStore : IWxPusherUserStore
return topics.Distinct().ToList();
}
+
+ public async virtual Task> GetBindUidsAsync(
+ IEnumerable userIds,
+ CancellationToken cancellationToken = default)
+ {
+ var uids = new List();
+
+ foreach (var userId in userIds)
+ {
+ var user = await UserManager.FindByIdAsync(userId.ToString());
+
+ var userUidClaim = user?.Claims
+ .Where(c => c.ClaimType.Equals(AbpWxPusherClaimTypes.Uid))
+ .FirstOrDefault();
+
+ if (userUidClaim != null)
+ {
+ uids.Add(userUidClaim.ClaimValue);
+ }
+ }
+
+ return uids.Distinct().ToList();
+ }
}
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/FodyWeavers.xml b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/FodyWeavers.xml
new file mode 100644
index 000000000..ac6b5b292
--- /dev/null
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/FodyWeavers.xsd b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/FodyWeavers.xsd
new file mode 100644
index 000000000..11da52550
--- /dev/null
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/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/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDataExtensions.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDataExtensions.cs
new file mode 100644
index 000000000..429e659a3
--- /dev/null
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDataExtensions.cs
@@ -0,0 +1,19 @@
+namespace LINGYUN.Abp.Notifications;
+public static class NotificationDataExtensions
+{
+ private const string Prefix = "wx-pusher:";
+ private const string UrlKey = Prefix + "url";
+
+ public static void SetUrl(
+ this NotificationData notificationData,
+ string url)
+ {
+ notificationData.TrySetData(UrlKey, url);
+ }
+
+ public static string GetUrlOrNull(
+ this NotificationData notificationData)
+ {
+ return notificationData.TryGetData(UrlKey)?.ToString();
+ }
+}
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
index 3889d7df5..fa11e4645 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
@@ -8,6 +8,7 @@ public static class NotificationDefinitionExtensions
private const string Prefix = "wx-pusher:";
private const string ContentTypeKey = Prefix + "contentType";
private const string TopicKey = Prefix + "topic";
+ private const string UrlKey = Prefix + "url";
///
/// 设定消息内容类型
///
@@ -71,4 +72,32 @@ public static class NotificationDefinitionExtensions
return new List();
}
+ ///
+ /// 用户点击标题跳转页面
+ ///
+ /// 群组编码
+ ///
+ ///
+ ///
+ ///
+ public static NotificationDefinition WithUrl(
+ this NotificationDefinition notification,
+ string url)
+ {
+ return notification.WithProperty(UrlKey, url);
+ }
+ ///
+ /// 获取标题跳转页面
+ ///
+ ///
+ public static string GetUrlOrNull(
+ this NotificationDefinition notification)
+ {
+ if (notification.Properties.TryGetValue(UrlKey, out var urlDefine))
+ {
+ return urlDefine.ToString();
+ }
+
+ return null;
+ }
}
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherModule.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherModule.cs
index 794e15038..9e6f57366 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherModule.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherModule.cs
@@ -6,7 +6,7 @@ namespace LINGYUN.Abp.Notifications.WxPusher;
[DependsOn(
typeof(AbpNotificationModule),
typeof(AbpWxPusherModule))]
-public class AbpNotificationsPushPlusModule : AbpModule
+public class AbpNotificationsWxPusherModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/WxPusherNotificationPublishProvider.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/WxPusherNotificationPublishProvider.cs
index a9bf27a0a..ee966ae20 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/WxPusherNotificationPublishProvider.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.Notifications.WxPusher/LINGYUN/Abp/Notifications/WxPusher/WxPusherNotificationPublishProvider.cs
@@ -1,13 +1,16 @@
using LINGYUN.Abp.RealTime.Localization;
+using LINGYUN.Abp.WxPusher.Features;
using LINGYUN.Abp.WxPusher.Messages;
using LINGYUN.Abp.WxPusher.User;
using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Volo.Abp.Features;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Notifications.WxPusher;
@@ -18,6 +21,8 @@ public class WxPusherNotificationPublishProvider : NotificationPublishProvider
public override string Name => ProviderName;
+ protected IFeatureChecker FeatureChecker { get; }
+
protected IWxPusherUserStore WxPusherUserStore { get; }
protected IWxPusherMessageSender WxPusherMessageSender { get; }
@@ -29,12 +34,14 @@ public class WxPusherNotificationPublishProvider : NotificationPublishProvider
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
public WxPusherNotificationPublishProvider(
+ IFeatureChecker featureChecker,
IWxPusherUserStore wxPusherUserStore,
IWxPusherMessageSender wxPusherMessageSender,
IStringLocalizerFactory localizerFactory,
IOptions localizationOptions,
INotificationDefinitionManager notificationDefinitionManager)
{
+ FeatureChecker = featureChecker;
WxPusherUserStore = wxPusherUserStore;
WxPusherMessageSender = wxPusherMessageSender;
LocalizerFactory = localizerFactory;
@@ -42,17 +49,31 @@ public class WxPusherNotificationPublishProvider : NotificationPublishProvider
NotificationDefinitionManager = notificationDefinitionManager;
}
+ protected async override Task CanPublishAsync(NotificationInfo notification, CancellationToken cancellationToken = default)
+ {
+ if (!await FeatureChecker.IsEnabledAsync(WxPusherFeatureNames.Message.Enable))
+ {
+ Logger.LogWarning(
+ "{0} cannot push messages because the feature {1} is not enabled",
+ Name,
+ WxPusherFeatureNames.Message.Enable);
+ return false;
+ }
+ return true;
+ }
+
protected async override Task PublishAsync(
NotificationInfo notification,
IEnumerable identifiers,
CancellationToken cancellationToken = default)
{
- var topics = await WxPusherUserStore
- .GetSubscribeTopicsAsync(
- identifiers.Select(x => x.UserId),
- cancellationToken);
+ var subscribeUserIds = identifiers.Select(x => x.UserId);
+
+ var topics = await WxPusherUserStore.GetSubscribeTopicsAsync(subscribeUserIds, cancellationToken);
+ var uids = await WxPusherUserStore.GetBindUidsAsync(subscribeUserIds, cancellationToken);
var notificationDefine = NotificationDefinitionManager.GetOrNull(notification.Name);
+ var url = notification.Data.GetUrlOrNull() ?? notificationDefine?.GetUrlOrNull();
var topicDefine = notificationDefine?.GetTopics();
if (topicDefine.Any())
{
@@ -71,6 +92,8 @@ public class WxPusherNotificationPublishProvider : NotificationPublishProvider
summary: title,
contentType: contentType,
topicIds: topics,
+ uids: uids,
+ url: url,
cancellationToken: cancellationToken);
}
else
@@ -88,6 +111,8 @@ public class WxPusherNotificationPublishProvider : NotificationPublishProvider
summary: title,
contentType: contentType,
topicIds: topics,
+ uids: uids,
+ url: url,
cancellationToken: cancellationToken);
}
}
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Features/WxPusherFeatureDefinitionProvider.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Features/WxPusherFeatureDefinitionProvider.cs
index 27b13ce08..b560fbc02 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Features/WxPusherFeatureDefinitionProvider.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Features/WxPusherFeatureDefinitionProvider.cs
@@ -14,7 +14,7 @@ public class WxPusherFeatureDefinitionProvider : FeatureDefinitionProvider
displayName: L("Features:WxPusher"));
group.AddFeature(
name: WxPusherFeatureNames.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:WxPusherEnable"),
description: L("Features:WxPusherEnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
@@ -26,7 +26,7 @@ public class WxPusherFeatureDefinitionProvider : FeatureDefinitionProvider
message.CreateChild(
name: WxPusherFeatureNames.Message.Enable,
- defaultValue: "true",
+ defaultValue: "false",
displayName: L("Features:MessageEnable"),
description: L("Features:MessageEnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Security/Claims/AbpWxPusherClaimTypes.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Security/Claims/AbpWxPusherClaimTypes.cs
index 73e178a38..dc41503c9 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Security/Claims/AbpWxPusherClaimTypes.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Security/Claims/AbpWxPusherClaimTypes.cs
@@ -5,5 +5,9 @@ public static class AbpWxPusherClaimTypes
///
/// 用户的唯一标识
///
- public static string Uid { get; set; } = "wx-pusher-uid";
+ public static string Uid { get; set; } = "wxp-uid";
+ ///
+ /// 用户订阅topic
+ ///
+ public static string Topic { get; set; } = "wxp-topic";
}
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/IWxPusherUserStore.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/IWxPusherUserStore.cs
index 340828fc5..e57815d12 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/IWxPusherUserStore.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/IWxPusherUserStore.cs
@@ -16,4 +16,13 @@ public interface IWxPusherUserStore
Task> GetSubscribeTopicsAsync(
IEnumerable userIds,
CancellationToken cancellationToken = default);
+ ///
+ /// 获取绑定用户uid列表
+ ///
+ ///
+ ///
+ ///
+ Task> GetBindUidsAsync(
+ IEnumerable userIds,
+ CancellationToken cancellationToken = default);
}
diff --git a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/NullWxPusherUserStore.cs b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/NullWxPusherUserStore.cs
index 80ec02cfe..3751d8bf7 100644
--- a/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/NullWxPusherUserStore.cs
+++ b/aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/NullWxPusherUserStore.cs
@@ -19,4 +19,11 @@ public sealed class NullWxPusherUserStore : IWxPusherUserStore
{
return Task.FromResult(new List());
}
+
+ public Task> GetBindUidsAsync(
+ IEnumerable userIds,
+ CancellationToken cancellationToken = default)
+ {
+ return Task.FromResult(new List());
+ }
}
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 369a4e39c..5bf413239 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
@@ -55,6 +55,7 @@
+
@@ -71,6 +72,7 @@
+
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 9cb850ee1..b2847ccee 100644
--- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs
+++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs
@@ -42,6 +42,8 @@ using Volo.Abp.Modularity;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TextTemplating.Scriban;
+using LINGYUN.Abp.Notifications.PushPlus;
+using LINGYUN.Abp.Notifications.WxPusher;
namespace LY.MicroService.RealtimeMessage;
@@ -76,6 +78,8 @@ namespace LY.MicroService.RealtimeMessage;
typeof(AbpNotificationsSmsModule),
typeof(AbpNotificationsEmailingModule),
typeof(AbpNotificationsSignalRModule),
+ typeof(AbpNotificationsWxPusherModule),
+ typeof(AbpNotificationsPushPlusModule),
typeof(AbpNotificationsWeChatMiniProgramModule),
typeof(AbpNotificationsExceptionHandlingModule),
typeof(AbpTextTemplatingScribanModule),
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/FakeNotificationSender.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/FakeNotificationSender.cs
new file mode 100644
index 000000000..713e2522d
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/FakeNotificationSender.cs
@@ -0,0 +1,205 @@
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Json;
+using Volo.Abp.TextTemplating;
+
+namespace LINGYUN.Abp.Notifications;
+
+[Dependency(ReplaceServices = true)]
+public class FakeNotificationSender : INotificationSender, ITransientDependency
+{
+ public ILogger Logger { get; set; }
+
+ protected AbpNotificationOptions Options { get; }
+
+ protected IJsonSerializer JsonSerializer { get; }
+
+ protected ITemplateRenderer TemplateRenderer { get; }
+
+ protected INotificationStore NotificationStore { get; }
+
+ protected IStringLocalizerFactory StringLocalizerFactory { get; }
+
+ protected INotificationDefinitionManager NotificationDefinitionManager { get; }
+
+ protected INotificationSubscriptionManager NotificationSubscriptionManager { get; }
+
+ protected INotificationPublishProviderManager NotificationPublishProviderManager { get; }
+
+ public FakeNotificationSender(
+ IJsonSerializer jsonSerializer,
+ ITemplateRenderer templateRenderer,
+ IStringLocalizerFactory stringLocalizerFactory,
+ IOptions options,
+ INotificationStore notificationStore,
+ INotificationDefinitionManager notificationDefinitionManager,
+ INotificationSubscriptionManager notificationSubscriptionManager,
+ INotificationPublishProviderManager notificationPublishProviderManager)
+ {
+ Options = options.Value;
+ JsonSerializer = jsonSerializer;
+ TemplateRenderer = templateRenderer;
+ StringLocalizerFactory = stringLocalizerFactory;
+ NotificationStore = notificationStore;
+ NotificationDefinitionManager = notificationDefinitionManager;
+ NotificationSubscriptionManager = notificationSubscriptionManager;
+ NotificationPublishProviderManager = notificationPublishProviderManager;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public async virtual Task SendNofiterAsync(
+ string name,
+ NotificationData data,
+ IEnumerable users = null,
+ Guid? tenantId = null,
+ NotificationSeverity severity = NotificationSeverity.Info)
+ {
+ var notification = NotificationDefinitionManager.GetOrNull(name);
+ if (notification == null)
+ {
+ return "";
+ }
+
+ var notificationInfo = new NotificationInfo
+ {
+ Name = notification.Name,
+ CreationTime = DateTime.Now,
+ Data = data,
+ Severity = severity,
+ Lifetime = notification.NotificationLifetime,
+ TenantId = tenantId,
+ Type = notification.NotificationType
+ };
+ notificationInfo.SetId(DateTimeOffset.Now.ToUnixTimeMilliseconds());
+
+ notificationInfo.Data = NotificationDataConverter.Convert(notificationInfo.Data);
+
+ Logger.LogDebug($"Persistent notification {notificationInfo.Name}");
+
+ await NotificationStore.InsertNotificationAsync(notificationInfo);
+
+ var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers);
+
+ if (notification.Providers.Any())
+ {
+ providers = providers.Where(p => notification.Providers.Contains(p.Name));
+ }
+
+ await PublishFromProvidersAsync(
+ providers,
+ users ?? new List(),
+ notificationInfo);
+
+ return notificationInfo.Id;
+ }
+
+ public async virtual Task SendNofiterAsync(
+ string name,
+ NotificationTemplate template,
+ IEnumerable users = null,
+ Guid? tenantId = null,
+ NotificationSeverity severity = NotificationSeverity.Info)
+ {
+ var notification = NotificationDefinitionManager.GetOrNull(name);
+ if (notification == null)
+ {
+ return "";
+ }
+
+ var notificationInfo = new NotificationInfo
+ {
+ Name = notification.Name,
+ TenantId = tenantId,
+ Severity = severity,
+ Type = notification.NotificationType,
+ CreationTime = DateTime.Now,
+ Lifetime = notification.NotificationLifetime,
+ };
+ notificationInfo.SetId(DateTimeOffset.Now.ToUnixTimeMilliseconds());
+
+ var title = notification.DisplayName.Localize(StringLocalizerFactory);
+
+ var message = await TemplateRenderer.RenderAsync(
+ templateName: name,
+ model: template.ExtraProperties);
+
+ var notificationData = new NotificationData();
+ notificationData.WriteStandardData(
+ title: title,
+ message: message,
+ createTime: notificationInfo.CreationTime,
+ formUser: "Fake User");
+ notificationData.ExtraProperties.AddIfNotContains(template.ExtraProperties);
+
+ notificationInfo.Data = notificationData;
+
+ Logger.LogDebug($"Persistent notification {notificationInfo.Name}");
+
+ // 持久化通知
+ await NotificationStore.InsertNotificationAsync(notificationInfo);
+
+ var providers = Enumerable.Reverse(NotificationPublishProviderManager.Providers);
+
+ // 过滤用户指定提供者
+ if (notification.Providers.Any())
+ {
+ providers = providers.Where(p => notification.Providers.Contains(p.Name));
+ }
+
+ await PublishFromProvidersAsync(
+ providers,
+ users ?? new List(),
+ notificationInfo);
+
+ return notificationInfo.Id;
+ }
+
+ ///
+ /// 指定提供者发布通知
+ ///
+ /// 提供者列表
+ /// 通知信息
+ ///
+ protected async Task PublishFromProvidersAsync(
+ IEnumerable providers,
+ IEnumerable users,
+ NotificationInfo notificationInfo)
+ {
+ foreach (var provider in providers)
+ {
+ await PublishAsync(provider, notificationInfo, users);
+ }
+ }
+ ///
+ /// 发布通知
+ ///
+ /// 通知发布者
+ /// 通知信息
+ /// 订阅用户列表
+ ///
+ protected async Task PublishAsync(
+ INotificationPublishProvider provider,
+ NotificationInfo notificationInfo,
+ IEnumerable subscriptionUserIdentifiers)
+ {
+ Logger.LogDebug($"Sending notification with provider {provider.Name}");
+ var notifacationDataMapping = Options.NotificationDataMappings
+ .GetMapItemOrDefault(provider.Name, notificationInfo.Name);
+ if (notifacationDataMapping != null)
+ {
+ notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
+ }
+ // 发布
+ await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
+
+ Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
+ }
+}
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs
index bbf8b951d..2516405e3 100644
--- a/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs
@@ -2,7 +2,7 @@
{
public static class NotificationsTestsNames
{
- public const string GroupName = "Abp.Notifications";
+ public const string GroupName = "Abp.NotificationTests";
public const string Test1 = GroupName + ".Test1";
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN.Abp.Notifications.WxPusher.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN.Abp.Notifications.WxPusher.Tests.csproj
new file mode 100644
index 000000000..c5a7e8e7c
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN.Abp.Notifications.WxPusher.Tests.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net6.0
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherTestBase.cs
new file mode 100644
index 000000000..2a12ce9dd
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherTestBase.cs
@@ -0,0 +1,7 @@
+using LINGYUN.Abp.Tests;
+
+namespace LINGYUN.Abp.Notifications.WxPusher;
+
+public abstract class AbpNotificationsWxPusherTestBase : AbpTestsBase
+{
+}
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherTestModule.cs
new file mode 100644
index 000000000..4e56c313d
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/AbpNotificationsWxPusherTestModule.cs
@@ -0,0 +1,12 @@
+using LINGYUN.Abp.WxPusher;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Notifications.WxPusher;
+
+[DependsOn(
+ typeof(AbpNotificationsWxPusherModule),
+ typeof(AbpWxPusherTestModule),
+ typeof(AbpNotificationsTestsModule))]
+public class AbpNotificationsWxPusherTestModule : AbpModule
+{
+}
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/NotificationSenderTests.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/NotificationSenderTests.cs
new file mode 100644
index 000000000..490acfa02
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/NotificationSenderTests.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Notifications.WxPusher;
+
+public class NotificationSenderTests : AbpNotificationsWxPusherTestBase
+{
+ protected INotificationSender NotificationSender { get; }
+
+ public NotificationSenderTests()
+ {
+ NotificationSender = GetRequiredService();
+ }
+
+ [Theory]
+ [InlineData(
+ "Title from the Xunit unit test",
+ "Text content from the Xunit unit test. \r\n Click the link at the top to redirect baidu site.")]
+ public async Task Send_Text_Test(
+ string title,
+ string message)
+ {
+ var notificationData = new NotificationData();
+ notificationData.WriteStandardData(
+ title,
+ message,
+ DateTime.Now,
+ "xUnit Test");
+ notificationData.SetUrl("https://www.baidu.com/");
+
+ await NotificationSender.SendNofiterAsync(
+ NotificationsTestsNames.Test1,
+ notificationData);
+ }
+
+ [Theory]
+ [InlineData(
+ "Title from the Xunit unit test",
+ "Html content from the Xunit unit test.
Click to redirect baidu site.")]
+ public async Task Send_Html_Test(
+ string title,
+ string message)
+ {
+ var notificationData = new NotificationData();
+ notificationData.WriteStandardData(
+ title,
+ message,
+ DateTime.Now,
+ "xUnit Test");
+ notificationData.SetUrl("https://www.baidu.com/");
+
+ await NotificationSender.SendNofiterAsync(
+ NotificationsTestsNames.Test2,
+ notificationData);
+ }
+
+ [Theory]
+ [InlineData(
+ "Title from the Xunit unit test",
+ "**Markdown content from the Xunit unit test.**
Click to redirect baidu site.")]
+ public async Task Send_Markdown_Test(
+ string title,
+ string message)
+ {
+ var notificationData = new NotificationData();
+ notificationData.WriteStandardData(
+ title,
+ message,
+ DateTime.Now,
+ "xUnit Test");
+ notificationData.SetUrl("https://www.baidu.com/");
+
+ await NotificationSender.SendNofiterAsync(
+ NotificationsTestsNames.Test3,
+ notificationData);
+ }
+}
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/NotificationsWxPusherTestsDefinitionProvider.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/NotificationsWxPusherTestsDefinitionProvider.cs
new file mode 100644
index 000000000..7915886fa
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/LINGYUN/Abp/Notifications/WxPusher/NotificationsWxPusherTestsDefinitionProvider.cs
@@ -0,0 +1,28 @@
+using LINGYUN.Abp.WxPusher.Messages;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace LINGYUN.Abp.Notifications.WxPusher;
+
+public class NotificationsWxPusherTestsDefinitionProvider : NotificationDefinitionProvider
+{
+ public override void Define(INotificationDefinitionContext context)
+ {
+ var group = context.GetGroupOrNull(NotificationsTestsNames.GroupName);
+
+ var nt1 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test1));
+ nt1.WithProviders(WxPusherNotificationPublishProvider.ProviderName)
+ .WithContentType(MessageContentType.Text)
+ .WithTopics(new List { 7182 });
+
+ var nt2 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test2));
+ nt2.WithProviders(WxPusherNotificationPublishProvider.ProviderName)
+ .WithContentType(MessageContentType.Html)
+ .WithTopics(new List { 7182 });
+
+ var nt3 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test3));
+ nt3.WithProviders(WxPusherNotificationPublishProvider.ProviderName)
+ .WithContentType(MessageContentType.Markdown)
+ .WithTopics(new List { 7182 });
+ }
+}
diff --git a/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/Usings.cs b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/Usings.cs
new file mode 100644
index 000000000..5cf9e838b
--- /dev/null
+++ b/aspnet-core/tests/LINGYUN.Abp.Notifications.WxPusher.Tests/Usings.cs
@@ -0,0 +1,2 @@
+global using Xunit;
+global using Shouldly;
\ No newline at end of file