From 28209ad3ed7b73c680ca53a4a2af305b143070f1 Mon Sep 17 00:00:00 2001
From: cKey <35512826+colinin@users.noreply.github.com>
Date: Wed, 10 Jun 2020 15:39:01 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BE=AE=E4=BF=A1=E5=B0=8F?=
=?UTF-8?q?=E7=A8=8B=E5=BA=8F=E9=80=9A=E7=9F=A5=E5=8A=9F=E8=83=BD,?=
=?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=B6=88=E6=81=AF=E6=A0=87?=
=?UTF-8?q?=E8=AF=86=E7=AC=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../AbpWeChatWeAppNotificationOptions.cs | 4 ++
.../WeChatWeAppNotificationPublishProvider.cs | 14 +++--
.../WeApp/WeChatWeAppNotificationSender.cs | 3 +-
.../WeApp/WeChatWeAppSendNotificationData.cs | 42 +++++++++++++++
.../LINGYUN.Abp.Notifications.csproj | 1 +
.../Notifications/AbpNotificationModule.cs | 5 ++
.../Internal/DefaultNotificationDispatcher.cs | 51 ++++++++++++++-----
.../Notifications/NotificationPublishJob.cs | 34 +++++++++++++
.../NotificationPublishJobArgs.cs | 20 ++++++++
.../Controllers/NotificationController.cs | 15 +++++-
10 files changed, 171 insertions(+), 18 deletions(-)
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJobArgs.cs
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs
index 17f20e7be..cacc4e47b 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs
@@ -2,6 +2,10 @@
{
public class AbpWeChatWeAppNotificationOptions
{
+ ///
+ /// 默认消息头部标记
+ ///
+ public string DefaultMsgPrefix { get; set; } = "[wx]";
///
/// 默认小程序模板
///
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs
index 837e8c7b2..f30a14580 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs
@@ -31,6 +31,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
// 如果不是,需要自行处理openid获取逻辑
// step2 调用微信消息推送接口
+
foreach (var identifier in identifiers)
{
await SendWeChatTemplateMessagAsync(notification, identifier);
@@ -42,18 +43,21 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
var templateId = GetOrDefaultTemplateId(notification.Data);
Logger.LogDebug($"Get wechat weapp template id: {templateId}");
- var redirect = GetOrDefault(notification.Data, "RedirectPage", "");
- Logger.LogDebug($"Get wechat weapp redirect page: {redirect}");
+ var redirect = GetOrDefault(notification.Data, "RedirectPage", null);
+ Logger.LogDebug($"Get wechat weapp redirect page: {redirect ?? "null"}");
var weAppState = GetOrDefault(notification.Data, "WeAppState", Options.DefaultWeAppState);
- Logger.LogDebug($"Get wechat weapp state: {weAppState}");
+ Logger.LogDebug($"Get wechat weapp state: {weAppState ?? null}");
var weAppLang = GetOrDefault(notification.Data, "WeAppLanguage", Options.DefaultWeAppLanguage);
- Logger.LogDebug($"Get wechat weapp language: {weAppLang}");
+ Logger.LogDebug($"Get wechat weapp language: {weAppLang ?? null}");
var weChatWeAppNotificationData = new WeChatWeAppSendNotificationData(identifier.UserName,
templateId, redirect, weAppState, weAppLang);
+ // 写入模板数据
+ weChatWeAppNotificationData.WriteData(Options.DefaultMsgPrefix, notification.Data.Properties);
+
Logger.LogDebug($"Sending wechat weapp notification: {notification.Name}");
// 发送小程序订阅消息
await NotificationSender.SendAsync(weChatWeAppNotificationData);
@@ -68,6 +72,8 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
if (data.Properties.TryGetValue(key, out object value))
{
+ // 取得了数据就删除对应键值
+ data.Properties.Remove(key);
return value.ToString();
}
return defaultValue;
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs
index ba912aaa4..701c11573 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs
@@ -43,7 +43,8 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
protected virtual async Task MakeRequestAndGetResultAsync(string url, WeChatWeAppSendNotificationData notificationData)
{
var client = HttpClientFactory.CreateClient(SendNotificationClientName);
- var requestContent = new StringContent(JsonSerializer.Serialize(notificationData));
+ var sendDataContent = JsonSerializer.Serialize(notificationData);
+ var requestContent = new StringContent(sendDataContent);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = requestContent
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs
index 27852d822..bf71c952a 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs
@@ -1,4 +1,6 @@
#pragma warning disable IDE1006 // 禁止编译器提示
+using System.Collections.Generic;
+
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
public class WeChatWeAppSendNotificationData
@@ -29,6 +31,11 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
/// 默认为zh_CN
///
public string lang { get; set; }
+ ///
+ /// 模板内容,
+ /// 格式形如 { "key1": { "value": any }, "key2": { "value": any } }
+ ///
+ public Dictionary data { get; set; }
public WeChatWeAppSendNotificationData() { }
public WeChatWeAppSendNotificationData(string openId, string templateId, string redirectPage = "",
@@ -39,6 +46,41 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
page = redirectPage;
miniprogram_state = state;
lang = miniLang;
+
+ data = new Dictionary();
+ }
+
+ public WeChatWeAppSendNotificationData WriteData(string prefix, string key, object value)
+ {
+ // 只截取符合标记的数据
+ if (key.StartsWith(prefix))
+ {
+ key = key.Replace(prefix, "");
+ if (!data.ContainsKey(key))
+ {
+ data.Add(key, new WeChatNotificationData(value));
+ }
+ }
+ return this;
+ }
+
+ public WeChatWeAppSendNotificationData WriteData(string prefix, IDictionary setData)
+ {
+ foreach(var kv in setData)
+ {
+ WriteData(prefix, kv.Key, kv.Value);
+ }
+ return this;
+ }
+ }
+
+ public class WeChatNotificationData
+ {
+ public object Value { get; }
+
+ public WeChatNotificationData(object value)
+ {
+ Value = value;
}
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj
index a6f38bfc2..8611e478a 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj
@@ -14,6 +14,7 @@
+
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 bc983485c..92b5fce3b 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
@@ -2,10 +2,15 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.Json;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications
{
+ [DependsOn(
+ typeof(AbpBackgroundJobsModule),
+ typeof(AbpJsonModule))]
public class AbpNotificationModule : AbpModule
{
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
index 36fea5853..b53ae524e 100644
--- a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using Volo.Abp.BackgroundJobs;
namespace LINGYUN.Abp.Notifications.Internal
{
@@ -11,14 +12,20 @@ namespace LINGYUN.Abp.Notifications.Internal
{
public ILogger Logger { get; set; }
+ private readonly IBackgroundJobManager _backgroundJobManager;
+
private readonly INotificationStore _notificationStore;
private readonly INotificationDefinitionManager _notificationDefinitionManager;
private readonly INotificationPublishProviderManager _notificationPublishProviderManager;
public DefaultNotificationDispatcher(
+ IBackgroundJobManager backgroundJobManager,
+
INotificationStore notificationStore,
INotificationDefinitionManager notificationDefinitionManager,
INotificationPublishProviderManager notificationPublishProviderManager)
{
+ _backgroundJobManager = backgroundJobManager;
+
_notificationStore = notificationStore;
_notificationDefinitionManager = notificationDefinitionManager;
_notificationPublishProviderManager = notificationPublishProviderManager;
@@ -100,21 +107,41 @@ namespace LINGYUN.Abp.Notifications.Internal
// 发布通知
foreach (var provider in providers)
{
- try
- {
- Logger.LogDebug($"Sending notification with provider {provider.Name}");
+ await PublishAsync(provider, notificationInfo, subscriptionUserIdentifiers);
+ }
+
+ // TODO: 需要计算队列大小,根据情况是否需要并行发布消息
+ //Parallel.ForEach(providers, async (provider) =>
+ //{
+ // await PublishAsync(provider, notificationInfo, subscriptionUserIdentifiers);
+ //});
+ }
- await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
+ protected async Task PublishAsync(INotificationPublishProvider provider, NotificationInfo notificationInfo,
+ IEnumerable subscriptionUserIdentifiers)
+ {
+ try
+ {
+ Logger.LogDebug($"Sending notification with provider {provider.Name}");
- Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
- }
- catch(Exception ex)
- {
- Logger.LogWarning($"Send notification error with provider {provider.Name}");
- Logger.LogWarning($"Error message:{ex.Message}");
+ await provider.PublishAsync(notificationInfo, subscriptionUserIdentifiers);
- Logger.LogTrace(ex, $"Send notification error with provider { provider.Name}");
- }
+ Logger.LogDebug($"Send notification {notificationInfo.Name} with provider {provider.Name} was successful");
+ }
+ catch (Exception ex)
+ {
+ Logger.LogWarning($"Send notification error with provider {provider.Name}");
+ Logger.LogWarning($"Error message:{ex.Message}");
+
+ Logger.LogTrace(ex, $"Send notification error with provider { provider.Name}");
+
+ Logger.LogDebug($"Send notification error, notification {notificationInfo.Name} entry queue");
+ // 发送失败的消息进入后台队列
+ await _backgroundJobManager.EnqueueAsync(
+ new NotificationPublishJobArgs(notificationInfo.GetId(),
+ provider.GetType().AssemblyQualifiedName,
+ subscriptionUserIdentifiers.ToList(),
+ notificationInfo.TenantId));
}
}
}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs
new file mode 100644
index 000000000..2ae41faff
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs
@@ -0,0 +1,34 @@
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Threading.Tasks;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class NotificationPublishJob : AsyncBackgroundJob, ITransientDependency
+ {
+ protected INotificationStore Store { get; }
+ protected IServiceProvider ServiceProvider { get; }
+
+ public NotificationPublishJob(
+ INotificationStore store,
+ IServiceProvider serviceProvider)
+ {
+ Store = store;
+ ServiceProvider = serviceProvider;
+ }
+
+ public override async Task ExecuteAsync(NotificationPublishJobArgs args)
+ {
+ var providerType = Type.GetType(args.ProviderType);
+
+ if (ServiceProvider.GetRequiredService(providerType) is INotificationPublishProvider publishProvider)
+ {
+ var notification = await Store.GetNotificationOrNullAsync(args.TenantId, args.NotificationId);
+
+ await publishProvider.PublishAsync(notification, args.UserIdentifiers);
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJobArgs.cs b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJobArgs.cs
new file mode 100644
index 000000000..128019301
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJobArgs.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+
+namespace LINGYUN.Abp.Notifications
+{
+ public class NotificationPublishJobArgs
+ {
+ public Guid? TenantId { get; set; }
+ public long NotificationId { get; set; }
+ public string ProviderType { get; set; }
+ public List UserIdentifiers { get; set; }
+ public NotificationPublishJobArgs(long id, string providerType, List userIdentifiers, Guid? tenantId = null )
+ {
+ NotificationId = id;
+ ProviderType = providerType;
+ UserIdentifiers = userIdentifiers;
+ TenantId = tenantId;
+ }
+ }
+}
diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
index 476873529..6ff6f3732 100644
--- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
+++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs
@@ -17,9 +17,22 @@ namespace LINGYUN.Abp.MessageService.Controllers
_notificationDispatcher = notificationDispatcher;
}
+ [HttpGet]
+ [Route("Test")]
+ public async Task> Test()
+ {
+ await Task.CompletedTask;
+
+ return new Dictionary()
+ {
+ {"thing2", "测试标题" },
+ {"name3", "测试人员" },
+ };
+ }
+
[HttpPost]
[Route("Send")]
- public async Task SendNofitication([FromForm] SendNotification notification)
+ public async Task SendNofitication([FromBody] SendNotification notification)
{
var notificationData = new NotificationData();
notificationData.Properties["title"] = notification.Title;