Browse Source

完善微信小程序通知功能,增加一个消息标识符

pull/7/head
cKey 6 years ago
parent
commit
28209ad3ed
  1. 4
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs
  2. 14
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs
  3. 3
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs
  4. 42
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs
  5. 1
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj
  6. 5
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
  7. 51
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/DefaultNotificationDispatcher.cs
  8. 34
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs
  9. 20
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJobArgs.cs
  10. 15
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/Controllers/NotificationController.cs

4
aspnet-core/modules/common/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs

@ -2,6 +2,10 @@
{
public class AbpWeChatWeAppNotificationOptions
{
/// <summary>
/// 默认消息头部标记
/// </summary>
public string DefaultMsgPrefix { get; set; } = "[wx]";
/// <summary>
/// 默认小程序模板
/// </summary>

14
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;

3
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<string> 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

42
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
/// </summary>
public string lang { get; set; }
/// <summary>
/// 模板内容,
/// 格式形如 { "key1": { "value": any }, "key2": { "value": any } }
/// </summary>
public Dictionary<string, WeChatNotificationData> 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<string, WeChatNotificationData>();
}
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<string, object> 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;
}
}
}

1
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN.Abp.Notifications.csproj

@ -14,6 +14,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Json" Version="2.9.0" />
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="2.9.0" />
</ItemGroup>
</Project>

5
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
{

51
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<DefaultNotificationDispatcher> 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<UserIdentifier> 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));
}
}
}

34
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<NotificationPublishJobArgs>, 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);
}
}
}
}

20
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<UserIdentifier> UserIdentifiers { get; set; }
public NotificationPublishJobArgs(long id, string providerType, List<UserIdentifier> userIdentifiers, Guid? tenantId = null )
{
NotificationId = id;
ProviderType = providerType;
UserIdentifiers = userIdentifiers;
TenantId = tenantId;
}
}
}

15
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<Dictionary<string, object>> Test()
{
await Task.CompletedTask;
return new Dictionary<string, object>()
{
{"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;

Loading…
Cancel
Save