Browse Source

Improved notification data mapping

pull/143/head
cKey 5 years ago
parent
commit
34d74058fc
  1. 45
      aspnet-core/LINGYUN.MicroService.All.sln
  2. 51
      aspnet-core/LINGYUN.MicroService.Messages.sln
  3. 29
      aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj
  4. 29
      aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/AbpAliyunCloudModule.cs
  5. 9
      aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Localization/AliyunResource.cs
  6. 5
      aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Localization/Resources/en.json
  7. 5
      aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Localization/Resources/zh-Hans.json
  8. 19
      aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Settings/AliyunSettingNames.cs
  9. 27
      aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINGYUN.Abp.Tencent.csproj
  10. 29
      aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/AbpTencentCloudModule.cs
  11. 5
      aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/Localization/Resources/en.json
  12. 5
      aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/Localization/Resources/zh-Hans.json
  13. 9
      aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/Localization/TencentResource.cs
  14. 19
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalROptions.cs
  15. 16
      aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs
  16. 3
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs
  17. 15
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalROptions.cs
  18. 6
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs
  19. 19
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/AbpNotificationsSmsModule.cs
  20. 31
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsModule.cs
  21. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsOptions.cs
  22. 21
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/ISmsNotificationSender.cs
  23. 42
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationPublishProvider.cs
  24. 47
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationSender.cs
  25. 37
      aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/README.md
  26. 1
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs
  27. 17
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs
  28. 13
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs
  29. 11
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs
  30. 4
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs
  31. 15
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataConverter.cs
  32. 49
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionary.cs
  33. 19
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionaryItem.cs
  34. 20
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionaryItemExtensions.cs
  35. 1
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs
  36. 32
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs
  37. 2
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs
  38. 8
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs
  39. 9
      aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/UserIdentifier.cs
  40. 6
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj
  41. 30
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramModule.cs
  42. 25
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramOptions.cs
  43. 20
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/Features/WeChatMiniProgramFeatureDefinitionProvider.cs
  44. 6
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/Features/WeChatMiniProgramFeatures.cs
  45. 27
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs
  46. 40
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/README.md
  47. 23
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpNotificationsWeChatWeAppModule.cs
  48. 22
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs
  49. 10
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/IWeChatWeAppNotificationSender.cs
  50. 123
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs
  51. 103
      aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs
  52. 24
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj
  53. 72
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationConsts.cs
  54. 28
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs
  55. 9
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationOptions.cs
  56. 47
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationOptionsFactory.cs
  57. 48
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatClaimTypes.cs
  58. 11
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Settings/WeChatAuthorizationSettingNames.cs
  59. 32
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Settings/WeChatAuthorizationSettingProvider.cs
  60. 10
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/IWeChatTokenProvider.cs
  61. 26
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatToken.cs
  62. 24
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenCacheItem.cs
  63. 89
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenProvider.cs
  64. 10
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenRequest.cs
  65. 41
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenResponse.cs
  66. 17
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/README.md
  67. 45
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs
  68. 39
      aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/Volo/Abp/Users/CurrentUserExtensions.cs
  69. 6
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs
  70. 16
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs
  71. 3
      aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj
  72. 24
      aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN.Abp.Notifications.Sms.Tests.csproj
  73. 8
      aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsTestsBase.cs
  74. 42
      aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsTestsModule.cs
  75. 82
      aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/SmsNotificationDataMapping_Tests.cs
  76. 23
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN.Abp.Notifications.Tests.csproj
  77. 8
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/AbpNotificationsTestsBase.cs
  78. 13
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/AbpNotificationsTestsModule.cs
  79. 22
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider.cs
  80. 51
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider_Tests.cs
  81. 13
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs
  82. 24
      aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests.csproj
  83. 8
      aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramTestsBase.cs
  84. 41
      aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramTestsModule.cs
  85. 77
      aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/WeChatMiniProgramNotificationDataMapping_Tests.cs

45
aspnet-core/LINGYUN.MicroService.All.sln

@ -109,8 +109,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.HttpApi", "modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj", "{9E12ADBF-713B-4FE7-B71F-52B5078A57CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.WeApp", "modules\wechat\LINGYUN.Abp.Notifications.WeChat\LINGYUN.Abp.Notifications.WeChat.WeApp.csproj", "{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Storage.MySql", "modules\common\LINGYUN.Abp.Hangfire.MySqlStorage\LINGYUN.Abp.Hangfire.Storage.MySql.csproj", "{47CC8F7A-681D-42B9-AE04-78453782C1B6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Storage.SqlServer", "modules\common\LINGYUN.Abp.Hangfire.Storage.SqlServer\LINGYUN.Abp.Hangfire.Storage.SqlServer.csproj", "{F595CB9F-B117-4D62-A1AE-48599927DB36}"
@ -261,6 +259,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.SettingM
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.WeChat", "modules\identityServer\LINGYUN.Abp.IdentityServer.WeChat\LINGYUN.Abp.IdentityServer.WeChat.csproj", "{7356FC4B-CAB2-4808-8C97-9AF74583F3A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj", "{DC15AE5F-D20E-47E4-92A4-DBBD1BD51E91}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cloud-aliyun", "cloud-aliyun", "{14CDBAD1-10C8-464A-B445-1F727C988010}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cloud-tencent", "cloud-tencent", "{3B96F4D8-4993-419B-BCEB-AFE4ED39449F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Aliyun", "modules\cloud-aliyun\LINGYUN.Abp.Aliyun\LINGYUN.Abp.Aliyun.csproj", "{FCFAF1AF-B3F6-45F3-85AB-8249EB8432CC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Tencent", "modules\cloud-tencent\LINGYUN.Abp.Tencent\LINGYUN.Abp.Tencent.csproj", "{97B4A37E-B93E-48C9-95D5-689CB9495D8B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms", "modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj", "{8C3312E7-F51E-4780-A893-CE0E0B80B579}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -427,10 +437,6 @@ Global
{9E12ADBF-713B-4FE7-B71F-52B5078A57CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E12ADBF-713B-4FE7-B71F-52B5078A57CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E12ADBF-713B-4FE7-B71F-52B5078A57CE}.Release|Any CPU.Build.0 = Release|Any CPU
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359}.Release|Any CPU.Build.0 = Release|Any CPU
{47CC8F7A-681D-42B9-AE04-78453782C1B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47CC8F7A-681D-42B9-AE04-78453782C1B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47CC8F7A-681D-42B9-AE04-78453782C1B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -691,6 +697,22 @@ Global
{7356FC4B-CAB2-4808-8C97-9AF74583F3A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7356FC4B-CAB2-4808-8C97-9AF74583F3A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7356FC4B-CAB2-4808-8C97-9AF74583F3A4}.Release|Any CPU.Build.0 = Release|Any CPU
{DC15AE5F-D20E-47E4-92A4-DBBD1BD51E91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC15AE5F-D20E-47E4-92A4-DBBD1BD51E91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC15AE5F-D20E-47E4-92A4-DBBD1BD51E91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC15AE5F-D20E-47E4-92A4-DBBD1BD51E91}.Release|Any CPU.Build.0 = Release|Any CPU
{FCFAF1AF-B3F6-45F3-85AB-8249EB8432CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FCFAF1AF-B3F6-45F3-85AB-8249EB8432CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FCFAF1AF-B3F6-45F3-85AB-8249EB8432CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FCFAF1AF-B3F6-45F3-85AB-8249EB8432CC}.Release|Any CPU.Build.0 = Release|Any CPU
{97B4A37E-B93E-48C9-95D5-689CB9495D8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97B4A37E-B93E-48C9-95D5-689CB9495D8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97B4A37E-B93E-48C9-95D5-689CB9495D8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97B4A37E-B93E-48C9-95D5-689CB9495D8B}.Release|Any CPU.Build.0 = Release|Any CPU
{8C3312E7-F51E-4780-A893-CE0E0B80B579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C3312E7-F51E-4780-A893-CE0E0B80B579}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C3312E7-F51E-4780-A893-CE0E0B80B579}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C3312E7-F51E-4780-A893-CE0E0B80B579}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -730,7 +752,7 @@ Global
{8B09385A-719C-4B83-B61E-0ECD5D2734BD} = {9E72FEB9-A626-4312-892B-CDD043879758}
{8E569C1C-2637-4D89-804C-50FBC83948FB} = {9E72FEB9-A626-4312-892B-CDD043879758}
{5A10C02B-D12C-479C-9E7F-9A7D9DDD753D} = {9E72FEB9-A626-4312-892B-CDD043879758}
{FF1839EA-FB6B-4ED5-9804-E40427046D35} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{FF1839EA-FB6B-4ED5-9804-E40427046D35} = {14CDBAD1-10C8-464A-B445-1F727C988010}
{9FE2A95F-D7A3-4305-9E12-E955EF74CF8D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{6E4A0D87-C3CE-430F-A475-A6B68C116D96} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
@ -747,7 +769,6 @@ Global
{608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F} = {672E1170-7B18-474B-85C7-1961BF2A48AE}
{0D1DB712-B48D-4FB7-9A47-694C668A62E3} = {608A3BD0-FC8D-48B0-B1C5-F3203A3BE99F}
{9E12ADBF-713B-4FE7-B71F-52B5078A57CE} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D}
{85EF4251-EFC4-4CC9-912B-EA5DB1E2E359} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{47CC8F7A-681D-42B9-AE04-78453782C1B6} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{F595CB9F-B117-4D62-A1AE-48599927DB36} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{5CF403B2-47C9-4E4E-8856-0294BDD64884} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
@ -755,7 +776,7 @@ Global
{059473BA-FAF9-405F-9985-33DDCA2E9F0D} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{B39B5FB6-E7B9-4A13-8FFA-FC7FEED4371B} = {370D7CD5-1E17-4F3D-BBFA-03429F6D4F2F}
{C8A00439-5B8D-4923-8FAA-AB75E2A786ED} = {370D7CD5-1E17-4F3D-BBFA-03429F6D4F2F}
{F3AE9617-983D-4940-B5EB-35E3580C0B0F} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
{F3AE9617-983D-4940-B5EB-35E3580C0B0F} = {14CDBAD1-10C8-464A-B445-1F727C988010}
{31B03DCB-ED12-4412-867A-61E347D40D8C} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D}
{AB984240-EF03-416F-A9B2-F5CF169E04B7} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D}
{EBBBBD00-74B5-49CB-8C24-4FD7C2ECC415} = {3CDBA2A6-DC8A-48C5-8A6C-AF207394B43D}
@ -822,6 +843,12 @@ Global
{42309C06-C0F2-490F-931B-CF41FA1970FF} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{EC19F867-E9EA-4B26-A1E7-87AAA3EB9296} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{7356FC4B-CAB2-4808-8C97-9AF74583F3A4} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{DC15AE5F-D20E-47E4-92A4-DBBD1BD51E91} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{14CDBAD1-10C8-464A-B445-1F727C988010} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{3B96F4D8-4993-419B-BCEB-AFE4ED39449F} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{FCFAF1AF-B3F6-45F3-85AB-8249EB8432CC} = {14CDBAD1-10C8-464A-B445-1F727C988010}
{97B4A37E-B93E-48C9-95D5-689CB9495D8B} = {3B96F4D8-4993-419B-BCEB-AFE4ED39449F}
{8C3312E7-F51E-4780-A893-CE0E0B80B579} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

51
aspnet-core/LINGYUN.MicroService.Messages.sln

@ -43,8 +43,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MessageService.
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wechat", "wechat", "{78164C5C-63B9-4FB6-ACC9-6496E236C946}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.WeChat.WeApp", "modules\wechat\LINGYUN.Abp.Notifications.WeChat\LINGYUN.Abp.Notifications.WeChat.WeApp.csproj", "{D7B2B2BE-C32C-47AE-A46C-62B7EF8C318E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Features.LimitValidation", "modules\common\LINGYUN.Abp.Features.LimitValidation\LINGYUN.Abp.Features.LimitValidation.csproj", "{93971F1F-F6AC-4F83-8119-21260FCE2828}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat", "modules\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj", "{3B87330F-A303-4413-B653-1C9536C74109}"
@ -53,6 +51,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "message", "message", "{D58F
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.WeChat.MiniProgram\LINGYUN.Abp.WeChat.MiniProgram.csproj", "{3A4601FE-B091-43A3-AEE6-6440BB37B277}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.Sms", "modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj", "{454059F7-D087-439A-A724-80BDFE94776F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram", "modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj", "{64E2622A-611D-4056-9497-0B52A91DC59C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{42800C56-9473-4B96-BF29-1B0F25C867F4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.Sms.Tests", "tests\LINGYUN.Abp.Notifications.Sms.Tests\LINGYUN.Abp.Notifications.Sms.Tests.csproj", "{5714481A-BDF5-4860-9158-3B18D3018EC5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TestsBase", "tests\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj", "{B5E23AED-3068-4CFE-84B0-3B7725665506}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.Tests", "tests\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj", "{E5257008-A0AD-473F-91B0-864FC601B84B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests", "tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests\LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests.csproj", "{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -123,10 +135,6 @@ Global
{8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8168B7B4-9F6B-4658-A28C-D0F9D10AB93D}.Release|Any CPU.Build.0 = Release|Any CPU
{D7B2B2BE-C32C-47AE-A46C-62B7EF8C318E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7B2B2BE-C32C-47AE-A46C-62B7EF8C318E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7B2B2BE-C32C-47AE-A46C-62B7EF8C318E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7B2B2BE-C32C-47AE-A46C-62B7EF8C318E}.Release|Any CPU.Build.0 = Release|Any CPU
{93971F1F-F6AC-4F83-8119-21260FCE2828}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93971F1F-F6AC-4F83-8119-21260FCE2828}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93971F1F-F6AC-4F83-8119-21260FCE2828}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -139,6 +147,30 @@ Global
{3A4601FE-B091-43A3-AEE6-6440BB37B277}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A4601FE-B091-43A3-AEE6-6440BB37B277}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A4601FE-B091-43A3-AEE6-6440BB37B277}.Release|Any CPU.Build.0 = Release|Any CPU
{454059F7-D087-439A-A724-80BDFE94776F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{454059F7-D087-439A-A724-80BDFE94776F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{454059F7-D087-439A-A724-80BDFE94776F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{454059F7-D087-439A-A724-80BDFE94776F}.Release|Any CPU.Build.0 = Release|Any CPU
{64E2622A-611D-4056-9497-0B52A91DC59C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64E2622A-611D-4056-9497-0B52A91DC59C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64E2622A-611D-4056-9497-0B52A91DC59C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64E2622A-611D-4056-9497-0B52A91DC59C}.Release|Any CPU.Build.0 = Release|Any CPU
{5714481A-BDF5-4860-9158-3B18D3018EC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5714481A-BDF5-4860-9158-3B18D3018EC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5714481A-BDF5-4860-9158-3B18D3018EC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5714481A-BDF5-4860-9158-3B18D3018EC5}.Release|Any CPU.Build.0 = Release|Any CPU
{B5E23AED-3068-4CFE-84B0-3B7725665506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5E23AED-3068-4CFE-84B0-3B7725665506}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5E23AED-3068-4CFE-84B0-3B7725665506}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5E23AED-3068-4CFE-84B0-3B7725665506}.Release|Any CPU.Build.0 = Release|Any CPU
{E5257008-A0AD-473F-91B0-864FC601B84B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5257008-A0AD-473F-91B0-864FC601B84B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5257008-A0AD-473F-91B0-864FC601B84B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5257008-A0AD-473F-91B0-864FC601B84B}.Release|Any CPU.Build.0 = Release|Any CPU
{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -162,11 +194,16 @@ Global
{3E9CCC0A-DAD5-4F32-8EAE-654D67DEE2B9} = {D58F1DF5-2DFE-40A2-B136-7606D4CDE903}
{8168B7B4-9F6B-4658-A28C-D0F9D10AB93D} = {E7A821D8-85B5-4098-897D-5A814BD8131D}
{78164C5C-63B9-4FB6-ACC9-6496E236C946} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
{D7B2B2BE-C32C-47AE-A46C-62B7EF8C318E} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
{93971F1F-F6AC-4F83-8119-21260FCE2828} = {C00828FB-E7D5-4086-BA50-02022594AB73}
{3B87330F-A303-4413-B653-1C9536C74109} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
{D58F1DF5-2DFE-40A2-B136-7606D4CDE903} = {0C7AA298-2957-4D71-A8F1-1C3C7932A1B3}
{3A4601FE-B091-43A3-AEE6-6440BB37B277} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
{454059F7-D087-439A-A724-80BDFE94776F} = {C00828FB-E7D5-4086-BA50-02022594AB73}
{64E2622A-611D-4056-9497-0B52A91DC59C} = {78164C5C-63B9-4FB6-ACC9-6496E236C946}
{5714481A-BDF5-4860-9158-3B18D3018EC5} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
{B5E23AED-3068-4CFE-84B0-3B7725665506} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
{E5257008-A0AD-473F-91B0-864FC601B84B} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
{DB425943-CEE6-4FF6-A0EE-233B6ADA3BD7} = {42800C56-9473-4B96-BF29-1B0F25C867F4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6238659A-7267-49B9-A499-8746BDEED6B8}

29
aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<Description>阿里云SDK基础框架</Description>
</PropertyGroup>
<ItemGroup>
<None Remove="LINYUN\Abp\Aliyun\Localization\Resources\en.json" />
<None Remove="LINYUN\Abp\Aliyun\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINYUN\Abp\Aliyun\Localization\Resources\en.json" />
<EmbeddedResource Include="LINYUN\Abp\Aliyun\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="aliyun-net-sdk-core" Version="1.5.8" />
<PackageReference Include="Volo.Abp.Localization" Version="3.3.0" />
<PackageReference Include="Volo.Abp.Json" Version="3.3.0" />
<PackageReference Include="Volo.Abp.Settings" Version="3.3.0" />
</ItemGroup>
</Project>

29
aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/AbpAliyunCloudModule.cs

@ -0,0 +1,29 @@
using LINYUN.Abp.Aliyun.Localization;
using Volo.Abp.Json;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Aliyun
{
[DependsOn(
typeof(AbpJsonModule),
typeof(AbpLocalizationModule))]
public class AbpAliyunCloudModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAliyunCloudModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AliyunResource>()
.AddVirtualJson("/LINGYUN/Abp/Aliyun/Localization/Resources");
});
}
}
}

9
aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Localization/AliyunResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINYUN.Abp.Aliyun.Localization
{
[LocalizationResourceName("Aliyun")]
public class AliyunResource
{
}
}

5
aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Localization/Resources/en.json

@ -0,0 +1,5 @@
{
"culture": "en",
"texts": {
}
}

5
aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Localization/Resources/zh-Hans.json

@ -0,0 +1,5 @@
{
"culture": "zh-Hans",
"texts": {
}
}

19
aspnet-core/modules/cloud-aliyun/LINGYUN.Abp.Aliyun/LINYUN/Abp/Aliyun/Settings/AliyunSettingNames.cs

@ -0,0 +1,19 @@
namespace LINYUN.Abp.Aliyun.Settings
{
public static class AliyunSettingNames
{
public const string Prefix = "Abp.Aliyun";
/// <summary>
/// 认证方式
/// </summary>
public class Authorization
{
public const string Prefix = AliyunSettingNames.Prefix + ".Authorization";
public const string AccessKeyId = Prefix + ".AccessKeyId";
public const string AccessKeySecret = Prefix + ".AccessKeySecret";
}
}
}

27
aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINGYUN.Abp.Tencent.csproj

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<Description>腾讯云SDK基础框架</Description>
</PropertyGroup>
<ItemGroup>
<None Remove="LINYUN\Abp\Tencent\Localization\Resources\en.json" />
<None Remove="LINYUN\Abp\Tencent\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINYUN\Abp\Tencent\Localization\Resources\en.json" />
<EmbeddedResource Include="LINYUN\Abp\Tencent\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Localization" Version="3.3.0" />
<PackageReference Include="Volo.Abp.Json" Version="3.3.0" />
<PackageReference Include="Volo.Abp.Settings" Version="3.3.0" />
</ItemGroup>
</Project>

29
aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/AbpTencentCloudModule.cs

@ -0,0 +1,29 @@
using LINYUN.Abp.Tencent.Localization;
using Volo.Abp.Json;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Tencent
{
[DependsOn(
typeof(AbpJsonModule),
typeof(AbpLocalizationModule))]
public class AbpTencentCloudModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpTencentCloudModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TencentResource>()
.AddVirtualJson("/LINGYUN/Abp/Tencent/Localization/Resources");
});
}
}
}

5
aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/Localization/Resources/en.json

@ -0,0 +1,5 @@
{
"culture": "en",
"texts": {
}
}

5
aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/Localization/Resources/zh-Hans.json

@ -0,0 +1,5 @@
{
"culture": "zh-Hans",
"texts": {
}
}

9
aspnet-core/modules/cloud-tencent/LINGYUN.Abp.Tencent/LINYUN/Abp/Tencent/Localization/TencentResource.cs

@ -0,0 +1,9 @@
using Volo.Abp.Localization;
namespace LINYUN.Abp.Tencent.Localization
{
[LocalizationResourceName("Tencent")]
public class TencentResource
{
}
}

19
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/AbpIMSignalROptions.cs

@ -0,0 +1,19 @@
namespace LINGYUN.Abp.IM.SignalR
{
public class AbpIMSignalROptions
{
/// <summary>
/// 自定义的客户端接收消息方法名称
/// </summary>
public string GetChatMessageMethod { get; set; }
/// <summary>
/// 用户上线接收方法名称
/// </summary>
public string UserOnlineMethod { get; set; }
public AbpIMSignalROptions()
{
GetChatMessageMethod = "getChatMessage";
UserOnlineMethod = "onUserOnlined";
}
}
}

16
aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Hubs/MessagesHub.cs

@ -6,18 +6,18 @@ using LINGYUN.Abp.RealTime.SignalR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Users;
namespace LINGYUN.Abp.IM.SignalR.Hubs
{
[Authorize]
public class MessagesHub : OnlineClientHubBase
{
protected AbpIMSignalROptions Options { get; }
protected IFriendStore FriendStore { get; }
protected IMessageStore MessageStore { get; }
protected IUserGroupStore UserGroupStore { get; }
@ -25,11 +25,13 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
public MessagesHub(
IFriendStore friendStore,
IMessageStore messageStore,
IUserGroupStore userGroupStore)
IUserGroupStore userGroupStore,
IOptions<AbpIMSignalROptions> options)
{
FriendStore = friendStore;
MessageStore = messageStore;
UserGroupStore = userGroupStore;
Options = options.Value;
}
protected override async Task OnClientConnectedAsync(IOnlineClient client)
@ -44,7 +46,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
if (groupClient != null)
{
// 发送用户上线通知
await groupClient.SendAsync("onUserOnlined", client.TenantId, client.UserId.Value);
await groupClient.SendAsync(Options.UserOnlineMethod, client.TenantId, client.UserId.Value);
}
}
@ -56,7 +58,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
var userClients = Clients.Users(friendClientIds);
if (userClients != null)
{
await userClients.SendAsync("onUserOnlined", client.TenantId, client.UserId.Value);
await userClients.SendAsync(Options.UserOnlineMethod, client.TenantId, client.UserId.Value);
}
}
}
@ -90,7 +92,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
return;
}
await signalRClient.SendAsync("getChatMessage", chatMessage, cancellationToken: Context.ConnectionAborted);
await signalRClient.SendAsync(Options.GetChatMessageMethod, chatMessage, cancellationToken: Context.ConnectionAborted);
}
protected virtual async Task SendMessageToUserAsync(ChatMessage chatMessage)
@ -108,7 +110,7 @@ namespace LINGYUN.Abp.IM.SignalR.Hubs
Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " with connectionId " + onlineClient.ConnectionId + " from SignalR hub!");
continue;
}
await signalRClient.SendAsync("getChatMessage", chatMessage, cancellationToken: Context.ConnectionAborted);
await signalRClient.SendAsync(Options.GetChatMessageMethod, chatMessage, cancellationToken: Context.ConnectionAborted);
}
catch (Exception ex)
{

3
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalRModule.cs

@ -17,6 +17,9 @@ namespace LINGYUN.Abp.Notifications.SignalR
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<SignalRNotificationPublishProvider>();
options.NotificationDataMappings
.MappingDefault(SignalRNotificationPublishProvider.ProviderName,
data => data);
});
Configure<AbpAspNetCoreSignalRJwtTokenMapPathOptions>(options =>

15
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/AbpNotificationsSignalROptions.cs

@ -0,0 +1,15 @@
namespace LINGYUN.Abp.Notifications.SignalR
{
public class AbpNotificationsSignalROptions
{
/// <summary>
/// 自定义的客户端订阅通知方法名称
/// </summary>
public string MethodName { get; set; }
public AbpNotificationsSignalROptions()
{
MethodName = "getNotification";
}
}
}

6
aspnet-core/modules/common/LINGYUN.Abp.Notifications.SignalR/LINGYUN/Abp/Notifications/SignalR/SignalRNotificationPublishProvider.cs

@ -2,6 +2,7 @@
using LINGYUN.Abp.RealTime.Client;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@ -20,12 +21,15 @@ namespace LINGYUN.Abp.Notifications.SignalR
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly AbpNotificationsSignalROptions _options;
public SignalRNotificationPublishProvider(
IOnlineClientManager onlineClientManager,
IHubContext<NotificationsHub> hubContext,
IOptions<AbpNotificationsSignalROptions> options,
IServiceProvider serviceProvider)
: base(serviceProvider)
{
_options = options.Value;
_hubContext = hubContext;
_onlineClientManager = onlineClientManager;
}
@ -44,7 +48,7 @@ namespace LINGYUN.Abp.Notifications.SignalR
}
// 租户通知群发
Logger.LogDebug($"Found a singalr group, begin senging notifications");
await singalRGroup.SendAsync("getNotification", notification, cancellationToken);
await singalRGroup.SendAsync(_options.MethodName, notification, cancellationToken);
}
else
{

19
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/AbpNotificationsSmsModule.cs

@ -1,19 +0,0 @@
using Volo.Abp.Modularity;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.Notifications.Sms
{
[DependsOn(
typeof(AbpNotificationModule),
typeof(AbpSmsModule))]
public class AbpNotificationsSmsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<SmsNotificationPublishProvider>();
});
}
}
}

31
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsModule.cs

@ -0,0 +1,31 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.Notifications.Sms
{
[DependsOn(
typeof(AbpNotificationModule),
typeof(AbpSmsModule))]
public class AbpNotificationsSmsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNotificationsSmsOptions>(options =>
{
context.Services.ExecutePreConfiguredActions(options);
});
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<SmsNotificationPublishProvider>();
var smsOptions = context.Services.ExecutePreConfiguredActions<AbpNotificationsSmsOptions>();
options.NotificationDataMappings
.MappingDefault(
SmsNotificationPublishProvider.ProviderName,
data => NotificationData.ToStandardData(smsOptions.TemplateParamsPrefix, data));
});
}
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/NotificationSmsOptions.cs → aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsOptions.cs

@ -1,6 +1,6 @@
namespace LINGYUN.Abp.Notifications.Sms
{
public class NotificationSmsOptions
public class AbpNotificationsSmsOptions
{
/// <summary>
/// 短信模板变量前缀

21
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/ISmsNotificationSender.cs

@ -0,0 +1,21 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications.Sms
{
/// <summary>
/// 短信通知发送接口
/// </summary>
/// <remarks>
/// 重写实现自定义的短信消息处理
/// </remarks>
public interface ISmsNotificationSender
{
/// <summary>
/// 发送通知
/// </summary>
/// <param name="notification">通知数据</param>
/// <param name="phoneNumbers">手机号列表,多个手机号通过,分隔</param>
/// <returns></returns>
Task SendAsync(NotificationInfo notification, string phoneNumbers);
}
}

42
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationPublishProvider.cs

@ -1,33 +1,34 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.Notifications.Sms
{
public class SmsNotificationPublishProvider : NotificationPublishProvider
{
public const string ProviderName = "Sms";
private IUserPhoneFinder _userPhoneFinder;
protected IUserPhoneFinder UserPhoneFinder => LazyGetRequiredService(ref _userPhoneFinder);
private ISmsSender _smsSender;
protected ISmsSender SmsSender => LazyGetRequiredService(ref _smsSender);
protected ISmsNotificationSender Sender { get; }
protected NotificationSmsOptions Options { get; }
protected AbpNotificationsSmsOptions Options { get; }
public SmsNotificationPublishProvider(
IServiceProvider serviceProvider,
IOptions<NotificationSmsOptions> options)
ISmsNotificationSender sender,
IOptions<AbpNotificationsSmsOptions> options)
: base(serviceProvider)
{
Sender = sender;
Options = options.Value;
}
public override string Name => "Sms";
public override string Name => ProviderName;
protected override async Task PublishAsync(
NotificationInfo notification,
@ -39,35 +40,12 @@ namespace LINGYUN.Abp.Notifications.Sms
return;
}
var templateCode = notification.Data.TryGetData("TemplateCode");
if (templateCode == null)
{
Logger.LogWarning("sms template code is empty, can not send sms message!");
return;
}
var sendToPhones = await UserPhoneFinder.FindByUserIdsAsync(identifiers.Select(usr => usr.UserId), cancellationToken);
if (!sendToPhones.Any())
{
return;
}
var message = new SmsMessage(sendToPhones.JoinAsString(","), "SmsNotification");
// TODO: 后期增强功能,增加短信模板、通知模板功能
message.Properties.Add("TemplateCode", templateCode);
message.Properties.Add("SignName", notification.Data.TryGetData("SignName"));
foreach (var property in notification.Data.Properties)
{
// TODO: 可以扩展下存储短信模板,根据模板变量自动匹配
// 必须加上需要发送短信的前缀让用户自己选择是否发送短信,因为资费太贵了...
if (property.Key.StartsWith(Options.TemplateParamsPrefix))
{
message.Properties.Add(property.Key.Replace(Options.TemplateParamsPrefix, ""), property.Value);
}
}
await SmsSender.SendAsync(message);
await Sender.SendAsync(notification, sendToPhones.JoinAsString(","));
}
}
}

47
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/LINGYUN/Abp/Notifications/Sms/SmsNotificationSender.cs

@ -0,0 +1,47 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.Notifications.Sms
{
/// <summary>
/// 短信通知的默认实现者
/// </summary>
public class SmsNotificationSender : ISmsNotificationSender, ITransientDependency
{
public ILogger Logger { protected get; set; }
protected ISmsSender SmsSender { get; }
public SmsNotificationSender(ISmsSender smsSender)
{
SmsSender = smsSender;
Logger = NullLogger<SmsNotificationSender>.Instance;
}
/// <summary>
/// 发送通知
/// </summary>
/// <param name="notification"></param>
/// <param name="phoneNumbers"></param>
/// <returns></returns>
public virtual async Task SendAsync(NotificationInfo notification, string phoneNumbers)
{
var templateCode = notification.Data.TryGetData("TemplateCode");
if (templateCode == null)
{
Logger.LogWarning("sms template code is empty, can not send sms message!");
return;
}
var message = new SmsMessage(phoneNumbers, "SmsNotification");
// TODO: 后期增强功能,增加短信模板、通知模板功能
message.Properties.Add("TemplateCode", templateCode);
message.Properties.Add("SignName", notification.Data.TryGetData("SignName"));
await SmsSender.SendAsync(message);
}
}
}

37
aspnet-core/modules/common/LINGYUN.Abp.Notifications.Sms/README.md

@ -0,0 +1,37 @@
# LINGYUN.Abp.Notifications.Sms
通知发布提供程序的短信实现
大部分重写的模块都和官方模块名称保持一致,通过命名空间区分,主要是只改写了一小部分或者增加额外的功能
如果大部分模块代码都重写,或者完全就是扩展模块,才会定义自己的名字
#### 注意
自定义的发送方法可以通过实现 ##ISmsNotificationSender## 接口或重写 ##SmsNotificationSender## 即可
内置了通知数据 NotificationDataMappings 方法
可通过 NotificationDataMappings.MappingAll(SmsNotificationPublishProvider.ProviderName, Func<NotificationData, NotificationData> func) 来自定义规则
## 配置使用
* 此配置项将在下一个短信相关大版本移除
```json
{
"Notifications": {
"Sms": {
"TemplateParamsPrefix": "短信模板变量前缀"
}
}
}
```
```csharp
[DependsOn(typeof(AbpNotificationsSmsModule))]
public class YouProjectModule : AbpModule
{
// other
}

1
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationModule.cs

@ -11,6 +11,7 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications
{
// TODO: 需要重命名 AbpNotificationsModule
[DependsOn(
typeof(AbpBackgroundJobsModule),
typeof(AbpJsonModule))]

17
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/AbpNotificationOptions.cs

@ -2,15 +2,28 @@
namespace LINGYUN.Abp.Notifications
{
// TODO: 需要重命名 AbpNotificationsOptions
public class AbpNotificationOptions
{
/// <summary>
/// 通知系统对于某个应用的定义
/// </summary>
public string Application { get; set; }
/// <summary>
/// 自定义通知集合
/// </summary>
public ITypeList<INotificationDefinitionProvider> DefinitionProviders { get; }
/// <summary>
/// 发布者集合
/// </summary>
public ITypeList<INotificationPublishProvider> PublishProviders { get; }
/// <summary>
/// 可以自定义某个通知的格式
/// </summary>
public NotificationDataMappingDictionary NotificationDataMappings { get; }
public AbpNotificationOptions()
{
Application = "Abp";
PublishProviders = new TypeList<INotificationPublishProvider>();
DefinitionProviders = new TypeList<INotificationDefinitionProvider>();
NotificationDataMappings = new NotificationDataMappingDictionary();

13
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/INotificationPublishProvider.cs

@ -3,10 +3,21 @@ using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// 通知发布提供者接口
/// </summary>
public interface INotificationPublishProvider
{
/// <summary>
/// 名称
/// </summary>
string Name { get; }
/// <summary>
/// 发布通知
/// </summary>
/// <param name="notification">通知信息</param>
/// <param name="identifiers">接收用户列表</param>
/// <returns></returns>
Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers);
}
}

11
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/Internal/NotificationSender.cs

@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,6 +10,10 @@ using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// 默认实现通过分布式事件发送通知
/// 可替换实现来发送实时通知
/// </summary>
public class NotificationSender : INotificationSender, ITransientDependency
{
/// <summary>
@ -20,9 +25,12 @@ namespace LINGYUN.Abp.Notifications
/// </summary>
public IDistributedEventBus DistributedEventBus { get; }
protected AbpNotificationOptions Options { get; }
public NotificationSender(
IDistributedEventBus distributedEventBus)
IDistributedEventBus distributedEventBus,
IOptions<AbpNotificationOptions> options)
{
Options = options.Value;
DistributedEventBus = distributedEventBus;
Logger = NullLogger<NotificationSender>.Instance;
}
@ -66,6 +74,7 @@ namespace LINGYUN.Abp.Notifications
.PublishAsync(
new NotificationEventData
{
Application = Options.Application,
TenantId = tenantId,
Users = users?.ToList(),
Name = name,

4
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationData.cs

@ -12,7 +12,11 @@ namespace LINGYUN.Abp.Notifications
/// </remarks>
public class NotificationData
{
/// <summary>
/// 用来标识是否需要本地化的信息
/// </summary>
public const string LocalizerKey = "localizer";
public virtual string Type => GetType().FullName;
public object this[string key]

15
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataConverter.cs

@ -10,10 +10,17 @@ namespace LINGYUN.Abp.Notifications
{
if (notificationData.NeedLocalizer())
{
var title = JsonConvert.DeserializeObject<LocalizableStringInfo>(notificationData.TryGetData("title").ToString());
var message = JsonConvert.DeserializeObject<LocalizableStringInfo>(notificationData.TryGetData("message").ToString());
notificationData.TrySetData("title", title);
notificationData.TrySetData("message", message);
// 潜在的空对象引用修复
if (notificationData.Properties.TryGetValue("title", out object title) && title != null)
{
var titleObj = JsonConvert.DeserializeObject<LocalizableStringInfo>(title.ToString());
notificationData.TrySetData("title", titleObj);
}
if (notificationData.Properties.TryGetValue("message", out object message) && message != null)
{
var messageObj = JsonConvert.DeserializeObject<LocalizableStringInfo>(message.ToString());
notificationData.TrySetData("message", messageObj);
}
if (notificationData.Properties.TryGetValue("description", out object description) && description != null)
{

49
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionary.cs

@ -6,28 +6,53 @@ namespace LINGYUN.Abp.Notifications
{
public class NotificationDataMappingDictionary : Dictionary<string, List<NotificationDataMappingDictionaryItem>>
{
public void Mapping(string name, string provider, Func<NotificationData, NotificationData> func)
public static string DefaultKey { get; set; } = "Default";
/// <summary>
/// 处理某个通知的数据
/// 特定于一个提供程序
/// </summary>
/// <param name="provider"></param>
/// <param name="name"></param>
/// <param name="func"></param>
public void Mapping(string provider, string name, Func<NotificationData, NotificationData> func)
{
if (ContainsKey(name))
if (!ContainsKey(provider))
{
this[name] = new List<NotificationDataMappingDictionaryItem>();
}
this[name].Add(new NotificationDataMappingDictionaryItem(provider, func));
this[provider] = new List<NotificationDataMappingDictionaryItem>();
}
public void MappingAll(string provider, Func<NotificationData, NotificationData> func)
var mapItem = this[provider].FirstOrDefault(item => item.Name.Equals(name));
if (mapItem == null)
{
foreach(var mapping in this)
this[provider].Add(new NotificationDataMappingDictionaryItem(name, func));
}
else
{
Mapping(mapping.Key, provider, func);
mapItem.Replace(func);
}
}
public NotificationDataMappingDictionaryItem GetMapItemOrNull(string name, string provider)
/// <summary>
/// 处理所有通知的数据
/// 特定于一个提供程序
/// </summary>
/// <param name="provider"></param>
/// <param name="func"></param>
public void MappingDefault(string provider, Func<NotificationData, NotificationData> func)
{
Mapping(provider, DefaultKey, func);
}
/// <summary>
/// 获取需要处理数据的方法
/// </summary>
/// <param name="name"></param>
/// <param name="provider"></param>
/// <returns></returns>
public NotificationDataMappingDictionaryItem GetMapItemOrDefault(string provider, string name)
{
if (ContainsKey(name))
if (ContainsKey(provider))
{
return this[name].FirstOrDefault(map => map.Provider.Equals(provider));
return this[provider].GetOrNullDefault(name);
}
return null;
}

19
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionaryItem.cs

@ -4,12 +4,23 @@ namespace LINGYUN.Abp.Notifications
{
public class NotificationDataMappingDictionaryItem
{
public string Provider { get; }
/// <summary>
/// 通知名称
/// </summary>
public string Name { get; }
/// <summary>
/// 转换方法
/// </summary>
public Func<NotificationData, NotificationData> MappingFunc { get; private set; }
public Func<NotificationData, NotificationData> MappingFunc { get; }
public NotificationDataMappingDictionaryItem(string prodiver, Func<NotificationData, NotificationData> func)
public NotificationDataMappingDictionaryItem(string name, Func<NotificationData, NotificationData> func)
{
Name = name;
MappingFunc = func;
}
public void Replace(Func<NotificationData, NotificationData> func)
{
Provider = prodiver;
MappingFunc = func;
}
}

20
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDataMappingDictionaryItemExtensions.cs

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Linq;
namespace LINGYUN.Abp.Notifications
{
public static class NotificationDataMappingDictionaryItemExtensions
{
public static NotificationDataMappingDictionaryItem GetOrNullDefault(
this IEnumerable<NotificationDataMappingDictionaryItem> items,
string name)
{
var item = items.FirstOrDefault(i => i.Name.Equals(name));
if (item == null)
{
return items.FirstOrDefault(i => i.Name.Equals(NotificationDataMappingDictionary.DefaultKey));
}
return item;
}
}
}

1
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationDefinition.cs

@ -3,7 +3,6 @@ using System;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
/*
* 2020-10-29

32
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationEventData.cs

@ -6,14 +6,46 @@ namespace LINGYUN.Abp.Notifications
{
public class NotificationEventData : IMultiTenant
{
/// <summary>
/// 租户
/// </summary>
public Guid? TenantId { get; set; }
/// <summary>
/// 通知名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 用来标识一个应用程序
/// </summary>
/// <remarks>
/// tips: 可以通过它来特定于应用程序的边界
/// </remarks>
public string Application { get; set; }
/// <summary>
/// 数据
/// </summary>
public NotificationData Data { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreationTime { get; set; }
/// <summary>
/// 紧急级别
/// </summary>
public NotificationSeverity Severity { get; set; }
/// <summary>
/// 指定的接收用户信息集合
/// </summary>
/// <remarks>
/// 注:<br/>
/// 如果指定了用户列表,应该在事件订阅程序中通过此集合过滤订阅用户<br/>
/// 如果未指定用户列表,应该在事件订阅程序中过滤所有订阅此通知的用户
/// </remarks>
public List<UserIdentifier> Users { get; set; }
public NotificationEventData()
{
Application = "Abp";
Users = new List<UserIdentifier>();
}
}

2
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishJob.cs

@ -33,7 +33,7 @@ namespace LINGYUN.Abp.Notifications
notification.Data = NotificationDataConverter.Convert(notification.Data);
var notifacationDataMapping = Options.NotificationDataMappings
.GetMapItemOrNull(notification.Name, publishProvider.Name);
.GetMapItemOrDefault(notification.Name, publishProvider.Name);
if (notifacationDataMapping != null)
{
notification.Data = notifacationDataMapping.MappingFunc(notification.Data);

8
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/NotificationPublishProvider.cs

@ -53,7 +53,13 @@ namespace LINGYUN.Abp.Notifications
{
await PublishAsync(notification, identifiers, CancellationTokenProvider.Token);
}
/// <summary>
/// 重写实现通知发布
/// </summary>
/// <param name="notification"></param>
/// <param name="identifiers"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected abstract Task PublishAsync(NotificationInfo notification, IEnumerable<UserIdentifier> identifiers, CancellationToken cancellationToken = default);
}
}

9
aspnet-core/modules/common/LINGYUN.Abp.Notifications/LINGYUN/Abp/Notifications/UserIdentifier.cs

@ -2,9 +2,18 @@
namespace LINGYUN.Abp.Notifications
{
/// <summary>
/// 用户信息
/// </summary>
public class UserIdentifier
{
/// <summary>
/// 用户标识
/// </summary>
public Guid UserId { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string UserName { get; set; }
public UserIdentifier(Guid userId, string userName)

6
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN.Abp.Notifications.WeChat.WeApp.csproj → aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj

@ -1,11 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
<Description>通知接口的微信小程序发布者实现</Description>
</PropertyGroup>
<ItemGroup>

30
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramModule.cs

@ -0,0 +1,30 @@
using LINGYUN.Abp.WeChat.MiniProgram;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
[DependsOn(
typeof(AbpWeChatMiniProgramModule),
typeof(AbpNotificationModule))]
public class AbpNotificationsWeChatMiniProgramModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNotificationsWeChatMiniProgramOptions>(options =>
{
context.Services.ExecutePreConfiguredActions(options);
});
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<WeChatMiniProgramNotificationPublishProvider>();
var wechatOptions = context.Services.ExecutePreConfiguredActions<AbpNotificationsWeChatMiniProgramOptions>();
options.NotificationDataMappings
.MappingDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName,
data => NotificationData.ToStandardData(wechatOptions.DefaultMsgPrefix, data));
});
}
}
}

25
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramOptions.cs

@ -0,0 +1,25 @@
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
/// <summary>
/// TODO: 后期改进,配置项集成到 <see cref="LINGYUN.Abp.WeChat.MiniProgram.AbpWeChatMiniProgramOptions"/>
/// </summary>
public class AbpNotificationsWeChatMiniProgramOptions
{
/// <summary>
/// 默认消息头部标记
/// </summary>
public string DefaultMsgPrefix { get; set; } = "[wmp]";
/// <summary>
/// 默认小程序模板
/// </summary>
public string DefaultTemplateId { get; set; }
/// <summary>
/// 默认跳转小程序类型
/// </summary>
public string DefaultState { get; set; } = "developer";
/// <summary>
/// 默认小程序语言
/// </summary>
public string DefaultLanguage { get; set; } = "zh_CN";
}
}

20
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/Features/WeChatWeAppFeatureDefinitionProvider.cs → aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/Features/WeChatMiniProgramFeatureDefinitionProvider.cs

@ -4,9 +4,9 @@ using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp.Features
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram.Features
{
public class WeChatWeAppFeatureDefinitionProvider : FeatureDefinitionProvider
public class WeChatMiniProgramFeatureDefinitionProvider : FeatureDefinitionProvider
{
public override void Define(IFeatureDefinitionContext context)
{
@ -15,31 +15,31 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp.Features
{
var weappFeature = wechatGroup
.AddFeature(
WeChatWeAppFeatures.GroupName,
WeChatMiniProgramFeatures.GroupName,
true.ToString(),
L("Features:WeApp"),
L("Features:WeAppDescription"),
L("Features:MiniProgram"),
L("Features:MiniProgramDescription"),
new ToggleStringValueType(new BooleanValueValidator()));
var weappNofitication = weappFeature
.CreateChild(
WeChatWeAppFeatures.Notifications.Default,
WeChatMiniProgramFeatures.Notifications.Default,
true.ToString(),
L("Features:Notifications"),
L("Features:Notifications"),
new ToggleStringValueType(new BooleanValueValidator()));
weappNofitication
.CreateChild(
WeChatWeAppFeatures.Notifications.PublishLimit,
WeChatWeAppFeatures.Notifications.DefaultPublishLimit.ToString(),
WeChatMiniProgramFeatures.Notifications.PublishLimit,
WeChatMiniProgramFeatures.Notifications.DefaultPublishLimit.ToString(),
L("Features:PublishLimit"),
L("Features:PublishLimitDescription"),
new ToggleStringValueType(new NumericValueValidator(0, 100000)));
weappNofitication
.CreateChild(
WeChatWeAppFeatures.Notifications.PublishLimitInterval,
WeChatWeAppFeatures.Notifications.DefaultPublishLimitInterval.ToString(),
WeChatMiniProgramFeatures.Notifications.PublishLimitInterval,
WeChatMiniProgramFeatures.Notifications.DefaultPublishLimitInterval.ToString(),
L("Features:PublishLimitInterval"),
L("Features:PublishLimitIntervalDescription"),
new ToggleStringValueType(new NumericValueValidator(1, 12)));

6
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/Features/WeChatWeAppFeatures.cs → aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/Features/WeChatMiniProgramFeatures.cs

@ -1,10 +1,10 @@
using LINGYUN.Abp.WeChat.Features;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp.Features
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram.Features
{
public static class WeChatWeAppFeatures
public static class WeChatMiniProgramFeatures
{
public const string GroupName = WeChatFeatures.GroupName + ".WeApp";
public const string GroupName = WeChatFeatures.GroupName + ".MiniProgram";
public static class Notifications
{

27
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationPublishProvider.cs → aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/LINGYUN/Abp/Notifications/WeChat/MiniProgram/WeChatMiniProgramNotificationPublishProvider.cs

@ -1,4 +1,4 @@
using LINGYUN.Abp.Notifications.WeChat.WeApp.Features;
using LINGYUN.Abp.Notifications.WeChat.MiniProgram.Features;
using LINGYUN.Abp.WeChat.MiniProgram.Messages;
using LINGYUN.Abp.WeChat.Security.Claims;
using Microsoft.Extensions.Logging;
@ -9,23 +9,24 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Features;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
/// <summary>
/// 微信小程序消息推送提供者
/// </summary>
public class WeChatWeAppNotificationPublishProvider : NotificationPublishProvider
public class WeChatMiniProgramNotificationPublishProvider : NotificationPublishProvider
{
public override string Name => "WeChat.WeApp";
public const string ProviderName = "WeChat.MiniProgram";
public override string Name => ProviderName;
private IFeatureChecker _featureChecker;
protected IFeatureChecker FeatureChecker => LazyGetRequiredService(ref _featureChecker);
protected ISubscribeMessager SubscribeMessager { get; }
protected AbpWeChatWeAppNotificationOptions Options { get; }
public WeChatWeAppNotificationPublishProvider(
protected AbpNotificationsWeChatMiniProgramOptions Options { get; }
public WeChatMiniProgramNotificationPublishProvider(
IServiceProvider serviceProvider,
ISubscribeMessager subscribeMessager,
IOptions<AbpWeChatWeAppNotificationOptions> options)
IOptions<AbpNotificationsWeChatMiniProgramOptions> options)
: base(serviceProvider)
{
Options = options.Value;
@ -36,7 +37,7 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
// 先检测微信小程序的功能限制
var publishEnabled = await FeatureChecker.GetAsync(WeChatWeAppFeatures.Notifications.Default, false);
var publishEnabled = await FeatureChecker.GetAsync(WeChatMiniProgramFeatures.Notifications.Default, false);
if (!publishEnabled)
{
@ -70,14 +71,12 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
var redirect = GetOrDefault(notification.Data, "RedirectPage", null);
Logger.LogDebug($"Get wechat weapp redirect page: {redirect ?? "null"}");
var weAppState = GetOrDefault(notification.Data, "WeAppState", Options.DefaultWeAppState);
var weAppState = GetOrDefault(notification.Data, "WeAppState", Options.DefaultState);
Logger.LogDebug($"Get wechat weapp state: {weAppState ?? null}");
var weAppLang = GetOrDefault(notification.Data, "WeAppLanguage", Options.DefaultWeAppLanguage);
var weAppLang = GetOrDefault(notification.Data, "WeAppLanguage", Options.DefaultLanguage);
Logger.LogDebug($"Get wechat weapp language: {weAppLang ?? null}");
var notificationData = NotificationData.ToStandardData(Options.DefaultMsgPrefix, notification.Data);
// TODO: 如果微信端发布通知,请组装好 openid 字段在通知数据内容里面
string openId = GetOrDefault(notification.Data, AbpWeChatClaimTypes.OpenId, "");
@ -87,13 +86,13 @@ namespace LINGYUN.Abp.Notifications.WeChat.WeApp
await SubscribeMessager
.SendAsync(
identifier.UserId, templateId, redirect, weAppLang,
weAppState, notificationData.Properties, cancellationToken);
weAppState, notification.Data.Properties, cancellationToken);
}
else
{
var weChatWeAppNotificationData = new SubscribeMessage(templateId, redirect, weAppState, weAppLang);
// 写入模板数据
weChatWeAppNotificationData.WriteData(notificationData.Properties);
weChatWeAppNotificationData.WriteData(notification.Data.Properties);
Logger.LogDebug($"Sending wechat weapp notification: {notification.Name}");

40
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat.MiniProgram/README.md

@ -0,0 +1,40 @@
# LINGYUN.Abp.Notifications.WeChat.MiniProgram
通知发布提供程序的微信小程序实现
大部分重写的模块都和官方模块名称保持一致,通过命名空间区分,主要是只改写了一小部分或者增加额外的功能
如果大部分模块代码都重写,或者完全就是扩展模块,才会定义自己的名字
#### 注意
内置了通知数据 NotificationDataMappings 方法
可通过 NotificationDataMappings.MappingAll(WeChatMiniProgramNotificationPublishProvider.ProviderName, Func<NotificationData, NotificationData> func) 来自定义规则
## 配置使用
* 此配置项将在下一个微信相关大版本移除,合并到 LINGYUN.Abp.WeChat.MiniProgram.AbpWeChatMiniProgramOptions
```json
{
"Notifications": {
"WeChat": {
"MiniProgram": {
"DefaultMsgPrefix": "默认消息头部标记",
"DefaultTemplateId": "默认小程序模板",
"DefaultState": "默认跳转小程序类型",
"DefaultLanguage": "默认小程序语言"
}
}
}
}
```
```csharp
[DependsOn(typeof(AbpNotificationsWeChatMiniProgramModule))]
public class YouProjectModule : AbpModule
{
// other
}

23
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpNotificationsWeChatWeAppModule.cs

@ -1,23 +0,0 @@
using LINGYUN.Abp.WeChat.MiniProgram;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
[DependsOn(
typeof(AbpWeChatMiniProgramModule),
typeof(AbpNotificationModule))]
public class AbpNotificationsWeChatWeAppModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpWeChatWeAppNotificationOptions>(configuration.GetSection("Notifications:WeChat:WeApp"));
Configure<AbpNotificationOptions>(options =>
{
options.PublishProviders.Add<WeChatWeAppNotificationPublishProvider>();
});
}
}
}

22
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/AbpWeChatWeAppNotificationOptions.cs

@ -1,22 +0,0 @@
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
public class AbpWeChatWeAppNotificationOptions
{
/// <summary>
/// 默认消息头部标记
/// </summary>
public string DefaultMsgPrefix { get; set; } = "[wx]";
/// <summary>
/// 默认小程序模板
/// </summary>
public string DefaultTemplateId { get; set; }
/// <summary>
/// 默认跳转小程序类型
/// </summary>
public string DefaultWeAppState { get; set; } = "developer";
/// <summary>
/// 默认小程序语言
/// </summary>
public string DefaultWeAppLanguage { get; set; } = "zh_CN";
}
}

10
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/IWeChatWeAppNotificationSender.cs

@ -1,10 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
public interface IWeChatWeAppNotificationSender
{
Task SendAsync(WeChatWeAppSendNotificationData notificationData, CancellationToken cancellationToken = default);
}
}

123
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppNotificationSender.cs

@ -1,123 +0,0 @@
using LINGYUN.Abp.Features.LimitValidation;
using LINGYUN.Abp.Notifications.WeChat.WeApp.Features;
using LINGYUN.Abp.WeChat.MiniProgram;
using LINGYUN.Abp.WeChat.Token;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
public class WeChatWeAppNotificationSender : IWeChatWeAppNotificationSender, ITransientDependency
{
public const string SendNotificationClientName = "WeChatWeAppSendNotificationClient";
public ILogger<WeChatWeAppNotificationSender> Logger { get; set; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IJsonSerializer JsonSerializer { get; }
protected AbpWeChatMiniProgramOptions MiniProgramOptions { get; }
protected IWeChatTokenProvider WeChatTokenProvider { get; }
public WeChatWeAppNotificationSender(
IJsonSerializer jsonSerializer,
IHttpClientFactory httpClientFactory,
IWeChatTokenProvider weChatTokenProvider,
IOptions<AbpWeChatMiniProgramOptions> miniProgramOptions)
{
JsonSerializer = jsonSerializer;
HttpClientFactory = httpClientFactory;
WeChatTokenProvider = weChatTokenProvider;
MiniProgramOptions = miniProgramOptions.Value;
Logger = NullLogger<WeChatWeAppNotificationSender>.Instance;
}
[RequiresLimitFeature( // 检查消息发布功能限制
WeChatWeAppFeatures.Notifications.PublishLimit,
WeChatWeAppFeatures.Notifications.PublishLimitInterval,
LimitPolicy.Month,
WeChatWeAppFeatures.Notifications.DefaultPublishLimit,
WeChatWeAppFeatures.Notifications.DefaultPublishLimitInterval
)]
public virtual async Task SendAsync(WeChatWeAppSendNotificationData notificationData, CancellationToken cancellationToken = default)
{
var weChatToken = await WeChatTokenProvider.GetTokenAsync(MiniProgramOptions.AppId, MiniProgramOptions.AppSecret, cancellationToken);
var requestParamters = new Dictionary<string, string>
{
{ "access_token", weChatToken.AccessToken }
};
var weChatSendNotificationUrl = "https://api.weixin.qq.com";
var weChatSendNotificationPath = "/cgi-bin/message/subscribe/send";
var requestUrl = BuildRequestUrl(weChatSendNotificationUrl, weChatSendNotificationPath, requestParamters);
var responseContent = await MakeRequestAndGetResultAsync(requestUrl, notificationData, cancellationToken);
var weChatSenNotificationResponse = JsonSerializer.Deserialize<WeChatSendNotificationResponse>(responseContent);
if (!weChatSenNotificationResponse.IsSuccessed)
{
Logger.LogWarning("Send wechat we app subscribe message failed");
Logger.LogWarning($"Error code: {weChatSenNotificationResponse.ErrorCode}, message: {weChatSenNotificationResponse.ErrorMessage}");
}
// 失败是否抛出异常
// weChatSenNotificationResponse.ThrowIfNotSuccess();
}
protected virtual async Task<string> MakeRequestAndGetResultAsync(string url, WeChatWeAppSendNotificationData notificationData, CancellationToken cancellationToken = default)
{
var client = HttpClientFactory.CreateClient(SendNotificationClientName);
var sendDataContent = JsonSerializer.Serialize(notificationData);
var requestContent = new StringContent(sendDataContent);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = requestContent
};
var response = await client.SendAsync(requestMessage, cancellationToken);
if (!response.IsSuccessStatusCode)
{
throw new AbpException($"WeChat send subscribe message http request service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
}
var resultContent = await response.Content.ReadAsStringAsync();
return resultContent;
}
protected virtual string BuildRequestUrl(string uri, string path, IDictionary<string, string> paramters)
{
var requestUrlBuilder = new StringBuilder(128);
requestUrlBuilder.Append(uri);
requestUrlBuilder.Append(path).Append("?");
foreach (var paramter in paramters)
{
requestUrlBuilder.AppendFormat("{0}={1}", paramter.Key, paramter.Value);
requestUrlBuilder.Append("&");
}
requestUrlBuilder.Remove(requestUrlBuilder.Length - 1, 1);
return requestUrlBuilder.ToString();
}
}
public class WeChatSendNotificationResponse
{
[JsonProperty("errcode")]
public int ErrorCode { get; set; }
[JsonProperty("errmsg")]
public string ErrorMessage { get; set; }
public bool IsSuccessed => ErrorCode == 0;
public void ThrowIfNotSuccess()
{
if (ErrorCode != 0)
{
throw new AbpException($"Send wechat weapp notification error:{ErrorMessage}");
}
}
}
}

103
aspnet-core/modules/wechat/LINGYUN.Abp.Notifications.WeChat/LINGYUN/Abp/Notifications/WeChat/WeApp/WeChatWeAppSendNotificationData.cs

@ -1,103 +0,0 @@
#pragma warning disable IDE1006 // 禁止编译器提示
using System.Collections.Generic;
namespace LINGYUN.Abp.Notifications.WeChat.WeApp
{
public class WeChatWeAppSendNotificationData
{
/// <summary>
/// 接收者(用户)的 openid
/// </summary>
public string touser { get; set; }
/// <summary>
/// 所需下发的订阅模板id
/// </summary>
public string template_id { get; set; }
/// <summary>
/// 点击模板卡片后的跳转页面,仅限本小程序内的页面。
/// 支持带参数,(示例index?foo=bar)。
/// 该字段不填则模板无跳转
/// </summary>
public string page { get; set; }
/// <summary>
/// 跳转小程序类型:
/// developer为开发版;trial为体验版;formal为正式版;
/// 默认为正式版
/// </summary>
public string miniprogram_state { get; set; }
/// <summary>
/// 进入小程序查看”的语言类型,
/// 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),
/// 默认为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 = "",
string state = "formal", string miniLang = "zh_CN")
{
touser = openId;
template_id = templateId;
page = redirectPage;
miniprogram_state = state;
lang = miniLang;
data = new Dictionary<string, WeChatNotificationData>();
}
/// <summary>
/// 写入标准数据
/// </summary>
/// <param name="writeData"></param>
/// <returns></returns>
public WeChatWeAppSendNotificationData WriteStandardData(NotificationData writeData)
{
foreach (var kv in writeData.Properties)
{
if (!data.ContainsKey(kv.Key))
{
data.Add(kv.Key, new WeChatNotificationData(kv.Value));
}
}
return this;
}
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;
}
}
}
#pragma warning restore IDE1006

24
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN.Abp.WeChat.Authorization.csproj

@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="3.1.8" />
<PackageReference Include="Volo.Abp.Caching" Version="3.3.0" />
<PackageReference Include="Volo.Abp.Json" Version="3.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\wechat\LINGYUN.Abp.WeChat\LINGYUN.Abp.WeChat.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="LINGYUN\Abp\WeChat\Authorization\OpenId\" />
</ItemGroup>
</Project>

72
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationConsts.cs

@ -1,72 +0,0 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
/// <summary>
/// 与微信认证相关的静态(可变)常量
/// </summary>
public static class AbpWeChatAuthorizationConsts
{
/// <summary>
/// 微信授权名称
/// </summary>
public const string AuthenticationScheme = "WeChat";
/// <summary>
/// 微信授权显示名称
/// </summary>
public static string DisplayName = "WeChat";
/// <summary>
/// 微信个人信息标识
/// </summary>
public static string ProfileKey { get; set; } = "wechat.profile";
/// <summary>
/// 微信提供者标识
/// </summary>
public static string ProviderKey { get; set; } = AuthenticationScheme;
/// <summary>
/// 回调地址
/// </summary>
public static string CallbackPath { get; set; } = "/signin-wechat";
/// <summary>
/// 微信客户端外的网页登录
/// </summary>
public const string QrConnectEndpoint = "https://open.weixin.qq.com/connect/qrconnect";
/// <summary>
/// 微信客户端内的网页登录
/// </summary>
public const string AuthorizationEndpoint = "https://open.weixin.qq.com/connect/oauth2/authorize";
/// <summary>
/// 用户允许授权后通过返回的code换取access_token地址
/// </summary>
public const string TokenEndpoint = "https://api.weixin.qq.com/sns/oauth2/access_token";
/// <summary>
/// 使用access_token获取用户个人信息地址
/// </summary>
public const string UserInformationEndpoint = "https://api.weixin.qq.com/sns/userinfo";
/// <summary>
/// 弹出授权页面,可通过openid拿到昵称、性别、所在地。
/// 并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
/// <br />
/// <br />
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
/// <remarks>
/// 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。
/// 但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息
/// </remarks>
public const string UserInfoScope = "snsapi_userinfo";
/// <summary>
/// 不弹出授权页面,直接跳转,只能获取用户openid
/// <br />
/// <br />
/// 详询: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
/// <remarks>
/// 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。
/// 用户感知的就是直接进入了回调页(往往是业务页面)
/// </remarks>
public const string LoginScope = "snsapi_login";
}
}

28
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationModule.cs

@ -1,28 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Polly;
using System;
using Volo.Abp.Caching;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WeChat.Authorization
{
[DependsOn(
typeof(AbpWeChatModule),
typeof(AbpJsonModule),
typeof(AbpCachingModule))]
public class AbpWeChatAuthorizationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpWeChatAuthorizationOptions>(configuration.GetSection("WeChat:Auth"));
context.Services.AddHttpClient("WeChatRequestClient", options =>
{
options.BaseAddress = new Uri("https://api.weixin.qq.com");
}).AddTransientHttpErrorPolicy(builder =>
builder.WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))));
}
}
}

9
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationOptions.cs

@ -1,9 +0,0 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
public class AbpWeChatAuthorizationOptions
{
public string AppId { get; set; }
public string AppSecret { get; set; }
}
}

47
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatAuthorizationOptionsFactory.cs

@ -1,47 +0,0 @@
using LINGYUN.Abp.WeChat.Authorization.Settings;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Options;
using Volo.Abp.Settings;
using Volo.Abp.Threading;
namespace LINGYUN.Abp.WeChat.Authorization
{
public class AbpWeChatAuthorizationOptionsFactory : AbpOptionsFactory<AbpWeChatAuthorizationOptions>
{
protected ISettingProvider SettingProvider { get; }
public AbpWeChatAuthorizationOptionsFactory(
ISettingProvider settingProvider,
IEnumerable<IConfigureOptions<AbpWeChatAuthorizationOptions>> setups,
IEnumerable<IPostConfigureOptions<AbpWeChatAuthorizationOptions>> postConfigures)
: base(setups, postConfigures)
{
SettingProvider = settingProvider;
}
public override AbpWeChatAuthorizationOptions Create(string name)
{
var options = base.Create(name);
OverrideOptions(options);
return options;
}
protected virtual void OverrideOptions(AbpWeChatAuthorizationOptions options)
{
AsyncHelper.RunSync(() => OverrideOptionsAsync(options));
}
protected virtual async Task OverrideOptionsAsync(AbpWeChatAuthorizationOptions options)
{
var appId = await SettingProvider.GetOrNullAsync(WeChatAuthorizationSettingNames.AppId);
var appSecret = await SettingProvider.GetOrNullAsync(WeChatAuthorizationSettingNames.AppSecret);
options.AppId = appId ?? options.AppId;
options.AppSecret = appSecret ?? options.AppSecret;
}
}
}

48
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/AbpWeChatClaimTypes.cs

@ -1,48 +0,0 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
/// <summary>
/// 微信认证身份类型,可以像 <see cref="Volo.Abp.Security.Claims.AbpClaimTypes"/> 自行配置
/// <br />
/// See: <see cref="https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html"/>
/// </summary>
public class AbpWeChatClaimTypes
{
/// <summary>
/// 用户的唯一标识
/// </summary>
public static string OpenId { get; set; } = "wx-openid"; // 可变更
/// <summary>
/// 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
/// </summary>
public static string UnionId { get; set; } = "wx-unionid"; //可变更
/// <summary>
/// 用户昵称
/// </summary>
public static string NickName { get; set; } = "nickname";
/// <summary>
/// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
/// </summary>
public static string Sex { get; set; } = "sex";
/// <summary>
/// 国家,如中国为CN
/// </summary>
public static string Country { get; set; } = "country";
/// <summary>
/// 用户个人资料填写的省份
/// </summary>
public static string Province { get; set; } = "province";
/// <summary>
/// 普通用户个人资料填写的城市
/// </summary>
public static string City { get; set; } = "city";
/// <summary>
/// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。
/// 若用户更换头像,原有头像URL将失效。
/// </summary>
public static string AvatarUrl { get; set; } = "avatar";
/// <summary>
/// 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
/// </summary>
public static string Privilege { get; set; } = "privilege";
}
}

11
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Settings/WeChatAuthorizationSettingNames.cs

@ -1,11 +0,0 @@
using LINGYUN.Abp.WeChat.Settings;
namespace LINGYUN.Abp.WeChat.Authorization.Settings
{
public class WeChatAuthorizationSettingNames
{
private const string Prefix = WeChatSettingNames.Prefix + ".Authorization";
public static string AppId = Prefix + "." + nameof(AbpWeChatAuthorizationOptions.AppId);
public static string AppSecret = Prefix + "." + nameof(AbpWeChatAuthorizationOptions.AppSecret);
}
}

32
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Settings/WeChatAuthorizationSettingProvider.cs

@ -1,32 +0,0 @@
using LINGYUN.Abp.WeChat.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.WeChat.Authorization.Settings
{
public class WeChatAuthorizationSettingProvider : SettingDefinitionProvider
{
public override void Define(ISettingDefinitionContext context)
{
context.Add(
new SettingDefinition(
WeChatAuthorizationSettingNames.AppId, "",
L("DisplayName:WeChat.Auth.AppId"),
L("Description:WeChat.Auth.AppId"),
isVisibleToClients: true,
isEncrypted: true),
new SettingDefinition(
WeChatAuthorizationSettingNames.AppSecret, "",
L("DisplayName:WeChat.Auth.AppSecret"),
L("Description:WeChat.Auth.AppSecret"),
isVisibleToClients: true,
isEncrypted: true)
);
}
protected ILocalizableString L(string name)
{
return LocalizableString.Create<WeChatResource>(name);
}
}
}

10
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/IWeChatTokenProvider.cs

@ -1,10 +0,0 @@
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Authorization
{
public interface IWeChatTokenProvider
{
Task<WeChatToken> GetTokenAsync(CancellationToken cancellationToken = default);
}
}

26
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatToken.cs

@ -1,26 +0,0 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
/// <summary>
/// 微信令牌
/// </summary>
public class WeChatToken
{
/// <summary>
/// 访问令牌
/// </summary>
public string AccessToken { get; set; }
/// <summary>
/// 过期时间,单位(s)
/// </summary>
public int ExpiresIn { get; set; }
public WeChatToken()
{
}
public WeChatToken(string token, int expiresIn)
{
AccessToken = token;
ExpiresIn = expiresIn;
}
}
}

24
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenCacheItem.cs

@ -1,24 +0,0 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
public class WeChatTokenCacheItem
{
public string AppId { get; set; }
public WeChatToken WeChatToken { get; set; }
public WeChatTokenCacheItem()
{
}
public WeChatTokenCacheItem(string appId, WeChatToken weChatToken)
{
AppId = appId;
WeChatToken = weChatToken;
}
public static string CalculateCacheKey(string provider, string appId)
{
return "p:" + provider + ",o:" + appId;
}
}
}

89
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenProvider.cs

@ -1,89 +0,0 @@
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace LINGYUN.Abp.WeChat.Authorization
{
public class WeChatTokenProvider : IWeChatTokenProvider, ISingletonDependency
{
public ILogger<WeChatTokenProvider> Logger { get; set; }
protected IHttpClientFactory HttpClientFactory { get; }
protected IJsonSerializer JsonSerializer { get; }
protected IDistributedCache<WeChatTokenCacheItem> Cache { get; }
protected AbpWeChatAuthorizationOptions Options { get; }
public WeChatTokenProvider(
IJsonSerializer jsonSerializer,
IHttpClientFactory httpClientFactory,
IOptions<AbpWeChatAuthorizationOptions> options,
IDistributedCache<WeChatTokenCacheItem> cache)
{
JsonSerializer = jsonSerializer;
HttpClientFactory = httpClientFactory;
Cache = cache;
Options = options.Value;
Logger = NullLogger<WeChatTokenProvider>.Instance;
}
public virtual async Task<WeChatToken> GetTokenAsync(CancellationToken cancellationToken = default)
{
return (await GetCacheItemAsync("WeChatToken", Options.AppId, cancellationToken)).WeChatToken;
}
protected virtual async Task<WeChatTokenCacheItem> GetCacheItemAsync(string provider, string appId, CancellationToken cancellationToken = default)
{
var cacheKey = WeChatTokenCacheItem.CalculateCacheKey(provider, appId);
Logger.LogDebug($"WeChatTokenProvider.GetCacheItemAsync: {cacheKey}");
var cacheItem = await Cache.GetAsync(cacheKey, token: cancellationToken);
if (cacheItem != null)
{
Logger.LogDebug($"Found in the cache: {cacheKey}");
return cacheItem;
}
Logger.LogDebug($"Not found in the cache, getting from the httpClient: {cacheKey}");
var client = HttpClientFactory.CreateClient("WeChatRequestClient");
var request = new WeChatTokenRequest
{
BaseUrl = client.BaseAddress.AbsoluteUri,
AppSecret = Options.AppSecret,
AppId = Options.AppId,
GrantType = "client_credential"
};
var response = await client.RequestWeChatCodeTokenAsync(request, cancellationToken);
var responseContent = await response.Content.ReadAsStringAsync();
var weChatTokenResponse = JsonSerializer.Deserialize<WeChatTokenResponse>(responseContent);
var weChatToken = weChatTokenResponse.ToWeChatToken();
cacheItem = new WeChatTokenCacheItem(appId, weChatToken);
Logger.LogDebug($"Setting the cache item: {cacheKey}");
var cacheOptions = new DistributedCacheEntryOptions
{
// 设置绝对过期时间为Token有效期剩余的二分钟
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(weChatToken.ExpiresIn - 120)
};
await Cache.SetAsync(cacheKey, cacheItem, cacheOptions, token: cancellationToken);
Logger.LogDebug($"Finished setting the cache item: {cacheKey}");
return cacheItem;
}
}
}

10
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenRequest.cs

@ -1,10 +0,0 @@
namespace LINGYUN.Abp.WeChat.Authorization
{
public class WeChatTokenRequest
{
public string BaseUrl { get; set; }
public string GrantType { get; set; }
public string AppId { get; set; }
public string AppSecret { get; set; }
}
}

41
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/LINGYUN/Abp/WeChat/Authorization/Token/WeChatTokenResponse.cs

@ -1,41 +0,0 @@
using Newtonsoft.Json;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Authorization
{
/// <summary>
/// 微信访问令牌返回对象
/// </summary>
public class WeChatTokenResponse
{
/// <summary>
/// 错误码
/// </summary>
[JsonProperty("errcode")]
public int ErrorCode { get; set; }
/// <summary>
/// 错误消息
/// </summary>
[JsonProperty("errmsg")]
public string ErrorMessage { get; set; }
/// <summary>
/// 访问令牌
/// </summary>
[JsonProperty("access_token")]
public string AccessToken { get; set; }
/// <summary>
/// 过期时间,单位(s)
/// </summary>
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
public WeChatToken ToWeChatToken()
{
if(ErrorCode != 0)
{
throw new AbpException(ErrorMessage);
}
return new WeChatToken(AccessToken, ExpiresIn);
}
}
}

17
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/README.md

@ -1,17 +0,0 @@
# LINGYUN.Abp.WeChat.Authorization
废弃模块,模块层次不清晰,微信有多端平台,不同平台授权规则不一致
#### 注意
## 配置使用
```csharp
[DependsOn(typeof(AbpWeChatAuthorizationModule))]
public class YouProjectModule : AbpModule
{
// other
}

45
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/System/Net/Http/HttpClientWeChatTokenRequestExtensions.cs

@ -1,45 +0,0 @@
using LINGYUN.Abp.WeChat.Authorization;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace System.Net.Http
{
public static class HttpClientWeChatTokenRequestExtensions
{
public static async Task<HttpResponseMessage> RequestWeChatCodeTokenAsync(this HttpMessageInvoker client, WeChatTokenRequest request, CancellationToken cancellationToken = default)
{
var getResuestUrlBuilder = new StringBuilder();
getResuestUrlBuilder.Append(request.BaseUrl);
getResuestUrlBuilder.Append("cgi-bin/token");
getResuestUrlBuilder.Append("?grant_type=client_credential");
getResuestUrlBuilder.AppendFormat("&appid={0}", request.AppId);
getResuestUrlBuilder.AppendFormat("&secret={0}", request.AppSecret);
var getRequest = new HttpRequestMessage(HttpMethod.Get, getResuestUrlBuilder.ToString());
HttpResponseMessage httpResponse;
httpResponse = await client.SendAsync(getRequest, cancellationToken).ConfigureAwait(false);
return httpResponse;
}
public static async Task<HttpResponseMessage> RequestWeChatOpenIdAsync(this HttpMessageInvoker client, WeChatOpenIdRequest request, CancellationToken cancellationToken = default)
{
var getResuestUrlBuiilder = new StringBuilder();
getResuestUrlBuiilder.Append(request.BaseUrl);
getResuestUrlBuiilder.Append("sns/jscode2session");
getResuestUrlBuiilder.AppendFormat("?appid={0}", request.AppId);
getResuestUrlBuiilder.AppendFormat("&secret={0}", request.Secret);
getResuestUrlBuiilder.AppendFormat("&js_code={0}", request.Code);
getResuestUrlBuiilder.Append("&grant_type=authorization_code");
var getRequest = new HttpRequestMessage(HttpMethod.Get, getResuestUrlBuiilder.ToString());
HttpResponseMessage httpResponse;
httpResponse = await client.SendAsync(getRequest, cancellationToken).ConfigureAwait(false);
return httpResponse;
}
}
}

39
aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Authorization/Volo/Abp/Users/CurrentUserExtensions.cs

@ -1,39 +0,0 @@
using LINGYUN.Abp.WeChat.Authorization;
namespace Volo.Abp.Users
{
public static class CurrentUserExtensions
{
/// <summary>
/// 获取用户微信id,如果不存在返回空值
/// </summary>
/// <param name="currentUser"></param>
/// <returns></returns>
public static string FindWeChatOpenId(this ICurrentUser currentUser)
{
var weChatClaim = currentUser.FindClaim(AbpWeChatClaimTypes.OpenId);
if (weChatClaim == null)
{
return null;
}
return weChatClaim.Value;
}
/// <summary>
/// 获取微信用户主体id,如果不存在返回空值
/// </summary>
/// <param name="currentUser"></param>
/// <returns></returns>
public static string FindWeChatUnionId(this ICurrentUser currentUser)
{
var weChatClaim = currentUser.FindClaim(AbpWeChatClaimTypes.UnionId);
if (weChatClaim == null)
{
return null;
}
return weChatClaim.Value;
}
}
}

6
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/AbpMessageServiceHttpApiHostModule.cs

@ -13,7 +13,8 @@ using LINGYUN.Abp.MessageService.Localization;
using LINGYUN.Abp.MessageService.MultiTenancy;
using LINGYUN.Abp.MultiTenancy.DbFinder;
using LINGYUN.Abp.Notifications.SignalR;
using LINGYUN.Abp.Notifications.WeChat.WeApp;
using LINGYUN.Abp.Notifications.Sms;
using LINGYUN.Abp.Notifications.WeChat.MiniProgram;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors;
@ -58,8 +59,9 @@ namespace LINGYUN.Abp.MessageService
typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpIMSignalRModule),
typeof(AbpNotificationsSmsModule),
typeof(AbpNotificationsSignalRModule),
typeof(AbpNotificationsWeChatWeAppModule),
typeof(AbpNotificationsWeChatMiniProgramModule),
typeof(AbpNotificationsExceptionHandlingModule),
typeof(AbpAspNetCoreSignalRProtocolJsonModule),
typeof(AbpCAPEventBusModule),

16
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/NotificationEventHandler.cs

@ -89,6 +89,16 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
[UnitOfWork]
public virtual async Task HandleEventAsync(NotificationEventData eventData)
{
// 这样做的话就要注意了
// 当只有一个消费者订阅时,事件总线会认为消息已经处理,从而发布Ack指令,从消息队列中移除此消息
// 可能造成通知数据丢失
var application = Options.Application ?? "Abp";
if (application.Equals(Options.Application))
{
// 不是当前监听应用的消息不做处理
return;
}
// 如果上面过滤了应用程序,这里可以使用Get方法,否则,最好使用GetOrNull加以判断
var notification = NotificationDefinitionManager.Get(eventData.Name);
var notificationInfo = new NotificationInfo
@ -103,6 +113,7 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
};
notificationInfo.SetId(SnowflakeIdGenerator.Create());
// TODO: 可以做成一个接口来序列化消息
notificationInfo.Data = NotificationDataConverter.Convert(notificationInfo.Data);
Logger.LogDebug($"Persistent notification {notificationInfo.Name}");
@ -189,7 +200,7 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
{
Logger.LogDebug($"Sending notification with provider {provider.Name}");
var notifacationDataMapping = Options.NotificationDataMappings
.GetMapItemOrNull(notificationInfo.Name, provider.Name);
.GetMapItemOrDefault(notificationInfo.Name, provider.Name);
if (notifacationDataMapping != null)
{
notificationInfo.Data = notifacationDataMapping.MappingFunc(notificationInfo.Data);
@ -209,7 +220,8 @@ namespace LINGYUN.Abp.MessageService.EventBus.Distributed
Logger.LogDebug($"Send notification error, notification {notificationInfo.Name} entry queue");
// 发送失败的消息进入后台队列
await BackgroundJobManager.EnqueueAsync(
new NotificationPublishJobArgs(notificationInfo.GetId(),
new NotificationPublishJobArgs(
notificationInfo.GetId(),
provider.GetType().AssemblyQualifiedName,
subscriptionUserIdentifiers.ToList(),
notificationInfo.TenantId));

3
aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/LINGYUN.Abp.MessageService.HttpApi.Host.csproj

@ -49,12 +49,13 @@
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.EventBus.CAP\LINGYUN.Abp.EventBus.CAP.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.IM.SignalR\LINGYUN.Abp.IM.SignalR.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Notifications.SignalR\LINGYUN.Abp.Notifications.SignalR.csproj" />
<ProjectReference Include="..\..\..\modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj" />
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.Application\LINGYUN.Abp.MessageService.Application.csproj" />
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.EntityFrameworkCore\LINGYUN.Abp.MessageService.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\modules\message\LINGYUN.Abp.MessageService.HttpApi\LINGYUN.Abp.MessageService.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy.DbFinder\LINGYUN.Abp.MultiTenancy.DbFinder.csproj" />
<ProjectReference Include="..\..\..\modules\tenants\LINGYUN.Abp.MultiTenancy\LINGYUN.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\..\..\modules\wechat\LINGYUN.Abp.Notifications.WeChat\LINGYUN.Abp.Notifications.WeChat.WeApp.csproj" />
<ProjectReference Include="..\..\..\modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj" />
</ItemGroup>
</Project>

24
aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN.Abp.Notifications.Sms.Tests.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="NSubstitute" Version="4.2.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Notifications.Sms\LINGYUN.Abp.Notifications.Sms.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

8
aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsTestsBase.cs

@ -0,0 +1,8 @@
using LINGYUN.Abp.Tests;
namespace LINGYUN.Abp.Notifications.Sms
{
public class AbpNotificationsSmsTestsBase : AbpTestsBase<AbpNotificationsSmsTestsModule>
{
}
}

42
aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/AbpNotificationsSmsTestsModule.cs

@ -0,0 +1,42 @@
using LINGYUN.Abp.Tests;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.Sms
{
[DependsOn(
typeof(AbpNotificationsSmsModule),
typeof(AbpNotificationsTestsModule),
typeof(AbpTestsBaseModule))]
public class AbpNotificationsSmsTestsModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
// 改变默认数据前缀方法
PreConfigure<AbpNotificationsSmsOptions>(options =>
{
options.TemplateParamsPrefix = "[sms-override]";
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
// 自定义数据处理方法
Configure<AbpNotificationOptions>(options =>
{
// 这条通知返回标准化的通知
options.NotificationDataMappings
.Mapping(
SmsNotificationPublishProvider.ProviderName,
NotificationsTestsNames.Test2,
data => NotificationData.ToStandardData(data));
// 这条通知不做任何处理
options.NotificationDataMappings
.Mapping(
SmsNotificationPublishProvider.ProviderName,
NotificationsTestsNames.Test3,
data => data);
});
}
}
}

82
aspnet-core/tests/LINGYUN.Abp.Notifications.Sms.Tests/LINGYUN/Abp/Notifications/Sms/SmsNotificationDataMapping_Tests.cs

@ -0,0 +1,82 @@
using Microsoft.Extensions.Options;
using Shouldly;
using System;
using Xunit;
namespace LINGYUN.Abp.Notifications.Sms
{
public class SmsNotificationDataMapping_Tests : AbpNotificationsSmsTestsBase
{
private readonly NotificationData _notificationData;
protected AbpNotificationOptions NotificationOptions { get; }
protected AbpNotificationsSmsOptions NotificationSmsOptions { get; }
public SmsNotificationDataMapping_Tests()
{
NotificationOptions = GetRequiredService<IOptions<AbpNotificationOptions>>().Value;
NotificationSmsOptions = GetRequiredService<IOptions<AbpNotificationsSmsOptions>>().Value;
_notificationData = new NotificationData();
InitNotificationData(_notificationData);
}
private void InitNotificationData(NotificationData data)
{
data.WriteStandardData("title", "message", DateTime.Now, "formUser", "description");
data.WriteStandardData(NotificationSmsOptions.TemplateParamsPrefix, "phoneNumber", "13800138000");
data.WriteStandardData(NotificationSmsOptions.TemplateParamsPrefix, "template", "SM_202011250901");
data.TrySetData("otherDataKey", "otherDataValue");
}
[Fact]
public void Mapping_Sms_Notification_Data_Test()
{
var mappingSmsItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test1);
mappingSmsItem.ShouldNotBeNull();
var mappingSmsData = mappingSmsItem.MappingFunc(_notificationData);
mappingSmsData.TryGetData("phoneNumber").ShouldNotBeNull();
mappingSmsData.TryGetData("phoneNumber").ToString().ShouldBe("13800138000");
mappingSmsData.TryGetData("template").ShouldNotBeNull();
mappingSmsData.TryGetData("template").ToString().ShouldBe("SM_202011250901");
// 按照预定义规则,这条数据被丢弃
mappingSmsData.TryGetData("otherDataKey").ShouldBeNull();
}
[Fact]
public void Mapping_Standard_Notification_Data_Test()
{
var mappingStandardItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test2);
var mappingStandardData = mappingStandardItem.MappingFunc(_notificationData);
// 按照自定义规则,其他数据被丢弃
mappingStandardData.TryGetData("phoneNumber").ShouldBeNull();
mappingStandardData.TryGetData("template").ShouldBeNull();
mappingStandardData.TryGetData("otherDataKey").ShouldBeNull();
mappingStandardData.Properties.Count.ShouldBe(6);
}
[Fact]
public void Mapping_Origin_Notification_Data_Test()
{
var mappingOriginItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(SmsNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test3);
var mappingOriginData = mappingOriginItem.MappingFunc(_notificationData);
// 按照自定义规则,所有数据被保留
mappingOriginData.TryGetData(NotificationSmsOptions.TemplateParamsPrefix + "phoneNumber").ShouldNotBeNull();
mappingOriginData.TryGetData(NotificationSmsOptions.TemplateParamsPrefix + "template").ShouldNotBeNull();
mappingOriginData.TryGetData("otherDataKey").ShouldNotBeNull();
mappingOriginData.Properties.Count.ShouldBe(9);
}
}
}

23
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN.Abp.Notifications.Tests.csproj

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="NSubstitute" Version="4.2.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

8
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/AbpNotificationsTestsBase.cs

@ -0,0 +1,8 @@
using LINGYUN.Abp.Tests;
namespace LINGYUN.Abp.Notifications
{
public class AbpNotificationsTestsBase : AbpTestsBase<AbpNotificationsTestsModule>
{
}
}

13
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/AbpNotificationsTestsModule.cs

@ -0,0 +1,13 @@
using LINGYUN.Abp.Tests;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications
{
[DependsOn(
typeof(AbpNotificationModule),
typeof(AbpTestsBaseModule))]
public class AbpNotificationsTestsModule : AbpModule
{
}
}

22
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider.cs

@ -0,0 +1,22 @@
namespace LINGYUN.Abp.Notifications
{
public class NotificationsTestsDefinitionProvider : NotificationDefinitionProvider
{
public override void Define(INotificationDefinitionContext context)
{
var group = context.AddGroup(NotificationsTestsNames.GroupName);
group.AddNotification(NotificationsTestsNames.Test1,
notificationType: NotificationType.Application,
lifetime: NotificationLifetime.OnlyOne);
group.AddNotification(NotificationsTestsNames.Test2,
notificationType: NotificationType.Application,
lifetime: NotificationLifetime.Persistent);
group.AddNotification(NotificationsTestsNames.Test3,
notificationType: NotificationType.User,
lifetime: NotificationLifetime.OnlyOne);
}
}
}

51
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider_Tests.cs

@ -0,0 +1,51 @@
using Shouldly;
using Volo.Abp.Localization;
using Xunit;
namespace LINGYUN.Abp.Notifications
{
public class NotificationsTestsDefinitionProvider_Tests : AbpNotificationsTestsBase
{
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
public NotificationsTestsDefinitionProvider_Tests()
{
NotificationDefinitionManager = GetRequiredService<INotificationDefinitionManager>();
}
[Fact]
public void GetGroups_Test()
{
var groups = NotificationDefinitionManager.GetGroups();
groups.Count.ShouldBe(1);
}
[Fact]
public void GetAll_Test()
{
var notifications = NotificationDefinitionManager.GetAll();
notifications.Count.ShouldBe(3);
}
[Fact]
public void GetOrNull_Test()
{
NotificationDefinitionManager.GetOrNull(NotificationsTestsNames.Test2).ShouldNotBeNull();
NotificationDefinitionManager.GetOrNull(NotificationsTestsNames.Test3).ShouldNotBeNull();
NotificationDefinitionManager.GetOrNull("NullOfNotification").ShouldBeNull();
}
[Theory]
[InlineData(NotificationsTestsNames.Test1)]
public void Get_Test(string name)
{
var notification = NotificationDefinitionManager.Get(name);
notification.Name.ShouldBe(name);
notification.DisplayName.ShouldBeOfType<FixedLocalizableString>();
notification.Description.ShouldBeNull();
notification.AllowSubscriptionToClients.ShouldBeFalse();
notification.NotificationLifetime.ShouldBe(NotificationLifetime.OnlyOne);
notification.NotificationType.ShouldBe(NotificationType.Application);
}
}
}

13
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs

@ -0,0 +1,13 @@
namespace LINGYUN.Abp.Notifications
{
public static class NotificationsTestsNames
{
public const string GroupName = "Abp.Notifications";
public const string Test1 = GroupName + ".Test1";
public const string Test2 = GroupName + ".Test2";
public const string Test3 = GroupName + ".Test3";
}
}

24
aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="NSubstitute" Version="4.2.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\wechat\LINGYUN.Abp.Notifications.WeChat.MiniProgram\LINGYUN.Abp.Notifications.WeChat.MiniProgram.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

8
aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramTestsBase.cs

@ -0,0 +1,8 @@
using LINGYUN.Abp.Tests;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
public class AbpNotificationsWeChatMiniProgramTestsBase : AbpTestsBase<AbpNotificationsWeChatMiniProgramTestsModule>
{
}
}

41
aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/MiniProgram/AbpNotificationsWeChatMiniProgramTestsModule.cs

@ -0,0 +1,41 @@
using LINGYUN.Abp.Tests;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
[DependsOn(
typeof(AbpNotificationsWeChatMiniProgramModule),
typeof(AbpNotificationsTestsModule),
typeof(AbpTestsBaseModule))]
public class AbpNotificationsWeChatMiniProgramTestsModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpNotificationsWeChatMiniProgramOptions>(options =>
{
options.DefaultMsgPrefix = "[wmp-override]";
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
// 自定义数据处理方法
Configure<AbpNotificationOptions>(options =>
{
// 这条通知返回标准化的通知
options.NotificationDataMappings
.Mapping(
WeChatMiniProgramNotificationPublishProvider.ProviderName,
NotificationsTestsNames.Test2,
data => NotificationData.ToStandardData(data));
// 这条通知不做任何处理
options.NotificationDataMappings
.Mapping(
WeChatMiniProgramNotificationPublishProvider.ProviderName,
NotificationsTestsNames.Test3,
data => data);
});
}
}
}

77
aspnet-core/tests/LINGYUN.Abp.Notifications.WeChat.MiniProgram.Tests/LINGYUN/Abp/Notifications/WeChat/WeChatMiniProgramNotificationDataMapping_Tests.cs

@ -0,0 +1,77 @@
using Microsoft.Extensions.Options;
using Shouldly;
using System;
using Xunit;
namespace LINGYUN.Abp.Notifications.WeChat.MiniProgram
{
public class WeChatMiniProgramNotificationDataMapping_Tests : AbpNotificationsWeChatMiniProgramTestsBase
{
private readonly NotificationData _notificationData;
protected AbpNotificationOptions NotificationOptions { get; }
protected AbpNotificationsWeChatMiniProgramOptions NotificationWeChatMiniProgramOptions { get; }
public WeChatMiniProgramNotificationDataMapping_Tests()
{
NotificationOptions = GetRequiredService<IOptions<AbpNotificationOptions>>().Value;
NotificationWeChatMiniProgramOptions = GetRequiredService<IOptions<AbpNotificationsWeChatMiniProgramOptions>>().Value;
_notificationData = new NotificationData();
InitNotificationData(_notificationData);
}
private void InitNotificationData(NotificationData data)
{
data.WriteStandardData("title", "message", DateTime.Now, "formUser", "description");
data.WriteStandardData(NotificationWeChatMiniProgramOptions.DefaultMsgPrefix, "openid", "TEST");
data.TrySetData("otherDataKey", "otherDataValue");
}
[Fact]
public void Mapping_WeChatMiniProgram_Notification_Data_Test()
{
var mappingOpenIdItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test1);
mappingOpenIdItem.ShouldNotBeNull();
var mappingOpenIdData = mappingOpenIdItem.MappingFunc(_notificationData);
mappingOpenIdData.TryGetData("openid").ShouldNotBeNull();
mappingOpenIdData.TryGetData("openid").ToString().ShouldBe("TEST");
// 按照预定义规则,这条数据被丢弃
mappingOpenIdData.TryGetData("otherDataKey").ShouldBeNull();
}
[Fact]
public void Mapping_Standard_Notification_Data_Test()
{
var mappingStandardItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test2);
var mappingStandardData = mappingStandardItem.MappingFunc(_notificationData);
// 按照自定义规则,其他数据被丢弃
mappingStandardData.TryGetData("openid").ShouldBeNull();
mappingStandardData.TryGetData("otherDataKey").ShouldBeNull();
mappingStandardData.Properties.Count.ShouldBe(6);
}
[Fact]
public void Mapping_Origin_Notification_Data_Test()
{
var mappingOriginItem = NotificationOptions
.NotificationDataMappings
.GetMapItemOrDefault(WeChatMiniProgramNotificationPublishProvider.ProviderName, NotificationsTestsNames.Test3);
var mappingOriginData = mappingOriginItem.MappingFunc(_notificationData);
// 按照自定义规则,所有数据被保留
mappingOriginData.TryGetData(NotificationWeChatMiniProgramOptions.DefaultMsgPrefix + "openid").ShouldNotBeNull();
mappingOriginData.TryGetData("otherDataKey").ShouldNotBeNull();
mappingOriginData.Properties.Count.ShouldBe(8);
}
}
}
Loading…
Cancel
Save